diff --git a/apps/frontend/src/components/ui/charts/ChartDisplay.vue b/apps/frontend/src/components/ui/charts/ChartDisplay.vue index f60edd47..f57a92f4 100644 --- a/apps/frontend/src/components/ui/charts/ChartDisplay.vue +++ b/apps/frontend/src/components/ui/charts/ChartDisplay.vue @@ -14,7 +14,7 @@ {{ formatCategoryHeader(selectedChart) }} + + {{ formattedCategorySubtitle }} +
@@ -322,7 +326,7 @@ const props = withDefaults( * @deprecated Use `ranges` instead */ resoloutions?: Record; - ranges?: Record; + ranges?: RangeObject[]; personal?: boolean; }>(), { @@ -335,12 +339,6 @@ const props = withDefaults( const projects = ref(props.projects || []); -const selectableRanges = Object.entries(props.ranges).map(([duration, extra]) => ({ - label: typeof extra === "string" ? extra : extra[0], - value: Number(duration), - res: typeof extra === "string" ? Number(duration) : extra[1], -})); - // const selectedChart = ref('downloads') const selectedChart = computed({ get: () => { @@ -413,33 +411,78 @@ const isUsingProjectColors = computed({ }, }); +const startDate = ref(dayjs().startOf("day")); +const endDate = ref(dayjs().endOf("day")); +const timeResolution = ref(30); + +onBeforeMount(() => { + // Load cached data and range from localStorage - cache. + if (import.meta.client) { + const rangeLabel = localStorage.getItem("analyticsSelectedRange"); + if (rangeLabel) { + const range = props.ranges.find((r) => r.getLabel([dayjs(), dayjs()]) === rangeLabel)!; + + if (range !== undefined) { + internalRange.value = range; + const ranges = range.getDates(dayjs()); + timeResolution.value = range.timeResolution; + startDate.value = ranges.startDate; + endDate.value = ranges.endDate; + } + } + } +}); + +onMounted(() => { + if (internalRange.value === null) { + internalRange.value = props.ranges.find( + (r) => r.getLabel([dayjs(), dayjs()]) === "Previous 30 days", + )!; + } + + const ranges = selectedRange.value.getDates(dayjs()); + startDate.value = ranges.startDate; + endDate.value = ranges.endDate; + timeResolution.value = selectedRange.value.timeResolution; +}); + +const internalRange: Ref = ref(null as unknown as RangeObject); + +const selectedRange = computed({ + get: () => { + return internalRange.value; + }, + set: (newRange) => { + const ranges = newRange.getDates(dayjs()); + startDate.value = ranges.startDate; + endDate.value = ranges.endDate; + timeResolution.value = newRange.timeResolution; + + internalRange.value = newRange; + + if (import.meta.client) { + localStorage.setItem( + "analyticsSelectedRange", + internalRange.value?.getLabel([dayjs(), dayjs()]) ?? "Previous 30 days", + ); + } + }, +}); + const analytics = useFetchAllAnalytics( resetCharts, projects, selectedDisplayProjects, props.personal, + startDate, + endDate, + timeResolution, ); -const { startDate, endDate, timeRange, timeResolution } = analytics; - -const selectedRange = computed({ - get: () => { - return ( - selectableRanges.find((option) => option.value === timeRange.value) || { - label: "Custom", - value: timeRange.value, - } - ); - }, - set: (newRange: { label: string; value: number; res?: number }) => { - timeRange.value = newRange.value; - startDate.value = Date.now() - timeRange.value * 60 * 1000; - endDate.value = Date.now(); - - if (newRange?.res) { - timeResolution.value = newRange.res; - } - }, +const formattedCategorySubtitle = computed(() => { + return ( + selectedRange.value?.getLabel([dayjs(startDate.value), dayjs(endDate.value)]) ?? "Loading..." + ); }); const selectedDataSet = computed(() => { @@ -484,6 +527,9 @@ const onToggleColors = () => {