felicity-lims/webapp/stores/dashboard.ts

327 lines
12 KiB
TypeScript
Raw Normal View History

2023-04-10 09:29:10 +08:00
import { defineStore } from 'pinia';
import { ref, watch } from 'vue';
import dayjs from 'dayjs';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
2022-04-04 02:54:31 +08:00
import {
GET_SAMPLE_GROUP_BY_STATUS,
GET_ANALYSIS_GROUP_BY_STATUS,
GET_WORKSHEET_GROUP_BY_STATUS,
GET_EXTRAS_GROUP_BY_STATUS,
2022-04-04 02:54:31 +08:00
GET_ANALYSIS_GROUP_BY_INSTRUMENT,
GET_SAMPLE_PROCESS_PEFORMANCE,
GET_ANALYSIS_PROCESS_PEFORMANCE,
GET_SAMPLE_GROUPS_BY_ACTION,
GET_SAMPLE_LAGGARDS,
2023-04-10 09:29:10 +08:00
} from '../graphql/dashboard.queries';
import { mapOrder } from '../utils';
2022-04-04 02:54:31 +08:00
2023-04-10 09:29:10 +08:00
import { useApiUtil } from '../composables';
2022-04-04 02:54:31 +08:00
const { withClientQuery } = useApiUtil();
interface GroupCount {
2023-04-10 09:29:10 +08:00
group: string;
count: number;
2022-04-04 02:54:31 +08:00
}
2022-04-09 22:57:06 +08:00
interface ISampleCounts {
totalSamples: number;
totalLate: number;
totalNotLate: number;
processAverage: number;
avgExtraDays: number;
}
interface IAnalysisGroup extends ISampleCounts {
2023-04-10 09:29:10 +08:00
service: string;
2022-04-09 22:57:06 +08:00
}
export interface IProcess {
2023-04-10 09:29:10 +08:00
process: string;
counts: ISampleCounts;
groups: IAnalysisGroup[];
2022-04-09 22:57:06 +08:00
}
2023-04-10 09:29:10 +08:00
dayjs.extend(quarterOfYear);
2022-04-04 02:54:31 +08:00
export const useDashBoardStore = defineStore('dashboard', () => {
const dashboard = ref({
currentTab: 'overview',
2022-11-06 21:09:15 +08:00
tabs: ['overview', 'resource', 'laggard', 'peformance', 'notices', 'line-listing'], // 'tat'
2022-04-09 22:57:06 +08:00
showFilters: false,
2023-04-10 09:29:10 +08:00
filterRange: { from: '', fromIso: '', to: '', toIso: '' },
currentFilter: 'TW',
2022-04-22 03:33:54 +08:00
filters: ['T', 'Y', 'TW', 'LW', 'TM', 'LM', 'TQ', 'LQ', 'TY'],
2023-04-10 09:29:10 +08:00
overViewStats: {
analyses: [] as GroupCount[],
samples: [] as GroupCount[],
extras: [] as GroupCount[],
2023-04-10 09:29:10 +08:00
worksheets: [] as GroupCount[],
2022-04-22 03:33:54 +08:00
},
2022-04-15 16:32:24 +08:00
fetchingOverViewStats: false,
2023-04-10 09:29:10 +08:00
resourceStats: {
instruments: [] as GroupCount[],
samples: [] as any[],
2022-04-22 03:33:54 +08:00
},
2022-04-15 16:32:24 +08:00
fetchingResourceStats: false,
2022-04-22 03:33:54 +08:00
peformancePeriods: [30, 60, 90, 180, 365],
currentPeformancePeriod: 30,
2023-04-10 09:29:10 +08:00
peformanceStats: {
sample: [] as IProcess[],
analysis: [] as IProcess[],
2022-04-22 03:33:54 +08:00
},
2022-04-15 16:32:24 +08:00
fetchingSampePeformanceStats: false,
fetchingAnalysisPeformanceStats: false,
2023-04-10 09:29:10 +08:00
currentPeformance: 'received_to_published',
performances: ['received_to_published', 'received_to_submitted', 'submitted_to_verified', 'verified_to_published'],
2023-04-09 04:28:39 +08:00
perfs: {
2023-04-10 09:29:10 +08:00
received_to_published: 'Received to Published',
received_to_submitted: 'Received to Submitted',
submitted_to_verified: 'Submitted to Verified',
verified_to_published: 'Verified to Published',
2023-04-09 04:28:39 +08:00
},
2022-04-15 16:32:24 +08:00
laggards: {} as any,
2023-04-10 09:29:10 +08:00
fetchingLaggards: false,
});
2022-04-04 02:54:31 +08:00
2022-12-22 22:42:05 +08:00
const filterToolTip = (filter: string): string => {
2023-04-10 09:29:10 +08:00
if (filter === 'T') return 'Today';
if (filter === 'Y') return 'Yesterday';
if (filter === 'TW') return 'This Week';
if (filter === 'LW') return 'Last Week';
if (filter === 'TM') return 'This Month';
if (filter === 'LM') return 'Last Month';
if (filter === 'TQ') return 'This Quarter';
if (filter === 'LQ') return 'Last Quarter';
if (filter === 'TY') return 'This Year';
return 'Unknown Filter';
};
2022-12-22 22:42:05 +08:00
2022-04-04 02:54:31 +08:00
// get_OverViewStats
const getOverViewStats = async () => {
2022-04-15 16:32:24 +08:00
dashboard.value.fetchingOverViewStats = true;
try {
await countSamplesGroupsByStatus();
await countAnalysisGroupsByStatus();
await countWrksheetGroupsByStatus();
await countExtrasGroupsByStatus();
2022-04-15 16:32:24 +08:00
} catch (error) {
dashboard.value.fetchingOverViewStats = false;
}
dashboard.value.fetchingOverViewStats = false;
2023-04-10 09:29:10 +08:00
};
2022-04-04 02:54:31 +08:00
// get_PeformanceStats
const getResourceStats = async () => {
2022-04-15 16:32:24 +08:00
dashboard.value.fetchingResourceStats = true;
try {
await countAnalysisGroupsByInstrument();
await getSampleGroupByAction();
} catch (error) {
dashboard.value.fetchingResourceStats = false;
}
dashboard.value.fetchingResourceStats = false;
2023-04-10 09:29:10 +08:00
};
2022-04-04 02:54:31 +08:00
// GET_SAMPLE_GROUP_BY_STATUS
const countSamplesGroupsByStatus = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-12-22 22:42:05 +08:00
startDate: dashboard.value.filterRange.fromIso,
2023-04-10 09:29:10 +08:00
endDate: dashboard.value.filterRange.toIso,
};
await withClientQuery(GET_SAMPLE_GROUP_BY_STATUS, filters, 'countSampleGroupByStatus', 'network-only').then(
payload =>
(dashboard.value.overViewStats.samples = mapOrder(
payload.data,
['scheduled', 'expected', 'received', 'awaiting', 'approved'],
'group'
))
);
};
2022-04-04 02:54:31 +08:00
// GET_ANALYSIS_GROUP_BY_STATUS
const countAnalysisGroupsByStatus = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-12-22 22:42:05 +08:00
startDate: dashboard.value.filterRange.fromIso,
2023-04-10 09:29:10 +08:00
endDate: dashboard.value.filterRange.toIso,
};
await withClientQuery(GET_ANALYSIS_GROUP_BY_STATUS, filters, 'countAnalyteGroupByStatus', 'network-only').then(
payload => (dashboard.value.overViewStats.analyses = mapOrder(payload.data, ['pending', 'resulted'], 'group'))
);
};
2022-04-04 02:54:31 +08:00
// GET_WORKSHEET_GROUP_BY_STATUS
const countWrksheetGroupsByStatus = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-12-22 22:42:05 +08:00
startDate: dashboard.value.filterRange.fromIso,
2023-04-10 09:29:10 +08:00
endDate: dashboard.value.filterRange.toIso,
};
await withClientQuery(GET_WORKSHEET_GROUP_BY_STATUS, filters, 'countWorksheetGroupByStatus', 'network-only').then(
payload => (dashboard.value.overViewStats.worksheets = mapOrder(payload.data, ['empty', 'awaiting', 'pending'], 'group'))
);
};
2022-04-04 02:54:31 +08:00
// GET_extras_GROUP_BY_STATUS
const countExtrasGroupsByStatus = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-12-22 22:42:05 +08:00
startDate: dashboard.value.filterRange.fromIso,
2023-04-10 09:29:10 +08:00
endDate: dashboard.value.filterRange.toIso,
};
await withClientQuery(GET_EXTRAS_GROUP_BY_STATUS, filters, 'countExtrasGroupByStatus', 'network-only').then(
payload =>
(dashboard.value.overViewStats.extras = mapOrder(
payload.data,
['sample cancelled', 'sample rejected', 'sample invalidated', 'analysis retracted', 'analysis retested'],
'group'
))
);
};
2022-04-04 02:54:31 +08:00
// GET_ANALYSIS_GROUP_BY_INSTRUMENT
const countAnalysisGroupsByInstrument = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-12-22 22:42:05 +08:00
startDate: dashboard.value.filterRange.fromIso,
2023-04-10 09:29:10 +08:00
endDate: dashboard.value.filterRange.toIso,
};
await withClientQuery(GET_ANALYSIS_GROUP_BY_INSTRUMENT, filters, 'countAnalyteGroupByInstrument', 'network-only').then(
payload => (dashboard.value.resourceStats.instruments = payload.data)
);
};
2022-04-04 02:54:31 +08:00
// GET_SAMPLE_GROUPS_BY_ACTION
const getSampleGroupByAction = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-12-22 22:42:05 +08:00
startDate: dashboard.value.filterRange.fromIso,
2023-04-10 09:29:10 +08:00
endDate: dashboard.value.filterRange.toIso,
};
await withClientQuery(GET_SAMPLE_GROUPS_BY_ACTION, filters, 'countSampleGroupByAction', 'network-only').then(
payload => (dashboard.value.resourceStats.samples = payload.data)
);
};
2022-04-04 02:54:31 +08:00
// GET_SAMPLE_PROCESS_PEFORMANCE
const getSampleProcessPeformance = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-04-22 03:33:54 +08:00
startDate: dayjs().startOf('day').subtract(dashboard.value.currentPeformancePeriod, 'day').toISOString(),
2023-04-10 09:29:10 +08:00
endDate: dayjs().endOf('day').toISOString(),
};
dashboard.value.fetchingSampePeformanceStats = true;
await withClientQuery(GET_SAMPLE_PROCESS_PEFORMANCE, filters, 'sampleProcessPerformance', 'network-only')
.then(payload => {
dashboard.value.fetchingSampePeformanceStats = false;
dashboard.value.peformanceStats.sample = payload.data;
})
.catch(err => (dashboard.value.fetchingSampePeformanceStats = false));
};
2022-04-04 02:54:31 +08:00
// GET_ANALYSIS_PROCESS_PEFORMANCE
const getAnalysisProcessPeformance = async () => {
2023-04-10 09:29:10 +08:00
const filters = {
2022-04-09 22:57:06 +08:00
process: dashboard.value.currentPeformance,
2022-04-22 03:33:54 +08:00
startDate: dayjs().startOf('day').subtract(dashboard.value.currentPeformancePeriod, 'day').toISOString(),
2023-04-10 09:29:10 +08:00
endDate: dayjs().endOf('day').toISOString(),
};
dashboard.value.fetchingAnalysisPeformanceStats = true;
await withClientQuery(GET_ANALYSIS_PROCESS_PEFORMANCE, filters, 'analysisProcessPerformance', 'network-only')
.then(payload => {
dashboard.value.fetchingAnalysisPeformanceStats = false;
dashboard.value.peformanceStats.analysis = payload.data;
console.log(payload);
})
.catch(err => (dashboard.value.fetchingAnalysisPeformanceStats = false));
};
2022-04-04 02:54:31 +08:00
// GET_SAMPLE_LAGGARDS
2022-04-09 22:57:06 +08:00
const getSampleLaggards = async () => {
2022-04-15 16:32:24 +08:00
dashboard.value.fetchingLaggards = true;
2022-04-22 03:33:54 +08:00
await withClientQuery(GET_SAMPLE_LAGGARDS, {}, 'sampleLaggards', 'network-only')
2023-04-10 09:29:10 +08:00
.then(payload => {
dashboard.value.laggards = payload.data;
dashboard.value.fetchingLaggards = false;
})
.catch(err => (dashboard.value.fetchingLaggards = false));
};
2022-04-04 02:54:31 +08:00
2023-04-10 09:29:10 +08:00
const setCurrentTab = (tab: string) => (dashboard.value.currentTab = tab);
const setCurrentFilter = (filter: string) => (dashboard.value.currentFilter = filter);
2022-12-22 22:42:05 +08:00
const setFilterRange = (from, to) => {
2023-04-10 09:29:10 +08:00
dashboard.value.filterRange.from = from.toDate().toLocaleDateString();
dashboard.value.filterRange.fromIso = from.toISOString();
2022-12-22 22:42:05 +08:00
dashboard.value.filterRange.to = to.toDate().toLocaleDateString();
dashboard.value.filterRange.toIso = to.toISOString();
2023-04-10 09:29:10 +08:00
};
2022-04-09 22:57:06 +08:00
const setCurrentPeformance = (event: any) => {
2023-04-10 09:29:10 +08:00
dashboard.value.currentPeformance = event.target.value;
2022-04-09 22:57:06 +08:00
};
2022-04-22 03:33:54 +08:00
const setCurrentPeformancePeriod = (event: any) => {
2023-04-10 09:29:10 +08:00
const period: number = +event.target.value;
dashboard.value.currentPeformancePeriod = period;
2022-04-22 03:33:54 +08:00
};
2023-04-10 09:29:10 +08:00
const setShowFilters = (show: boolean) => (dashboard.value.showFilters = show);
2022-04-04 02:54:31 +08:00
const calculateFilterRange = (filter: string): void => {
switch (filter) {
2022-04-22 03:33:54 +08:00
case 'T':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('day'), dayjs().endOf('day'));
2022-04-09 22:57:06 +08:00
break;
2022-04-22 03:33:54 +08:00
case 'Y':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('day').subtract(1, 'day'), dayjs().endOf('day').subtract(1, 'day'));
2022-04-04 02:54:31 +08:00
break;
2022-04-09 22:57:06 +08:00
2022-04-22 03:33:54 +08:00
case 'TW':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('week'), dayjs().endOf('week'));
2022-04-09 22:57:06 +08:00
break;
2022-04-22 03:33:54 +08:00
case 'LW':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('week').subtract(1, 'week'), dayjs().endOf('week').subtract(1, 'week'));
2022-04-09 22:57:06 +08:00
break;
2022-04-22 03:33:54 +08:00
case 'TM':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('month'), dayjs().endOf('month'));
2022-04-09 22:57:06 +08:00
break;
2022-04-22 03:33:54 +08:00
case 'LM':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('month').subtract(1, 'month'), dayjs().endOf('month').subtract(1, 'month'));
2022-04-09 22:57:06 +08:00
break;
2022-04-22 03:33:54 +08:00
case 'TQ':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('quarter'), dayjs().endOf('quarter'));
2022-04-09 22:57:06 +08:00
break;
2022-04-22 03:33:54 +08:00
case 'LQ':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('quarter').subtract(1, 'quarter'), dayjs().endOf('quarter').subtract(1, 'quarter'));
2022-04-09 22:57:06 +08:00
break;
2023-04-10 09:29:10 +08:00
2022-04-22 03:33:54 +08:00
case 'TY':
2023-04-10 09:29:10 +08:00
setFilterRange(dayjs().startOf('year'), dayjs().endOf('year'));
2022-04-09 22:57:06 +08:00
break;
2022-04-04 02:54:31 +08:00
default:
2023-04-10 09:29:10 +08:00
alert('Unknown Range Selected');
2022-04-04 02:54:31 +08:00
break;
}
2023-04-10 09:29:10 +08:00
};
2022-04-09 22:57:06 +08:00
calculateFilterRange(dashboard.value.currentFilter);
2022-04-04 02:54:31 +08:00
2023-04-10 09:29:10 +08:00
watch(
() => dashboard.value.currentFilter,
(filter, prev) => {
calculateFilterRange(filter);
}
);
return {
dashboard,
setShowFilters,
filterToolTip,
setCurrentTab,
setCurrentFilter,
setFilterRange,
getOverViewStats,
getResourceStats,
getSampleLaggards,
getSampleProcessPeformance,
getAnalysisProcessPeformance,
setCurrentPeformance,
setCurrentPeformancePeriod,
};
});