mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-06-06 20:37:32 +00:00
180 lines
5.4 KiB
TypeScript
180 lines
5.4 KiB
TypeScript
import { defineStore, storeToRefs } from 'pinia';
|
|
import { api } from '@/packages/api/src';
|
|
import { type Component, computed, ref } from 'vue';
|
|
import type {
|
|
AggregatedTimeEntries,
|
|
AggregatedTimeEntriesQueryParams,
|
|
ReportingResponse,
|
|
} from '@/packages/api/src';
|
|
import { getCurrentOrganizationId } from '@/utils/useUser';
|
|
import { useNotificationsStore } from '@/utils/notification';
|
|
import { useProjectsStore } from '@/utils/useProjects';
|
|
import { useMembersStore } from '@/utils/useMembers';
|
|
import { useTasksStore } from '@/utils/useTasks';
|
|
import { useClientsStore } from '@/utils/useClients';
|
|
import {
|
|
CheckCircleIcon,
|
|
UserCircleIcon,
|
|
UserGroupIcon,
|
|
} from '@heroicons/vue/20/solid';
|
|
import { DocumentTextIcon, FolderIcon } from '@heroicons/vue/16/solid';
|
|
import BillableIcon from '@/packages/ui/src/Icons/BillableIcon.vue';
|
|
|
|
export type GroupingOption =
|
|
| 'project'
|
|
| 'task'
|
|
| 'user'
|
|
| 'billable'
|
|
| 'client'
|
|
| 'description';
|
|
|
|
export const useReportingStore = defineStore('reporting', () => {
|
|
const reportingGraphResponse = ref<ReportingResponse | null>(null);
|
|
const reportingTableResponse = ref<ReportingResponse | null>(null);
|
|
|
|
const { handleApiRequestNotifications } = useNotificationsStore();
|
|
|
|
async function fetchGraphReporting(
|
|
params: AggregatedTimeEntriesQueryParams
|
|
) {
|
|
const organization = getCurrentOrganizationId();
|
|
if (organization) {
|
|
reportingGraphResponse.value = await handleApiRequestNotifications(
|
|
() =>
|
|
api.getAggregatedTimeEntries({
|
|
params: {
|
|
organization: organization,
|
|
},
|
|
queries: params,
|
|
}),
|
|
undefined,
|
|
'Failed to fetch reporting data'
|
|
);
|
|
}
|
|
}
|
|
|
|
async function fetchTableReporting(
|
|
params: AggregatedTimeEntriesQueryParams
|
|
) {
|
|
const organization = getCurrentOrganizationId();
|
|
if (organization) {
|
|
reportingTableResponse.value = await handleApiRequestNotifications(
|
|
() =>
|
|
api.getAggregatedTimeEntries({
|
|
params: {
|
|
organization: organization,
|
|
},
|
|
queries: params,
|
|
}),
|
|
undefined,
|
|
'Failed to fetch reporting data'
|
|
);
|
|
}
|
|
}
|
|
|
|
const aggregatedGraphTimeEntries = computed<AggregatedTimeEntries>(() => {
|
|
return reportingGraphResponse.value?.data as AggregatedTimeEntries;
|
|
});
|
|
|
|
const aggregatedTableTimeEntries = computed<AggregatedTimeEntries>(() => {
|
|
return reportingTableResponse.value?.data as AggregatedTimeEntries;
|
|
});
|
|
|
|
const emptyPlaceholder = {
|
|
user: 'No User',
|
|
project: 'No Project',
|
|
task: 'No Task',
|
|
billable: 'Non-Billable',
|
|
client: 'No Client',
|
|
description: 'No Description',
|
|
} as Record<string, string>;
|
|
|
|
function getNameForReportingRowEntry(
|
|
key: string | null,
|
|
type: string | null
|
|
) {
|
|
if (type === null) {
|
|
return null;
|
|
}
|
|
if (key === null) {
|
|
return emptyPlaceholder[type as keyof typeof emptyPlaceholder];
|
|
}
|
|
|
|
if (type === 'project') {
|
|
const projectsStore = useProjectsStore();
|
|
const { projects } = storeToRefs(projectsStore);
|
|
return projects.value.find((project) => project.id === key)?.name;
|
|
}
|
|
if (type === 'user') {
|
|
const memberStore = useMembersStore();
|
|
const { members } = storeToRefs(memberStore);
|
|
return members.value.find((member) => member.user_id === key)?.name;
|
|
}
|
|
if (type === 'task') {
|
|
const taskStore = useTasksStore();
|
|
const { tasks } = storeToRefs(taskStore);
|
|
return tasks.value.find((task) => task.id === key)?.name;
|
|
}
|
|
if (type === 'client') {
|
|
const clientsStore = useClientsStore();
|
|
const { clients } = storeToRefs(clientsStore);
|
|
return clients.value.find((client) => client.id === key)?.name;
|
|
}
|
|
if (type === 'billable') {
|
|
if (key === '0') {
|
|
return 'Non-Billable';
|
|
} else {
|
|
return 'Billable';
|
|
}
|
|
}
|
|
return key;
|
|
}
|
|
|
|
const groupByOptions: {
|
|
label: string;
|
|
value: GroupingOption;
|
|
icon: Component;
|
|
}[] = [
|
|
{
|
|
label: 'Members',
|
|
value: 'user',
|
|
icon: UserGroupIcon,
|
|
},
|
|
{
|
|
label: 'Projects',
|
|
value: 'project',
|
|
icon: FolderIcon,
|
|
},
|
|
{
|
|
label: 'Tasks',
|
|
value: 'task',
|
|
icon: CheckCircleIcon,
|
|
},
|
|
{
|
|
label: 'Clients',
|
|
value: 'client',
|
|
icon: UserCircleIcon,
|
|
},
|
|
{
|
|
label: 'Billable',
|
|
value: 'billable',
|
|
icon: BillableIcon,
|
|
},
|
|
{
|
|
label: 'Description',
|
|
value: 'description',
|
|
icon: DocumentTextIcon,
|
|
},
|
|
];
|
|
|
|
return {
|
|
aggregatedGraphTimeEntries,
|
|
fetchGraphReporting,
|
|
fetchTableReporting,
|
|
aggregatedTableTimeEntries,
|
|
getNameForReportingRowEntry,
|
|
groupByOptions,
|
|
emptyPlaceholder,
|
|
};
|
|
});
|