Skip to content

Commit 37b9f61

Browse files
feat: add permalink to downloads modal
1 parent 96a4969 commit 37b9f61

File tree

4 files changed

+66
-32
lines changed

4 files changed

+66
-32
lines changed

app/components/Package/DownloadAnalytics.vue

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import { useDebounceFn, useElementSize } from '@vueuse/core'
55
import { useCssVariables } from '~/composables/useColors'
66
import { OKLCH_NEUTRAL_FALLBACK, transparentizeOklch } from '~/utils/colors'
77
import { getFrameworkColor, isListedFramework } from '~/utils/frameworks'
8+
import type {
9+
ChartTimeGranularity,
10+
DailyDownloadPoint,
11+
DateRangeFields,
12+
EvolutionData,
13+
MonthlyDownloadPoint,
14+
WeeklyDownloadPoint,
15+
YearlyDownloadPoint,
16+
} from '~/types/chart'
817
918
const props = defineProps<{
1019
// For single package downloads history
@@ -100,18 +109,6 @@ const accent = computed(() => {
100109
const mobileBreakpointWidth = 640
101110
const isMobile = computed(() => width.value > 0 && width.value < mobileBreakpointWidth)
102111
103-
type ChartTimeGranularity = 'daily' | 'weekly' | 'monthly' | 'yearly'
104-
type EvolutionData =
105-
| DailyDownloadPoint[]
106-
| WeeklyDownloadPoint[]
107-
| MonthlyDownloadPoint[]
108-
| YearlyDownloadPoint[]
109-
110-
type DateRangeFields = {
111-
startDate?: string
112-
endDate?: string
113-
}
114-
115112
function isRecord(value: unknown): value is Record<string, unknown> {
116113
return typeof value === 'object' && value !== null
117114
}
@@ -314,7 +311,10 @@ const effectivePackageNames = computed<string[]>(() => {
314311
return single ? [single] : []
315312
})
316313
317-
const selectedGranularity = shallowRef<ChartTimeGranularity>('weekly')
314+
const selectedGranularity = defineModel<ChartTimeGranularity>('granularity', {
315+
default: 'weekly',
316+
})
317+
318318
const displayedGranularity = shallowRef<ChartTimeGranularity>('weekly')
319319
320320
const isEndDateOnPeriodEnd = computed(() => {
@@ -344,8 +344,8 @@ const shouldRenderEstimationOverlay = computed(
344344
() => !pending.value && isEstimationGranularity.value,
345345
)
346346
347-
const startDate = shallowRef<string>('') // YYYY-MM-DD
348-
const endDate = shallowRef<string>('') // YYYY-MM-DD
347+
const startDate = defineModel<string>('startDate', { default: '' })
348+
const endDate = defineModel<string>('endDate', { default: '' })
349349
const hasUserEditedDates = shallowRef(false)
350350
351351
/**

app/components/Package/WeeklyDownloadStats.vue

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import { VueUiSparkline } from 'vue-data-ui/vue-ui-sparkline'
33
import { useCssVariables } from '~/composables/useColors'
4+
import type { ChartTimeGranularity, WeeklyDownloadPoint } from '~/types/chart'
45
import { OKLCH_NEUTRAL_FALLBACK, lightenOklch } from '~/utils/colors'
56
67
const props = defineProps<{
@@ -10,10 +11,19 @@ const props = defineProps<{
1011
1112
const chartModal = useModal('chart-modal')
1213
const hasChartModalTransitioned = shallowRef(false)
13-
const isChartModalOpen = shallowRef(false)
14+
15+
const modal = useRouteQuery<'downloads' | undefined>('modal')
16+
const granularity = useRouteQuery<ChartTimeGranularity | undefined>('granularity')
17+
const startDate = useRouteQuery<string | undefined>('start')
18+
const endDate = useRouteQuery<string | undefined>('end')
19+
20+
const isChartModalOpen = computed<boolean>(() => modal.value === 'downloads')
1421
1522
function handleModalClose() {
16-
isChartModalOpen.value = false
23+
modal.value = undefined
24+
granularity.value = undefined
25+
startDate.value = undefined
26+
endDate.value = undefined
1727
hasChartModalTransitioned.value = false
1828
}
1929
@@ -93,7 +103,7 @@ const hasWeeklyDownloads = computed(() => weeklyDownloads.value.length > 0)
93103
async function openChartModal() {
94104
if (!hasWeeklyDownloads.value) return
95105
96-
isChartModalOpen.value = true
106+
modal.value = 'downloads'
97107
hasChartModalTransitioned.value = false
98108
// ensure the component renders before opening the dialog
99109
await nextTick()
@@ -119,8 +129,11 @@ async function loadWeeklyDownloads() {
119129
}
120130
}
121131
122-
onMounted(() => {
123-
loadWeeklyDownloads()
132+
onMounted(async () => {
133+
await loadWeeklyDownloads()
134+
if (isChartModalOpen.value && hasWeeklyDownloads.value) {
135+
openChartModal()
136+
}
124137
})
125138
126139
watch(
@@ -287,6 +300,9 @@ const config = computed(() => {
287300
:inModal="true"
288301
:packageName="props.packageName"
289302
:createdIso="createdIso"
303+
v-model:granularity="granularity"
304+
v-model:startDate="startDate"
305+
v-model:endDate="endDate"
290306
/>
291307
</Transition>
292308

app/composables/useCharts.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
import type { MaybeRefOrGetter } from 'vue'
22
import { toValue } from 'vue'
3+
import type {
4+
DailyDownloadPoint,
5+
MonthlyDownloadPoint,
6+
WeeklyDownloadPoint,
7+
YearlyDownloadPoint,
8+
} from '~/types/chart'
39
import { fetchNpmDownloadsRange } from '~/utils/npm/api'
410

511
export type PackumentLikeForTime = {
612
time?: Record<string, string>
713
}
814

9-
export type DailyDownloadPoint = { downloads: number; day: string; timestamp: number }
10-
export type WeeklyDownloadPoint = {
11-
downloads: number
12-
weekKey: string
13-
weekStart: string
14-
weekEnd: string
15-
timestampStart: number
16-
timestampEnd: number
17-
}
18-
export type MonthlyDownloadPoint = { downloads: number; month: string; timestamp: number }
19-
export type YearlyDownloadPoint = { downloads: number; year: string; timestamp: number }
20-
2115
type PackageDownloadEvolutionOptionsBase = {
2216
startDate?: string
2317
endDate?: string

app/types/chart.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export type DailyDownloadPoint = { downloads: number; day: string; timestamp: number }
2+
export type WeeklyDownloadPoint = {
3+
downloads: number
4+
weekKey: string
5+
weekStart: string
6+
weekEnd: string
7+
timestampStart: number
8+
timestampEnd: number
9+
}
10+
export type MonthlyDownloadPoint = { downloads: number; month: string; timestamp: number }
11+
export type YearlyDownloadPoint = { downloads: number; year: string; timestamp: number }
12+
13+
export type ChartTimeGranularity = 'daily' | 'weekly' | 'monthly' | 'yearly'
14+
15+
export type EvolutionData =
16+
| DailyDownloadPoint[]
17+
| WeeklyDownloadPoint[]
18+
| MonthlyDownloadPoint[]
19+
| YearlyDownloadPoint[]
20+
21+
export type DateRangeFields = {
22+
startDate?: string
23+
endDate?: string
24+
}

0 commit comments

Comments
 (0)