@antelopejs/dms 0.7.21 → 0.8.1

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 (208) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/implementations/dms/resolver-timeout.d.ts +1 -0
  3. package/dist/implementations/dms/resolver-timeout.js +13 -3
  4. package/dist/implementations/dms/resolver-timeout.js.map +1 -1
  5. package/dist/implementations/dms-auth/account-emails.d.ts +4 -0
  6. package/dist/implementations/dms-auth/account-emails.js +62 -0
  7. package/dist/implementations/dms-auth/account-emails.js.map +1 -0
  8. package/dist/implementations/dms-auth/index.d.ts +1 -3
  9. package/dist/implementations/dms-auth/index.js +15 -61
  10. package/dist/implementations/dms-auth/index.js.map +1 -1
  11. package/dist/pages/settings/users/email-change.js +3 -4
  12. package/dist/pages/settings/users/email-change.js.map +1 -1
  13. package/dist/pages/settings/users/invites.js +1 -1
  14. package/dist/pages/settings/users/invites.js.map +1 -1
  15. package/dist/pages/settings/users/members.js +1 -1
  16. package/dist/pages/settings/users/members.js.map +1 -1
  17. package/dist/pages/settings/users/notifications.js +1 -0
  18. package/dist/pages/settings/users/notifications.js.map +1 -1
  19. package/dist/test/antelope.test.js +2 -1
  20. package/dist/test/antelope.test.js.map +1 -1
  21. package/dist/test/helpers/db.js +19 -11
  22. package/dist/test/helpers/db.js.map +1 -1
  23. package/dist/test/integration/auth/two-factor-codes.test.js +4 -2
  24. package/dist/test/integration/auth/two-factor-codes.test.js.map +1 -1
  25. package/dist/test/unit/implementations/dms/dynamic-menu-hardening.test.js +8 -5
  26. package/dist/test/unit/implementations/dms/dynamic-menu-hardening.test.js.map +1 -1
  27. package/dist/test/unit/implementations/dms/layout-banners.test.js +20 -7
  28. package/dist/test/unit/implementations/dms/layout-banners.test.js.map +1 -1
  29. package/dist/test/unit/implementations/dms-html-render/built-in-emails.test.js +34 -0
  30. package/dist/test/unit/implementations/dms-html-render/built-in-emails.test.js.map +1 -0
  31. package/dist/test/unit/interfaces/dms/hook-handler-results.test.js +49 -0
  32. package/dist/test/unit/interfaces/dms/hook-handler-results.test.js.map +1 -0
  33. package/dist/test/unit/interfaces/dms/page-topics.test.js +17 -0
  34. package/dist/test/unit/interfaces/dms/page-topics.test.js.map +1 -1
  35. package/dist/test/unit/interfaces/dms-base/confirm-dialog-secondary-action.test.js +2 -2
  36. package/dist/test/unit/interfaces/dms-base/confirm-dialog-secondary-action.test.js.map +1 -1
  37. package/dist/test/unit/interfaces/dms-base/query-response-delta.test.js +29 -0
  38. package/dist/test/unit/interfaces/dms-base/query-response-delta.test.js.map +1 -0
  39. package/dist/test/unit/interfaces/dms-base/resource-form.test.js +5 -0
  40. package/dist/test/unit/interfaces/dms-base/resource-form.test.js.map +1 -1
  41. package/dist/test/unit/interfaces/dms-base/table-view-form-redirect.test.js +12 -2
  42. package/dist/test/unit/interfaces/dms-base/table-view-form-redirect.test.js.map +1 -1
  43. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js +29 -4
  44. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js.map +1 -1
  45. package/dist/test/unit/interfaces/dms-base/table-view-source-reorder.test.js +14 -11
  46. package/dist/test/unit/interfaces/dms-base/table-view-source-reorder.test.js.map +1 -1
  47. package/dist/test/unit/interfaces/dms-base/table-view-views.test.js +8 -5
  48. package/dist/test/unit/interfaces/dms-base/table-view-views.test.js.map +1 -1
  49. package/dist/test/unit/utils/email-subjects.test.js +27 -0
  50. package/dist/test/unit/utils/email-subjects.test.js.map +1 -0
  51. package/dist/utils/admin-invite-email.js +2 -4
  52. package/dist/utils/admin-invite-email.js.map +1 -1
  53. package/dist/utils/email-change-mail.d.ts +1 -1
  54. package/dist/utils/email-change-mail.js +11 -6
  55. package/dist/utils/email-change-mail.js.map +1 -1
  56. package/dist/utils/email-subjects.d.ts +3 -0
  57. package/dist/utils/email-subjects.js +32 -0
  58. package/dist/utils/email-subjects.js.map +1 -0
  59. package/dist/utils/export-jobs.js +15 -10
  60. package/dist/utils/export-jobs.js.map +1 -1
  61. package/frontend-vue/layers/dms-core/app/utils/url-interpolation.ts +29 -11
  62. package/frontend-vue/layers/dms-core/shared/types/app-config.ts +17 -0
  63. package/frontend-vue/layers/dms-layout/app/app.config.ts +5 -0
  64. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +18 -2
  65. package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +16 -1
  66. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useHeaderActionControls.ts +14 -0
  67. package/frontend-vue/layers/dms-layout/app/components/layout/HStack.vue +16 -0
  68. package/frontend-vue/layers/dms-layout/app/components/layout/VStack.vue +2 -0
  69. package/frontend-vue/layers/dms-layout/app/composables/useFooterLinks.ts +11 -1
  70. package/frontend-vue/layers/dms-layout/app/custom-pages/settings/roles.vue +1 -1
  71. package/frontend-vue/layers/dms-layout/app/emails/EmailAdminInvite.vue +1 -1
  72. package/frontend-vue/layers/dms-layout/app/emails/EmailChangeNotice.vue +13 -7
  73. package/frontend-vue/layers/dms-layout/app/emails/EmailChangeVerification.vue +18 -7
  74. package/frontend-vue/layers/dms-layout/app/emails/EmailExportReady.vue +23 -12
  75. package/frontend-vue/layers/dms-layout/app/emails/EmailResetPassword.vue +18 -7
  76. package/frontend-vue/layers/dms-layout/app/emails/EmailTwoFactor.vue +23 -4
  77. package/frontend-vue/layers/dms-layout/app/emails/EmailUserValidation.vue +18 -6
  78. package/frontend-vue/layers/dms-layout/app/emails/components/EmailOTP.vue +8 -2
  79. package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +40 -0
  80. package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +40 -0
  81. package/frontend-vue/layers/dms-ui/app/build/components/form/FormFieldControl.vue +2 -1
  82. package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +11 -3
  83. package/frontend-vue/layers/dms-ui/app/build/composables/actions/useActionTargets.ts +27 -36
  84. package/frontend-vue/layers/dms-ui/app/build/composables/chart/apexTheme.ts +59 -2
  85. package/frontend-vue/layers/dms-ui/app/build/composables/confirm/confirmDialogTexts.ts +27 -4
  86. package/frontend-vue/layers/dms-ui/app/build/composables/confirm/useActionConfirm.ts +10 -2
  87. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +0 -5
  88. package/frontend-vue/layers/dms-ui/app/build/composables/form/formEntryOrder.ts +23 -0
  89. package/frontend-vue/layers/dms-ui/app/build/composables/form/formFooter.ts +19 -15
  90. package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +26 -2
  91. package/frontend-vue/layers/dms-ui/app/build/composables/page/pageUrlValues.ts +41 -0
  92. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/registerDefaultFunctions.ts +2 -2
  93. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableRows.ts +3 -5
  94. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewConfig.ts +7 -12
  95. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/useTableViewRowActions.ts +3 -3
  96. package/frontend-vue/layers/dms-ui/app/build/utils/link.ts +7 -3
  97. package/frontend-vue/layers/dms-ui/app/build/utils/urlVariables.ts +32 -9
  98. package/frontend-vue/layers/dms-ui/app/components/activity-feed/ActivityFeed.vue +8 -1
  99. package/frontend-vue/layers/dms-ui/app/components/banner/Banner.vue +9 -4
  100. package/frontend-vue/layers/dms-ui/app/components/blocks/BannerBlock.vue +5 -11
  101. package/frontend-vue/layers/dms-ui/app/components/blocks/NavCardGridBlock.vue +2 -1
  102. package/frontend-vue/layers/dms-ui/app/components/chart/ApexChartHost.vue +32 -1
  103. package/frontend-vue/layers/dms-ui/app/components/check-list/CheckList.vue +1 -1
  104. package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +12 -2
  105. package/frontend-vue/layers/dms-ui/app/components/form/components/Cascader.vue +7 -3
  106. package/frontend-vue/layers/dms-ui/app/components/form/components/File.vue +7 -0
  107. package/frontend-vue/layers/dms-ui/app/components/form/components/InputAddress.vue +4 -1
  108. package/frontend-vue/layers/dms-ui/app/components/form/components/InputCode.vue +4 -2
  109. package/frontend-vue/layers/dms-ui/app/components/form/components/InputSecret.vue +3 -2
  110. package/frontend-vue/layers/dms-ui/app/components/form/components/Relation.vue +4 -1
  111. package/frontend-vue/layers/dms-ui/app/components/grid/GridRow.vue +14 -6
  112. package/frontend-vue/layers/dms-ui/app/components/grid/columns.ts +52 -3
  113. package/frontend-vue/layers/dms-ui/app/components/key-value-list/KeyValueList.vue +2 -1
  114. package/frontend-vue/layers/dms-ui/app/components/list-row/ListRow.vue +9 -2
  115. package/frontend-vue/layers/dms-ui/app/components/save-bar/InstantSaveBadge.vue +13 -5
  116. package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +1 -1
  117. package/frontend-vue/layers/dms-ui/app/components/stat-group/StatGroup.vue +3 -2
  118. package/frontend-vue/layers/dms-ui/app/components/table-view/CascaderPath.vue +53 -31
  119. package/frontend-vue/layers/dms-ui/app/composables/chart/apexPlotOptions.ts +15 -4
  120. package/frontend-vue/layers/dms-ui/app/composables/chart/apexYRange.ts +123 -0
  121. package/frontend-vue/layers/dms-ui/app/composables/chart/useApexChart.ts +49 -49
  122. package/frontend-vue/layers/dms-ui/app/composables/chart/useChartTheme.ts +20 -1
  123. package/frontend-vue/layers/dms-ui/app/composables/confirm/types.ts +1 -1
  124. package/frontend-vue/layers/dms-ui/app/composables/form/types/props.ts +2 -0
  125. package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +8 -6
  126. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/action-target.ts +1 -1
  127. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +3 -5
  128. package/frontend-vue/layers/dms-ui/app/utils/bannerToneIcons.ts +13 -0
  129. package/frontend-vue/layers/dms-ui/app/utils/cascader.ts +26 -0
  130. package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +4 -0
  131. package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +4 -0
  132. package/frontend-vue/package.json +1 -1
  133. package/frontend-vue/pnpm-lock.yaml +5 -5
  134. package/frontend-vue/tests/activity-feed-fill-height.test.ts +7 -0
  135. package/frontend-vue/tests/banner-tone-icon.test.ts +55 -0
  136. package/frontend-vue/tests/builtin-emails.test.ts +141 -0
  137. package/frontend-vue/tests/cascader.test.ts +27 -0
  138. package/frontend-vue/tests/chart-auto-y-range.test.ts +25 -9
  139. package/frontend-vue/tests/chart-colors.test.ts +8 -0
  140. package/frontend-vue/tests/chart-resize-after-animation.test.ts +100 -0
  141. package/frontend-vue/tests/chart-type-defaults.test.ts +128 -0
  142. package/frontend-vue/tests/check-list-marker.test.ts +58 -0
  143. package/frontend-vue/tests/confirm-from.test.ts +1 -1
  144. package/frontend-vue/tests/confirm-secondary-action.test.ts +2 -2
  145. package/frontend-vue/tests/context-links.test.ts +2 -2
  146. package/frontend-vue/tests/custom-action-confirm-from.test.ts +2 -2
  147. package/frontend-vue/tests/download-action-target.test.ts +2 -2
  148. package/frontend-vue/tests/file-drop-prompt.test.ts +72 -0
  149. package/frontend-vue/tests/footer-config.test.ts +135 -0
  150. package/frontend-vue/tests/form-actions.test.ts +7 -0
  151. package/frontend-vue/tests/form-enclosing-form.test.ts +0 -21
  152. package/frontend-vue/tests/form-entry-order.test.ts +45 -0
  153. package/frontend-vue/tests/form-footer-kind.test.ts +11 -6
  154. package/frontend-vue/tests/form-load-error.test.ts +38 -23
  155. package/frontend-vue/tests/grid-responsive-columns.test.ts +39 -31
  156. package/frontend-vue/tests/header-actions.test.ts +55 -9
  157. package/frontend-vue/tests/instant-save-badge.test.ts +11 -4
  158. package/frontend-vue/tests/list-row-truncate.test.ts +46 -0
  159. package/frontend-vue/tests/nuxt-ui-aria-labels.test.ts +1 -28
  160. package/frontend-vue/tests/period-live-pause.test.ts +0 -13
  161. package/frontend-vue/tests/period-max-days.test.ts +0 -14
  162. package/frontend-vue/tests/roles-name-errors.test.ts +2 -3
  163. package/frontend-vue/tests/row-side-panel.test.ts +0 -12
  164. package/frontend-vue/tests/save-bar.test.ts +15 -3
  165. package/frontend-vue/tests/save-status-error.test.ts +2 -2
  166. package/frontend-vue/tests/table-cell-wrap.test.ts +0 -12
  167. package/frontend-vue/tests/table-density-menu.test.ts +0 -21
  168. package/frontend-vue/tests/table-live-hold.test.ts +0 -44
  169. package/frontend-vue/tests/table-row-action-errors.test.ts +5 -5
  170. package/frontend-vue/tests/table-row-hover.test.ts +2 -12
  171. package/frontend-vue/tests/table-scroll-area.test.ts +0 -8
  172. package/frontend-vue/tests/table-view-card-props.test.ts +0 -17
  173. package/frontend-vue/tests/table-view-cards-reorder.test.ts +0 -16
  174. package/frontend-vue/tests/table-view-grouped.test.ts +0 -55
  175. package/frontend-vue/tests/table-view-pinned-rows.test.ts +0 -15
  176. package/frontend-vue/tests/table-view-record-link.test.ts +0 -17
  177. package/frontend-vue/tests/table-view-refresh.test.ts +0 -17
  178. package/frontend-vue/tests/table-view-sources.test.ts +1 -1
  179. package/frontend-vue/tests/table-view-url-tab.test.ts +0 -14
  180. package/frontend-vue/tests/template-tokens.test.ts +235 -0
  181. package/frontend-vue/tests/tone.test.ts +0 -19
  182. package/frontend-vue/tests/url-interpolation.test.ts +6 -6
  183. package/package.json +6 -6
  184. package/skills/dms/SKILL.md +2 -1
  185. package/skills/dms-pages/REFERENCE.md +2 -2
  186. package/skills/dms-project/SKILL.md +0 -1
  187. package/dist/test/integration/auth/login.test.js +0 -57
  188. package/dist/test/integration/auth/login.test.js.map +0 -1
  189. package/dist/test/integration/auth/refresh.test.js +0 -59
  190. package/dist/test/integration/auth/refresh.test.js.map +0 -1
  191. package/dist/test/integration/auth/sessions.test.js +0 -58
  192. package/dist/test/integration/auth/sessions.test.js.map +0 -1
  193. package/dist/test/integration/auth/signup.test.js +0 -99
  194. package/dist/test/integration/auth/signup.test.js.map +0 -1
  195. package/dist/test/unit/skills/dms-dev-script.test.d.ts +0 -1
  196. package/dist/test/unit/skills/dms-dev-script.test.js +0 -137
  197. package/dist/test/unit/skills/dms-dev-script.test.js.map +0 -1
  198. package/frontend-vue/tests/form-reload-on-reopen.test.ts +0 -20
  199. package/frontend-vue/tests/icon-aria-hidden.test.ts +0 -29
  200. package/frontend-vue/tests/skeleton-paragraph.test.ts +0 -30
  201. package/frontend-vue/tests/tab-slot-spacing.test.ts +0 -29
  202. package/frontend-vue/tests/table-empty-body-viewport.test.ts +0 -25
  203. package/frontend-vue/tests/table-header-placement.test.ts +0 -21
  204. package/frontend-vue/tests/vue-inventory.test.ts +0 -107
  205. /package/dist/test/{integration/auth/login.test.d.ts → unit/implementations/dms-html-render/built-in-emails.test.d.ts} +0 -0
  206. /package/dist/test/{integration/auth/sessions.test.d.ts → unit/interfaces/dms/hook-handler-results.test.d.ts} +0 -0
  207. /package/dist/test/{integration/auth/refresh.test.d.ts → unit/interfaces/dms-base/query-response-delta.test.d.ts} +0 -0
  208. /package/dist/test/{integration/auth/signup.test.d.ts → unit/utils/email-subjects.test.d.ts} +0 -0
@@ -30,6 +30,7 @@ const html_render_1 = require("@antelopejs/interface-dms/html-render");
30
30
  const sync_1 = require("csv-stringify/sync");
31
31
  const config_1 = require("../config");
32
32
  const exportJobs_model_1 = require("@antelopejs/interface-dms/db/internal/exportJobs.model");
33
+ const email_subjects_1 = require("./email-subjects");
33
34
  const run_in_batches_1 = require("./run-in-batches");
34
35
  const export_jobs_1 = require("@antelopejs/interface-dms/base/export-jobs");
35
36
  const time_1 = require("@antelopejs/interface-dms/utils/internal/time");
@@ -92,7 +93,6 @@ const downloadDeliverer = {
92
93
  async deliver() { },
93
94
  };
94
95
  const ExportReadyTemplate = (0, html_render_1.RegisterHtmlTemplate)("EmailExportReady");
95
- const EXPORT_READY_SUBJECT = "Your data export is ready";
96
96
  function buildDeliveryLink(exportRecord) {
97
97
  const baseUrl = (0, config_1.getClientBaseUrl)();
98
98
  (0, interface_api_util_1.assert)(baseUrl, 500, "clientBaseUrl is required to deliver an export link");
@@ -103,6 +103,18 @@ function readJobResult(exportRecord) {
103
103
  return undefined;
104
104
  return JSON.parse(exportRecord.json_result);
105
105
  }
106
+ function exportReadyEmailData(user, exportRecord) {
107
+ const result = readJobResult(exportRecord);
108
+ const expiresInHours = export_jobs_1.EXPORT_TTL_MS / time_1.MILLISECONDS_PER_HOUR;
109
+ return {
110
+ userName: user.name || user.email,
111
+ downloadLink: buildDeliveryLink(exportRecord),
112
+ expiresIn: `${expiresInHours} hours`,
113
+ expiresInHours,
114
+ partial: result?.partial ?? false,
115
+ failedSources: (result?.failures ?? []).map((failure) => failure.source),
116
+ };
117
+ }
106
118
  const emailDeliverer = {
107
119
  validate(options) {
108
120
  (0, interface_api_util_1.assert)(options.deliveryPath, 400, "Email delivery requires a deliveryPath to build the download link");
@@ -110,17 +122,10 @@ const emailDeliverer = {
110
122
  async deliver(exportRecord) {
111
123
  const user = await (0, interface_database_decorators_1.GetModel)(db_2.UserModel).get(exportRecord.userId);
112
124
  (0, interface_api_util_1.assert)(user, 500, "Export recipient not found");
113
- const result = readJobResult(exportRecord);
114
- const html = await (0, html_render_1.GenerateHtml)(ExportReadyTemplate, {
115
- userName: user.name || user.email,
116
- downloadLink: buildDeliveryLink(exportRecord),
117
- expiresIn: `${export_jobs_1.EXPORT_TTL_MS / time_1.MILLISECONDS_PER_HOUR} hours`,
118
- partial: result?.partial ?? false,
119
- failedSources: (result?.failures ?? []).map((failure) => failure.source),
120
- });
125
+ const html = await (0, html_render_1.GenerateHtml)(ExportReadyTemplate, exportReadyEmailData(user, exportRecord), user.language);
121
126
  const sent = await (0, interface_email_1.Send)({
122
127
  to: user.email,
123
- subject: EXPORT_READY_SUBJECT,
128
+ subject: (0, email_subjects_1.builtInEmailSubject)("exportReady", user.language),
124
129
  html,
125
130
  });
126
131
  (0, interface_api_util_1.assert)(sent.success, 500, `Failed to send export email: ${sent.error?.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"export-jobs.js","sourceRoot":"","sources":["../../src/utils/export-jobs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"export-jobs.js","sourceRoot":"","sources":["../../src/utils/export-jobs.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,18 @@
1
1
  import { get } from "@nuxt/ui/runtime/utils/index.js";
2
2
 
3
- const VARIABLE_PATTERN = /{([^}]+)}/g;
3
+ // A row field is named `{{row.<field>}}` (a dotted path reaching into it), as
4
+ // the page's values are `{{params.X}}` / `{{query.X}}`, filled elsewhere.
5
+ const ROW_TOKEN = /\{\{\s*row\.([^{}\s]+)\s*\}\}/g;
6
+
7
+ /** Whether a template names a field of a row (`{{row.X}}`). */
8
+ export const namesRowField = (template: string): boolean =>
9
+ new RegExp(ROW_TOKEN.source).test(template);
10
+
11
+ const rowValue = (data: Record<string, unknown>, key: string): string => {
12
+ const value: unknown = get(data, key);
13
+ return value === undefined || value === null ? "" : String(value);
14
+ };
15
+
4
16
  // A colon is a valid path character (RFC 3986 pchar) and the API router
5
17
  // matches path parameters without decoding them: tenant-scoped ids
6
18
  // ("default:<uuid>") must reach a `/:id/...` route as they are.
@@ -11,7 +23,7 @@ const SAFE_SCHEMES: ReadonlySet<string> = new Set(["http", "https", "mailto"]);
11
23
  const REFUSED_URL = "";
12
24
 
13
25
  // The colon survives the encoding, so a template starting with a field
14
- // (`{website}`) takes its scheme from row data: `javascript:` must not reach
26
+ // (`{{row.website}}`) takes its scheme from row data: `javascript:` must not reach
15
27
  // a link or `location.href`.
16
28
  function hasSafeScheme(url: string): boolean {
17
29
  const scheme = SCHEME_PATTERN.exec(url)?.[1];
@@ -19,19 +31,25 @@ function hasSafeScheme(url: string): boolean {
19
31
  }
20
32
 
21
33
  /**
22
- * Fills `{field}` placeholders of a URL template with encoded row values. A
23
- * result with a scheme other than http, https or mailto comes back empty.
34
+ * Fills the `{{row.field}}` tokens of a URL template with encoded row values,
35
+ * a field the row lacks left empty. A result with a scheme other than http,
36
+ * https or mailto comes back empty.
24
37
  */
25
38
  export const interpolateUrl = (
26
39
  url: string,
27
40
  data: Record<string, unknown>,
28
41
  ): string => {
29
- const interpolated = url.replace(VARIABLE_PATTERN, (_, key: string) => {
30
- const value = get(data, key);
31
- if (value === undefined || value === null) {
32
- return "";
33
- }
34
- return encodeURIComponent(String(value)).replace(ENCODED_COLON, ":");
35
- });
42
+ const interpolated = url.replace(ROW_TOKEN, (_, key: string) =>
43
+ encodeURIComponent(rowValue(data, key)).replace(ENCODED_COLON, ":"),
44
+ );
36
45
  return hasSafeScheme(interpolated) ? interpolated : REFUSED_URL;
37
46
  };
47
+
48
+ /**
49
+ * Fills the `{{row.field}}` tokens of a plain value (a file name) with the
50
+ * row's values as they are, a field the row lacks left empty.
51
+ */
52
+ export const interpolateRowText = (
53
+ text: string,
54
+ data: Record<string, unknown>,
55
+ ): string => text.replace(ROW_TOKEN, (_, key: string) => rowValue(data, key));
@@ -12,6 +12,22 @@ export interface DmsLogoSources {
12
12
  dark: string;
13
13
  }
14
14
 
15
+ /**
16
+ * What the footer of the public and auth pages shows besides its links
17
+ * (`registerFooterLink`).
18
+ */
19
+ export interface DmsFooterConfig {
20
+ /**
21
+ * Name after the `©`, a literal or a `$`-prefixed i18n key; `false` drops
22
+ * the copyright.
23
+ */
24
+ copyright?: string | false;
25
+ /** The GitHub "Star" button of the DMS repository. */
26
+ githubStar?: boolean;
27
+ /** The language picker. */
28
+ localeSwitcher?: boolean;
29
+ }
30
+
15
31
  export interface DmsBrandingConfig {
16
32
  /**
17
33
  * Absent when an instance ships no logo of its own; the layer's app config
@@ -21,6 +37,7 @@ export interface DmsBrandingConfig {
21
37
  default: DmsLogoSources;
22
38
  collapsed: DmsLogoSources;
23
39
  };
40
+ footer?: DmsFooterConfig;
24
41
  }
25
42
 
26
43
  export interface DmsAppConfig {
@@ -194,5 +194,10 @@ export default {
194
194
  dark: "/images/antelope-logo/icon.svg",
195
195
  },
196
196
  },
197
+ footer: {
198
+ copyright: "Antelope",
199
+ githubStar: true,
200
+ localeSwitcher: true,
201
+ },
197
202
  },
198
203
  };
@@ -1,9 +1,13 @@
1
1
  <script setup lang="ts">
2
2
  import type { BreadcrumbItem, DropdownMenuItem } from "@nuxt/ui";
3
+ import { onMounted, ref } from "vue";
3
4
  import NotificationPopover from "../notification/NotificationPopover.vue";
4
5
  import QuickActionsPopover from "./QuickActionsPopover.vue";
5
6
  import { useSidebarState } from "./sidebarState";
6
- import { useHeaderActionControls } from "../../composables/layout/useHeaderActionControls";
7
+ import {
8
+ isPlainDataHeaderAction,
9
+ useHeaderActionControls,
10
+ } from "../../composables/layout/useHeaderActionControls";
7
11
  import { usePageRecordLabel } from "#dms-core/app/composables/page/usePageRecordLabel";
8
12
  import type { CategoryInfo } from "../../../types/page";
9
13
  import { resolveModuleLandingSlug } from "../../../utils/moduleLanding";
@@ -30,7 +34,19 @@ const { open: sidebarOpen, collapsed: sidebarCollapsed } = useSidebarState();
30
34
 
31
35
  // Modules register their own header buttons through this generic registry, so
32
36
  // core has no knowledge of any specific module.
33
- const { actions: registeredActions } = useHeaderActions();
37
+ const { actions: visibleActions } = useHeaderActions();
38
+ // A `.client` plugin's action is missing from the server markup: drawn while
39
+ // hydrating, its button would be patched onto the next one's node. It joins
40
+ // once the header has mounted.
41
+ const isMounted = ref(false);
42
+ onMounted(() => {
43
+ isMounted.value = true;
44
+ });
45
+ const registeredActions = computed(() =>
46
+ isMounted.value
47
+ ? visibleActions.value
48
+ : visibleActions.value.filter(isPlainDataHeaderAction),
49
+ );
34
50
 
35
51
  // The builder button keeps its fixed slot first in the toolbar, and only
36
52
  // exists when a module (the Builder) registers the action that drives it.
@@ -6,6 +6,7 @@ import {
6
6
  } from "../../utils/github-repository";
7
7
 
8
8
  const EXTERNAL_LINK_PATTERN = /^https?:\/\//;
9
+ const DEFAULT_COPYRIGHT = "Antelope";
9
10
  const GITHUB_REPOSITORY_API = `https://api.github.com/repos/${GITHUB_REPOSITORY}`;
10
11
  const GITHUB_STARS_CACHE_KEY = "dms-github-stars";
11
12
  // GitHub allows 60 anonymous API calls an hour per visitor: the count is
@@ -15,6 +16,17 @@ const GITHUB_STARS_CACHE_TTL_MS = 60 * 60 * 1000;
15
16
  const { locale, setLocale, t } = useI18n();
16
17
  const { uniqueLocales } = useUniqueLocales();
17
18
  const { links } = useFooterLinks();
19
+ const { processI18n } = useTranslation();
20
+ const footer = computed(() => useDmsAppConfig().branding.footer ?? {});
21
+ const copyright = computed(() =>
22
+ footer.value.copyright === false
23
+ ? null
24
+ : processI18n(footer.value.copyright ?? DEFAULT_COPYRIGHT),
25
+ );
26
+ const showsGithubStar = computed(() => footer.value.githubStar !== false);
27
+ const showsLocaleSwitcher = computed(
28
+ () => footer.value.localeSwitcher !== false,
29
+ );
18
30
 
19
31
  const localesOptions: SelectItem[] = uniqueLocales.value.map((lang) => ({
20
32
  label: lang.name,
@@ -87,6 +99,7 @@ async function loadGithubStars(): Promise<void> {
87
99
  }
88
100
 
89
101
  onMounted(async () => {
102
+ if (!showsGithubStar.value) return;
90
103
  await loadGithubStars();
91
104
  githubStarsSettled.value = true;
92
105
  });
@@ -103,7 +116,7 @@ async function onLocaleChange(code: unknown) {
103
116
  <footer
104
117
  class="border-default text-dimmed flex flex-wrap items-center gap-x-[18px] gap-y-1.5 border-t px-5 py-3 text-[12.5px] max-sm:justify-center"
105
118
  >
106
- <span>&copy; Antelope</span>
119
+ <span v-if="copyright">&copy; {{ copyright }}</span>
107
120
  <template v-for="link in links" :key="link.id">
108
121
  <a
109
122
  v-if="isExternal(link.to)"
@@ -125,6 +138,7 @@ async function onLocaleChange(code: unknown) {
125
138
 
126
139
  <!-- GitHub star button: icon + "Star" | live count, opens the repository. -->
127
140
  <a
141
+ v-if="showsGithubStar"
128
142
  :href="GITHUB_REPOSITORY_URL"
129
143
  target="_blank"
130
144
  rel="noopener noreferrer"
@@ -152,6 +166,7 @@ async function onLocaleChange(code: unknown) {
152
166
  </a>
153
167
 
154
168
  <USelect
169
+ v-if="showsLocaleSwitcher"
155
170
  :model-value="locale"
156
171
  :items="localesOptions"
157
172
  :aria-label="t('empty_layout.footer.language')"
@@ -15,6 +15,20 @@ export interface HeaderActionControls {
15
15
  select: (action: HeaderAction) => void;
16
16
  }
17
17
 
18
+ const ACTION_CALLABLES = ["onSelect", "isVisible", "isActive"] as const;
19
+
20
+ /**
21
+ * Whether the action is plain data, which a universal plugin registers on the
22
+ * server and the client alike, so the server markup holds its button. One
23
+ * carrying a callable belongs in a `.client` plugin: the server never drew
24
+ * it, and the header adds it once mounted rather than during hydration.
25
+ *
26
+ * @internal
27
+ */
28
+ export function isPlainDataHeaderAction(action: HeaderAction): boolean {
29
+ return ACTION_CALLABLES.every((key) => typeof action[key] !== "function");
30
+ }
31
+
18
32
  /**
19
33
  * How the header reads and runs any {@link HeaderAction}: an action linked to
20
34
  * a side panel gets its state and its click from the DMS, any other one from
@@ -9,6 +9,7 @@ interface HStackProps {
9
9
  distribution?: StackDistribution;
10
10
  spacing?: string;
11
11
  wrap?: boolean;
12
+ grow?: number;
12
13
  }
13
14
 
14
15
  const props = withDefaults(defineProps<HStackProps>(), {
@@ -28,6 +29,7 @@ const props = withDefaults(defineProps<HStackProps>(), {
28
29
  justifyContent: distributionMap[props.distribution],
29
30
  gap: props.spacing,
30
31
  '--dms-stack-gap': props.spacing,
32
+ flexGrow: props.grow,
31
33
  flexWrap: props.wrap ? 'wrap' : 'nowrap',
32
34
  }"
33
35
  class="dms-hstack w-full"
@@ -35,3 +37,17 @@ const props = withDefaults(defineProps<HStackProps>(), {
35
37
  <slot />
36
38
  </div>
37
39
  </template>
40
+
41
+ <style>
42
+ /* A stack fills what holds it, except along a row, where it is one item among
43
+ its siblings: sibling stacks share the row (in their `grow` ratio), and in
44
+ a row with a Spacer they keep their content width so the Spacer can push
45
+ them aside. An inline `grow` wins over both. */
46
+ .dms-hstack > :is(.dms-hstack, .dms-vstack) {
47
+ width: auto;
48
+ flex: 1 1 0%;
49
+ }
50
+ .dms-hstack:has(> .dms-spacer) > :is(.dms-hstack, .dms-vstack) {
51
+ flex: 0 1 auto;
52
+ }
53
+ </style>
@@ -8,6 +8,7 @@ interface VStackProps {
8
8
  alignment?: StackAlignment;
9
9
  distribution?: StackDistribution;
10
10
  spacing?: string;
11
+ grow?: number;
11
12
  }
12
13
 
13
14
  const props = withDefaults(defineProps<VStackProps>(), {
@@ -26,6 +27,7 @@ const props = withDefaults(defineProps<VStackProps>(), {
26
27
  justifyContent: distributionMap[props.distribution],
27
28
  gap: props.spacing,
28
29
  '--dms-stack-gap': props.spacing,
30
+ flexGrow: props.grow,
29
31
  }"
30
32
  class="dms-vstack w-full"
31
33
  >
@@ -7,7 +7,8 @@ export interface FooterLink {
7
7
 
8
8
  /**
9
9
  * The Antelope links every footer starts with. A layer replaces one by
10
- * registering an entry under the same id.
10
+ * registering an entry under the same id, or removes it with
11
+ * `unregisterFooterLink`.
11
12
  */
12
13
  const DEFAULT_FOOTER_LINKS: FooterLink[] = [
13
14
  {
@@ -43,6 +44,15 @@ export function registerFooterLink(link: FooterLink): void {
43
44
  links.value = next;
44
45
  }
45
46
 
47
+ /**
48
+ * Removes a link from the footer, one of the Antelope defaults
49
+ * (`dms:documentation`, `dms:website`) or another layer's. An id never
50
+ * registered is ignored.
51
+ */
52
+ export function unregisterFooterLink(id: string): void {
53
+ links.value = links.value.filter((entry) => entry.id !== id);
54
+ }
55
+
46
56
  export function useFooterLinks() {
47
57
  const sortedLinks = computed<FooterLink[]>(() =>
48
58
  [...links.value].sort(compareByOrder),
@@ -32,7 +32,7 @@ interface RoleEditorHandle {
32
32
 
33
33
  const NAME_REQUIRED = "$page.settings.roles.error.name_required";
34
34
  const NAME_TAKEN = "$page.settings.roles.error.name_taken";
35
- const ROLE_DELETE_CONFIRM_URL = `${ROLES_API_PATH}/{id}/delete-confirm`;
35
+ const ROLE_DELETE_CONFIRM_URL = `${ROLES_API_PATH}/{{row.id}}/delete-confirm`;
36
36
 
37
37
  const api = useRolesApi();
38
38
  const { t } = useI18n();
@@ -51,7 +51,7 @@ const invitation = computed(() => {
51
51
  </script>
52
52
 
53
53
  <template>
54
- <EmailLayout :title="title" :lang="locale">
54
+ <EmailLayout :title="title" :lang="locale" public-logo-only>
55
55
  <EText :style="emailStyles.text">
56
56
  {{ t("emails.admin_invite.greeting") }}
57
57
  </EText>
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "vue-i18n";
2
3
  import EmailLayout from "./components/EmailLayout.vue";
3
4
  import { emailStyles } from "./components/index";
4
5
 
@@ -6,22 +7,27 @@ defineProps<{
6
7
  userName: string;
7
8
  newEmail: string;
8
9
  }>();
10
+
11
+ const { t, locale } = useI18n();
9
12
  </script>
10
13
 
11
14
  <template>
12
- <EmailLayout title="Your sign-in email is being changed">
13
- <EText :style="emailStyles.text">Hello {{ userName }},</EText>
15
+ <EmailLayout
16
+ :title="t('emails.email_change_notice.title')"
17
+ :lang="locale"
18
+ public-logo-only
19
+ >
20
+ <EText :style="emailStyles.text">
21
+ {{ t("emails.common.greeting", { name: userName }) }}
22
+ </EText>
14
23
 
15
24
  <EText :style="emailStyles.text">
16
- Someone signed in to your account asked to change its sign-in email to
17
- {{ newEmail }}. The change takes effect once that address is confirmed.
25
+ {{ t("emails.email_change_notice.body", { email: newEmail }) }}
18
26
  </EText>
19
27
 
20
28
  <template #footer>
21
29
  <EText :style="emailStyles.footer">
22
- If this wasn't you, change your password now and sign out the other
23
- sessions in Security: your account keeps this address until the new
24
- one is confirmed.
30
+ {{ t("emails.email_change_notice.footer") }}
25
31
  </EText>
26
32
  </template>
27
33
  </EmailLayout>
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "vue-i18n";
2
3
  import EmailLayout from "./components/EmailLayout.vue";
3
4
  import EmailOTP from "./components/EmailOTP.vue";
4
5
  import { emailStyles } from "./components/index";
@@ -8,24 +9,34 @@ defineProps<{
8
9
  newEmail: string;
9
10
  code: string;
10
11
  expiresIn: string;
12
+ expiresInHours: number;
11
13
  }>();
14
+
15
+ const { t, locale } = useI18n();
12
16
  </script>
13
17
 
14
18
  <template>
15
- <EmailLayout title="Confirm your new sign-in email">
16
- <EText :style="emailStyles.text">Hello {{ userName }},</EText>
19
+ <EmailLayout
20
+ :title="t('emails.email_change_verification.title')"
21
+ :lang="locale"
22
+ public-logo-only
23
+ >
24
+ <EText :style="emailStyles.text">
25
+ {{ t("emails.common.greeting", { name: userName }) }}
26
+ </EText>
17
27
 
18
28
  <EText :style="emailStyles.text">
19
- Enter the code below to make {{ newEmail }} the sign-in email of your
20
- account:
29
+ {{ t("emails.email_change_verification.body", { email: newEmail }) }}
21
30
  </EText>
22
31
 
23
- <EmailOTP :code="code" :expires-in="expiresIn" />
32
+ <EmailOTP
33
+ :code="code"
34
+ :expires-in="t('emails.common.hours', expiresInHours)"
35
+ />
24
36
 
25
37
  <template #footer>
26
38
  <EText :style="emailStyles.footer">
27
- If you didn't ask for this change, you can safely ignore this email:
28
- your account keeps its current address.
39
+ {{ t("emails.email_change_verification.footer") }}
29
40
  </EText>
30
41
  </template>
31
42
  </EmailLayout>
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { I18nT, useI18n } from "vue-i18n";
2
3
  import EmailLayout from "./components/EmailLayout.vue";
3
4
  import EmailButton from "./components/EmailButton.vue";
4
5
  import { emailStyles } from "./components/index";
@@ -7,38 +8,48 @@ defineProps<{
7
8
  userName: string;
8
9
  downloadLink: string;
9
10
  expiresIn: string;
11
+ expiresInHours: number;
10
12
  partial: boolean;
11
13
  failedSources: string[];
12
14
  }>();
15
+
16
+ const { t, locale } = useI18n();
13
17
  </script>
14
18
 
15
19
  <template>
16
- <EmailLayout title="Your data export is ready">
17
- <EText :style="emailStyles.text">Hello {{ userName }},</EText>
20
+ <EmailLayout
21
+ :title="t('emails.export_ready.title')"
22
+ :lang="locale"
23
+ public-logo-only
24
+ >
25
+ <EText :style="emailStyles.text">
26
+ {{ t("emails.common.greeting", { name: userName }) }}
27
+ </EText>
18
28
 
19
29
  <EText :style="emailStyles.text">
20
- Your data export has been prepared. Use the button below to download the
21
- archive:
30
+ {{ t("emails.export_ready.body") }}
22
31
  </EText>
23
32
 
24
33
  <EmailButton
25
34
  :href="downloadLink"
26
- :expires-in="expiresIn"
27
- expires-label="This download link expires in"
35
+ :expires-in="t('emails.common.hours', expiresInHours)"
36
+ :expires-label="t('emails.export_ready.expires_label')"
28
37
  >
29
- Download export
38
+ {{ t("emails.export_ready.button") }}
30
39
  </EmailButton>
31
40
 
32
41
  <EText v-if="partial" :style="emailStyles.text">
33
- This export is
34
- <strong>incomplete</strong>
35
- : the following parts could not be included —
36
- {{ failedSources.join(", ") }}. Request a new export if you need them.
42
+ <I18nT keypath="emails.export_ready.partial" scope="global">
43
+ <template #incomplete>
44
+ <strong>{{ t("emails.export_ready.incomplete") }}</strong>
45
+ </template>
46
+ <template #sources>{{ failedSources.join(", ") }}</template>
47
+ </I18nT>
37
48
  </EText>
38
49
 
39
50
  <template #footer>
40
51
  <EText :style="emailStyles.footer">
41
- If you didn't request this export, you can safely ignore this email.
52
+ {{ t("emails.export_ready.footer") }}
42
53
  </EText>
43
54
  </template>
44
55
  </EmailLayout>
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "vue-i18n";
2
3
  import EmailLayout from "./components/EmailLayout.vue";
3
4
  import EmailOTP from "./components/EmailOTP.vue";
4
5
  import { emailStyles } from "./components/index";
@@ -7,24 +8,34 @@ defineProps<{
7
8
  userName: string;
8
9
  resetCode: string;
9
10
  expiresIn: string;
11
+ expiresInHours: number;
10
12
  }>();
13
+
14
+ const { t, locale } = useI18n();
11
15
  </script>
12
16
 
13
17
  <template>
14
- <EmailLayout title="Reset Your Password">
15
- <EText :style="emailStyles.text">Hello {{ userName }},</EText>
18
+ <EmailLayout
19
+ :title="t('emails.reset_password.title')"
20
+ :lang="locale"
21
+ public-logo-only
22
+ >
23
+ <EText :style="emailStyles.text">
24
+ {{ t("emails.common.greeting", { name: userName }) }}
25
+ </EText>
16
26
 
17
27
  <EText :style="emailStyles.text">
18
- We received a request to reset your password. Enter the verification code
19
- below to reset your password:
28
+ {{ t("emails.reset_password.body") }}
20
29
  </EText>
21
30
 
22
- <EmailOTP :code="resetCode" :expires-in="expiresIn" />
31
+ <EmailOTP
32
+ :code="resetCode"
33
+ :expires-in="t('emails.common.hours', expiresInHours)"
34
+ />
23
35
 
24
36
  <template #footer>
25
37
  <EText :style="emailStyles.footer">
26
- If you didn't request a password reset, you can safely ignore this
27
- email. Your password will remain unchanged.
38
+ {{ t("emails.reset_password.footer") }}
28
39
  </EText>
29
40
  </template>
30
41
  </EmailLayout>