Files
solidtime/resources/js/utils/useReporting.ts

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,
};
});