@antelopejs/dms 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/db/models/notification-feed-filter.d.ts +0 -1
  3. package/dist/db/models/notification-feed-filter.js +0 -4
  4. package/dist/db/models/notification-feed-filter.js.map +1 -1
  5. package/dist/db/models/signInAttempts.model.d.ts +18 -0
  6. package/dist/db/models/signInAttempts.model.js +83 -12
  7. package/dist/db/models/signInAttempts.model.js.map +1 -1
  8. package/dist/db/models/userEmailChanges.model.d.ts +8 -1
  9. package/dist/db/models/userEmailChanges.model.js +27 -2
  10. package/dist/db/models/userEmailChanges.model.js.map +1 -1
  11. package/dist/db/models/userNotificationPreferences.model.d.ts +0 -2
  12. package/dist/db/models/userNotificationPreferences.model.js +0 -13
  13. package/dist/db/models/userNotificationPreferences.model.js.map +1 -1
  14. package/dist/db/models/userNotifications.model.d.ts +5 -2
  15. package/dist/db/models/userNotifications.model.js +19 -2
  16. package/dist/db/models/userNotifications.model.js.map +1 -1
  17. package/dist/db/tables/signInAttempts.table.d.ts +2 -1
  18. package/dist/db/tables/signInAttempts.table.js +4 -0
  19. package/dist/db/tables/signInAttempts.table.js.map +1 -1
  20. package/dist/db/tables/userEmailChanges.table.d.ts +2 -1
  21. package/dist/db/tables/userEmailChanges.table.js +6 -1
  22. package/dist/db/tables/userEmailChanges.table.js.map +1 -1
  23. package/dist/db/tables/userNotificationPreferences.table.d.ts +0 -1
  24. package/dist/db/tables/userNotificationPreferences.table.js +0 -4
  25. package/dist/db/tables/userNotificationPreferences.table.js.map +1 -1
  26. package/dist/implementations/dms/layout-banners.d.ts +4 -1
  27. package/dist/implementations/dms/layout-banners.js +33 -18
  28. package/dist/implementations/dms/layout-banners.js.map +1 -1
  29. package/dist/implementations/dms/nav-badges.d.ts +6 -4
  30. package/dist/implementations/dms/nav-badges.js +6 -5
  31. package/dist/implementations/dms/nav-badges.js.map +1 -1
  32. package/dist/implementations/dms/page.d.ts +1 -0
  33. package/dist/implementations/dms/page.js +46 -8
  34. package/dist/implementations/dms/page.js.map +1 -1
  35. package/dist/implementations/dms/permission-preview.d.ts +1 -1
  36. package/dist/implementations/dms/permission-preview.js +9 -4
  37. package/dist/implementations/dms/permission-preview.js.map +1 -1
  38. package/dist/implementations/dms-auth/index.d.ts +3 -2
  39. package/dist/implementations/dms-auth/index.js +39 -35
  40. package/dist/implementations/dms-auth/index.js.map +1 -1
  41. package/dist/implementations/dms-auth/token-session.d.ts +3 -0
  42. package/dist/implementations/dms-auth/token-session.js +22 -0
  43. package/dist/implementations/dms-auth/token-session.js.map +1 -0
  44. package/dist/implementations/dms-notifications/index.d.ts +0 -1
  45. package/dist/implementations/dms-notifications/index.js +0 -7
  46. package/dist/implementations/dms-notifications/index.js.map +1 -1
  47. package/dist/pages/settings/settings-index.js +3 -2
  48. package/dist/pages/settings/settings-index.js.map +1 -1
  49. package/dist/pages/settings/users/account-activity-feed.d.ts +1 -1
  50. package/dist/pages/settings/users/account-activity-feed.js +1 -1
  51. package/dist/pages/settings/users/account-activity-feed.js.map +1 -1
  52. package/dist/pages/settings/users/account-activity.d.ts +1 -1
  53. package/dist/pages/settings/users/account-activity.js +1 -1
  54. package/dist/pages/settings/users/account-activity.js.map +1 -1
  55. package/dist/pages/settings/users/account-credentials.d.ts +3 -0
  56. package/dist/pages/settings/users/account-credentials.js +2 -0
  57. package/dist/pages/settings/users/account-credentials.js.map +1 -1
  58. package/dist/pages/settings/users/current-password.d.ts +1 -1
  59. package/dist/pages/settings/users/current-password.js +23 -2
  60. package/dist/pages/settings/users/current-password.js.map +1 -1
  61. package/dist/pages/settings/users/email-change.d.ts +1 -1
  62. package/dist/pages/settings/users/email-change.js +33 -26
  63. package/dist/pages/settings/users/email-change.js.map +1 -1
  64. package/dist/pages/settings/users/invite-resend.js +0 -1
  65. package/dist/pages/settings/users/invite-resend.js.map +1 -1
  66. package/dist/pages/settings/users/invites.d.ts +1 -2
  67. package/dist/pages/settings/users/invites.js +21 -19
  68. package/dist/pages/settings/users/invites.js.map +1 -1
  69. package/dist/pages/settings/users/member-invite-batch.js +0 -1
  70. package/dist/pages/settings/users/member-invite-batch.js.map +1 -1
  71. package/dist/pages/settings/users/member-invite-form.js +10 -22
  72. package/dist/pages/settings/users/member-invite-form.js.map +1 -1
  73. package/dist/pages/settings/users/member-role-options.d.ts +6 -4
  74. package/dist/pages/settings/users/member-role-options.js +15 -4
  75. package/dist/pages/settings/users/member-role-options.js.map +1 -1
  76. package/dist/pages/settings/users/members.d.ts +2 -3
  77. package/dist/pages/settings/users/members.js +7 -12
  78. package/dist/pages/settings/users/members.js.map +1 -1
  79. package/dist/pages/settings/users/notifications.d.ts +1 -8
  80. package/dist/pages/settings/users/notifications.js +6 -38
  81. package/dist/pages/settings/users/notifications.js.map +1 -1
  82. package/dist/pages/settings/users/permission-tree-nodes.d.ts +1 -1
  83. package/dist/pages/settings/users/permission-tree-nodes.js +23 -9
  84. package/dist/pages/settings/users/permission-tree-nodes.js.map +1 -1
  85. package/dist/pages/settings/users/permission-warnings.d.ts +7 -0
  86. package/dist/pages/settings/users/permission-warnings.js +42 -0
  87. package/dist/pages/settings/users/permission-warnings.js.map +1 -0
  88. package/dist/pages/settings/users/profile-helpers.d.ts +1 -3
  89. package/dist/pages/settings/users/profile-helpers.js +0 -16
  90. package/dist/pages/settings/users/profile-helpers.js.map +1 -1
  91. package/dist/pages/settings/users/role-editor-store.js +6 -3
  92. package/dist/pages/settings/users/role-editor-store.js.map +1 -1
  93. package/dist/pages/settings/users/role-editor.d.ts +2 -1
  94. package/dist/pages/settings/users/role-editor.js +8 -4
  95. package/dist/pages/settings/users/role-editor.js.map +1 -1
  96. package/dist/pages/settings/users/role-preview.js +2 -1
  97. package/dist/pages/settings/users/role-preview.js.map +1 -1
  98. package/dist/pages/settings/users/roles.js +5 -1
  99. package/dist/pages/settings/users/roles.js.map +1 -1
  100. package/dist/pages/settings/users/security-attention.d.ts +4 -0
  101. package/dist/pages/settings/users/security-attention.js +23 -7
  102. package/dist/pages/settings/users/security-attention.js.map +1 -1
  103. package/dist/pages/settings/users/security.d.ts +2 -1
  104. package/dist/pages/settings/users/security.js +13 -2
  105. package/dist/pages/settings/users/security.js.map +1 -1
  106. package/dist/pages/settings/users/two-factor-operations.d.ts +2 -1
  107. package/dist/pages/settings/users/two-factor-operations.js +28 -29
  108. package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
  109. package/dist/routes/auth/forgot-password.js +3 -0
  110. package/dist/routes/auth/forgot-password.js.map +1 -1
  111. package/dist/routes/auth/index.d.ts +1 -0
  112. package/dist/routes/auth/index.js +1 -0
  113. package/dist/routes/auth/index.js.map +1 -1
  114. package/dist/routes/auth/invite.js +28 -4
  115. package/dist/routes/auth/invite.js.map +1 -1
  116. package/dist/routes/auth/login-throttle.d.ts +2 -0
  117. package/dist/routes/auth/login-throttle.js +5 -4
  118. package/dist/routes/auth/login-throttle.js.map +1 -1
  119. package/dist/routes/auth/request-2fa-email.js +6 -18
  120. package/dist/routes/auth/request-2fa-email.js.map +1 -1
  121. package/dist/routes/auth/reset-code.d.ts +3 -0
  122. package/dist/routes/auth/reset-code.js +37 -0
  123. package/dist/routes/auth/reset-code.js.map +1 -0
  124. package/dist/routes/auth/reset-password.d.ts +2 -2
  125. package/dist/routes/auth/reset-password.js +5 -10
  126. package/dist/routes/auth/reset-password.js.map +1 -1
  127. package/dist/routes/auth/signup.js +10 -32
  128. package/dist/routes/auth/signup.js.map +1 -1
  129. package/dist/routes/auth/two-factor-throttle.d.ts +5 -0
  130. package/dist/routes/auth/two-factor-throttle.js +81 -0
  131. package/dist/routes/auth/two-factor-throttle.js.map +1 -0
  132. package/dist/routes/auth/validate-forgot-password-token.js +2 -8
  133. package/dist/routes/auth/validate-forgot-password-token.js.map +1 -1
  134. package/dist/routes/auth/validate-invite-token.d.ts +1 -0
  135. package/dist/routes/auth/validate-invite-token.js +11 -0
  136. package/dist/routes/auth/validate-invite-token.js.map +1 -0
  137. package/dist/routes/auth/verify-2fa.js +10 -13
  138. package/dist/routes/auth/verify-2fa.js.map +1 -1
  139. package/dist/routes/auth.d.ts +1 -0
  140. package/dist/routes/auth.js +11 -1
  141. package/dist/routes/auth.js.map +1 -1
  142. package/dist/test/helpers/auth.d.ts +0 -1
  143. package/dist/test/helpers/auth.js +0 -1
  144. package/dist/test/helpers/auth.js.map +1 -1
  145. package/dist/test/helpers/emails.d.ts +10 -0
  146. package/dist/test/helpers/emails.js +36 -0
  147. package/dist/test/helpers/emails.js.map +1 -0
  148. package/dist/test/helpers/fixtures.d.ts +0 -1
  149. package/dist/test/helpers/fixtures.js +1 -2
  150. package/dist/test/helpers/fixtures.js.map +1 -1
  151. package/dist/test/helpers/page-access.d.ts +1 -0
  152. package/dist/test/helpers/page-access.js +6 -1
  153. package/dist/test/helpers/page-access.js.map +1 -1
  154. package/dist/test/integration/auth/current-password.test.d.ts +1 -0
  155. package/dist/test/integration/auth/current-password.test.js +65 -0
  156. package/dist/test/integration/auth/current-password.test.js.map +1 -0
  157. package/dist/test/integration/auth/password-reset.test.d.ts +1 -0
  158. package/dist/test/integration/auth/password-reset.test.js +126 -0
  159. package/dist/test/integration/auth/password-reset.test.js.map +1 -0
  160. package/dist/test/integration/auth/session-revocation.test.d.ts +1 -0
  161. package/dist/test/integration/auth/session-revocation.test.js +45 -0
  162. package/dist/test/integration/auth/session-revocation.test.js.map +1 -0
  163. package/dist/test/integration/auth/two-factor-codes.test.d.ts +1 -0
  164. package/dist/test/integration/auth/two-factor-codes.test.js +335 -0
  165. package/dist/test/integration/auth/two-factor-codes.test.js.map +1 -0
  166. package/dist/test/integration/auth/two-factor-password.test.js +5 -1
  167. package/dist/test/integration/auth/two-factor-password.test.js.map +1 -1
  168. package/dist/test/integration/auth/two-factor-token.test.d.ts +1 -0
  169. package/dist/test/integration/auth/two-factor-token.test.js +92 -0
  170. package/dist/test/integration/auth/two-factor-token.test.js.map +1 -0
  171. package/dist/test/integration/email-change.test.js +36 -0
  172. package/dist/test/integration/email-change.test.js.map +1 -1
  173. package/dist/test/integration/invite-extension-edit.test.js +0 -1
  174. package/dist/test/integration/invite-extension-edit.test.js.map +1 -1
  175. package/dist/test/integration/invite-link-status.test.d.ts +1 -0
  176. package/dist/test/integration/invite-link-status.test.js +110 -0
  177. package/dist/test/integration/invite-link-status.test.js.map +1 -0
  178. package/dist/test/integration/invite-resolution.test.js +0 -3
  179. package/dist/test/integration/invite-resolution.test.js.map +1 -1
  180. package/dist/test/integration/member-settings-access.test.js +17 -0
  181. package/dist/test/integration/member-settings-access.test.js.map +1 -1
  182. package/dist/test/integration/notification-unread-badge.test.d.ts +1 -0
  183. package/dist/test/integration/notification-unread-badge.test.js +92 -0
  184. package/dist/test/integration/notification-unread-badge.test.js.map +1 -0
  185. package/dist/test/integration/permission-warnings.test.d.ts +1 -0
  186. package/dist/test/integration/permission-warnings.test.js +71 -0
  187. package/dist/test/integration/permission-warnings.test.js.map +1 -0
  188. package/dist/test/integration/removed-member-notifications.test.d.ts +1 -0
  189. package/dist/test/integration/removed-member-notifications.test.js +80 -0
  190. package/dist/test/integration/removed-member-notifications.test.js.map +1 -0
  191. package/dist/test/integration/role-permission-ancestors.test.d.ts +1 -0
  192. package/dist/test/integration/role-permission-ancestors.test.js +146 -0
  193. package/dist/test/integration/role-permission-ancestors.test.js.map +1 -0
  194. package/dist/test/integration/tenant-lifecycle.test.js +0 -4
  195. package/dist/test/integration/tenant-lifecycle.test.js.map +1 -1
  196. package/dist/test/unit/auth-session-revocation.test.d.ts +1 -0
  197. package/dist/test/unit/auth-session-revocation.test.js +105 -0
  198. package/dist/test/unit/auth-session-revocation.test.js.map +1 -0
  199. package/dist/test/unit/db/email-normalization.test.js +0 -1
  200. package/dist/test/unit/db/email-normalization.test.js.map +1 -1
  201. package/dist/test/unit/db/notification-feed-filter.test.js +0 -16
  202. package/dist/test/unit/db/notification-feed-filter.test.js.map +1 -1
  203. package/dist/test/unit/db/notification-inbox.test.js +63 -13
  204. package/dist/test/unit/db/notification-inbox.test.js.map +1 -1
  205. package/dist/test/unit/db/notification-preferences.test.js +0 -17
  206. package/dist/test/unit/db/notification-preferences.test.js.map +1 -1
  207. package/dist/test/unit/implementations/dms/empty-menu-group.test.d.ts +1 -0
  208. package/dist/test/unit/implementations/dms/empty-menu-group.test.js +133 -0
  209. package/dist/test/unit/implementations/dms/empty-menu-group.test.js.map +1 -0
  210. package/dist/test/unit/implementations/dms/layout-banners.test.js +78 -1
  211. package/dist/test/unit/implementations/dms/layout-banners.test.js.map +1 -1
  212. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.d.ts +1 -0
  213. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js +149 -0
  214. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js.map +1 -0
  215. package/dist/test/unit/implementations/dms/nav-badges.test.js +55 -4
  216. package/dist/test/unit/implementations/dms/nav-badges.test.js.map +1 -1
  217. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.d.ts +1 -0
  218. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js +118 -0
  219. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js.map +1 -0
  220. package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js +16 -0
  221. package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js.map +1 -1
  222. package/dist/test/unit/implementations/dms/permission-preview-cost.test.js +5 -3
  223. package/dist/test/unit/implementations/dms/permission-preview-cost.test.js.map +1 -1
  224. package/dist/test/unit/implementations/dms/permission-preview-menu.test.js +29 -3
  225. package/dist/test/unit/implementations/dms/permission-preview-menu.test.js.map +1 -1
  226. package/dist/test/unit/implementations/dms/quick-actions-button.test.js +4 -2
  227. package/dist/test/unit/implementations/dms/quick-actions-button.test.js.map +1 -1
  228. package/dist/test/unit/implementations/dms/user-permissions-gate.test.js +2 -1
  229. package/dist/test/unit/implementations/dms/user-permissions-gate.test.js.map +1 -1
  230. package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js +2 -1
  231. package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js.map +1 -1
  232. package/dist/test/unit/interfaces/dms/component-children-permissions.test.js +7 -2
  233. package/dist/test/unit/interfaces/dms/component-children-permissions.test.js.map +1 -1
  234. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.d.ts +1 -0
  235. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js +133 -0
  236. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js.map +1 -0
  237. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.d.ts +1 -0
  238. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js +149 -0
  239. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js.map +1 -0
  240. package/dist/test/unit/interfaces/dms/invite-extension.test.js +13 -0
  241. package/dist/test/unit/interfaces/dms/invite-extension.test.js.map +1 -1
  242. package/dist/test/unit/interfaces/dms/member-access.test.js +27 -1
  243. package/dist/test/unit/interfaces/dms/member-access.test.js.map +1 -1
  244. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.d.ts +1 -0
  245. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js +31 -0
  246. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js.map +1 -0
  247. package/dist/test/unit/interfaces/dms/page-extension.test.js +4 -1
  248. package/dist/test/unit/interfaces/dms/page-extension.test.js.map +1 -1
  249. package/dist/test/unit/interfaces/dms/permission-requirements.test.d.ts +1 -0
  250. package/dist/test/unit/interfaces/dms/permission-requirements.test.js +144 -0
  251. package/dist/test/unit/interfaces/dms/permission-requirements.test.js.map +1 -0
  252. package/dist/test/unit/interfaces/dms-base/column-display.test.js +70 -0
  253. package/dist/test/unit/interfaces/dms-base/column-display.test.js.map +1 -1
  254. package/dist/test/unit/interfaces/dms-base/display-blocks-catalog.test.js +38 -0
  255. package/dist/test/unit/interfaces/dms-base/display-blocks-catalog.test.js.map +1 -1
  256. package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js +6 -2
  257. package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js.map +1 -1
  258. package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js +1 -1
  259. package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js.map +1 -1
  260. package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js +2 -1
  261. package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js.map +1 -1
  262. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js +2 -1
  263. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js.map +1 -1
  264. package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js +2 -1
  265. package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js.map +1 -1
  266. package/dist/test/unit/pages/settings/account-activity-feed.test.js +2 -2
  267. package/dist/test/unit/pages/settings/account-activity-feed.test.js.map +1 -1
  268. package/dist/test/unit/pages/settings/account-activity.test.js +11 -2
  269. package/dist/test/unit/pages/settings/account-activity.test.js.map +1 -1
  270. package/dist/test/unit/pages/settings/invite-email-delivery.test.js +0 -1
  271. package/dist/test/unit/pages/settings/invite-email-delivery.test.js.map +1 -1
  272. package/dist/test/unit/pages/settings/invite-email-validation-option.test.d.ts +1 -0
  273. package/dist/test/unit/pages/settings/invite-email-validation-option.test.js +33 -0
  274. package/dist/test/unit/pages/settings/invite-email-validation-option.test.js.map +1 -0
  275. package/dist/test/unit/pages/settings/member-lists-page-size.test.d.ts +1 -0
  276. package/dist/test/unit/pages/settings/member-lists-page-size.test.js +22 -0
  277. package/dist/test/unit/pages/settings/member-lists-page-size.test.js.map +1 -0
  278. package/dist/test/unit/pages/settings/member-table-widths.test.js +2 -2
  279. package/dist/test/unit/pages/settings/member-table-widths.test.js.map +1 -1
  280. package/dist/test/unit/pages/settings/members-page.test.js +7 -10
  281. package/dist/test/unit/pages/settings/members-page.test.js.map +1 -1
  282. package/dist/test/unit/pages/settings/notifications-access-gate.test.js +3 -10
  283. package/dist/test/unit/pages/settings/notifications-access-gate.test.js.map +1 -1
  284. package/dist/test/unit/pages/settings/permission-tree-nodes.test.js +57 -0
  285. package/dist/test/unit/pages/settings/permission-tree-nodes.test.js.map +1 -1
  286. package/dist/test/unit/pages/settings/permission-warnings.test.d.ts +1 -0
  287. package/dist/test/unit/pages/settings/permission-warnings.test.js +49 -0
  288. package/dist/test/unit/pages/settings/permission-warnings.test.js.map +1 -0
  289. package/dist/test/unit/pages/settings/role-editor.test.js +16 -0
  290. package/dist/test/unit/pages/settings/role-editor.test.js.map +1 -1
  291. package/dist/test/unit/pages/settings/role-preview.test.js +7 -0
  292. package/dist/test/unit/pages/settings/role-preview.test.js.map +1 -1
  293. package/dist/test/unit/pages/settings/security-attention.test.d.ts +1 -0
  294. package/dist/test/unit/pages/settings/security-attention.test.js +74 -0
  295. package/dist/test/unit/pages/settings/security-attention.test.js.map +1 -0
  296. package/dist/test/unit/sanitize-user.test.d.ts +1 -0
  297. package/dist/test/unit/sanitize-user.test.js +21 -0
  298. package/dist/test/unit/sanitize-user.test.js.map +1 -0
  299. package/dist/test/unit/signup-email-validation.test.d.ts +1 -0
  300. package/dist/test/unit/signup-email-validation.test.js +79 -0
  301. package/dist/test/unit/signup-email-validation.test.js.map +1 -0
  302. package/dist/test/unit/validation/member-invite.schema.test.js +14 -52
  303. package/dist/test/unit/validation/member-invite.schema.test.js.map +1 -1
  304. package/dist/utils/account-notifications.d.ts +5 -0
  305. package/dist/utils/account-notifications.js +8 -0
  306. package/dist/utils/account-notifications.js.map +1 -1
  307. package/dist/utils/notification-emitter.d.ts +1 -1
  308. package/dist/utils/notification-emitter.js +1 -1
  309. package/dist/utils/notification-emitter.js.map +1 -1
  310. package/dist/utils/notification-tones.d.ts +2 -1
  311. package/dist/utils/notification-tones.js +5 -1
  312. package/dist/utils/notification-tones.js.map +1 -1
  313. package/dist/utils/one-time-code.d.ts +3 -0
  314. package/dist/utils/one-time-code.js +21 -0
  315. package/dist/utils/one-time-code.js.map +1 -0
  316. package/dist/utils/sign-in-monitor.d.ts +1 -0
  317. package/dist/utils/sign-in-monitor.js +3 -2
  318. package/dist/utils/sign-in-monitor.js.map +1 -1
  319. package/dist/utils/two-factor-codes.d.ts +10 -0
  320. package/dist/utils/two-factor-codes.js +76 -0
  321. package/dist/utils/two-factor-codes.js.map +1 -0
  322. package/dist/validation/auth.schema.d.ts +17 -0
  323. package/dist/validation/auth.schema.js +17 -6
  324. package/dist/validation/auth.schema.js.map +1 -1
  325. package/dist/validation/issue-message.d.ts +1 -0
  326. package/dist/validation/issue-message.js +9 -0
  327. package/dist/validation/issue-message.js.map +1 -0
  328. package/dist/validation/member-invite.schema.d.ts +1 -25
  329. package/dist/validation/member-invite.schema.js +2 -23
  330. package/dist/validation/member-invite.schema.js.map +1 -1
  331. package/frontend-vue/dms.frontend.ts +2 -0
  332. package/frontend-vue/layers/dms-auth/app/custom-pages/auth/forgot-validation.vue +3 -0
  333. package/frontend-vue/layers/dms-auth/app/custom-pages/auth/signup.vue +105 -5
  334. package/frontend-vue/layers/dms-auth/i18n/locales/auth-en-GB.json +20 -4
  335. package/frontend-vue/layers/dms-auth/i18n/locales/auth-fr-FR.json +20 -4
  336. package/frontend-vue/layers/dms-core/app/composables/translation/useComposedText.ts +25 -0
  337. package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +3 -2
  338. package/frontend-vue/layers/dms-core/app/types/composed-text.ts +64 -0
  339. package/frontend-vue/layers/dms-core/app/types/menu.ts +15 -0
  340. package/frontend-vue/layers/dms-core/app/utils/composedText.ts +227 -0
  341. package/frontend-vue/layers/dms-core/app/utils/formatter.ts +49 -0
  342. package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +4 -1
  343. package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +4 -1
  344. package/frontend-vue/layers/dms-layout/app/assets/css/main.css +20 -0
  345. package/frontend-vue/layers/dms-layout/app/build/components/layout/CommandPaletteAssistantAnswer.vue +75 -0
  346. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardBanners.vue +17 -3
  347. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardFrame.vue +22 -0
  348. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +24 -10
  349. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidePanel.vue +139 -0
  350. package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +4 -2
  351. package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +90 -0
  352. package/frontend-vue/layers/dms-layout/app/build/components/layout/SidePanelHost.vue +17 -0
  353. package/frontend-vue/layers/dms-layout/app/build/components/notification/NotificationPopover.vue +25 -43
  354. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/members/MemberRolePicker.vue +24 -2
  355. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationMatrixCategory.vue +70 -25
  356. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationPreferencesForm.vue +25 -10
  357. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/notificationDisplay.ts +41 -5
  358. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfilePreferencesSummary.vue +2 -1
  359. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfileSecuritySummary.vue +20 -4
  360. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RoleEditor.vue +21 -0
  361. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionArea.vue +16 -2
  362. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionBranch.vue +1 -0
  363. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionLeaf.vue +13 -1
  364. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionTree.vue +9 -0
  365. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionWarning.vue +46 -0
  366. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +108 -29
  367. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-types.ts +2 -0
  368. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityDialogFrame.vue +6 -6
  369. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityEmail.vue +7 -1
  370. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecuritySessions.vue +5 -4
  371. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityStatus.vue +4 -3
  372. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityTwoFactor.vue +54 -18
  373. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/shell/SettingsNav.vue +13 -8
  374. package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/assistantGroups.ts +143 -0
  375. package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/useCommandPaletteAssistantMode.ts +249 -0
  376. package/frontend-vue/layers/dms-layout/app/build/composables/general/useGithubStarPrompt.ts +178 -0
  377. package/frontend-vue/layers/dms-layout/app/build/composables/layout/sidePanelState.ts +191 -0
  378. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useHeaderActionControls.ts +51 -0
  379. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +113 -0
  380. package/frontend-vue/layers/dms-layout/app/build/composables/navigation/useCategoryNavCards.ts +17 -10
  381. package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +45 -0
  382. package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/useProfilePreferences.ts +8 -1
  383. package/frontend-vue/layers/dms-layout/app/build/composables/settings/security/useSecurityOverview.ts +50 -3
  384. package/frontend-vue/layers/dms-layout/app/build/composables/settings/useSettingsNavigation.ts +3 -0
  385. package/frontend-vue/layers/dms-layout/app/build/utils/categoryPages.ts +1 -2
  386. package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +5 -0
  387. package/frontend-vue/layers/dms-layout/app/components/layout/DashboardSearch.vue +109 -7
  388. package/frontend-vue/layers/dms-layout/app/components/navigation/NavigationMenu.vue +19 -9
  389. package/frontend-vue/layers/dms-layout/app/composables/notification/useNotifications.ts +22 -40
  390. package/frontend-vue/layers/dms-layout/app/composables/useAppSidePanels.ts +96 -0
  391. package/frontend-vue/layers/dms-layout/app/composables/useCommandPaletteAssistant.ts +129 -0
  392. package/frontend-vue/layers/dms-layout/app/composables/useHeaderActions.ts +33 -11
  393. package/frontend-vue/layers/dms-layout/app/composables/useSidePanel.ts +41 -0
  394. package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +15 -0
  395. package/frontend-vue/layers/dms-layout/app/plugins/notification-stream.client.ts +1 -7
  396. package/frontend-vue/layers/dms-layout/app/plugins/side-panel-host.ts +13 -0
  397. package/frontend-vue/layers/dms-layout/app/types/page.ts +11 -1
  398. package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +43 -13
  399. package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +43 -13
  400. package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +45 -0
  401. package/frontend-vue/layers/dms-ui/app/build/components/modal/ModalEscHint.vue +28 -0
  402. package/frontend-vue/layers/dms-ui/app/build/components/table-view/IdentityCell.vue +36 -7
  403. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/cellHelpers.ts +57 -0
  404. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/metricCells.ts +19 -5
  405. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/registerDefaults.ts +22 -2
  406. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/twoLineCell.ts +118 -0
  407. package/frontend-vue/layers/dms-ui/app/build/composables/data-types/useColumnValueRenderer.ts +5 -3
  408. package/frontend-vue/layers/dms-ui/app/build/composables/form/floatingSaveBars.ts +38 -0
  409. package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +66 -0
  410. package/frontend-vue/layers/dms-ui/app/build/composables/navigation/useNavBadges.ts +50 -9
  411. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +7 -1
  412. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/chrome.ts +2 -2
  413. package/frontend-vue/layers/dms-ui/app/build/types/tree.ts +14 -10
  414. package/frontend-vue/layers/dms-ui/app/build/utils/navBadge.ts +12 -0
  415. package/frontend-vue/layers/dms-ui/app/build/utils/relativeDate.ts +4 -35
  416. package/frontend-vue/layers/dms-ui/app/build/utils/tone.ts +22 -0
  417. package/frontend-vue/layers/dms-ui/app/components/activity-feed/ActivityFeed.vue +117 -82
  418. package/frontend-vue/layers/dms-ui/app/components/blocks/BannerBlock.vue +8 -5
  419. package/frontend-vue/layers/dms-ui/app/components/blocks/KeyValueListBlock.vue +38 -18
  420. package/frontend-vue/layers/dms-ui/app/components/blocks/NavCardGridBlock.vue +12 -1
  421. package/frontend-vue/layers/dms-ui/app/components/blocks/StatGroupBlock.vue +26 -23
  422. package/frontend-vue/layers/dms-ui/app/components/card/NavCard.vue +16 -1
  423. package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +7 -8
  424. package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +28 -6
  425. package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +5 -1
  426. package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +4 -0
  427. package/frontend-vue/layers/dms-ui/app/components/status-pill/StatusPill.vue +7 -2
  428. package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +7 -2
  429. package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +48 -34
  430. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +13 -3
  431. package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -14
  432. package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -14
  433. package/frontend-vue/package.json +2 -2
  434. package/frontend-vue/pnpm-lock.yaml +5 -5
  435. package/frontend-vue/tests/activity-feed-fill-height.test.ts +107 -0
  436. package/frontend-vue/tests/category-nav-cards.test.ts +21 -13
  437. package/frontend-vue/tests/command-palette-assistant.test.ts +344 -0
  438. package/frontend-vue/tests/composed-text-blocks.test.ts +205 -0
  439. package/frontend-vue/tests/composed-text.test.ts +265 -0
  440. package/frontend-vue/tests/fixtures/dashboard-search-stub.ts +91 -0
  441. package/frontend-vue/tests/forgot-validation-resend.test.ts +234 -0
  442. package/frontend-vue/tests/form-display-options.test.ts +64 -0
  443. package/frontend-vue/tests/form-load-error.test.ts +160 -0
  444. package/frontend-vue/tests/form-saved-before-success.test.ts +110 -0
  445. package/frontend-vue/tests/github-star-prompt.test.ts +328 -0
  446. package/frontend-vue/tests/header-actions.test.ts +191 -0
  447. package/frontend-vue/tests/invites-edit-modal.test.ts +157 -0
  448. package/frontend-vue/tests/layout-banners.test.ts +56 -0
  449. package/frontend-vue/tests/member-role-picker.test.ts +26 -0
  450. package/frontend-vue/tests/menu-hidden-page.test.ts +93 -0
  451. package/frontend-vue/tests/nav-badge-tones.test.ts +274 -0
  452. package/frontend-vue/tests/nav-card-badge.test.ts +69 -0
  453. package/frontend-vue/tests/nav-card-grid-empty-category.test.ts +163 -0
  454. package/frontend-vue/tests/notification-popover-errors.test.ts +71 -37
  455. package/frontend-vue/tests/notification-preferences-groups.test.ts +268 -0
  456. package/frontend-vue/tests/notification-tone-contract.test.ts +70 -0
  457. package/frontend-vue/tests/page-fill-height.test.ts +9 -1
  458. package/frontend-vue/tests/page-no-visible-blocks.test.ts +202 -0
  459. package/frontend-vue/tests/profile-preferences-summary.test.ts +26 -2
  460. package/frontend-vue/tests/profile-security-summary.test.ts +121 -0
  461. package/frontend-vue/tests/role-permission-tree.test.ts +102 -8
  462. package/frontend-vue/tests/role-permissions.test.ts +178 -56
  463. package/frontend-vue/tests/side-panels.test.ts +470 -0
  464. package/frontend-vue/tests/signup-invitation-link.test.ts +71 -2
  465. package/frontend-vue/tests/table-actions-column-width.test.ts +51 -1
  466. package/frontend-vue/tests/table-cell-sublines.test.ts +466 -0
  467. package/frontend-vue/tests/table-metric-cells.test.ts +4 -0
  468. package/frontend-vue/tests/table-view-chrome.test.ts +2 -2
  469. package/frontend-vue/tests/vue-inventory.test.ts +1 -1
  470. package/package.json +2 -2
  471. package/skills/dms/REFERENCE.md +1 -1
  472. package/skills/dms/SKILL.md +7 -0
@@ -0,0 +1,113 @@
1
+ import type { Ref } from "vue";
2
+ import {
3
+ resolveSidePanelWidthBounds,
4
+ type SidePanel,
5
+ type SidePanelWidthBounds,
6
+ } from "../../../composables/useAppSidePanels";
7
+ import {
8
+ clampSidePanelWidth,
9
+ readSidePanelPreferences,
10
+ storedSidePanelWidth,
11
+ storeSidePanelWidth,
12
+ useSidePanelDragWidth,
13
+ useSidePanelPreferences,
14
+ } from "./sidePanelState";
15
+
16
+ /** @internal */
17
+ export const SIDE_PANEL_KEYBOARD_STEP_PX = 16;
18
+
19
+ type WidthStep = (width: number, bounds: SidePanelWidthBounds) => number;
20
+
21
+ // The panel sits on the right: the arrow pointing away from it widens it.
22
+ const KEYBOARD_STEPS: Record<string, WidthStep> = {
23
+ ArrowLeft: (width) => width + SIDE_PANEL_KEYBOARD_STEP_PX,
24
+ ArrowRight: (width) => width - SIDE_PANEL_KEYBOARD_STEP_PX,
25
+ Home: (_, bounds) => bounds.minWidth,
26
+ End: (_, bounds) => bounds.maxWidth,
27
+ };
28
+
29
+ interface DragStart {
30
+ x: number;
31
+ width: number;
32
+ }
33
+
34
+ /** @internal */
35
+ export interface SidePanelWidth {
36
+ width: Readonly<Ref<number>>;
37
+ bounds: SidePanelWidthBounds;
38
+ isDragging: Readonly<Ref<boolean>>;
39
+ startDrag: (event: PointerEvent, renderedWidth: number) => void;
40
+ drag: (event: PointerEvent) => void;
41
+ endDrag: () => void;
42
+ resizeFromKey: (event: KeyboardEvent) => void;
43
+ reset: () => void;
44
+ }
45
+
46
+ /**
47
+ * The width of a side panel and the handlers of its resize handle: dragging,
48
+ * the arrow / Home / End keys, and a reset to the default width. The width is
49
+ * kept per panel id in the side panel cookie, written once a change settles;
50
+ * while the handle is dragged, the shared drag width moves the page with it.
51
+ *
52
+ * @internal
53
+ */
54
+ export function useSidePanelWidth(panel: SidePanel): SidePanelWidth {
55
+ const bounds = resolveSidePanelWidthBounds(panel);
56
+ const preferences = useSidePanelPreferences();
57
+ const dragWidth = useSidePanelDragWidth();
58
+ const width = computed(
59
+ () =>
60
+ dragWidth.value ??
61
+ storedSidePanelWidth(
62
+ readSidePanelPreferences(preferences.value),
63
+ panel.id,
64
+ bounds,
65
+ ),
66
+ );
67
+ let dragStart: DragStart | null = null;
68
+
69
+ function commit(next: number): void {
70
+ storeSidePanelWidth(
71
+ preferences,
72
+ panel.id,
73
+ clampSidePanelWidth(next, bounds),
74
+ );
75
+ }
76
+
77
+ function startDrag(event: PointerEvent, renderedWidth: number): void {
78
+ event.preventDefault();
79
+ dragStart = { x: event.clientX, width: renderedWidth };
80
+ dragWidth.value = clampSidePanelWidth(renderedWidth, bounds);
81
+ }
82
+
83
+ function drag(event: PointerEvent): void {
84
+ if (dragStart === null) return;
85
+ const next = dragStart.width + dragStart.x - event.clientX;
86
+ dragWidth.value = clampSidePanelWidth(next, bounds);
87
+ }
88
+
89
+ function endDrag(): void {
90
+ if (dragStart === null) return;
91
+ dragStart = null;
92
+ commit(width.value);
93
+ dragWidth.value = null;
94
+ }
95
+
96
+ function resizeFromKey(event: KeyboardEvent): void {
97
+ const step = KEYBOARD_STEPS[event.key];
98
+ if (!step) return;
99
+ event.preventDefault();
100
+ commit(step(width.value, bounds));
101
+ }
102
+
103
+ return {
104
+ width,
105
+ bounds,
106
+ isDragging: computed(() => dragWidth.value !== null),
107
+ startDrag,
108
+ drag,
109
+ endDrag,
110
+ resizeFromKey,
111
+ reset: () => commit(bounds.defaultWidth),
112
+ };
113
+ }
@@ -1,5 +1,6 @@
1
1
  import { usePermissionPreview } from "#dms-core/app/build/composables/auth/usePermissionPreview";
2
2
  import { useNavBadges } from "#dms-ui/app/build/composables/navigation/useNavBadges";
3
+ import type { Tone } from "#dms-ui/app/types/tone";
3
4
  import { findTreeNode, listCategoryPages } from "../../utils/categoryPages";
4
5
 
5
6
  const DEFAULT_PAGE_ICON = "i-ph-file";
@@ -13,7 +14,9 @@ export interface CategoryNavCard {
13
14
  icon: string;
14
15
  to: string;
15
16
  /** The page's navigation badge, as the menu shows it. */
16
- state?: string;
17
+ badge?: string;
18
+ /** The badge's tone, as the menu draws it. */
19
+ badgeTone?: Tone;
17
20
  }
18
21
 
19
22
  /**
@@ -24,21 +27,25 @@ export interface CategoryNavCard {
24
27
  */
25
28
  export function useCategoryNavCards(categoryId: () => string | undefined) {
26
29
  const siteLayout = useSiteLayout();
27
- const { badges } = useNavBadges();
30
+ const { navBadgeOf } = useNavBadges();
28
31
  const cards = computed<CategoryNavCard[]>(() => {
29
32
  const id = categoryId();
30
33
  const category = id
31
34
  ? findTreeNode(siteLayout.siteLayoutTree.value, id)
32
35
  : undefined;
33
36
  if (!category) return [];
34
- return listCategoryPages(category).map((page) => ({
35
- id: page.fullId,
36
- title: page.displayName,
37
- description: page.description,
38
- icon: page.icon || DEFAULT_PAGE_ICON,
39
- to: page.fullSlug,
40
- state: (badges.value[page.fullId] ?? page.badge) || undefined,
41
- }));
37
+ return listCategoryPages(category).map((page) => {
38
+ const badge = navBadgeOf(page);
39
+ return {
40
+ id: page.fullId,
41
+ title: page.displayName,
42
+ description: page.description,
43
+ icon: page.icon || DEFAULT_PAGE_ICON,
44
+ to: page.fullSlug,
45
+ badge: badge?.label,
46
+ badgeTone: badge?.tone,
47
+ };
48
+ });
42
49
  });
43
50
  return { cards };
44
51
  }
@@ -0,0 +1,45 @@
1
+ /** `localStorage` key prefix of the open or folded state of each preferences group. */
2
+ export const NOTIFICATION_GROUP_STORAGE_PREFIX = "dms-notification-group:";
3
+
4
+ const OPEN = "open";
5
+ const FOLDED = "folded";
6
+
7
+ function storageKey(categoryId: string): string {
8
+ return `${NOTIFICATION_GROUP_STORAGE_PREFIX}${categoryId}`;
9
+ }
10
+
11
+ function readStorage(key: string): string | null {
12
+ try {
13
+ return localStorage.getItem(key);
14
+ } catch {
15
+ return null;
16
+ }
17
+ }
18
+
19
+ function writeStorage(key: string, value: string): void {
20
+ try {
21
+ localStorage.setItem(key, value);
22
+ } catch {
23
+ /* storage unavailable (private mode, quota): the group folds on reload */
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Which groups of the preferences matrix are open. A group starts folded,
29
+ * so the page opens short and each group row's count sums it up; the state
30
+ * the viewer picks is kept per group in this browser.
31
+ */
32
+ export const useNotificationGroupsOpen = () => {
33
+ const picked = ref<Record<string, boolean>>({});
34
+
35
+ const isOpen = (categoryId: string): boolean =>
36
+ picked.value[categoryId] ?? readStorage(storageKey(categoryId)) === OPEN;
37
+
38
+ const toggleOpen = (categoryId: string) => {
39
+ const open = !isOpen(categoryId);
40
+ picked.value = { ...picked.value, [categoryId]: open };
41
+ writeStorage(storageKey(categoryId), open ? OPEN : FOLDED);
42
+ };
43
+
44
+ return { isOpen, toggleOpen };
45
+ };
@@ -3,6 +3,7 @@ import { computed, onMounted, ref } from "vue";
3
3
  import { useUserRegionalPreferences } from "#dms-core/app/composables/user/useUserRegionalPreferences";
4
4
  import { useUniqueLocales } from "#dms-core/app/composables/translation/useUniqueLocales";
5
5
  import { formatDate } from "#dms-core/app/utils/formatter";
6
+ import { iconWellToneOf } from "#dms-ui/app/build/utils/tone";
6
7
  import { useAccessibilityPreferences } from "../../../../composables/general/useAccessibilityPreferences";
7
8
  import { useColorModePreference } from "../../../../composables/general/useColorModePreference";
8
9
  import { useInterfaceScale } from "../../../../composables/general/useInterfaceScale";
@@ -118,7 +119,7 @@ export function useProfilePreferences() {
118
119
 
119
120
  const notificationPreferences = useNotificationPreferences();
120
121
  const { subjects } = useNotificationCatalog();
121
- const { unreadCount, areCountsLoaded } = useNotifications();
122
+ const { unreadCount, unreadTone, areCountsLoaded } = useNotifications();
122
123
  const isNotificationsLoading = computed(
123
124
  () => notificationPreferences.isLoading.value || !areCountsLoaded.value,
124
125
  );
@@ -132,6 +133,11 @@ export function useProfilePreferences() {
132
133
  const hasUnread = computed(
133
134
  () => !isNotificationsLoading.value && unreadCount.value > 0,
134
135
  );
136
+ // The well takes the unread badge's tone, the bell's and the navigation's,
137
+ // which the server weighs; quiet when nothing is unread.
138
+ const notificationsTone = computed(() =>
139
+ hasUnread.value ? iconWellToneOf(unreadTone.value) : "muted",
140
+ );
135
141
 
136
142
  const colorMode = useColorModePreference();
137
143
  const scale = useInterfaceScale();
@@ -192,6 +198,7 @@ export function useProfilePreferences() {
192
198
  regionSummary,
193
199
  notificationsSummary,
194
200
  hasUnread,
201
+ notificationsTone,
195
202
  appearanceSummary,
196
203
  placeholders,
197
204
  };
@@ -1,4 +1,5 @@
1
1
  import { useNavBadges } from "#dms-ui/app/build/composables/navigation/useNavBadges";
2
+ import type { Tone } from "#dms-ui/app/types/tone";
2
3
 
3
4
  /** Base URL of the Security page API. */
4
5
  export const SECURITY_ENDPOINT = "/settings/user/security";
@@ -29,6 +30,13 @@ export interface SecurityOverview {
29
30
  activeSessions: number;
30
31
  /** What needs the user's attention, most important first. */
31
32
  attention: SecurityAttention[];
33
+ /**
34
+ * The strongest tone of `attention`, which the navigation badge takes;
35
+ * null when nothing needs attention.
36
+ */
37
+ attentionTone: Tone | null;
38
+ /** The tone of each item of `attention`. */
39
+ attentionTones: Partial<Record<SecurityAttention, Tone>>;
32
40
  }
33
41
 
34
42
  /** What the API returns to enrol an authenticator app. */
@@ -47,11 +55,23 @@ export type SecurityAttention =
47
55
  | "backup_codes_unsaved"
48
56
  | "backup_codes_low";
49
57
 
58
+ /** Strongest first, as the server ranks the attention tones. */
59
+ const ATTENTION_TONE_ORDER: Tone[] = [
60
+ "error",
61
+ "warning",
62
+ "primary",
63
+ "secondary",
64
+ "success",
65
+ "info",
66
+ "neutral",
67
+ ];
68
+
50
69
  /**
51
70
  * Shared Security summary: the status strip, every Security block and the
52
71
  * profile pointer card read the same state, and any change refreshes it for
53
72
  * all of them. It also keeps the navigation badge of the Security page, the
54
- * count of what needs attention, in sync after a change.
73
+ * count of what needs attention in the tone the server gives it, in sync
74
+ * after a change.
55
75
  */
56
76
  export function useSecurityOverview() {
57
77
  const overview = useDmsState<SecurityOverview | null>(
@@ -68,6 +88,22 @@ export function useSecurityOverview() {
68
88
  const attention = computed<SecurityAttention[]>(
69
89
  () => overview.value?.attention ?? [],
70
90
  );
91
+ const attentionTone = computed<Tone | undefined>(
92
+ () => overview.value?.attentionTone ?? undefined,
93
+ );
94
+
95
+ /**
96
+ * The strongest tone the server gives to those of `items` that need
97
+ * attention; undefined when none does. A block concerned by several items
98
+ * (the backup codes: unsaved, running low) is drawn in it.
99
+ */
100
+ function attentionToneOf(items: SecurityAttention[]): Tone | undefined {
101
+ const tones = overview.value?.attentionTones ?? {};
102
+ const present = items
103
+ .map((item) => tones[item])
104
+ .filter((tone): tone is Tone => !!tone);
105
+ return ATTENTION_TONE_ORDER.find((tone) => present.includes(tone));
106
+ }
71
107
 
72
108
  async function refresh(): Promise<void> {
73
109
  try {
@@ -78,8 +114,19 @@ export function useSecurityOverview() {
78
114
  return;
79
115
  }
80
116
  const count = attention.value.length;
81
- setNavBadge(SECURITY_PAGE_ID, count > 0 ? String(count) : "");
117
+ setNavBadge(
118
+ SECURITY_PAGE_ID,
119
+ count > 0 ? String(count) : "",
120
+ attentionTone.value,
121
+ );
82
122
  }
83
123
 
84
- return { overview, attention, isUnavailable, refresh };
124
+ return {
125
+ overview,
126
+ attention,
127
+ attentionTone,
128
+ attentionToneOf,
129
+ isUnavailable,
130
+ refresh,
131
+ };
85
132
  }
@@ -17,6 +17,8 @@ export interface SettingsNavPage {
17
17
  to: string;
18
18
  /** Badge the server counted or the page declared for its entry. */
19
19
  badge?: string;
20
+ /** The tone of a counted badge; neutral when absent. */
21
+ badgeTone?: MenuItemBadgeTone;
20
22
  /** Dot the page declared for its entry. */
21
23
  status?: MenuItemStatus;
22
24
  }
@@ -36,6 +38,7 @@ const toNavPage = (node: SiteLayoutTree): SettingsNavPage => ({
36
38
  icon: node.icon || DEFAULT_SETTINGS_ICON,
37
39
  to: node.fullSlug,
38
40
  badge: node.badge,
41
+ badgeTone: node.badgeTone,
39
42
  status: node.status,
40
43
  });
41
44
 
@@ -24,8 +24,7 @@ const isOpenablePage = (node: SiteLayoutTree): boolean =>
24
24
 
25
25
  /**
26
26
  * The pages the viewer can open among `nodes` and under them, in menu order,
27
- * each one followed by the pages nested under it (Member invitations under
28
- * Members). The page answering at `landingSlug` leads to the others rather
27
+ * each one followed by the pages nested under it. The page answering at `landingSlug` leads to the others rather
29
28
  * than being one of them.
30
29
  */
31
30
  export function listPagesAmong(
@@ -0,0 +1,5 @@
1
+ /** The DMS repository on GitHub, as `owner/name`. */
2
+ export const GITHUB_REPOSITORY = "AntelopeJS/dms";
3
+
4
+ /** Opened by the auth footer's star button and by the dashboard's star prompt. */
5
+ export const GITHUB_REPOSITORY_URL = `https://github.com/${GITHUB_REPOSITORY}`;
@@ -1,7 +1,59 @@
1
1
  <script setup lang="ts">
2
+ import { computed, nextTick, useTemplateRef } from "vue";
3
+ import CommandPaletteAssistantAnswer from "../../build/components/layout/CommandPaletteAssistantAnswer.vue";
4
+ import { ASSISTANT_MODE_KEY } from "../../build/composables/command-palette/assistantGroups";
5
+ import { useCommandPaletteAssistantMode } from "../../build/composables/command-palette/useCommandPaletteAssistantMode";
6
+
2
7
  const { t } = useI18n();
3
- const { groups } = useCommandPaletteGroups();
8
+ const appConfig = useDmsAppConfig();
9
+ const { groups: sourceGroups } = useCommandPaletteGroups();
4
10
  const fuse = COMMAND_PALETTE_FUSE_OPTIONS;
11
+ const {
12
+ isOpen,
13
+ searchTerm,
14
+ assistant,
15
+ isAssistantMode,
16
+ answer,
17
+ groups,
18
+ announcement,
19
+ setMode,
20
+ onInputKeydown,
21
+ } = useCommandPaletteAssistantMode(sourceGroups);
22
+
23
+ const footerRef = useTemplateRef<HTMLElement>("footer");
24
+ const input = { onKeydown: onInputKeydown };
25
+ // The halo eases between the accent ring and the violet assistant ring.
26
+ const MODAL_TRANSITION_CLASS = "transition-shadow duration-300";
27
+ // In assistant mode, the empty slot holds the DMS's own padded states.
28
+ const ASSISTANT_EMPTY_CLASS = "p-0 text-start";
29
+ const SEARCH_UI = { modal: MODAL_TRANSITION_CLASS };
30
+ const ASSISTANT_UI = {
31
+ modal: `${MODAL_TRANSITION_CLASS} shadow-[var(--dms-shadow-cmdk),var(--dms-assistant-halo)]`,
32
+ input: "[&_input]:caret-secondary [&_[data-slot=leadingIcon]]:text-secondary",
33
+ empty: ASSISTANT_EMPTY_CLASS,
34
+ };
35
+
36
+ const paletteUi = computed(() =>
37
+ isAssistantMode.value ? ASSISTANT_UI : SEARCH_UI,
38
+ );
39
+
40
+ /** Brings focus back to the prompt after the control that held it goes away. */
41
+ async function focusInput(): Promise<void> {
42
+ await nextTick();
43
+ footerRef.value
44
+ ?.closest('[role="dialog"]')
45
+ ?.querySelector<HTMLInputElement>("input")
46
+ ?.focus();
47
+ }
48
+
49
+ function switchMode(): void {
50
+ setMode(isAssistantMode.value ? "search" : "assistant");
51
+ void focusInput();
52
+ }
53
+
54
+ function close(): void {
55
+ isOpen.value = false;
56
+ }
5
57
  </script>
6
58
 
7
59
  <template>
@@ -9,26 +61,76 @@ const fuse = COMMAND_PALETTE_FUSE_OPTIONS;
9
61
  leaving these props out exposes those raw keys as the dialog's
10
62
  accessible name. -->
11
63
  <UDashboardSearch
64
+ v-model:open="isOpen"
65
+ v-model:search-term="searchTerm"
12
66
  :groups="groups"
13
67
  :fuse="fuse"
68
+ :color-mode="!isAssistantMode"
69
+ :input="input"
70
+ :icon="isAssistantMode ? assistant?.icon : undefined"
71
+ :placeholder="isAssistantMode ? assistant?.placeholder : undefined"
72
+ :ui="paletteUi"
14
73
  :title="t('commandPalette.dialog.title')"
15
74
  :description="t('commandPalette.dialog.description')"
16
75
  >
76
+ <template v-if="assistant && isAssistantMode" #empty>
77
+ <CommandPaletteAssistantAnswer
78
+ v-if="answer"
79
+ :key="answer.id"
80
+ :label="assistant.label"
81
+ :icon="assistant.icon"
82
+ :component="assistant.answerComponent"
83
+ :prompt="answer.prompt"
84
+ :close="close"
85
+ />
86
+ <p v-else class="text-muted px-6 py-8 text-center text-sm">
87
+ {{ t("commandPalette.assistant.emptyPrompt") }}
88
+ </p>
89
+ </template>
90
+
17
91
  <!-- v2 footer band: the keys that drive the palette. -->
18
92
  <template #footer>
19
- <span class="inline-flex items-center gap-1.5">
20
- <UKbd value="↑" size="sm" />
21
- <UKbd value="↓" size="sm" />
22
- {{ t("commandPalette.footer.navigate") }}
93
+ <span ref="footer" class="sr-only" aria-live="polite">
94
+ {{ announcement }}
23
95
  </span>
24
- <span class="inline-flex items-center gap-1.5">
96
+ <span v-if="isAssistantMode" class="inline-flex items-center gap-1.5">
25
97
  <UKbd value="↵" size="sm" />
26
- {{ t("commandPalette.footer.open") }}
98
+ {{ t("commandPalette.footer.send") }}
27
99
  </span>
100
+ <template v-else>
101
+ <span class="inline-flex items-center gap-1.5">
102
+ <UKbd value="↑" size="sm" />
103
+ <UKbd value="↓" size="sm" />
104
+ {{ t("commandPalette.footer.navigate") }}
105
+ </span>
106
+ <span class="inline-flex items-center gap-1.5">
107
+ <UKbd value="↵" size="sm" />
108
+ {{ t("commandPalette.footer.open") }}
109
+ </span>
110
+ </template>
28
111
  <span class="inline-flex items-center gap-1.5">
29
112
  <UKbd value="Esc" size="sm" />
30
113
  {{ t("commandPalette.footer.close") }}
31
114
  </span>
115
+ <UButton
116
+ v-if="assistant"
117
+ class="text-muted hover:text-secondary ms-auto gap-1.5 px-2 py-0.5 text-xs hover:bg-(--dms-assistant-tint)"
118
+ color="neutral"
119
+ variant="ghost"
120
+ size="xs"
121
+ :icon="isAssistantMode ? appConfig.ui.icons.search : assistant.icon"
122
+ :ui="{ leadingIcon: isAssistantMode ? undefined : 'text-secondary' }"
123
+ data-slot="assistantToggle"
124
+ @mousedown.prevent
125
+ @click="switchMode"
126
+ >
127
+ {{
128
+ isAssistantMode
129
+ ? t("commandPalette.footer.backToSearch")
130
+ : t("commandPalette.footer.askAi")
131
+ }}
132
+ <UKbd :value="ASSISTANT_MODE_KEY" size="sm" />
133
+ </UButton>
32
134
  </template>
33
135
  </UDashboardSearch>
34
136
  </template>
@@ -50,13 +50,16 @@ const VARIANT_CLASSES: Record<MenuItemVariant, MenuVariantClasses> = {
50
50
 
51
51
  const STATUS_DOT_ICON = "i-ph-circle-fill";
52
52
  const STATUS_DOT_SIZE = "size-1.5";
53
- /** v2 nav trail badge: a small neutral pill with a mono count. */
53
+ /**
54
+ * v2 nav trail badge: a small soft pill with a mono count, in the tone the
55
+ * count carries (neutral grey without one).
56
+ */
54
57
  const MENU_BADGE_PROPS = {
55
- color: "neutral",
56
58
  variant: "soft",
57
59
  size: "sm",
58
60
  class: "font-mono tabular-nums",
59
61
  } as const;
62
+ const DEFAULT_BADGE_TONE: MenuItemBadgeTone = "neutral";
60
63
 
61
64
  /** The per-item slot classes Nuxt UI accepts on a navigation menu item. */
62
65
  type MenuItemUi = NonNullable<DmsMenuItem["ui"]>;
@@ -110,11 +113,18 @@ function buildItemUi(
110
113
  : undefined;
111
114
  }
112
115
 
113
- // A plain badge value (a page's `badge`) gets the v2 look; a badge already
114
- // given as props is the caller's own choice.
115
- function resolveMenuBadge(badge: DmsMenuItem["badge"]): DmsMenuItem["badge"] {
116
+ // A plain badge value (a page's `badge`) gets the v2 look in its tone; a
117
+ // badge already given as props is the caller's own choice.
118
+ function resolveMenuBadge(
119
+ badge: DmsMenuItem["badge"],
120
+ tone: MenuItemBadgeTone | undefined,
121
+ ): DmsMenuItem["badge"] {
116
122
  if (typeof badge === "string" || typeof badge === "number") {
117
- return { ...MENU_BADGE_PROPS, label: String(badge) };
123
+ return {
124
+ ...MENU_BADGE_PROPS,
125
+ color: tone ?? DEFAULT_BADGE_TONE,
126
+ label: String(badge),
127
+ };
118
128
  }
119
129
  return badge;
120
130
  }
@@ -177,8 +187,8 @@ const { badges: navBadges } = useNavBadges();
177
187
  function badgeOf(item: DmsMenuItem): DmsMenuItem["badge"] {
178
188
  const live =
179
189
  item.fullId === undefined ? undefined : navBadges.value[item.fullId];
180
- if (live === undefined) return item.badge;
181
- return live || undefined;
190
+ if (live === undefined) return resolveMenuBadge(item.badge, item.badgeTone);
191
+ return live.label ? resolveMenuBadge(live.label, live.tone) : undefined;
182
192
  }
183
193
 
184
194
  // A status dot lands in the trailing slot, which a parent entry already uses for
@@ -187,7 +197,7 @@ function badgeOf(item: DmsMenuItem): DmsMenuItem["badge"] {
187
197
  function decorateMenuItem(item: DmsMenuItem): DmsMenuItem {
188
198
  const variant = VARIANT_CLASSES[item.variant ?? "default"];
189
199
  const hasChildren = (item.children?.length ?? 0) > 0;
190
- const badge = resolveMenuBadge(badgeOf(item));
200
+ const badge = badgeOf(item);
191
201
  const statusClass =
192
202
  item.status && !hasChildren && !badge
193
203
  ? MENU_STATUS_TEXT_CLASSES[item.status]