@cosmicdrift/kumiko-document-designer 0.363.0 → 0.364.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/constants.d.ts +3 -0
- package/dist/constants.js +4 -0
- package/dist/i18n.js +144 -50
- package/dist/web/cells.js +1 -1
- package/dist/web/editor-header.d.ts +37 -0
- package/dist/web/editor-header.js +43 -0
- package/dist/web/editor-shell.d.ts +40 -0
- package/dist/web/editor-shell.js +36 -0
- package/dist/web/i18n.js +35 -59
- package/dist/web/layout-editor-body.d.ts +2 -2
- package/dist/web/layout-editor-body.js +94 -49
- package/dist/web/layout-editor.js +8 -6
- package/dist/web/layout-html.d.ts +2 -0
- package/dist/web/layout-html.js +13 -1
- package/dist/web/layout-meta.d.ts +29 -0
- package/dist/web/layout-meta.js +32 -0
- package/dist/web/layout-rails.d.ts +15 -5
- package/dist/web/layout-rails.js +61 -68
- package/dist/web/layout-types.d.ts +4 -0
- package/dist/web/layout-users.d.ts +1 -0
- package/dist/web/layout-users.js +4 -1
- package/dist/web/mail-dialogs.d.ts +1 -6
- package/dist/web/mail-dialogs.js +2 -2
- package/dist/web/mail-draft.d.ts +8 -6
- package/dist/web/mail-draft.js +33 -11
- package/dist/web/mail-edit-center.d.ts +3 -1
- package/dist/web/mail-edit-center.js +5 -4
- package/dist/web/mail-editor-body.d.ts +0 -1
- package/dist/web/mail-editor-body.js +57 -41
- package/dist/web/mail-editor.js +2 -5
- package/dist/web/mail-footer.d.ts +3 -14
- package/dist/web/mail-footer.js +12 -13
- package/dist/web/mail-left-rail.d.ts +9 -4
- package/dist/web/mail-left-rail.js +18 -15
- package/dist/web/mail-missing-locale.d.ts +10 -0
- package/dist/web/mail-missing-locale.js +45 -0
- package/dist/web/mail-origin-bar.d.ts +3 -5
- package/dist/web/mail-origin-bar.js +26 -50
- package/dist/web/mail-preview-side.d.ts +12 -5
- package/dist/web/mail-preview-side.js +14 -5
- package/dist/web/mail-preview.d.ts +9 -5
- package/dist/web/mail-preview.js +24 -13
- package/dist/web/mail-right-rail.js +23 -13
- package/dist/web/mail-types.d.ts +6 -1
- package/dist/web/mail-versions.js +3 -3
- package/dist/web/origin-bar.d.ts +11 -2
- package/dist/web/origin-bar.js +46 -24
- package/dist/web/overrides-drawer.d.ts +3 -2
- package/dist/web/overrides-drawer.js +87 -11
- package/dist/web/overview-row.d.ts +2 -0
- package/dist/web/overview-row.js +2 -1
- package/dist/web/page-canvas.d.ts +1 -0
- package/dist/web/page-canvas.js +23 -13
- package/dist/web/pdf-footer.d.ts +13 -0
- package/dist/web/pdf-footer.js +34 -0
- package/dist/web/pdf-left-rail.d.ts +9 -0
- package/dist/web/pdf-left-rail.js +16 -0
- package/dist/web/pdf-meta.d.ts +3 -5
- package/dist/web/pdf-meta.js +10 -16
- package/dist/web/pdf-preview.js +21 -8
- package/dist/web/pdf-template-editor.js +90 -76
- package/dist/web/rail.d.ts +13 -1
- package/dist/web/rail.js +15 -7
- package/dist/web/relative-time.d.ts +1 -0
- package/dist/web/relative-time.js +18 -0
- package/dist/web/settings-panel.d.ts +11 -5
- package/dist/web/settings-panel.js +24 -13
- package/dist/web/status-label.d.ts +7 -0
- package/dist/web/status-label.js +8 -0
- package/dist/web/types.d.ts +23 -0
- package/dist/web/use-insert-targets.d.ts +1 -1
- package/dist/web/use-mail-persistence.d.ts +0 -1
- package/dist/web/use-mail-persistence.js +1 -1
- package/dist/web/use-own-address.d.ts +5 -0
- package/dist/web/use-own-address.js +14 -0
- package/package.json +8 -8
- package/src/changes.json +24 -0
- package/dist/web/mail-header.d.ts +0 -23
- package/dist/web/mail-header.js +0 -16
- package/dist/web/placeholder-panel.d.ts +0 -21
- package/dist/web/placeholder-panel.js +0 -35
package/dist/constants.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ export declare const TEMPLATES_NAV_ID: "templates";
|
|
|
8
8
|
export declare const PLATFORM_TEMPLATES_NAV_ID: "platform-templates";
|
|
9
9
|
export declare const BRANDING_SCREEN_QN: "managed-pages:screen:branding-settings";
|
|
10
10
|
export declare const BRANDING_QUERY_QN: "managed-pages:query:branding";
|
|
11
|
+
export declare const USER_ME_QUERY_QN: "user:query:user:me";
|
|
12
|
+
export declare const PROFILE_FEATURE_NAME: "user-profile";
|
|
13
|
+
export declare const PROFILE_SCREEN_ID: "profile";
|
|
11
14
|
export declare const DEFAULT_LAYOUT_SLUG: "default";
|
|
12
15
|
export type TemplateEditorKind = "mail" | "document-pdf" | "mail-layout" | "pdf-layout";
|
|
13
16
|
export declare const TEMPLATE_EDITOR_SCREENS: Partial<Record<TemplateEditorKind, string>>;
|
package/dist/constants.js
CHANGED
|
@@ -10,6 +10,10 @@ export const TEMPLATES_NAV_ID = "templates";
|
|
|
10
10
|
export const PLATFORM_TEMPLATES_NAV_ID = "platform-templates";
|
|
11
11
|
export const BRANDING_SCREEN_QN = "managed-pages:screen:branding-settings";
|
|
12
12
|
export const BRANDING_QUERY_QN = "managed-pages:query:branding";
|
|
13
|
+
// Pinned like the branding names: the user features' constants are not exported to the web barrel.
|
|
14
|
+
export const USER_ME_QUERY_QN = "user:query:user:me";
|
|
15
|
+
export const PROFILE_FEATURE_NAME = "user-profile";
|
|
16
|
+
export const PROFILE_SCREEN_ID = "profile";
|
|
13
17
|
export const DEFAULT_LAYOUT_SLUG = "default";
|
|
14
18
|
// Short screen id per template kind. A kind without an entry gets no "Edit" row action.
|
|
15
19
|
// The mail editor adds `mail` here and declares its screen in this feature, because the
|
package/dist/i18n.js
CHANGED
|
@@ -29,6 +29,8 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
29
29
|
"documentDesigner.kind.layout": { en: "Layout", de: "Layout" },
|
|
30
30
|
"documentDesigner.source.system": { en: "System", de: "System" },
|
|
31
31
|
"documentDesigner.source.tenant": { en: "Tenant", de: "Mandant" },
|
|
32
|
+
"documentDesigner.origin.system": { en: "System template", de: "System-Vorlage" },
|
|
33
|
+
"documentDesigner.origin.override": { en: "Customised", de: "Mandanten-Anpassung" },
|
|
32
34
|
"documentDesigner.status.active": { en: "Active", de: "Aktiv" },
|
|
33
35
|
"documentDesigner.status.draft": { en: "Draft", de: "Entwurf" },
|
|
34
36
|
"documentDesigner.status.archived": { en: "Archived", de: "Archiviert" },
|
|
@@ -77,19 +79,55 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
77
79
|
"documentDesigner.appearance.title": { en: "Appearance", de: "Darstellung" },
|
|
78
80
|
"documentDesigner.appearance.width": { en: "Width", de: "Breite" },
|
|
79
81
|
"documentDesigner.appearance.font": { en: "Font", de: "Schrift" },
|
|
80
|
-
"documentDesigner.appearance.systemFont": {
|
|
81
|
-
en: "System font (Helvetica, Arial)",
|
|
82
|
-
de: "Systemschrift (Helvetica, Arial)",
|
|
83
|
-
},
|
|
84
82
|
"documentDesigner.appearance.background": { en: "Outer background", de: "Hintergrund außen" },
|
|
85
|
-
"documentDesigner.appearance.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
83
|
+
"documentDesigner.appearance.font.sans": {
|
|
84
|
+
en: "System font (Arial, Helvetica)",
|
|
85
|
+
de: "Systemschrift (Arial, Helvetica)",
|
|
86
|
+
},
|
|
87
|
+
"documentDesigner.appearance.font.serif": {
|
|
88
|
+
en: "Serif font (Georgia)",
|
|
89
|
+
de: "Serifenschrift (Georgia)",
|
|
90
|
+
},
|
|
91
|
+
"documentDesigner.appearance.fontHint": {
|
|
92
|
+
en: "Custom fonts in mails come later. PDF uses the bundled framework font.",
|
|
93
|
+
de: "Eigene Schriften in Mails kommen sp\u00e4ter. PDF nutzt die geb\u00fcndelte Schrift des Frameworks.",
|
|
94
|
+
},
|
|
95
|
+
"documentDesigner.appearance.backgroundInvalid": {
|
|
96
|
+
en: "Enter a colour like #f3f2ee.",
|
|
97
|
+
de: "Eine Farbe wie #f3f2ee angeben.",
|
|
98
|
+
},
|
|
99
|
+
"documentDesigner.appearance.accentLine": {
|
|
100
|
+
en: "Accent line at the top",
|
|
101
|
+
de: "Akzentlinie oben",
|
|
102
|
+
},
|
|
103
|
+
"documentDesigner.appearance.accentLine.branding": {
|
|
104
|
+
en: "Accent colour from branding",
|
|
105
|
+
de: "Akzentfarbe aus Branding",
|
|
106
|
+
},
|
|
107
|
+
"documentDesigner.appearance.accentLine.none": { en: "None", de: "Keine" },
|
|
108
|
+
"documentDesigner.appearance.buttonStyle": { en: "Button style", de: "Button-Stil" },
|
|
109
|
+
"documentDesigner.appearance.buttonStyle.filled-rounded": {
|
|
110
|
+
en: "Filled, rounded",
|
|
111
|
+
de: "Gef\u00fcllt, abgerundet",
|
|
112
|
+
},
|
|
113
|
+
"documentDesigner.appearance.buttonStyle.filled-square": {
|
|
114
|
+
en: "Filled, square",
|
|
115
|
+
de: "Gef\u00fcllt, eckig",
|
|
116
|
+
},
|
|
117
|
+
"documentDesigner.appearance.buttonStyle.outline": { en: "Outline", de: "Umriss" },
|
|
118
|
+
"documentDesigner.appearance.fromMjml": {
|
|
119
|
+
en: "The appearance comes from this layout's MJML source.",
|
|
120
|
+
de: "Die Darstellung kommt aus der MJML-Quelle dieses Layouts.",
|
|
90
121
|
},
|
|
91
122
|
"documentDesigner.mjml.title": { en: "MJML source", de: "MJML-Quelle" },
|
|
92
|
-
"documentDesigner.
|
|
123
|
+
"documentDesigner.mjml.hint": {
|
|
124
|
+
en: "Platform admins can edit the MJML source directly. Tenants only see the draft mode.",
|
|
125
|
+
de: "Plattform-Admins k\u00f6nnen die MJML-Quelle direkt bearbeiten. Mandanten sehen nur den Entwurfs-Modus.",
|
|
126
|
+
},
|
|
127
|
+
"documentDesigner.renderer.title": { en: "Renderer", de: "Renderer" },
|
|
128
|
+
"documentDesigner.renderer.mjml": { en: "MJML", de: "MJML" },
|
|
129
|
+
"documentDesigner.renderer.chromium": { en: "Chromium (PDF)", de: "Chromium (PDF)" },
|
|
130
|
+
"documentDesigner.renderer.active": { en: "active", de: "aktiv" },
|
|
93
131
|
"documentDesigner.editor.title.mail": { en: "Mail layout", de: "Mail-Layout" },
|
|
94
132
|
"documentDesigner.editor.title.pdf": { en: "Letterhead", de: "Briefpapier" },
|
|
95
133
|
"documentDesigner.editor.kindSwitch": { en: "Layout kind", de: "Layout-Art" },
|
|
@@ -136,8 +174,8 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
136
174
|
de: "System-Layout v{version} · {active} von {total} Mandanten haben eine eigene Fassung",
|
|
137
175
|
},
|
|
138
176
|
"documentDesigner.editor.diff.open": {
|
|
139
|
-
en: "
|
|
140
|
-
de: "Unterschied
|
|
177
|
+
en: "Show difference",
|
|
178
|
+
de: "Unterschied anzeigen",
|
|
141
179
|
},
|
|
142
180
|
"documentDesigner.editor.diff.title": {
|
|
143
181
|
en: "Difference to the system layout",
|
|
@@ -148,8 +186,8 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
148
186
|
de: "Ihr Layout entspricht dem System-Layout.",
|
|
149
187
|
},
|
|
150
188
|
"documentDesigner.editor.reset.open": {
|
|
151
|
-
en: "Reset
|
|
152
|
-
de: "
|
|
189
|
+
en: "Reset",
|
|
190
|
+
de: "Zurücksetzen",
|
|
153
191
|
},
|
|
154
192
|
"documentDesigner.editor.reset.title": {
|
|
155
193
|
en: "Reset to system layout?",
|
|
@@ -161,6 +199,10 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
161
199
|
},
|
|
162
200
|
"documentDesigner.editor.reset.confirm": { en: "Reset", de: "Zurücksetzen" },
|
|
163
201
|
"documentDesigner.editor.region.header": { en: "Header", de: "Kopf" },
|
|
202
|
+
"documentDesigner.editor.logoCaption": {
|
|
203
|
+
en: "Logo · from branding, max. 180 px wide",
|
|
204
|
+
de: "Logo · aus Branding, max. 180 px breit",
|
|
205
|
+
},
|
|
164
206
|
"documentDesigner.editor.region.content": { en: "Template content", de: "Inhalt der Vorlage" },
|
|
165
207
|
"documentDesigner.editor.region.signature": { en: "Signature area", de: "Signatur-Bereich" },
|
|
166
208
|
"documentDesigner.editor.region.footer": { en: "Footer", de: "Fuß" },
|
|
@@ -223,10 +265,6 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
223
265
|
en: "Preview",
|
|
224
266
|
de: "Vorschau",
|
|
225
267
|
},
|
|
226
|
-
"documentDesigner.mail.header.testMail": {
|
|
227
|
-
en: "Send test mail to me",
|
|
228
|
-
de: "Test-Mail an mich",
|
|
229
|
-
},
|
|
230
268
|
"documentDesigner.mail.language.de": {
|
|
231
269
|
en: "German",
|
|
232
270
|
de: "Deutsch",
|
|
@@ -240,8 +278,8 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
240
278
|
de: "Spanisch",
|
|
241
279
|
},
|
|
242
280
|
"documentDesigner.mail.origin.overrides": {
|
|
243
|
-
en:
|
|
244
|
-
de: "Überschreibt die System-Vorlage
|
|
281
|
+
en: "Overrides the system template v{version}.",
|
|
282
|
+
de: "Überschreibt die System-Vorlage v{version}.",
|
|
245
283
|
},
|
|
246
284
|
"documentDesigner.mail.origin.tenantOnly": {
|
|
247
285
|
en: "This template exists only for your tenant.",
|
|
@@ -260,8 +298,8 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
260
298
|
de: "Archiviert.",
|
|
261
299
|
},
|
|
262
300
|
"documentDesigner.mail.origin.reset": {
|
|
263
|
-
en: "Reset
|
|
264
|
-
de: "
|
|
301
|
+
en: "Reset",
|
|
302
|
+
de: "Zurücksetzen",
|
|
265
303
|
},
|
|
266
304
|
"documentDesigner.mail.origin.system": {
|
|
267
305
|
en: "You are viewing the system template v{version}. Saving creates a customisation for your tenant.",
|
|
@@ -272,21 +310,37 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
272
310
|
de: "System-Vorlage v{version}. Speichern ändert sie für alle Mandanten ohne eigene Anpassung.",
|
|
273
311
|
},
|
|
274
312
|
"documentDesigner.mail.origin.missing": {
|
|
275
|
-
en: "There is no
|
|
276
|
-
de: "Für {language} gibt es keine
|
|
313
|
+
en: "There is no version for {language} yet.",
|
|
314
|
+
de: "Für {language} gibt es noch keine Fassung.",
|
|
315
|
+
},
|
|
316
|
+
"documentDesigner.mail.missing.text": {
|
|
317
|
+
en: "There is no version for {language} yet. Recipients with language {locale} get the {fallbackAdjective} version.",
|
|
318
|
+
de: "Für {language} gibt es noch keine Fassung. Empfänger mit Sprache {locale} bekommen die {fallbackAdjective} Fassung.",
|
|
319
|
+
},
|
|
320
|
+
"documentDesigner.mail.missing.textNoFallback": {
|
|
321
|
+
en: "There is no version for {language} yet.",
|
|
322
|
+
de: "Für {language} gibt es noch keine Fassung.",
|
|
323
|
+
},
|
|
324
|
+
"documentDesigner.mail.missing.copy": {
|
|
325
|
+
en: "Copy from {language}",
|
|
326
|
+
de: "Aus {language} kopieren",
|
|
327
|
+
},
|
|
328
|
+
"documentDesigner.mail.languageAdjective.de": {
|
|
329
|
+
en: "German",
|
|
330
|
+
de: "deutsche",
|
|
277
331
|
},
|
|
278
|
-
"documentDesigner.mail.
|
|
279
|
-
en: "
|
|
280
|
-
de: "
|
|
332
|
+
"documentDesigner.mail.languageAdjective.en": {
|
|
333
|
+
en: "English",
|
|
334
|
+
de: "englische",
|
|
335
|
+
},
|
|
336
|
+
"documentDesigner.mail.languageAdjective.es": {
|
|
337
|
+
en: "Spanish",
|
|
338
|
+
de: "spanische",
|
|
281
339
|
},
|
|
282
340
|
"documentDesigner.mail.origin.copyNote": {
|
|
283
341
|
en: "Copying a system version does not bring images or attachments along; upload them again afterwards.",
|
|
284
342
|
de: "Beim Kopieren einer System-Fassung kommen Bilder und Anhänge nicht mit; laden Sie sie danach neu hoch.",
|
|
285
343
|
},
|
|
286
|
-
"documentDesigner.mail.origin.copyFrom": {
|
|
287
|
-
en: "Copy from {fallback}",
|
|
288
|
-
de: "Aus {fallback} kopieren",
|
|
289
|
-
},
|
|
290
344
|
"documentDesigner.mail.origin.createBlank": {
|
|
291
345
|
en: "Start empty",
|
|
292
346
|
de: "Leer anlegen",
|
|
@@ -323,6 +377,14 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
323
377
|
en: "System placeholders",
|
|
324
378
|
de: "System-Platzhalter",
|
|
325
379
|
},
|
|
380
|
+
"documentDesigner.mail.system.layout": {
|
|
381
|
+
en: "Layout",
|
|
382
|
+
de: "Layout",
|
|
383
|
+
},
|
|
384
|
+
"documentDesigner.mail.system.hint": {
|
|
385
|
+
en: "Filled in by the platform. Imprint and unsubscribe link come from the layout.",
|
|
386
|
+
de: "Füllt die Plattform. Impressum und Abmeldelink liefert das Layout.",
|
|
387
|
+
},
|
|
326
388
|
"documentDesigner.mail.resource.title": {
|
|
327
389
|
en: "Resources",
|
|
328
390
|
de: "Ressourcen",
|
|
@@ -352,8 +414,8 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
352
414
|
de: "Entfernen",
|
|
353
415
|
},
|
|
354
416
|
"documentDesigner.mail.resource.caption": {
|
|
355
|
-
en: "{key} · embedded as CID",
|
|
356
|
-
de: "{key} · als CID eingebettet",
|
|
417
|
+
en: "{key} · {size} · embedded as CID",
|
|
418
|
+
de: "{key} · {size} · als CID eingebettet",
|
|
357
419
|
},
|
|
358
420
|
"documentDesigner.mail.resource.hint": {
|
|
359
421
|
en: "Inline images are sent as CID. Attachments from PDF templates are generated when the mail is sent.",
|
|
@@ -431,6 +493,18 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
431
493
|
en: "Default sender of the tenant",
|
|
432
494
|
de: "Standard-Absender des Mandanten",
|
|
433
495
|
},
|
|
496
|
+
"documentDesigner.mail.props.senderPlaceholder": {
|
|
497
|
+
en: "Name shown to recipients",
|
|
498
|
+
de: "Name, den Empfänger sehen",
|
|
499
|
+
},
|
|
500
|
+
"documentDesigner.mail.props.senderHint": {
|
|
501
|
+
en: "The address comes from the platform's mail delivery.",
|
|
502
|
+
de: "Die Adresse kommt vom Mail-Versand der Plattform.",
|
|
503
|
+
},
|
|
504
|
+
"documentDesigner.mail.props.replyTo": {
|
|
505
|
+
en: "Reply to",
|
|
506
|
+
de: "Antwort an",
|
|
507
|
+
},
|
|
434
508
|
"documentDesigner.mail.props.category": {
|
|
435
509
|
en: "Category",
|
|
436
510
|
de: "Kategorie",
|
|
@@ -467,6 +541,10 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
467
541
|
en: "File",
|
|
468
542
|
de: "Datei",
|
|
469
543
|
},
|
|
544
|
+
"documentDesigner.mail.attachments.hint": {
|
|
545
|
+
en: "PDF templates are generated when the mail is sent; files go out as uploaded.",
|
|
546
|
+
de: "PDF-Vorlagen werden beim Versand erzeugt, Dateien gehen so mit, wie sie hochgeladen wurden.",
|
|
547
|
+
},
|
|
470
548
|
"documentDesigner.mail.pdfLink.title": {
|
|
471
549
|
en: "Attachment from PDF template",
|
|
472
550
|
de: "Anhang aus PDF-Vorlage",
|
|
@@ -511,6 +589,10 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
511
589
|
en: "v{version} {when}, {name}",
|
|
512
590
|
de: "v{version} {when}, {name}",
|
|
513
591
|
},
|
|
592
|
+
"documentDesigner.mail.versions.hint": {
|
|
593
|
+
en: "Every save creates a new version. The active one is what recipients get.",
|
|
594
|
+
de: "Jedes Speichern legt eine neue Version an. Aktiv ist die Version, die Empfänger bekommen.",
|
|
595
|
+
},
|
|
514
596
|
"documentDesigner.mail.footer.missing": {
|
|
515
597
|
en: 'Required placeholder "{names}" is missing in subject, preview text and content. Publishing is blocked.',
|
|
516
598
|
de: "Pflicht-Platzhalter „{names}“ fehlt in Betreff, Vorschautext und Inhalt. Veröffentlichen ist gesperrt.",
|
|
@@ -539,17 +621,9 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
539
621
|
en: "Discard",
|
|
540
622
|
de: "Verwerfen",
|
|
541
623
|
},
|
|
542
|
-
"documentDesigner.
|
|
543
|
-
en: "
|
|
544
|
-
de: "
|
|
545
|
-
},
|
|
546
|
-
"documentDesigner.mail.activeSave.description": {
|
|
547
|
-
en: "Saving as a draft takes the active customisation offline until you publish. Publish instead?",
|
|
548
|
-
de: "Speichern als Entwurf nimmt die aktive Anpassung offline, bis Sie veröffentlichen. Stattdessen veröffentlichen?",
|
|
549
|
-
},
|
|
550
|
-
"documentDesigner.mail.activeSave.confirm": {
|
|
551
|
-
en: "Save as draft",
|
|
552
|
-
de: "Als Entwurf speichern",
|
|
624
|
+
"documentDesigner.origin.draftBesideActive": {
|
|
625
|
+
en: "Version {active} is sent, your draft (version {draft}) is not published yet.",
|
|
626
|
+
de: "Verschickt wird Version {active}, Ihr Entwurf (Version {draft}) ist noch nicht veröffentlicht.",
|
|
553
627
|
},
|
|
554
628
|
"documentDesigner.mail.leave.title": {
|
|
555
629
|
en: "Unsaved changes",
|
|
@@ -568,8 +642,8 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
568
642
|
de: "Verwerfen",
|
|
569
643
|
},
|
|
570
644
|
"documentDesigner.mail.preview.bar": {
|
|
571
|
-
en: 'Preview with sample values from the placeholder schema. Rendered through "{
|
|
572
|
-
de: "Vorschau mit Beispielwerten aus dem Platzhalter-Schema. Gerendert über „{
|
|
645
|
+
en: 'Preview with sample values from the placeholder schema. Rendered through "Mail layout v{version}", renderer: MJML.',
|
|
646
|
+
de: "Vorschau mit Beispielwerten aus dem Platzhalter-Schema. Gerendert über „Mail-Layout v{version}“, Renderer: MJML.",
|
|
573
647
|
},
|
|
574
648
|
"documentDesigner.mail.preview.barPlain": {
|
|
575
649
|
en: "Preview with sample values from the placeholder schema.",
|
|
@@ -611,6 +685,14 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
611
685
|
en: "Mail preview",
|
|
612
686
|
de: "Mail-Vorschau",
|
|
613
687
|
},
|
|
688
|
+
"documentDesigner.mail.preview.from": {
|
|
689
|
+
en: "From",
|
|
690
|
+
de: "Von",
|
|
691
|
+
},
|
|
692
|
+
"documentDesigner.mail.preview.to": {
|
|
693
|
+
en: "To",
|
|
694
|
+
de: "An",
|
|
695
|
+
},
|
|
614
696
|
"documentDesigner.mail.preview.samples": {
|
|
615
697
|
en: "Sample values",
|
|
616
698
|
de: "Beispielwerte",
|
|
@@ -631,6 +713,10 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
631
713
|
en: "Checks",
|
|
632
714
|
de: "Prüfung",
|
|
633
715
|
},
|
|
716
|
+
"documentDesigner.mail.preview.checksHint": {
|
|
717
|
+
en: "What the server found while rendering this mail.",
|
|
718
|
+
de: "Das hat der Server beim Rendern dieser Mail gefunden.",
|
|
719
|
+
},
|
|
634
720
|
"documentDesigner.mail.testMail.title": {
|
|
635
721
|
en: "Test mail",
|
|
636
722
|
de: "Test-Mail",
|
|
@@ -643,13 +729,21 @@ export const DOCUMENT_DESIGNER_I18N = {
|
|
|
643
729
|
en: "Your address",
|
|
644
730
|
de: "Ihre Adresse",
|
|
645
731
|
},
|
|
646
|
-
"documentDesigner.mail.testMail.
|
|
647
|
-
en: "
|
|
732
|
+
"documentDesigner.mail.testMail.changeAddress": {
|
|
733
|
+
en: "Change address",
|
|
734
|
+
de: "Adresse ändern",
|
|
735
|
+
},
|
|
736
|
+
"documentDesigner.mail.testMail.prefixSubject": {
|
|
737
|
+
en: "Prefix the subject with [TEST]",
|
|
648
738
|
de: "Betreff mit Präfix [TEST]",
|
|
649
739
|
},
|
|
650
740
|
"documentDesigner.mail.testMail.attachments": {
|
|
651
|
-
en: "
|
|
652
|
-
de: "
|
|
741
|
+
en: "Send attachments along",
|
|
742
|
+
de: "Anhang mitsenden",
|
|
743
|
+
},
|
|
744
|
+
"documentDesigner.mail.testMail.noAttachments": {
|
|
745
|
+
en: "This template has no attachments",
|
|
746
|
+
de: "Diese Vorlage hat keine Anhänge",
|
|
653
747
|
},
|
|
654
748
|
"documentDesigner.mail.testMail.send": {
|
|
655
749
|
en: "Send test mail",
|
package/dist/web/cells.js
CHANGED
|
@@ -44,7 +44,7 @@ export function createLocalesCell(appLocales) {
|
|
|
44
44
|
}
|
|
45
45
|
export function StatusCell({ row }) {
|
|
46
46
|
const t = useTranslation();
|
|
47
|
-
return withRow(row, (r) => (_jsx(StatusBadge, { tone: statusTone(r.status), testId: "document-designer-status", children: statusLabel(t, r.status, r.version) })));
|
|
47
|
+
return withRow(row, (r) => (_jsxs("span", { className: "flex flex-col items-start gap-1", children: [_jsx(StatusBadge, { tone: statusTone(r.status), testId: "document-designer-status", children: statusLabel(t, r.status, r.version) }), r.status === "active" && r.draftVersion !== null && (_jsx(StatusBadge, { tone: statusTone("draft"), testId: "document-designer-draft-status", children: statusLabel(t, "draft", r.draftVersion) }))] })));
|
|
48
48
|
}
|
|
49
49
|
export function UsedByCell({ row }) {
|
|
50
50
|
const t = useTranslation();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type EditorMode = "edit" | "preview";
|
|
3
|
+
/** "override" is a tenant row that replaces a system version; "tenant" has no system counterpart. */
|
|
4
|
+
export type EditorOrigin = "system" | "override" | "tenant";
|
|
5
|
+
export declare function originOf(isSystemRow: boolean, hasSystemVersion: boolean): EditorOrigin;
|
|
6
|
+
export declare function OriginBadge({ origin }: {
|
|
7
|
+
readonly origin: EditorOrigin;
|
|
8
|
+
}): ReactNode;
|
|
9
|
+
export declare function EditorModeSwitch({ testIdPrefix, mode, onMode, }: {
|
|
10
|
+
readonly testIdPrefix: string;
|
|
11
|
+
readonly mode: EditorMode;
|
|
12
|
+
readonly onMode: (mode: EditorMode) => void;
|
|
13
|
+
}): ReactNode;
|
|
14
|
+
export declare function EditorLocaleSwitch({ testIdPrefix, locales, locale, onLocale, }: {
|
|
15
|
+
readonly testIdPrefix: string;
|
|
16
|
+
readonly locales: readonly string[];
|
|
17
|
+
readonly locale: string;
|
|
18
|
+
readonly onLocale: (locale: string) => void;
|
|
19
|
+
}): ReactNode;
|
|
20
|
+
export type StoredVersion = {
|
|
21
|
+
readonly status: string;
|
|
22
|
+
readonly version: number;
|
|
23
|
+
};
|
|
24
|
+
export type EditorSaveActions = {
|
|
25
|
+
readonly busy: boolean;
|
|
26
|
+
readonly canSave: boolean;
|
|
27
|
+
readonly canPublish: boolean;
|
|
28
|
+
readonly onSave: () => void;
|
|
29
|
+
readonly onPublish: () => void;
|
|
30
|
+
};
|
|
31
|
+
export declare function EditorHeader({ title, stored, actions, children, }: {
|
|
32
|
+
readonly title: string;
|
|
33
|
+
readonly stored: StoredVersion | null;
|
|
34
|
+
readonly actions: EditorSaveActions;
|
|
35
|
+
/** View controls left of the save actions (mode or kind switch). */
|
|
36
|
+
readonly children: ReactNode;
|
|
37
|
+
}): ReactNode;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// @runtime client
|
|
3
|
+
import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
4
|
+
import { ModeSwitch, StatusBadge } from "@cosmicdrift/kumiko-renderer-web";
|
|
5
|
+
import { asRowStatus, statusLabel, statusTone } from "./status-label.js";
|
|
6
|
+
const ORIGIN_LABEL = {
|
|
7
|
+
system: "documentDesigner.origin.system",
|
|
8
|
+
override: "documentDesigner.origin.override",
|
|
9
|
+
tenant: "documentDesigner.source.tenant",
|
|
10
|
+
};
|
|
11
|
+
export function originOf(isSystemRow, hasSystemVersion) {
|
|
12
|
+
return isSystemRow ? "system" : hasSystemVersion ? "override" : "tenant";
|
|
13
|
+
}
|
|
14
|
+
export function OriginBadge({ origin }) {
|
|
15
|
+
const t = useTranslation();
|
|
16
|
+
return (_jsx(StatusBadge, { tone: origin === "system" ? "muted" : "accent", testId: "document-designer-editor-origin", children: t(ORIGIN_LABEL[origin]) }));
|
|
17
|
+
}
|
|
18
|
+
export function EditorModeSwitch({ testIdPrefix, mode, onMode, }) {
|
|
19
|
+
const t = useTranslation();
|
|
20
|
+
return (_jsx(ModeSwitch, { value: mode, onChange: onMode, ariaLabel: t("documentDesigner.mail.header.modeSwitch"), testId: `${testIdPrefix}-mode-switch`, options: [
|
|
21
|
+
{ value: "edit", label: t("documentDesigner.mail.header.edit") },
|
|
22
|
+
{ value: "preview", label: t("documentDesigner.mail.header.preview") },
|
|
23
|
+
] }));
|
|
24
|
+
}
|
|
25
|
+
export function EditorLocaleSwitch({ testIdPrefix, locales, locale, onLocale, }) {
|
|
26
|
+
const t = useTranslation();
|
|
27
|
+
return (_jsx(ModeSwitch, { value: locale, onChange: onLocale, ariaLabel: t("documentDesigner.mail.header.localeSwitch"), testId: `${testIdPrefix}-locale-switch`, options: locales.map((code) => ({ value: code, label: code })) }));
|
|
28
|
+
}
|
|
29
|
+
function StoredStatus({ stored }) {
|
|
30
|
+
const t = useTranslation();
|
|
31
|
+
const status = asRowStatus(stored.status);
|
|
32
|
+
return (_jsx(StatusBadge, { tone: statusTone(status), testId: "document-designer-editor-status", children: statusLabel(t, status, stored.version) }));
|
|
33
|
+
}
|
|
34
|
+
// Title, status and the save/publish actions live in the shell header. The origin badge, the
|
|
35
|
+
// locale switch and the secondary action sit in the info bar below: at 1280px next to the
|
|
36
|
+
// sidebar, assistant and theme toggle the header has no room for them and the title would clip.
|
|
37
|
+
export function EditorHeader({ title, stored, actions, children, }) {
|
|
38
|
+
const t = useTranslation();
|
|
39
|
+
const { Button, PageHeader } = usePrimitives();
|
|
40
|
+
if (PageHeader === undefined)
|
|
41
|
+
return null;
|
|
42
|
+
return (_jsx(PageHeader, { title: title, status: stored !== null && _jsx(StoredStatus, { stored: stored }), actions: _jsxs("span", { className: "flex items-center gap-2 [&_button]:px-2.5 [&_button]:text-sm", children: [children, _jsx(Button, { variant: "secondary", size: "sm", disabled: !actions.canSave, loading: actions.busy, onClick: actions.onSave, testId: "document-designer-header-save", children: t("documentDesigner.editor.save") }), _jsx(Button, { size: "sm", disabled: !actions.canPublish, onClick: actions.onPublish, testId: "document-designer-header-publish", children: t("documentDesigner.editor.publish") })] }) }));
|
|
43
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type EditorOrigin } from "./editor-header.js";
|
|
3
|
+
export type InfoBarTone = "active" | "muted" | "warn";
|
|
4
|
+
export type FooterTone = "bad" | "warn" | "ok";
|
|
5
|
+
export declare function EditorFrame({ testId, children, }: {
|
|
6
|
+
readonly testId: string;
|
|
7
|
+
readonly children: ReactNode;
|
|
8
|
+
}): ReactNode;
|
|
9
|
+
export declare function EditorInfoBar({ tone, testId, origin, controls, links, overlays, children, }: {
|
|
10
|
+
readonly tone: InfoBarTone;
|
|
11
|
+
readonly testId: string;
|
|
12
|
+
readonly origin?: EditorOrigin | null;
|
|
13
|
+
/** Right side, before the links: locale switch and the editor's secondary action. */
|
|
14
|
+
readonly controls?: ReactNode;
|
|
15
|
+
readonly links?: ReactNode;
|
|
16
|
+
readonly overlays?: ReactNode;
|
|
17
|
+
readonly children: ReactNode;
|
|
18
|
+
}): ReactNode;
|
|
19
|
+
export declare function EditorBody({ left, center, right, testId, }: {
|
|
20
|
+
readonly left?: ReactNode;
|
|
21
|
+
readonly center: ReactNode;
|
|
22
|
+
readonly right: ReactNode;
|
|
23
|
+
readonly testId?: string;
|
|
24
|
+
}): ReactNode;
|
|
25
|
+
export declare function EditorFooter({ testIdPrefix, message, saveError, modifiedAt, dirty, busy, canSave, canPublish, onDiscard, onSave, onPublish, }: {
|
|
26
|
+
readonly testIdPrefix: string;
|
|
27
|
+
readonly message: {
|
|
28
|
+
readonly tone: FooterTone;
|
|
29
|
+
readonly text: string;
|
|
30
|
+
} | null;
|
|
31
|
+
readonly saveError: string | null;
|
|
32
|
+
readonly modifiedAt: string | null;
|
|
33
|
+
readonly dirty: boolean;
|
|
34
|
+
readonly busy: boolean;
|
|
35
|
+
readonly canSave: boolean;
|
|
36
|
+
readonly canPublish: boolean;
|
|
37
|
+
readonly onDiscard: () => void;
|
|
38
|
+
readonly onSave: () => void;
|
|
39
|
+
readonly onPublish: () => void;
|
|
40
|
+
}): ReactNode;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// @runtime client
|
|
3
|
+
import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
4
|
+
import { cn } from "@cosmicdrift/kumiko-renderer-web";
|
|
5
|
+
import { OriginBadge } from "./editor-header.js";
|
|
6
|
+
import { formatRelativeWhen } from "./relative-time.js";
|
|
7
|
+
const INFO_BAR_TONE = {
|
|
8
|
+
active: "bg-primary/10",
|
|
9
|
+
muted: "bg-muted",
|
|
10
|
+
warn: "bg-status-warn-surface",
|
|
11
|
+
};
|
|
12
|
+
const FOOTER_TONE = {
|
|
13
|
+
ok: { text: "text-status-ok", glyph: "✓" },
|
|
14
|
+
warn: { text: "text-status-warn", glyph: "!" },
|
|
15
|
+
bad: { text: "text-status-bad", glyph: "!" },
|
|
16
|
+
};
|
|
17
|
+
// Height below the shell header: the rails and the center scroll on their own.
|
|
18
|
+
export function EditorFrame({ testId, children, }) {
|
|
19
|
+
return (_jsx("div", { className: "flex h-[calc(100svh-var(--shell-header-height))] min-h-[600px] flex-col", "data-testid": testId, children: children }));
|
|
20
|
+
}
|
|
21
|
+
export function EditorInfoBar({ tone, testId, origin, controls, links, overlays, children, }) {
|
|
22
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: cn("flex items-start gap-4 border-b px-6 py-2 text-sm", INFO_BAR_TONE[tone]), "data-testid": testId, "data-variant": tone === "warn" ? "warn" : undefined, children: [_jsxs("span", { className: "min-w-0 flex-1", children: [origin != null && _jsx(OriginBadge, { origin: origin }), " ", children] }), controls !== undefined && (_jsx("div", { className: "flex shrink-0 items-center gap-2", children: controls })), links !== undefined && _jsx("div", { className: "flex shrink-0 items-center gap-4", children: links })] }), overlays] }));
|
|
23
|
+
}
|
|
24
|
+
export function EditorBody({ left, center, right, testId, }) {
|
|
25
|
+
return (_jsxs("div", { className: cn("grid min-h-0 flex-1", left === undefined
|
|
26
|
+
? "grid-cols-[minmax(0,1fr)_280px]"
|
|
27
|
+
: "grid-cols-[240px_minmax(0,1fr)_280px]"), "data-testid": testId, children: [left !== undefined && (_jsx("aside", { className: "min-h-0 overflow-y-auto border-r bg-background", children: left })), _jsx("div", { className: "flex min-h-0 min-w-0 flex-col overflow-hidden bg-muted", children: center }), _jsx("aside", { className: "min-h-0 overflow-y-auto border-l bg-background", children: right })] }));
|
|
28
|
+
}
|
|
29
|
+
export function EditorFooter({ testIdPrefix, message, saveError, modifiedAt, dirty, busy, canSave, canPublish, onDiscard, onSave, onPublish, }) {
|
|
30
|
+
const t = useTranslation();
|
|
31
|
+
const { Banner, Button, Text } = usePrimitives();
|
|
32
|
+
const tone = message === null ? null : FOOTER_TONE[message.tone];
|
|
33
|
+
return (_jsxs("div", { className: "flex items-center gap-4 border-t bg-background px-6 py-3", "data-testid": `${testIdPrefix}-footer`, children: [_jsxs("div", { className: "min-w-0 flex-1 text-sm", children: [saveError !== null ? (_jsx(Banner, { variant: "error", testId: `${testIdPrefix}-save-error`, children: saveError })) : (_jsx("span", { className: cn(tone === null ? "text-muted-foreground" : tone.text), "data-testid": `${testIdPrefix}-footer-message`, "data-tone": message?.tone, children: message === null
|
|
34
|
+
? t("documentDesigner.editor.footer.checking")
|
|
35
|
+
: `${tone?.glyph ?? ""} ${message.text}` })), modifiedAt !== null && (_jsxs(_Fragment, { children: [" ", _jsx(Text, { variant: "muted", testId: `${testIdPrefix}-saved-at`, children: t("documentDesigner.mail.footer.savedAt", { when: formatRelativeWhen(modifiedAt) }) })] }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [_jsx(Button, { variant: "ghost", disabled: !dirty, onClick: onDiscard, testId: "document-designer-discard", children: t("documentDesigner.editor.discard") }), _jsx(Button, { variant: "secondary", disabled: !canSave, loading: busy, onClick: onSave, testId: "document-designer-save", children: t("documentDesigner.editor.save") }), _jsx(Button, { disabled: !canPublish, onClick: onPublish, testId: "document-designer-publish", children: t("documentDesigner.editor.publish") })] })] }));
|
|
36
|
+
}
|