mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 08:12:17 +01:00
add TimeEntryCreateModal and MoreOptionsDropdown to ui package
This commit is contained in:
@@ -24,7 +24,7 @@ import { useProjectsStore } from '@/utils/useProjects';
|
||||
import TimeEntryGroupedTable from '@/packages/ui/src/TimeEntry/TimeEntryGroupedTable.vue';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import TimeEntryCreateModal from '@/Components/Common/TimeEntry/TimeEntryCreateModal.vue';
|
||||
import TimeEntryCreateModal from '@/packages/ui/src/TimeEntry/TimeEntryCreateModal.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import TimeEntryMassActionRow from '@/packages/ui/src/TimeEntry/TimeEntryMassActionRow.vue';
|
||||
import type { UpdateMultipleTimeEntriesChangeset } from '@/packages/api/src';
|
||||
@@ -123,7 +123,12 @@ function deleteSelected() {
|
||||
:enableEstimatedTime="isAllowedToPerformPremiumAction()"
|
||||
:createProject="createProject"
|
||||
:createClient="createClient"
|
||||
:createTag="createTag"
|
||||
:createTimeEntry="createTimeEntry"
|
||||
:projects
|
||||
:tasks
|
||||
:tags
|
||||
:clients
|
||||
v-model:show="showManualTimeEntryModal"></TimeEntryCreateModal>
|
||||
<AppLayout title="Dashboard" data-testid="time_view">
|
||||
<MainContainer
|
||||
|
||||
2
resources/js/packages/ui/package-lock.json
generated
2
resources/js/packages/ui/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@solidtime/ui",
|
||||
"version": "0.0.9",
|
||||
"version": "0.0.10",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@solidtime/ui",
|
||||
"version": "0.0.9",
|
||||
"version": "0.0.10",
|
||||
"description": "Package containing the solidtime ui components",
|
||||
"main": "./dist/solidtime-ui-lib.umd.cjs",
|
||||
"module": "./dist/solidtime-ui-lib.js",
|
||||
|
||||
@@ -90,7 +90,12 @@ const emit = defineEmits(['changed']);
|
||||
|
||||
useFocus(timeInput, { initialValue: props.focus });
|
||||
|
||||
const getStartOptions = computed(() => {
|
||||
type TimeOption = {
|
||||
timestamp: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
const getStartOptions = computed<TimeOption[]>(() => {
|
||||
// options for the entire day in 15 minute intervals
|
||||
const options = [];
|
||||
for (let hour = 0; hour < 24; hour++) {
|
||||
@@ -141,8 +146,8 @@ const closestValue = computed({
|
||||
:class="twMerge('mine-w-0 w-24', size === 'large' && 'w-28')"
|
||||
v-model="closestValue"
|
||||
v-model:open="open"
|
||||
:get-key-from-item="(item) => item.timestamp"
|
||||
:get-name-for-item="(item) => item.name"
|
||||
:get-key-from-item="(item: TimeOption) => item.timestamp"
|
||||
:get-name-for-item="(item: TimeOption) => item.name"
|
||||
:items="getStartOptions">
|
||||
<template #trigger>
|
||||
<TextInput
|
||||
|
||||
@@ -5,17 +5,12 @@ import DialogModal from '@/packages/ui/src/DialogModal.vue';
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import PrimaryButton from '@/packages/ui/src/Buttons/PrimaryButton.vue';
|
||||
import TimeTrackerProjectTaskDropdown from '@/packages/ui/src/TimeTracker/TimeTrackerProjectTaskDropdown.vue';
|
||||
import { getCurrentUserId } from '@/utils/useUser';
|
||||
import InputLabel from '@/packages/ui/src/Input/InputLabel.vue';
|
||||
import { TagIcon } from '@heroicons/vue/20/solid';
|
||||
import {
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/packages/ui/src/utils/time';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useTasksStore } from '@/utils/useTasks';
|
||||
import { useProjectsStore } from '@/utils/useProjects';
|
||||
import { useTagsStore } from '@/utils/useTags';
|
||||
import type {
|
||||
CreateClientBody,
|
||||
CreateProjectBody,
|
||||
@@ -23,24 +18,18 @@ import type {
|
||||
Client,
|
||||
CreateTimeEntryBody,
|
||||
} from '@/packages/api/src';
|
||||
import { useClientsStore } from '@/utils/useClients';
|
||||
import TimePicker from '@/packages/ui/src/Input/TimePicker.vue';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import { canCreateProjects } from '@/utils/permissions';
|
||||
import TagDropdown from '@/packages/ui/src/Tag/TagDropdown.vue';
|
||||
import { Badge } from '@/packages/ui/src';
|
||||
import BillableIcon from '@/packages/ui/src/Icons/BillableIcon.vue';
|
||||
import SelectDropdown from '../../../packages/ui/src/Input/SelectDropdown.vue';
|
||||
import SelectDropdown from '@/packages/ui/src/Input/SelectDropdown.vue';
|
||||
import DatePicker from '@/packages/ui/src/Input/DatePicker.vue';
|
||||
import DurationHumanInput from '@/packages/ui/src/Input/DurationHumanInput.vue';
|
||||
|
||||
import { InformationCircleIcon } from '@heroicons/vue/20/solid';
|
||||
const projectStore = useProjectsStore();
|
||||
const { projects } = storeToRefs(projectStore);
|
||||
const taskStore = useTasksStore();
|
||||
const { tasks } = storeToRefs(taskStore);
|
||||
const clientStore = useClientsStore();
|
||||
const { clients } = storeToRefs(clientStore);
|
||||
import type { Tag, Task } from '@/packages/api';
|
||||
|
||||
const show = defineModel('show', { default: false });
|
||||
const saving = ref(false);
|
||||
@@ -52,6 +41,11 @@ const props = defineProps<{
|
||||
) => Promise<void>;
|
||||
createClient: (client: CreateClientBody) => Promise<Client | undefined>;
|
||||
createProject: (project: CreateProjectBody) => Promise<Project | undefined>;
|
||||
createTag: (name: string) => Promise<Tag | undefined>;
|
||||
tags: Tag[];
|
||||
projects: Project[];
|
||||
tasks: Task[];
|
||||
clients: Client[];
|
||||
}>();
|
||||
|
||||
const description = ref<HTMLInputElement | null>(null);
|
||||
@@ -72,7 +66,6 @@ const timeEntryDefaultValues = {
|
||||
billable: false,
|
||||
start: getDayJsInstance().utc().subtract(1, 'h').format(),
|
||||
end: getDayJsInstance().utc().format(),
|
||||
user_id: getCurrentUserId(),
|
||||
};
|
||||
|
||||
const timeEntry = ref({ ...timeEntryDefaultValues });
|
||||
@@ -101,10 +94,6 @@ async function submit() {
|
||||
localEnd.value = getLocalizedDayJs(timeEntryDefaultValues.end).format();
|
||||
show.value = false;
|
||||
}
|
||||
const { tags } = storeToRefs(useTagsStore());
|
||||
async function createTag(tag: string) {
|
||||
return await useTagsStore().createTag(tag);
|
||||
}
|
||||
|
||||
const billableProxy = computed({
|
||||
get: () => (timeEntry.value.billable ? 'true' : 'false'),
|
||||
@@ -112,6 +101,11 @@ const billableProxy = computed({
|
||||
timeEntry.value.billable = value === 'true';
|
||||
},
|
||||
});
|
||||
|
||||
type BillableOption = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -183,8 +177,12 @@ const billableProxy = computed({
|
||||
<div class="flex-col">
|
||||
<SelectDropdown
|
||||
v-model="billableProxy"
|
||||
:get-key-from-item="(item) => item.value"
|
||||
:get-name-for-item="(item) => item.label"
|
||||
:get-key-from-item="
|
||||
(item: BillableOption) => item.value
|
||||
"
|
||||
:get-name-for-item="
|
||||
(item: BillableOption) => item.label
|
||||
"
|
||||
:items="[
|
||||
{
|
||||
label: 'Billable',
|
||||
@@ -26,6 +26,8 @@ import Badge from './Badge.vue';
|
||||
import Checkbox from './Input/Checkbox.vue';
|
||||
import TimeEntryGroupedTable from './TimeEntry/TimeEntryGroupedTable.vue';
|
||||
import TimeEntryMassActionRow from './TimeEntry/TimeEntryMassActionRow.vue';
|
||||
import TimeEntryCreateModal from './TimeEntry/TimeEntryCreateModal.vue';
|
||||
import MoreOptionsDropdown from './MoreOptionsDropdown.vue';
|
||||
|
||||
export {
|
||||
money,
|
||||
@@ -48,4 +50,6 @@ export {
|
||||
Checkbox,
|
||||
TimeEntryGroupedTable,
|
||||
TimeEntryMassActionRow,
|
||||
MoreOptionsDropdown,
|
||||
TimeEntryCreateModal,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user