@antelopejs/dms-mailing 0.4.1 → 0.5.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.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/frontend-vue/app/components/CategoriesInput.vue +7 -14
  3. package/frontend-vue/app/components/DuplicateModal.vue +9 -3
  4. package/frontend-vue/app/components/Editor.vue +3 -3
  5. package/frontend-vue/app/components/NewTemplateModal.vue +9 -3
  6. package/frontend-vue/app/components/OverviewGate.vue +20 -29
  7. package/frontend-vue/app/components/PageHeader.vue +8 -12
  8. package/frontend-vue/app/components/RealSendModal.vue +3 -1
  9. package/frontend-vue/app/components/RenderingModal.vue +5 -7
  10. package/frontend-vue/app/components/RetentionInput.vue +13 -23
  11. package/frontend-vue/app/components/SendDrawer.vue +5 -2
  12. package/frontend-vue/app/components/StarterGallery.vue +11 -9
  13. package/frontend-vue/app/components/TemplateCard.vue +19 -4
  14. package/frontend-vue/app/components/TemplateDrawer.vue +8 -2
  15. package/frontend-vue/app/components/TemplateGallery.vue +25 -20
  16. package/frontend-vue/app/components/TemplatePreviewFrame.vue +8 -6
  17. package/frontend-vue/app/components/TestSendModal.vue +3 -1
  18. package/frontend-vue/app/components/VersionHistory.vue +3 -3
  19. package/frontend-vue/app/components/WebhookStatus.vue +20 -17
  20. package/frontend-vue/app/components/editor/EditorWorkspace.vue +5 -0
  21. package/frontend-vue/app/composables/useEditorActions.ts +3 -1
  22. package/frontend-vue/app/composables/useEditorSession.ts +6 -4
  23. package/frontend-vue/app/composables/useMailingApi.ts +5 -58
  24. package/frontend-vue/app/composables/useMailingReads.ts +229 -0
  25. package/frontend-vue/app/composables/useOverviewSetup.ts +15 -7
  26. package/frontend-vue/app/composables/useTemplateCategories.ts +8 -27
  27. package/frontend-vue/app/utils/gallery.ts +19 -7
  28. package/frontend-vue/app/utils/period.ts +0 -5
  29. package/frontend-vue/package.json +1 -1
  30. package/frontend-vue/tests/categories-input.test.ts +43 -13
  31. package/frontend-vue/tests/editor-session.test.ts +4 -0
  32. package/frontend-vue/tests/gallery.test.ts +16 -0
  33. package/frontend-vue/tests/helpers/api-data.ts +173 -0
  34. package/frontend-vue/tests/new-template-modal.test.ts +17 -5
  35. package/frontend-vue/tests/on-demand-reads.test.ts +81 -0
  36. package/frontend-vue/tests/overview-gate.test.ts +59 -21
  37. package/frontend-vue/tests/page-reads.test.ts +157 -0
  38. package/frontend-vue/tests/period.test.ts +0 -9
  39. package/frontend-vue/tests/retention-input.test.ts +30 -9
  40. package/frontend-vue/tests/send-modals.test.ts +8 -1
  41. package/frontend-vue/tests/template-drawer.test.ts +30 -14
  42. package/frontend-vue/tests/template-gallery.test.ts +45 -24
  43. package/package.json +2 -2
@@ -12,15 +12,15 @@ import {
12
12
  type NuxtStubs,
13
13
  } from './helpers/nuxt-globals'
14
14
 
15
- const api = {
16
- listCategories: vi.fn(),
17
- templatesOverview: vi.fn(),
18
- listTemplates: vi.fn(),
19
- }
15
+ import {
16
+ stubApiData,
17
+ stubRegionalFormat,
18
+ type ApiDataStub,
19
+ } from './helpers/api-data'
20
20
 
21
- vi.mock('../app/composables/useMailingApi', () => ({
22
- useMailingApi: () => api,
23
- }))
21
+ const CATEGORIES_URL = '/api/mailing/templates/categories'
22
+ const OVERVIEW_URL = '/api/mailing/templates/overview'
23
+ const LIST_URL = '/api/mailing/tables/templates/list'
24
24
 
25
25
  const RECENT = new Date(Date.now() - 3_600_000).toISOString()
26
26
 
@@ -114,22 +114,32 @@ const globals = {
114
114
  }
115
115
 
116
116
  let stubs: NuxtStubs
117
+ let api: ApiDataStub
117
118
  let routeQuery: Record<string, unknown> = {}
119
+ let templateTotal = 3
120
+
121
+ const readsOf = (url: string) => api.reads.filter((read) => read.url === url)
118
122
 
119
123
  beforeEach(() => {
120
124
  stubs = stubNuxtGlobals()
125
+ stubRegionalFormat()
121
126
  routeQuery = {}
127
+ templateTotal = 3
122
128
  vi.stubGlobal('useDmsRoute', () => ({ query: routeQuery }))
123
- api.listCategories.mockResolvedValue({
124
- categories: [
125
- { id: 'orders', label: 'Orders', icon: 'i-ph-package' },
126
- { id: 'billing', label: 'Billing', icon: 'i-ph-file-text' },
127
- ],
128
- })
129
- api.templatesOverview.mockResolvedValue({
130
- items: [stats('live', 6812), stats('missing', 12)],
129
+ api = stubApiData()
130
+ api.respond(({ url }) => {
131
+ if (url === CATEGORIES_URL)
132
+ return {
133
+ categories: [
134
+ { id: 'orders', label: 'Orders', icon: 'i-ph-package' },
135
+ { id: 'billing', label: 'Billing', icon: 'i-ph-file-text' },
136
+ ],
137
+ }
138
+ if (url === OVERVIEW_URL)
139
+ return { items: [stats('live', 6812), stats('missing', 12)] }
140
+ if (url === LIST_URL) return { results: [LIVE], total: templateTotal }
141
+ throw new Error(`unexpected read ${url}`)
131
142
  })
132
- api.listTemplates.mockResolvedValue({ results: [], total: 3 })
133
143
  })
134
144
 
135
145
  afterEach(() => {
@@ -206,21 +216,32 @@ describe('TemplateGallery', () => {
206
216
  cleared.unmount()
207
217
  })
208
218
 
219
+ it('reads the template count alone, not the rows', async () => {
220
+ const view = mount(
221
+ TemplateGallery,
222
+ { context: context({ items: [LIVE] }) },
223
+ globals,
224
+ )
225
+ await flush()
226
+ expect(readsOf(LIST_URL)).toEqual([
227
+ { url: LIST_URL, query: { limit: '1' } },
228
+ ])
229
+ view.unmount()
230
+ })
231
+
209
232
  it('reloads the figures when the table refreshes, not when it pages', async () => {
210
- api.listTemplates.mockClear()
211
- api.templatesOverview.mockClear()
212
233
  const ctx = reactive(context({ items: [LIVE] }))
213
234
  const view = mount(TemplateGallery, { context: ctx }, globals)
214
235
  await flush()
215
- expect(api.listTemplates).toHaveBeenCalledTimes(1)
236
+ expect(readsOf(LIST_URL)).toHaveLength(1)
216
237
  ctx.items = [LIVE]
217
238
  await flush()
218
- expect(api.listTemplates).toHaveBeenCalledTimes(2)
219
- expect(api.templatesOverview).toHaveBeenCalledTimes(2)
239
+ expect(readsOf(LIST_URL)).toHaveLength(2)
240
+ expect(readsOf(OVERVIEW_URL)).toHaveLength(2)
220
241
  ctx.pagination.pageIndex = 1
221
242
  ctx.items = [MISSING_DE]
222
243
  await flush()
223
- expect(api.listTemplates).toHaveBeenCalledTimes(2)
244
+ expect(readsOf(LIST_URL)).toHaveLength(2)
224
245
  view.unmount()
225
246
  })
226
247
 
@@ -262,7 +283,7 @@ describe('TemplateGallery', () => {
262
283
  })
263
284
 
264
285
  it('shows the starters on a first run', async () => {
265
- api.listTemplates.mockResolvedValue({ results: [], total: 0 })
286
+ templateTotal = 0
266
287
  const view = mount(
267
288
  TemplateGallery,
268
289
  { context: context({ items: [] }) },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms-mailing",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -38,7 +38,7 @@
38
38
  "@antelopejs/interface-data-api": ">=0.2.1 <1.0.0",
39
39
  "@antelopejs/interface-database": ">=0.1.9 <1.0.0",
40
40
  "@antelopejs/interface-database-decorators": ">=0.1.7 <1.0.0",
41
- "@antelopejs/interface-dms": ">=0.6.0 <1.0.0",
41
+ "@antelopejs/interface-dms": ">=0.7.0 <1.0.0",
42
42
  "@antelopejs/interface-dms-mailing": ">=0.7.0 <0.8.0",
43
43
  "@antelopejs/interface-email": ">=0.0.5 <1.0.0",
44
44
  "node-cron": "^4.2.1",