diff --git a/package.json b/package.json index 3d2aa640..ad2dd653 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "name": "solidtime", "private": true, "type": "module", "workspaces": [ diff --git a/resources/js/Components/CommandPalette/CommandPaletteProvider.vue b/resources/js/Components/CommandPalette/CommandPaletteProvider.vue index f9e5fb7e..e5b7a4f6 100644 --- a/resources/js/Components/CommandPalette/CommandPaletteProvider.vue +++ b/resources/js/Components/CommandPalette/CommandPaletteProvider.vue @@ -9,6 +9,8 @@ import { useTagsStore } from '@/utils/useTags'; import { useTimeEntriesMutations } from '@/utils/useTimeEntriesMutations'; import { getOrganizationCurrencyString } from '@/utils/money'; import { isAllowedToPerformPremiumAction } from '@/utils/billing'; +import { useOrganizationQuery } from '@/utils/useOrganizationQuery'; +import { getCurrentOrganizationId } from '@/utils/useUser'; import { canCreateProjects } from '@/utils/permissions'; import type { CreateClientBody, @@ -37,6 +39,8 @@ import TagDropdown from '@/packages/ui/src/Tag/TagDropdown.vue'; import DialogModal from '@/packages/ui/src/DialogModal.vue'; import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue'; +const { organization } = useOrganizationQuery(getCurrentOrganizationId()!); + const { isOpen, searchTerm, @@ -162,6 +166,7 @@ const firstProjectId = computed(() => projects.value[0]?.id ?? ''); :create-client="createClient" :clients="activeClients" :currency="getOrganizationCurrencyString()" + :organization-billable-rate="organization?.billable_rate ?? null" :enable-estimated-time="isAllowedToPerformPremiumAction()" /> @@ -192,7 +197,8 @@ const firstProjectId = computed(() => projects.value[0]?.id ?? ''); :clients="activeClients" :currency="getOrganizationCurrencyString()" :enable-estimated-time="isAllowedToPerformPremiumAction()" - :can-create-project="canCreateProjects()" /> + :can-create-project="canCreateProjects()" + :organization-billable-rate="organization?.billable_rate ?? null" /> @@ -210,6 +216,7 @@ const firstProjectId = computed(() => projects.value[0]?.id ?? ''); :can-create-project="canCreateProjects()" :currency="getOrganizationCurrencyString()" :enable-estimated-time="isAllowedToPerformPremiumAction()" + :organization-billable-rate="organization?.billable_rate ?? null" class="w-full" /> diff --git a/resources/js/Components/Common/Project/ProjectEditModal.vue b/resources/js/Components/Common/Project/ProjectEditModal.vue index 725bc2e4..d9b53e28 100644 --- a/resources/js/Components/Common/Project/ProjectEditModal.vue +++ b/resources/js/Components/Common/Project/ProjectEditModal.vue @@ -20,9 +20,12 @@ import ProjectBillableRateModal from '@/packages/ui/src/Project/ProjectBillableR import { getOrganizationCurrencyString } from '@/utils/money'; import ProjectEditBillableSection from '@/packages/ui/src/Project/ProjectEditBillableSection.vue'; import { isAllowedToPerformPremiumAction } from '@/utils/billing'; +import { useOrganizationQuery } from '@/utils/useOrganizationQuery'; +import { getCurrentOrganizationId } from '@/utils/useUser'; const { updateProject } = useProjectsStore(); const { clients } = useClientsQuery(); +const { organization } = useOrganizationQuery(getCurrentOrganizationId()!); const show = defineModel('show', { default: false }); const saving = ref(false); const showBillableRateModal = ref(false); @@ -117,6 +120,7 @@ async function submitBillableRate() { v-model:is-billable="project.is_billable" v-model:billable-rate="project.billable_rate" :currency="getOrganizationCurrencyString()" + :organization-billable-rate="organization?.billable_rate ?? null" @submit="submit"> { :create-project :create-client :currency="getOrganizationCurrencyString()" + :organization-billable-rate="organization?.billable_rate ?? null" :clients="clients" :enable-estimated-time="isAllowedToPerformPremiumAction()">
diff --git a/resources/js/Components/Common/Reporting/ReportingTabNavbar.vue b/resources/js/Components/Common/Reporting/ReportingTabNavbar.vue index 46a0ee66..bb03b73d 100644 --- a/resources/js/Components/Common/Reporting/ReportingTabNavbar.vue +++ b/resources/js/Components/Common/Reporting/ReportingTabNavbar.vue @@ -2,8 +2,7 @@ import { router } from '@inertiajs/vue3'; import { canViewReport } from '@/utils/permissions'; import { computed } from 'vue'; -import TabBar from '@/Components/Common/TabBar/TabBar.vue'; -import TabBarItem from '@/Components/Common/TabBar/TabBarItem.vue'; +import { TabBar, TabBarItem } from '@/packages/ui/src'; const props = defineProps<{ active: 'reporting' | 'detailed' | 'shared'; diff --git a/resources/js/Components/TimeTracker.vue b/resources/js/Components/TimeTracker.vue index 270b5806..8779b01c 100644 --- a/resources/js/Components/TimeTracker.vue +++ b/resources/js/Components/TimeTracker.vue @@ -11,6 +11,7 @@ import duration from 'dayjs/plugin/duration'; import { useCurrentTimeEntryStore } from '@/utils/useCurrentTimeEntry'; import { storeToRefs } from 'pinia'; import { getCurrentOrganizationId } from '@/utils/useUser'; +import { useOrganizationQuery } from '@/utils/useOrganizationQuery'; import { switchOrganization } from '@/utils/useOrganization'; import { useProjectsQuery } from '@/utils/useProjectsQuery'; import { useTasksQuery } from '@/utils/useTasksQuery'; @@ -47,6 +48,8 @@ dayjs.extend(duration); dayjs.extend(utc); +const { organization } = useOrganizationQuery(getCurrentOrganizationId()!); + const currentTimeEntryStore = useCurrentTimeEntryStore(); const { currentTimeEntry, isActive, now } = storeToRefs(currentTimeEntryStore); const { startLiveTimer, stopLiveTimer, setActiveState } = currentTimeEntryStore; @@ -152,6 +155,7 @@ const { tags } = useTagsQuery(); :create-time-entry="createTimeEntry" :currency="getOrganizationCurrencyString()" :can-create-project="canCreateProjects()" + :organization-billable-rate="organization?.billable_rate ?? null" :projects :tasks :tags @@ -173,6 +177,7 @@ const { tags } = useTagsQuery(); :create-project :enable-estimated-time="isAllowedToPerformPremiumAction()" :can-create-project="canCreateProjects()" + :organization-billable-rate="organization?.billable_rate ?? null" :create-client :clients :tags diff --git a/resources/js/Pages/Calendar.vue b/resources/js/Pages/Calendar.vue index b457776c..3d85ef3e 100644 --- a/resources/js/Pages/Calendar.vue +++ b/resources/js/Pages/Calendar.vue @@ -23,7 +23,10 @@ import { useClientsStore } from '@/utils/useClients'; import { getOrganizationCurrencyString } from '@/utils/money'; import { canCreateProjects } from '@/utils/permissions'; import { useCurrentTimeEntryStore } from '@/utils/useCurrentTimeEntry'; +import { useOrganizationQuery } from '@/utils/useOrganizationQuery'; +import { getCurrentOrganizationId } from '@/utils/useUser'; +const { organization } = useOrganizationQuery(getCurrentOrganizationId()!); const calendarStart = ref(undefined); const calendarEnd = ref(undefined); @@ -124,6 +127,7 @@ function onRefresh() { :enable-estimated-time="isAllowedToPerformPremiumAction()" :currency="getOrganizationCurrencyString()" :can-create-project="canCreateProjects()" + :organization-billable-rate="organization?.billable_rate ?? null" :create-time-entry="createTimeEntry" :update-time-entry="updateTimeEntry" :delete-time-entry="deleteTimeEntry" diff --git a/resources/js/Pages/Clients.vue b/resources/js/Pages/Clients.vue index a6304954..206599f4 100644 --- a/resources/js/Pages/Clients.vue +++ b/resources/js/Pages/Clients.vue @@ -10,8 +10,7 @@ import ClientTable from '@/Components/Common/Client/ClientTable.vue'; import ClientCreateModal from '@/Components/Common/Client/ClientCreateModal.vue'; import PageTitle from '@/Components/Common/PageTitle.vue'; import { canCreateClients } from '@/utils/permissions'; -import TabBarItem from '@/Components/Common/TabBar/TabBarItem.vue'; -import TabBar from '@/Components/Common/TabBar/TabBar.vue'; +import { TabBar, TabBarItem } from '@/packages/ui/src'; import { useStorage } from '@vueuse/core'; import type { SortColumn, SortDirection } from '@/Components/Common/Client/ClientTable.vue'; diff --git a/resources/js/Pages/Members.vue b/resources/js/Pages/Members.vue index 03d323d7..f01872b0 100644 --- a/resources/js/Pages/Members.vue +++ b/resources/js/Pages/Members.vue @@ -4,8 +4,7 @@ import AppLayout from '@/Layouts/AppLayout.vue'; import { PlusIcon } from '@heroicons/vue/16/solid'; import { UserGroupIcon } from '@heroicons/vue/20/solid'; import SecondaryButton from '@/packages/ui/src/Buttons/SecondaryButton.vue'; -import TabBar from '@/Components/Common/TabBar/TabBar.vue'; -import TabBarItem from '@/Components/Common/TabBar/TabBarItem.vue'; +import { TabBar, TabBarItem } from '@/packages/ui/src'; import { ref } from 'vue'; import MemberTable from '@/Components/Common/Member/MemberTable.vue'; import MemberInviteModal from '@/Components/Common/Member/MemberInviteModal.vue'; diff --git a/resources/js/Pages/ProjectShow.vue b/resources/js/Pages/ProjectShow.vue index cd271737..0675ae94 100644 --- a/resources/js/Pages/ProjectShow.vue +++ b/resources/js/Pages/ProjectShow.vue @@ -21,8 +21,7 @@ import ProjectMemberTable from '@/Components/Common/ProjectMember/ProjectMemberT import ProjectMemberCreateModal from '@/Components/Common/ProjectMember/ProjectMemberCreateModal.vue'; import { useProjectMembersQuery } from '@/utils/useProjectMembersQuery'; import { canCreateProjects, canCreateTasks, canViewProjectMembers } from '@/utils/permissions'; -import TabBarItem from '@/Components/Common/TabBar/TabBarItem.vue'; -import TabBar from '@/Components/Common/TabBar/TabBar.vue'; +import { TabBar, TabBarItem } from '@/packages/ui/src'; import { useTasksQuery } from '@/utils/useTasksQuery'; import ProjectEditModal from '@/Components/Common/Project/ProjectEditModal.vue'; import { Badge } from '@/packages/ui/src'; diff --git a/resources/js/Pages/Projects.vue b/resources/js/Pages/Projects.vue index 9cf8829b..f096032b 100644 --- a/resources/js/Pages/Projects.vue +++ b/resources/js/Pages/Projects.vue @@ -131,6 +131,7 @@ const showBillableRate = computed(() => { :enable-estimated-time="isAllowedToPerformPremiumAction()" :create-client :currency="getOrganizationCurrencyString()" + :organization-billable-rate="organization?.billable_rate ?? null" :clients="clients" @submit="createProject"> diff --git a/resources/js/Pages/ReportingDetailed.vue b/resources/js/Pages/ReportingDetailed.vue index bfa3e8ec..90580375 100644 --- a/resources/js/Pages/ReportingDetailed.vue +++ b/resources/js/Pages/ReportingDetailed.vue @@ -66,6 +66,7 @@ import ReportingExportModal from '@/Components/Common/Reporting/ReportingExportM import ReportingFilterBar from '@/Components/Common/Reporting/ReportingFilterBar.vue'; import { useTimeEntriesReportQuery } from '@/utils/useTimeEntriesReportQuery'; import { useTimeEntriesMutations } from '@/utils/useTimeEntriesMutations'; +import { useOrganizationQuery } from '@/utils/useOrganizationQuery'; // TimeEntryRoundingType is now defined in ReportingRoundingControls component type TimeEntryRoundingType = 'up' | 'down' | 'nearest'; @@ -89,6 +90,7 @@ const roundingType = ref('nearest'); const roundingMinutes = ref(15); const { members } = useMembersQuery(); +const { organization } = useOrganizationQuery(getCurrentOrganizationId()!); const pageLimit = 15; // Watch rounding enabled state to trigger updates @@ -353,6 +355,7 @@ async function downloadExport(format: ExportFormat) { :tags="tags" :currency="getOrganizationCurrencyString()" :clients="clients" + :organization-billable-rate="organization?.billable_rate ?? null" class="border-b border-default-background-separator" :update-time-entries=" (args) => @@ -384,6 +387,7 @@ async function downloadExport(format: ExportFormat) { :on-start-stop-click="() => startTimeEntryFromExisting(entry)" :delete-time-entry="() => deleteTimeEntries([entry])" :currency="getOrganizationCurrencyString()" + :organization-billable-rate="organization?.billable_rate ?? null" :duplicate-time-entry="() => createTimeEntry(entry)" :members="members" show-date diff --git a/resources/js/Pages/Time.vue b/resources/js/Pages/Time.vue index cdfb2a65..7d772682 100644 --- a/resources/js/Pages/Time.vue +++ b/resources/js/Pages/Time.vue @@ -26,6 +26,8 @@ import TimeEntryMassActionRow from '@/packages/ui/src/TimeEntry/TimeEntryMassAct import type { UpdateMultipleTimeEntriesChangeset } from '@/packages/api/src'; import { isAllowedToPerformPremiumAction } from '@/utils/billing'; import { canCreateProjects } from '@/utils/permissions'; +import { useOrganizationQuery } from '@/utils/useOrganizationQuery'; +import { getCurrentOrganizationId } from '@/utils/useUser'; import { useTagsStore } from '@/utils/useTags'; import { useProjectsStore } from '@/utils/useProjects'; import { useClientsStore } from '@/utils/useClients'; @@ -87,6 +89,8 @@ async function createClient(body: CreateClientBody): Promise return await useClientsStore().createClient(body); } +const { organization } = useOrganizationQuery(getCurrentOrganizationId()!); + const selectedTimeEntries = ref([] as TimeEntry[]); async function clearSelectionAndState() { @@ -115,6 +119,7 @@ function deleteSelected() { :tags="tags" :currency="getOrganizationCurrencyString()" :clients="clients" + :organization-billable-rate="organization?.billable_rate ?? null" class="border-t border-default-background-separator hidden sm:block" :update-time-entries=" (args) => @@ -134,6 +139,7 @@ function deleteSelected() { :create-project :enable-estimated-time="isAllowedToPerformPremiumAction()" :can-create-project="canCreateProjects()" + :organization-billable-rate="organization?.billable_rate ?? null" :clients :create-client :update-time-entry diff --git a/resources/js/packages/ui/src/FullCalendar/CalendarToolbar.vue b/resources/js/packages/ui/src/FullCalendar/CalendarToolbar.vue index de855855..2412ad37 100644 --- a/resources/js/packages/ui/src/FullCalendar/CalendarToolbar.vue +++ b/resources/js/packages/ui/src/FullCalendar/CalendarToolbar.vue @@ -1,8 +1,8 @@