@antelopejs/dms-marketing 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +3 -0
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -1
- package/dist/data-api/websites.d.ts +10 -4
- package/dist/data-api/websites.js +79 -3
- package/dist/data-api/websites.js.map +1 -1
- package/dist/db/models/page_snapshots.model.d.ts +2 -0
- package/dist/db/models/page_snapshots.model.js +6 -0
- package/dist/db/models/page_snapshots.model.js.map +1 -1
- package/dist/db/models/websites.model.d.ts +1 -0
- package/dist/db/models/websites.model.js +9 -0
- package/dist/db/models/websites.model.js.map +1 -1
- package/dist/db/tables/page_snapshots.table.d.ts +1 -0
- package/dist/db/tables/page_snapshots.table.js +4 -0
- package/dist/db/tables/page_snapshots.table.js.map +1 -1
- package/dist/db/tables/websites.table.d.ts +2 -0
- package/dist/db/tables/websites.table.js +4 -0
- package/dist/db/tables/websites.table.js.map +1 -1
- package/dist/frontend-module.d.ts +6 -0
- package/dist/frontend-module.js +46 -0
- package/dist/frontend-module.js.map +1 -0
- package/dist/index.js +3 -11
- package/dist/index.js.map +1 -1
- package/dist/pages/acquisition/page.d.ts +1 -0
- package/dist/pages/acquisition/page.js +9 -4
- package/dist/pages/acquisition/page.js.map +1 -1
- package/dist/pages/blocks.d.ts +11 -2
- package/dist/pages/blocks.js +43 -5
- package/dist/pages/blocks.js.map +1 -1
- package/dist/pages/funnel/page.d.ts +1 -0
- package/dist/pages/funnel/page.js +1 -0
- package/dist/pages/funnel/page.js.map +1 -1
- package/dist/pages/funnels/page.d.ts +1 -0
- package/dist/pages/funnels/page.js +4 -2
- package/dist/pages/funnels/page.js.map +1 -1
- package/dist/pages/overview/page.d.ts +1 -0
- package/dist/pages/overview/page.js +5 -6
- package/dist/pages/overview/page.js.map +1 -1
- package/dist/pages/pages/page.d.ts +1 -0
- package/dist/pages/pages/page.js +1 -0
- package/dist/pages/pages/page.js.map +1 -1
- package/dist/pages/settings/form.js +1 -0
- package/dist/pages/settings/form.js.map +1 -1
- package/dist/pages/websites/page.d.ts +2 -3
- package/dist/pages/websites/page.js +63 -5
- package/dist/pages/websites/page.js.map +1 -1
- package/dist/routes/dashboard-tracking.js +5 -1
- package/dist/routes/dashboard-tracking.js.map +1 -1
- package/dist/routes/funnels.d.ts +2 -0
- package/dist/routes/funnels.js +6 -5
- package/dist/routes/funnels.js.map +1 -1
- package/dist/routes/public-endpoints.js +1 -1
- package/dist/routes/public-endpoints.js.map +1 -1
- package/dist/routes/snapshot.d.ts +1 -1
- package/dist/routes/snapshot.js +30 -13
- package/dist/routes/snapshot.js.map +1 -1
- package/dist/routes/stats.d.ts +10 -4
- package/dist/routes/stats.js +77 -23
- package/dist/routes/stats.js.map +1 -1
- package/dist/routes/websites.d.ts +5 -1
- package/dist/routes/websites.js +31 -13
- package/dist/routes/websites.js.map +1 -1
- package/dist/services/acquisition-report.d.ts +1 -0
- package/dist/services/acquisition-report.js +1 -0
- package/dist/services/acquisition-report.js.map +1 -1
- package/dist/services/collect.js +7 -2
- package/dist/services/collect.js.map +1 -1
- package/dist/services/dashboard-tracking.d.ts +7 -14
- package/dist/services/dashboard-tracking.js +42 -26
- package/dist/services/dashboard-tracking.js.map +1 -1
- package/dist/services/funnels-table.d.ts +3 -2
- package/dist/services/funnels-table.js +9 -9
- package/dist/services/funnels-table.js.map +1 -1
- package/dist/services/heatmap.d.ts +6 -0
- package/dist/services/heatmap.js +82 -17
- package/dist/services/heatmap.js.map +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/prune.js +6 -1
- package/dist/services/prune.js.map +1 -1
- package/dist/services/realtime.d.ts +3 -0
- package/dist/services/realtime.js +49 -0
- package/dist/services/realtime.js.map +1 -0
- package/dist/services/request-body.d.ts +1 -0
- package/dist/services/request-body.js +18 -0
- package/dist/services/request-body.js.map +1 -1
- package/dist/services/sessionize.d.ts +1 -0
- package/dist/services/sessionize.js +9 -0
- package/dist/services/sessionize.js.map +1 -1
- package/dist/services/snapshots.d.ts +28 -1
- package/dist/services/snapshots.js +147 -26
- package/dist/services/snapshots.js.map +1 -1
- package/dist/services/tenant-website.d.ts +11 -0
- package/dist/services/tenant-website.js +27 -5
- package/dist/services/tenant-website.js.map +1 -1
- package/dist/services/website-report.d.ts +5 -0
- package/dist/services/website-report.js +13 -1
- package/dist/services/website-report.js.map +1 -1
- package/dist/services/workspace-scope.d.ts +31 -0
- package/dist/services/workspace-scope.js +72 -0
- package/dist/services/workspace-scope.js.map +1 -0
- package/dist/types/constants.d.ts +7 -0
- package/dist/types/constants.js +8 -1
- package/dist/types/constants.js.map +1 -1
- package/dist/types/events.d.ts +25 -25
- package/dist/types/snapshots.d.ts +29 -29
- package/dist/types/snapshots.js +1 -1
- package/dist/types/snapshots.js.map +1 -1
- package/dist/utils/funnel-steps-type.d.ts +13 -13
- package/frontend-vue/app/components/ChannelsCard.vue +19 -2
- package/frontend-vue/app/components/Context.vue +50 -376
- package/frontend-vue/app/components/FunnelBuilder.vue +28 -22
- package/frontend-vue/app/components/FunnelFigure.vue +15 -2
- package/frontend-vue/app/components/FunnelReport.vue +3 -0
- package/frontend-vue/app/components/FunnelTemplates.vue +15 -13
- package/frontend-vue/app/components/InstallGuide.vue +1 -1
- package/frontend-vue/app/components/PagePreview.vue +330 -74
- package/frontend-vue/app/components/PagesExplorer.vue +230 -85
- package/frontend-vue/app/components/TopListTabs.vue +51 -18
- package/frontend-vue/app/components/WebsiteCard.vue +394 -0
- package/frontend-vue/app/components/WebsiteCreate.vue +159 -0
- package/frontend-vue/app/components/WebsitePicker.vue +210 -0
- package/frontend-vue/app/components/WebsiteSettings.vue +539 -0
- package/frontend-vue/app/components/WorkspaceScope.vue +119 -0
- package/frontend-vue/app/composables/useContextWebsite.ts +105 -0
- package/frontend-vue/app/composables/useCopyDraft.ts +47 -0
- package/frontend-vue/app/composables/useMarketingApi.ts +92 -4
- package/frontend-vue/app/composables/useMarketingReads.ts +32 -23
- package/frontend-vue/app/composables/useMarketingRoutes.ts +25 -2
- package/frontend-vue/app/composables/useRecordCrumb.ts +17 -0
- package/frontend-vue/app/composables/useSnapshotFrame.ts +35 -1
- package/frontend-vue/app/utils/anchor-drift.ts +58 -0
- package/frontend-vue/app/utils/drift-dismissals.ts +20 -0
- package/frontend-vue/app/utils/fill-height.ts +141 -0
- package/frontend-vue/app/utils/format.ts +21 -2
- package/frontend-vue/app/utils/funnel-draft.ts +22 -0
- package/frontend-vue/app/utils/heatmap.ts +17 -0
- package/frontend-vue/app/utils/page-snapshot.ts +75 -0
- package/frontend-vue/app/utils/snapshot-options.ts +148 -0
- package/frontend-vue/app/utils/snapshotScrollRoot.ts +93 -0
- package/frontend-vue/app/utils/website-card.ts +93 -0
- package/frontend-vue/app/utils/website-purge.ts +95 -0
- package/frontend-vue/app/utils/website-settings.ts +121 -0
- package/frontend-vue/app/utils/website-state.ts +93 -0
- package/frontend-vue/app/utils/workspace-scope.ts +51 -0
- package/frontend-vue/i18n/locales/marketing-en-GB.json +112 -36
- package/frontend-vue/i18n/locales/marketing-fr-FR.json +112 -36
- package/frontend-vue/package.json +1 -1
- package/frontend-vue/tests/anchor-drift.test.ts +59 -0
- package/frontend-vue/tests/build-flags.test.ts +38 -0
- package/frontend-vue/tests/context-bar.test.ts +226 -0
- package/frontend-vue/tests/copy-draft.test.ts +64 -0
- package/frontend-vue/tests/drift-dismissals.test.ts +12 -0
- package/frontend-vue/tests/fill-height.test.ts +110 -0
- package/frontend-vue/tests/format.test.ts +14 -0
- package/frontend-vue/tests/funnel-draft.test.ts +37 -0
- package/frontend-vue/tests/heatmap.test.ts +25 -0
- package/frontend-vue/tests/install-guide.test.ts +25 -0
- package/frontend-vue/tests/marketing-reads.test.ts +20 -6
- package/frontend-vue/tests/page-snapshot.test.ts +62 -0
- package/frontend-vue/tests/record-crumb.test.ts +43 -0
- package/frontend-vue/tests/registration.test.ts +4 -1
- package/frontend-vue/tests/routes.test.ts +21 -0
- package/frontend-vue/tests/save-funnel.test.ts +47 -0
- package/frontend-vue/tests/server-parity.test.ts +3 -0
- package/frontend-vue/tests/snapshot-options.test.ts +148 -0
- package/frontend-vue/tests/snapshot-scroll-root.test.ts +84 -0
- package/frontend-vue/tests/stubs/frontend-module.ts +5 -1
- package/frontend-vue/tests/top-list-tabs.test.ts +158 -0
- package/frontend-vue/tests/website-card.test.ts +119 -0
- package/frontend-vue/tests/website-purge.test.ts +70 -0
- package/frontend-vue/tests/website-settings.test.ts +133 -0
- package/frontend-vue/tests/website-state.test.ts +96 -0
- package/frontend-vue/tests/workspace-scope-control.test.ts +113 -0
- package/frontend-vue/tests/workspace-scope.test.ts +55 -0
- package/package.json +5 -4
- package/skills/dms-marketing/SKILL.md +47 -6
- package/static/snapshot.js +539 -48
- package/static/tracker.js +154 -5
- package/frontend-vue/app/components/WebsitesGrid.vue +0 -812
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { useI18n } from '#dms/frontend-module'
|
|
4
|
+
import type { ContextWebsite } from '../composables/useMarketingContext'
|
|
5
|
+
import { useContextWebsite } from '../composables/useContextWebsite'
|
|
6
|
+
import { useMarketingNow } from '../composables/useMarketingNow'
|
|
7
|
+
import { installLink } from '../composables/useMarketingRoutes'
|
|
8
|
+
import { initials, utcDayStart } from '../utils/format'
|
|
9
|
+
import {
|
|
10
|
+
WEBSITE_STATE_DOTS,
|
|
11
|
+
websiteDisplayState,
|
|
12
|
+
websiteStateLine,
|
|
13
|
+
websiteStateShort,
|
|
14
|
+
} from '../utils/website-state'
|
|
15
|
+
import { MAX_PERIOD_DAYS, MS_PER_DAY, PERIOD_SCOPE } from '../constants'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The leading child of an analytics page's toolbar (`marketingToolbar()`):
|
|
19
|
+
* the website picker, its state (a dot and the age of its last event, the
|
|
20
|
+
* full line in a tooltip) and the period's hints. The toolbar puts Direct /
|
|
21
|
+
* Pause and the period after it.
|
|
22
|
+
*
|
|
23
|
+
* The website is the page's `?website=` (`useContextWebsite`): a pick saves
|
|
24
|
+
* it and writes the URL, which the blocks read through a `{{query.website}}`
|
|
25
|
+
* token. The websites' last events are read again on the module's arrivals,
|
|
26
|
+
* through the page's live gate (nothing while paused).
|
|
27
|
+
*/
|
|
28
|
+
const props = withDefaults(
|
|
29
|
+
defineProps<{
|
|
30
|
+
periodScope?: string
|
|
31
|
+
realtimeTopic?: string
|
|
32
|
+
}>(),
|
|
33
|
+
{
|
|
34
|
+
periodScope: PERIOD_SCOPE,
|
|
35
|
+
realtimeTopic: undefined,
|
|
36
|
+
},
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
/** How often the ages the picker shows ("1 min ago") move: display only. */
|
|
40
|
+
const CLOCK_TICK_MS = 15_000
|
|
41
|
+
|
|
42
|
+
const { t, locale } = useI18n()
|
|
43
|
+
const { size } = usePageToolbarSize()
|
|
44
|
+
const {
|
|
45
|
+
context,
|
|
46
|
+
failed,
|
|
47
|
+
websites,
|
|
48
|
+
selectedId,
|
|
49
|
+
selected,
|
|
50
|
+
switching,
|
|
51
|
+
select,
|
|
52
|
+
reload,
|
|
53
|
+
} = useContextWebsite()
|
|
54
|
+
|
|
55
|
+
usePageLiveRefresh(() => void reload(), {
|
|
56
|
+
realtimeTopic: props.realtimeTopic,
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const now = useMarketingNow(CLOCK_TICK_MS)
|
|
60
|
+
const period = usePeriodScope(props.periodScope)
|
|
61
|
+
|
|
62
|
+
/** A custom range longer than the routes read: only its last days are shown. */
|
|
63
|
+
const cutHint = computed(() => {
|
|
64
|
+
const range = selected.value ? period.value?.range : null
|
|
65
|
+
if (!range) {
|
|
66
|
+
return ''
|
|
67
|
+
}
|
|
68
|
+
const days = Math.round(
|
|
69
|
+
(range.to.getTime() - range.from.getTime()) / MS_PER_DAY,
|
|
70
|
+
)
|
|
71
|
+
return days > MAX_PERIOD_DAYS
|
|
72
|
+
? t('page.marketing.context.range_cut', { days: MAX_PERIOD_DAYS })
|
|
73
|
+
: ''
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const displayState = (site: ContextWebsite) =>
|
|
77
|
+
websiteDisplayState(site, now.value)
|
|
78
|
+
|
|
79
|
+
const stateLine = (site: ContextWebsite) =>
|
|
80
|
+
websiteStateLine(site, now.value, t, locale.value)
|
|
81
|
+
|
|
82
|
+
const stateShort = (site: ContextWebsite) =>
|
|
83
|
+
websiteStateShort(site, now.value, t, locale.value)
|
|
84
|
+
|
|
85
|
+
const websiteItems = computed(() => [
|
|
86
|
+
websites.value.map((site) => ({
|
|
87
|
+
label: site.name,
|
|
88
|
+
description: site.domain,
|
|
89
|
+
type: 'checkbox' as const,
|
|
90
|
+
checked: site.id === selectedId.value,
|
|
91
|
+
slot: 'website' as const,
|
|
92
|
+
site,
|
|
93
|
+
onSelect: () => void select(site.id),
|
|
94
|
+
})),
|
|
95
|
+
[
|
|
96
|
+
{
|
|
97
|
+
label: t('page.marketing.context.add_website'),
|
|
98
|
+
icon: 'i-ph-plus',
|
|
99
|
+
to: installLink(),
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
])
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The statistics are kept per UTC day: where the reader's midnight is not
|
|
106
|
+
* UTC's, the state's tooltip says when their days really start.
|
|
107
|
+
*/
|
|
108
|
+
const utcHint = computed(() => {
|
|
109
|
+
// The reader's zone: the browser's, which a server render reads from its
|
|
110
|
+
// cookie.
|
|
111
|
+
const time = utcDayStart(now.value, locale.value, readerTimeZone())
|
|
112
|
+
return time ? t('page.marketing.context.utc_days', { time }) : ''
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
/** The full state line and the UTC days: the compact state's name. */
|
|
116
|
+
const stateHint = computed(() =>
|
|
117
|
+
selected.value
|
|
118
|
+
? [stateLine(selected.value), utcHint.value].filter(Boolean).join('. ')
|
|
119
|
+
: '',
|
|
120
|
+
)
|
|
121
|
+
</script>
|
|
122
|
+
|
|
123
|
+
<template>
|
|
124
|
+
<USkeleton v-if="!context && !failed" class="h-7 w-72" />
|
|
125
|
+
<!-- One group, tighter than the toolbar's gaps: with the live toggle and
|
|
126
|
+
the period, the bar stays on one line at desktop width. -->
|
|
127
|
+
<div
|
|
128
|
+
v-else-if="selected"
|
|
129
|
+
class="flex min-w-0 flex-wrap items-center gap-2"
|
|
130
|
+
data-website-picker
|
|
131
|
+
>
|
|
132
|
+
<UDropdownMenu :items="websiteItems" :content="{ align: 'start' }">
|
|
133
|
+
<UButton
|
|
134
|
+
color="neutral"
|
|
135
|
+
variant="outline"
|
|
136
|
+
:size="size"
|
|
137
|
+
trailing-icon="i-ph-caret-up-down"
|
|
138
|
+
:loading="switching"
|
|
139
|
+
:aria-label="t('page.marketing.context.switch_website')"
|
|
140
|
+
>
|
|
141
|
+
<span
|
|
142
|
+
class="grid size-5 place-items-center rounded bg-primary/15 font-mono text-[10px] font-semibold text-(--ui-color-primary-800) dark:text-primary"
|
|
143
|
+
>
|
|
144
|
+
{{ initials(selected.name) }}
|
|
145
|
+
</span>
|
|
146
|
+
<span class="font-semibold">{{ selected.name }}</span>
|
|
147
|
+
</UButton>
|
|
148
|
+
<template #website="{ item }">
|
|
149
|
+
<span
|
|
150
|
+
class="grid size-6 shrink-0 place-items-center rounded bg-primary/15 font-mono text-[10px] font-semibold text-(--ui-color-primary-800) dark:text-primary"
|
|
151
|
+
>
|
|
152
|
+
{{ initials(item.site.name) }}
|
|
153
|
+
</span>
|
|
154
|
+
<span class="min-w-0 flex-1 text-left">
|
|
155
|
+
<span class="block truncate text-sm font-medium text-highlighted">
|
|
156
|
+
{{ item.site.name }}
|
|
157
|
+
</span>
|
|
158
|
+
<span class="flex min-w-0 items-center gap-1.5 text-xs text-dimmed">
|
|
159
|
+
<span
|
|
160
|
+
class="size-1.5 shrink-0 rounded-full"
|
|
161
|
+
:class="WEBSITE_STATE_DOTS[displayState(item.site)]"
|
|
162
|
+
aria-hidden="true"
|
|
163
|
+
/>
|
|
164
|
+
<span class="truncate font-mono">{{ item.site.domain }}</span>
|
|
165
|
+
<span class="shrink-0">· {{ stateLine(item.site) }}</span>
|
|
166
|
+
</span>
|
|
167
|
+
</span>
|
|
168
|
+
<UIcon
|
|
169
|
+
v-if="item.checked"
|
|
170
|
+
name="i-ph-check"
|
|
171
|
+
class="size-4 shrink-0 text-primary"
|
|
172
|
+
/>
|
|
173
|
+
</template>
|
|
174
|
+
</UDropdownMenu>
|
|
175
|
+
|
|
176
|
+
<UTooltip>
|
|
177
|
+
<span
|
|
178
|
+
class="flex items-center gap-1.5 text-xs whitespace-nowrap text-muted tabular-nums"
|
|
179
|
+
role="status"
|
|
180
|
+
tabindex="0"
|
|
181
|
+
:aria-label="stateHint"
|
|
182
|
+
>
|
|
183
|
+
<span
|
|
184
|
+
class="size-2 rounded-full"
|
|
185
|
+
:class="WEBSITE_STATE_DOTS[displayState(selected)]"
|
|
186
|
+
aria-hidden="true"
|
|
187
|
+
/>
|
|
188
|
+
<span aria-hidden="true">{{ stateShort(selected) }}</span>
|
|
189
|
+
</span>
|
|
190
|
+
<template #content>
|
|
191
|
+
<span class="grid max-w-72 gap-1">
|
|
192
|
+
<span>{{ stateLine(selected) }}</span>
|
|
193
|
+
<span v-if="utcHint" class="text-dimmed">{{ utcHint }}</span>
|
|
194
|
+
</span>
|
|
195
|
+
</template>
|
|
196
|
+
</UTooltip>
|
|
197
|
+
|
|
198
|
+
<span
|
|
199
|
+
v-if="cutHint"
|
|
200
|
+
class="flex items-center gap-1 text-xs text-warning"
|
|
201
|
+
role="status"
|
|
202
|
+
>
|
|
203
|
+
<UIcon name="i-ph-warning" class="size-3.5 shrink-0" />
|
|
204
|
+
{{ cutHint }}
|
|
205
|
+
</span>
|
|
206
|
+
</div>
|
|
207
|
+
<span v-else-if="!failed" class="text-sm text-muted">
|
|
208
|
+
{{ t('page.marketing.context.no_website') }}
|
|
209
|
+
</span>
|
|
210
|
+
</template>
|