mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-14 03:02:15 +01:00
Move tabs and TabBar into UI package
This commit is contained in:
@@ -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()" />
|
||||
|
||||
<!-- Client Create Modal -->
|
||||
@@ -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" />
|
||||
|
||||
<!-- Project Selector Dialog for Active Timer -->
|
||||
<DialogModal :show="showProjectSelector" closeable @close="showProjectSelector = false">
|
||||
@@ -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" />
|
||||
</template>
|
||||
<template #footer>
|
||||
@@ -234,6 +241,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" />
|
||||
</template>
|
||||
<template #footer>
|
||||
|
||||
@@ -20,7 +20,10 @@ import { useClientsQuery } from '@/utils/useClientsQuery';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import { isAllowedToPerformPremiumAction } from '@/utils/billing';
|
||||
import { canCreateProjects } from '@/utils/permissions';
|
||||
import { useOrganizationQuery } from '@/utils/useOrganizationQuery';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
|
||||
const { organization } = useOrganizationQuery(getCurrentOrganizationId()!);
|
||||
const searchValue = ref('');
|
||||
const searchInput = ref<HTMLElement | null>(null);
|
||||
const model = defineModel<string | null>({
|
||||
@@ -156,6 +159,7 @@ function updateValue(project: Project) {
|
||||
:create-client="handleCreateClient"
|
||||
:clients="activeClients"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
:organization-billable-rate="organization?.billable_rate ?? null"
|
||||
:enable-estimated-time="isAllowedToPerformPremiumAction()" />
|
||||
</template>
|
||||
|
||||
|
||||
@@ -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"></ProjectEditBillableSection>
|
||||
<EstimatedTimeSection
|
||||
v-if="isAllowedToPerformPremiumAction()"
|
||||
|
||||
@@ -22,6 +22,8 @@ import { useClientsStore } from '@/utils/useClients';
|
||||
import { useClientsQuery } from '@/utils/useClientsQuery';
|
||||
import { getOrganizationCurrencyString } from '@/utils/money';
|
||||
import { isAllowedToPerformPremiumAction } from '@/utils/billing';
|
||||
import { useOrganizationQuery } from '@/utils/useOrganizationQuery';
|
||||
import { getCurrentOrganizationId } from '@/utils/useUser';
|
||||
import {
|
||||
useVueTable,
|
||||
getCoreRowModel,
|
||||
@@ -29,6 +31,8 @@ import {
|
||||
type SortingState,
|
||||
} from '@tanstack/vue-table';
|
||||
|
||||
const { organization } = useOrganizationQuery(getCurrentOrganizationId()!);
|
||||
|
||||
const props = defineProps<{
|
||||
projects: Project[];
|
||||
showBillableRate: boolean;
|
||||
@@ -155,6 +159,7 @@ const gridTemplate = computed(() => {
|
||||
:create-project
|
||||
:create-client
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
:organization-billable-rate="organization?.billable_rate ?? null"
|
||||
:clients="clients"
|
||||
:enable-estimated-time="isAllowedToPerformPremiumAction()"></ProjectCreateModal>
|
||||
<div class="flow-root max-w-[100vw] overflow-x-auto">
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { Tabs, TabsList } from '@/Components/ui/tabs';
|
||||
|
||||
defineProps<{
|
||||
defaultValue?: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Tabs :default-value="defaultValue" class="w-full">
|
||||
<TabsList class="flex items-center space-x-0.5 sm:space-x-1">
|
||||
<slot></slot>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -1,27 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { TabsTrigger } from '@/Components/ui/tabs';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import type { Component } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
||||
value: string;
|
||||
class?: string;
|
||||
icon?: Component;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TabsTrigger
|
||||
:value="value"
|
||||
:icon="icon"
|
||||
:class="
|
||||
twMerge(
|
||||
'rounded-md px-2 sm:px-3 border py-1.5 text-xs sm:text-sm font-medium text-text-tertiary hover:text-text-primary focus-visible:outline-none data-[state=active]:bg-tab-background data-[state=active]:border-input-border data-[state=active]:text-text-primary border-tab-border',
|
||||
props.class
|
||||
)
|
||||
">
|
||||
<slot></slot>
|
||||
</TabsTrigger>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -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
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { TabsRootEmits, TabsRootProps } from 'reka-ui';
|
||||
import { TabsRoot, useForwardPropsEmits } from 'reka-ui';
|
||||
|
||||
const props = defineProps<TabsRootProps>();
|
||||
const emits = defineEmits<TabsRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TabsRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</TabsRoot>
|
||||
</template>
|
||||
@@ -1,26 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils';
|
||||
import { TabsContent, type TabsContentProps } from 'reka-ui';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<TabsContentProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TabsContent
|
||||
:class="
|
||||
cn(
|
||||
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
v-bind="delegatedProps">
|
||||
<slot />
|
||||
</TabsContent>
|
||||
</template>
|
||||
@@ -1,21 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils';
|
||||
import { TabsList, type TabsListProps } from 'reka-ui';
|
||||
import { computed, type HTMLAttributes } from 'vue';
|
||||
|
||||
const props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TabsList
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('inline-flex items-center rounded-lg text-muted-foreground', props.class)">
|
||||
<slot />
|
||||
</TabsList>
|
||||
</template>
|
||||
@@ -1,35 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils';
|
||||
import { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'reka-ui';
|
||||
import { computed, type HTMLAttributes, type Component } from 'vue';
|
||||
|
||||
const props = defineProps<
|
||||
TabsTriggerProps & { class?: HTMLAttributes['class']; icon?: Component }
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TabsTrigger
|
||||
v-bind="forwardedProps"
|
||||
:class="
|
||||
cn(
|
||||
'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',
|
||||
props.class
|
||||
)
|
||||
">
|
||||
<div v-if="props.icon" class="mr-2 h-4 w-4">
|
||||
<props.icon />
|
||||
</div>
|
||||
<span class="truncate">
|
||||
<slot />
|
||||
</span>
|
||||
</TabsTrigger>
|
||||
</template>
|
||||
Reference in New Issue
Block a user