@antelopejs/dms-mailing 0.4.0 → 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.
- package/README.md +1 -1
- package/dist/pages/sends.js +2 -2
- package/dist/pages/sends.js.map +1 -1
- package/dist/pages/suppressions.js +2 -2
- package/dist/pages/suppressions.js.map +1 -1
- package/dist/pages/templates.js +3 -3
- package/dist/pages/templates.js.map +1 -1
- package/frontend-vue/app/components/CategoriesInput.vue +7 -14
- package/frontend-vue/app/components/DuplicateModal.vue +9 -3
- package/frontend-vue/app/components/Editor.vue +3 -3
- package/frontend-vue/app/components/NewTemplateModal.vue +9 -3
- package/frontend-vue/app/components/OverviewGate.vue +20 -29
- package/frontend-vue/app/components/PageHeader.vue +8 -12
- package/frontend-vue/app/components/RealSendModal.vue +3 -1
- package/frontend-vue/app/components/RenderingModal.vue +5 -7
- package/frontend-vue/app/components/RetentionInput.vue +13 -23
- package/frontend-vue/app/components/SendDrawer.vue +5 -2
- package/frontend-vue/app/components/StarterGallery.vue +11 -9
- package/frontend-vue/app/components/TemplateCard.vue +19 -4
- package/frontend-vue/app/components/TemplateDrawer.vue +8 -2
- package/frontend-vue/app/components/TemplateGallery.vue +25 -20
- package/frontend-vue/app/components/TemplatePreviewFrame.vue +8 -6
- package/frontend-vue/app/components/TestSendModal.vue +3 -1
- package/frontend-vue/app/components/VersionHistory.vue +3 -3
- package/frontend-vue/app/components/WebhookStatus.vue +20 -17
- package/frontend-vue/app/components/editor/EditorWorkspace.vue +5 -0
- package/frontend-vue/app/composables/useEditorActions.ts +3 -1
- package/frontend-vue/app/composables/useEditorSession.ts +6 -4
- package/frontend-vue/app/composables/useMailingApi.ts +5 -58
- package/frontend-vue/app/composables/useMailingReads.ts +229 -0
- package/frontend-vue/app/composables/useOverviewSetup.ts +15 -7
- package/frontend-vue/app/composables/useTemplateCategories.ts +8 -27
- package/frontend-vue/app/utils/gallery.ts +19 -7
- package/frontend-vue/app/utils/period.ts +0 -5
- package/frontend-vue/package.json +1 -1
- package/frontend-vue/tests/block-components.test.ts +0 -3
- package/frontend-vue/tests/categories-input.test.ts +44 -13
- package/frontend-vue/tests/conditions.test.ts +0 -2
- package/frontend-vue/tests/editor-block-list.test.ts +1 -0
- package/frontend-vue/tests/editor-session.test.ts +5 -0
- package/frontend-vue/tests/footer-block.test.ts +1 -0
- package/frontend-vue/tests/funnel-card.test.ts +1 -0
- package/frontend-vue/tests/gallery.test.ts +16 -0
- package/frontend-vue/tests/helpers/api-data.ts +173 -0
- package/frontend-vue/tests/i18n-editor.test.ts +0 -9
- package/frontend-vue/tests/new-template-modal.test.ts +18 -5
- package/frontend-vue/tests/on-demand-reads.test.ts +81 -0
- package/frontend-vue/tests/overview-gate.test.ts +60 -21
- package/frontend-vue/tests/page-reads.test.ts +157 -0
- package/frontend-vue/tests/period.test.ts +0 -9
- package/frontend-vue/tests/retention-input.test.ts +31 -9
- package/frontend-vue/tests/send-modals.test.ts +9 -1
- package/frontend-vue/tests/shortcuts.test.ts +1 -0
- package/frontend-vue/tests/template-drawer.test.ts +31 -14
- package/frontend-vue/tests/template-gallery.test.ts +46 -24
- package/frontend-vue/tests/variable-path.test.ts +1 -0
- package/frontend-vue/vitest.config.ts +4 -1
- package/package.json +5 -5
- package/src/pages/sends.ts +2 -2
- package/src/pages/suppressions.ts +2 -2
- package/src/pages/templates.ts +3 -3
- package/frontend-vue/tests/smoke.test.ts +0 -8
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
1
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
3
|
import { computed, createApp, h, nextTick, reactive, type App } from 'vue'
|
|
3
4
|
import RetentionInput from '../app/components/RetentionInput.vue'
|
|
@@ -7,15 +8,14 @@ import {
|
|
|
7
8
|
stubNuxtGlobals,
|
|
8
9
|
type NuxtStubs,
|
|
9
10
|
} from './helpers/nuxt-globals'
|
|
11
|
+
import {
|
|
12
|
+
stubApiData,
|
|
13
|
+
stubRegionalFormat,
|
|
14
|
+
type ApiDataStub,
|
|
15
|
+
} from './helpers/api-data'
|
|
10
16
|
import type { RetentionPreview } from '../app/types/mailing'
|
|
11
17
|
|
|
12
|
-
const
|
|
13
|
-
retentionPreview: vi.fn(),
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
vi.mock('../app/composables/useMailingApi', () => ({
|
|
17
|
-
useMailingApi: () => api,
|
|
18
|
-
}))
|
|
18
|
+
const PREVIEW_URL = '/api/mailing/settings/retention-preview'
|
|
19
19
|
|
|
20
20
|
const SAVED_DAYS = 90
|
|
21
21
|
const DEBOUNCE_MS = 400
|
|
@@ -70,15 +70,37 @@ function segmented(host: HTMLElement): HTMLElement {
|
|
|
70
70
|
|
|
71
71
|
describe('RetentionInput', () => {
|
|
72
72
|
let stubs: NuxtStubs
|
|
73
|
+
let api: ApiDataStub
|
|
73
74
|
let harness: Harness | undefined
|
|
74
75
|
|
|
75
76
|
beforeEach(() => {
|
|
76
77
|
vi.useFakeTimers()
|
|
77
78
|
stubs = stubNuxtGlobals()
|
|
78
79
|
vi.stubGlobal('computed', computed)
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
stubRegionalFormat()
|
|
81
|
+
api = stubApiData()
|
|
82
|
+
api.respond(({ query }) => {
|
|
83
|
+
const days = Number(query.days)
|
|
84
|
+
return preview(days, days < SAVED_DAYS ? 3 : 0)
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('reads the saved days at once, then the days picked once they hold still', async () => {
|
|
89
|
+
harness = mountRetention()
|
|
90
|
+
await flush()
|
|
91
|
+
expect(api.reads).toEqual([
|
|
92
|
+
{ url: PREVIEW_URL, query: { days: String(SAVED_DAYS) } },
|
|
93
|
+
])
|
|
94
|
+
expect(harness.host.textContent).toContain(
|
|
95
|
+
'dms_mailing.settings.retention.preview_none',
|
|
81
96
|
)
|
|
97
|
+
harness.state.days = 30
|
|
98
|
+
await nextTick()
|
|
99
|
+
harness.state.days = 365
|
|
100
|
+
await nextTick()
|
|
101
|
+
await vi.advanceTimersByTimeAsync(DEBOUNCE_MS)
|
|
102
|
+
await flush()
|
|
103
|
+
expect(api.reads.map((read) => read.query.days)).toEqual(['90', '365'])
|
|
82
104
|
})
|
|
83
105
|
|
|
84
106
|
afterEach(() => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
1
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
3
|
import RealSendModal from '../app/components/RealSendModal.vue'
|
|
3
4
|
import RecipientsField from '../app/components/RecipientsField.vue'
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
typeInto,
|
|
17
18
|
type NuxtStubs,
|
|
18
19
|
} from './helpers/nuxt-globals'
|
|
20
|
+
import { mailingReads, stubApiData } from './helpers/api-data'
|
|
19
21
|
|
|
20
22
|
const api = {
|
|
21
23
|
templateContent: vi.fn(),
|
|
@@ -24,7 +26,8 @@ const api = {
|
|
|
24
26
|
realSend: vi.fn(),
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
vi.mock('../app/composables/useMailingApi', () => ({
|
|
29
|
+
vi.mock('../app/composables/useMailingApi', async (importOriginal) => ({
|
|
30
|
+
...(await importOriginal<object>()),
|
|
28
31
|
useMailingApi: () => api,
|
|
29
32
|
}))
|
|
30
33
|
|
|
@@ -101,6 +104,11 @@ let stubs: NuxtStubs
|
|
|
101
104
|
|
|
102
105
|
beforeEach(() => {
|
|
103
106
|
stubs = stubNuxtGlobals('camille@acme.com')
|
|
107
|
+
stubApiData().respond(
|
|
108
|
+
mailingReads({ templateContent: api.templateContent }, ({ url }) => {
|
|
109
|
+
throw new Error(`unexpected read ${url}`)
|
|
110
|
+
}),
|
|
111
|
+
)
|
|
104
112
|
api.preview.mockResolvedValue({
|
|
105
113
|
html: '',
|
|
106
114
|
subject: '20% off every chair',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
1
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
3
|
import DuplicateModal from '../app/components/DuplicateModal.vue'
|
|
3
4
|
import StarterGallery from '../app/components/StarterGallery.vue'
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
typeInto,
|
|
17
18
|
type NuxtStubs,
|
|
18
19
|
} from './helpers/nuxt-globals'
|
|
20
|
+
import { mailingReads, stubApiData } from './helpers/api-data'
|
|
19
21
|
|
|
20
22
|
const api = {
|
|
21
23
|
templateContent: vi.fn(),
|
|
@@ -28,12 +30,12 @@ const api = {
|
|
|
28
30
|
listTemplates: vi.fn(),
|
|
29
31
|
duplicate: vi.fn(),
|
|
30
32
|
starters: vi.fn(),
|
|
31
|
-
listCategories: vi.fn(),
|
|
32
33
|
createTemplate: vi.fn(),
|
|
33
34
|
saveTemplateDetails: vi.fn(),
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
vi.mock('../app/composables/useMailingApi', () => ({
|
|
37
|
+
vi.mock('../app/composables/useMailingApi', async (importOriginal) => ({
|
|
38
|
+
...(await importOriginal<object>()),
|
|
37
39
|
useMailingApi: () => api,
|
|
38
40
|
}))
|
|
39
41
|
|
|
@@ -107,9 +109,27 @@ const globals = {
|
|
|
107
109
|
|
|
108
110
|
let stubs: NuxtStubs
|
|
109
111
|
|
|
112
|
+
let starters: unknown[] = []
|
|
113
|
+
|
|
110
114
|
beforeEach(() => {
|
|
111
115
|
stubs = stubNuxtGlobals()
|
|
112
116
|
menuGroups = []
|
|
117
|
+
starters = []
|
|
118
|
+
stubApiData().respond(
|
|
119
|
+
mailingReads(
|
|
120
|
+
{
|
|
121
|
+
templateContent: api.templateContent,
|
|
122
|
+
performance: api.performance,
|
|
123
|
+
listTemplates: api.listTemplates,
|
|
124
|
+
},
|
|
125
|
+
({ url }) => {
|
|
126
|
+
if (url === '/api/mailing/templates/categories')
|
|
127
|
+
return { categories: [] }
|
|
128
|
+
if (url === '/api/mailing/templates/starters') return { starters }
|
|
129
|
+
throw new Error(`unexpected read ${url}`)
|
|
130
|
+
},
|
|
131
|
+
),
|
|
132
|
+
)
|
|
113
133
|
api.performance.mockResolvedValue({
|
|
114
134
|
id: 't1',
|
|
115
135
|
slug: 'order-confirmed',
|
|
@@ -402,18 +422,15 @@ describe('DuplicateModal', () => {
|
|
|
402
422
|
|
|
403
423
|
describe('StarterGallery', () => {
|
|
404
424
|
beforeEach(() => {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
],
|
|
415
|
-
})
|
|
416
|
-
api.listCategories.mockResolvedValue({ categories: [] })
|
|
425
|
+
starters = [
|
|
426
|
+
{
|
|
427
|
+
id: 'order-confirmed',
|
|
428
|
+
name: 'Order confirmation',
|
|
429
|
+
slug: 'order-confirmed',
|
|
430
|
+
category: 'orders',
|
|
431
|
+
locales: ['en'],
|
|
432
|
+
},
|
|
433
|
+
]
|
|
417
434
|
})
|
|
418
435
|
|
|
419
436
|
it('creates a starter as a draft and opens it', async () => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
1
2
|
import { reactive } from 'vue'
|
|
2
3
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
4
|
import TemplateGallery from '../app/components/TemplateGallery.vue'
|
|
@@ -11,15 +12,15 @@ import {
|
|
|
11
12
|
type NuxtStubs,
|
|
12
13
|
} from './helpers/nuxt-globals'
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
15
|
+
import {
|
|
16
|
+
stubApiData,
|
|
17
|
+
stubRegionalFormat,
|
|
18
|
+
type ApiDataStub,
|
|
19
|
+
} from './helpers/api-data'
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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'
|
|
23
24
|
|
|
24
25
|
const RECENT = new Date(Date.now() - 3_600_000).toISOString()
|
|
25
26
|
|
|
@@ -113,22 +114,32 @@ const globals = {
|
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
let stubs: NuxtStubs
|
|
117
|
+
let api: ApiDataStub
|
|
116
118
|
let routeQuery: Record<string, unknown> = {}
|
|
119
|
+
let templateTotal = 3
|
|
120
|
+
|
|
121
|
+
const readsOf = (url: string) => api.reads.filter((read) => read.url === url)
|
|
117
122
|
|
|
118
123
|
beforeEach(() => {
|
|
119
124
|
stubs = stubNuxtGlobals()
|
|
125
|
+
stubRegionalFormat()
|
|
120
126
|
routeQuery = {}
|
|
127
|
+
templateTotal = 3
|
|
121
128
|
vi.stubGlobal('useDmsRoute', () => ({ query: routeQuery }))
|
|
122
|
-
api
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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}`)
|
|
130
142
|
})
|
|
131
|
-
api.listTemplates.mockResolvedValue({ results: [], total: 3 })
|
|
132
143
|
})
|
|
133
144
|
|
|
134
145
|
afterEach(() => {
|
|
@@ -205,21 +216,32 @@ describe('TemplateGallery', () => {
|
|
|
205
216
|
cleared.unmount()
|
|
206
217
|
})
|
|
207
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
|
+
|
|
208
232
|
it('reloads the figures when the table refreshes, not when it pages', async () => {
|
|
209
|
-
api.listTemplates.mockClear()
|
|
210
|
-
api.templatesOverview.mockClear()
|
|
211
233
|
const ctx = reactive(context({ items: [LIVE] }))
|
|
212
234
|
const view = mount(TemplateGallery, { context: ctx }, globals)
|
|
213
235
|
await flush()
|
|
214
|
-
expect(
|
|
236
|
+
expect(readsOf(LIST_URL)).toHaveLength(1)
|
|
215
237
|
ctx.items = [LIVE]
|
|
216
238
|
await flush()
|
|
217
|
-
expect(
|
|
218
|
-
expect(
|
|
239
|
+
expect(readsOf(LIST_URL)).toHaveLength(2)
|
|
240
|
+
expect(readsOf(OVERVIEW_URL)).toHaveLength(2)
|
|
219
241
|
ctx.pagination.pageIndex = 1
|
|
220
242
|
ctx.items = [MISSING_DE]
|
|
221
243
|
await flush()
|
|
222
|
-
expect(
|
|
244
|
+
expect(readsOf(LIST_URL)).toHaveLength(2)
|
|
223
245
|
view.unmount()
|
|
224
246
|
})
|
|
225
247
|
|
|
@@ -261,7 +283,7 @@ describe('TemplateGallery', () => {
|
|
|
261
283
|
})
|
|
262
284
|
|
|
263
285
|
it('shows the starters on a first run', async () => {
|
|
264
|
-
|
|
286
|
+
templateTotal = 0
|
|
265
287
|
const view = mount(
|
|
266
288
|
TemplateGallery,
|
|
267
289
|
{ context: context({ items: [] }) },
|
|
@@ -4,7 +4,10 @@ import { defineConfig } from 'vitest/config'
|
|
|
4
4
|
export default defineConfig({
|
|
5
5
|
plugins: [vue()],
|
|
6
6
|
test: {
|
|
7
|
-
|
|
7
|
+
// Most suites need no DOM, and setting jsdom up per file is the bulk of
|
|
8
|
+
// the run; the files that mount components opt in with a
|
|
9
|
+
// `// @vitest-environment jsdom` header.
|
|
10
|
+
environment: 'node',
|
|
8
11
|
include: ['tests/**/*.test.ts'],
|
|
9
12
|
},
|
|
10
13
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antelopejs/dms-mailing",
|
|
3
|
-
"version": "0.
|
|
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.
|
|
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",
|
|
@@ -86,9 +86,9 @@
|
|
|
86
86
|
"knip:all": "knip",
|
|
87
87
|
"release": "pnpm --filter @antelopejs/interface-dms-mailing build && pnpm --dir frontend-vue install --frozen-lockfile && release-it",
|
|
88
88
|
"test": "pnpm run test:backend && pnpm run test:layer",
|
|
89
|
-
"test:backend": "pnpm run build && ajs module test .",
|
|
89
|
+
"test:backend": "([ -n \"$DMS_PREBUILT\" ] || pnpm run build) && ajs module test .",
|
|
90
90
|
"test:layer": "cd frontend-vue && pnpm test",
|
|
91
|
-
"test:unit": "pnpm run build && DMS_MAILING_TEST_DIR=dist/test/unit ajs module test .",
|
|
92
|
-
"test:integration": "pnpm run build && DMS_MAILING_TEST_DIR=dist/test/integration ajs module test ."
|
|
91
|
+
"test:unit": "([ -n \"$DMS_PREBUILT\" ] || pnpm run build) && DMS_MAILING_TEST_DIR=dist/test/unit ajs module test .",
|
|
92
|
+
"test:integration": "([ -n \"$DMS_PREBUILT\" ] || pnpm run build) && DMS_MAILING_TEST_DIR=dist/test/integration ajs module test ."
|
|
93
93
|
}
|
|
94
94
|
}
|
package/src/pages/sends.ts
CHANGED
|
@@ -122,7 +122,7 @@ const sendAgainAction = (isTest: boolean): SendRowAction => ({
|
|
|
122
122
|
},
|
|
123
123
|
target: {
|
|
124
124
|
type: "api",
|
|
125
|
-
url: `${API_BASE_PATH}/sends/{_id}/replay`,
|
|
125
|
+
url: `${API_BASE_PATH}/sends/{{row._id}}/replay`,
|
|
126
126
|
method: "POST",
|
|
127
127
|
successMessage: "$dms_mailing.sends.actions.sent_again",
|
|
128
128
|
},
|
|
@@ -152,7 +152,7 @@ const suppressedAddressAction: SendRowAction = {
|
|
|
152
152
|
},
|
|
153
153
|
target: {
|
|
154
154
|
type: "page",
|
|
155
|
-
url: `${SUPPRESSIONS_PAGE}?email={suppressionAddress}`,
|
|
155
|
+
url: `${SUPPRESSIONS_PAGE}?email={{row.suppressionAddress}}`,
|
|
156
156
|
},
|
|
157
157
|
};
|
|
158
158
|
|
|
@@ -133,7 +133,7 @@ export class SuppressionsPageController extends PageController(
|
|
|
133
133
|
showLabel: true,
|
|
134
134
|
target: {
|
|
135
135
|
type: "api",
|
|
136
|
-
url: `${SUPPRESSIONS_URL}/{_id}`,
|
|
136
|
+
url: `${SUPPRESSIONS_URL}/{{row._id}}`,
|
|
137
137
|
method: "DELETE",
|
|
138
138
|
successMessage: key("actions.reactivated"),
|
|
139
139
|
},
|
|
@@ -149,7 +149,7 @@ export class SuppressionsPageController extends PageController(
|
|
|
149
149
|
label: key("actions.see_send"),
|
|
150
150
|
icon: "i-ph-paper-plane-tilt",
|
|
151
151
|
rule: { field: "sendId", notEquals: "" },
|
|
152
|
-
target: { type: "page", url: `${SENDS_PATH}?record={sendId}` },
|
|
152
|
+
target: { type: "page", url: `${SENDS_PATH}?record={{row.sendId}}` },
|
|
153
153
|
},
|
|
154
154
|
],
|
|
155
155
|
},
|
package/src/pages/templates.ts
CHANGED
|
@@ -144,7 +144,7 @@ export class TemplatesPageController extends PageController(
|
|
|
144
144
|
label: "$dms_mailing.templates.actions.open_editor",
|
|
145
145
|
icon: "i-ph-pencil-simple",
|
|
146
146
|
isDefault: true,
|
|
147
|
-
target: { type: "page", url: `${TEMPLATES_PATH}/{_id}` },
|
|
147
|
+
target: { type: "page", url: `${TEMPLATES_PATH}/{{row._id}}` },
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
150
|
label: "$dms_mailing.templates.actions.details",
|
|
@@ -184,7 +184,7 @@ export class TemplatesPageController extends PageController(
|
|
|
184
184
|
rule: { field: "status", notEquals: ARCHIVED_STATUS },
|
|
185
185
|
target: {
|
|
186
186
|
type: "api",
|
|
187
|
-
url: `${API_BASE_PATH}/templates/{_id}/archive`,
|
|
187
|
+
url: `${API_BASE_PATH}/templates/{{row._id}}/archive`,
|
|
188
188
|
method: "POST",
|
|
189
189
|
successMessage: "$dms_mailing.templates.actions.archived",
|
|
190
190
|
},
|
|
@@ -200,7 +200,7 @@ export class TemplatesPageController extends PageController(
|
|
|
200
200
|
rule: { field: "status", equals: ARCHIVED_STATUS },
|
|
201
201
|
target: {
|
|
202
202
|
type: "api",
|
|
203
|
-
url: `${API_BASE_PATH}/templates/{_id}/restore`,
|
|
203
|
+
url: `${API_BASE_PATH}/templates/{{row._id}}/restore`,
|
|
204
204
|
method: "POST",
|
|
205
205
|
successMessage: "$dms_mailing.templates.actions.restored",
|
|
206
206
|
},
|