@antelopejs/dms 0.6.2 → 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 (444) hide show
  1. package/CHANGELOG.md +22 -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/nav-badges.d.ts +6 -4
  27. package/dist/implementations/dms/nav-badges.js +6 -5
  28. package/dist/implementations/dms/nav-badges.js.map +1 -1
  29. package/dist/implementations/dms/page.d.ts +1 -0
  30. package/dist/implementations/dms/page.js +46 -8
  31. package/dist/implementations/dms/page.js.map +1 -1
  32. package/dist/implementations/dms/permission-preview.d.ts +1 -1
  33. package/dist/implementations/dms/permission-preview.js +9 -4
  34. package/dist/implementations/dms/permission-preview.js.map +1 -1
  35. package/dist/implementations/dms-auth/index.d.ts +3 -2
  36. package/dist/implementations/dms-auth/index.js +39 -35
  37. package/dist/implementations/dms-auth/index.js.map +1 -1
  38. package/dist/implementations/dms-auth/token-session.d.ts +3 -0
  39. package/dist/implementations/dms-auth/token-session.js +22 -0
  40. package/dist/implementations/dms-auth/token-session.js.map +1 -0
  41. package/dist/implementations/dms-notifications/index.d.ts +0 -1
  42. package/dist/implementations/dms-notifications/index.js +0 -7
  43. package/dist/implementations/dms-notifications/index.js.map +1 -1
  44. package/dist/pages/settings/settings-index.js +3 -2
  45. package/dist/pages/settings/settings-index.js.map +1 -1
  46. package/dist/pages/settings/users/account-activity-feed.d.ts +1 -1
  47. package/dist/pages/settings/users/account-activity-feed.js +1 -1
  48. package/dist/pages/settings/users/account-activity-feed.js.map +1 -1
  49. package/dist/pages/settings/users/account-activity.d.ts +1 -1
  50. package/dist/pages/settings/users/account-activity.js +1 -1
  51. package/dist/pages/settings/users/account-activity.js.map +1 -1
  52. package/dist/pages/settings/users/account-credentials.d.ts +3 -0
  53. package/dist/pages/settings/users/account-credentials.js +2 -0
  54. package/dist/pages/settings/users/account-credentials.js.map +1 -1
  55. package/dist/pages/settings/users/current-password.d.ts +1 -1
  56. package/dist/pages/settings/users/current-password.js +23 -2
  57. package/dist/pages/settings/users/current-password.js.map +1 -1
  58. package/dist/pages/settings/users/email-change.d.ts +1 -1
  59. package/dist/pages/settings/users/email-change.js +33 -26
  60. package/dist/pages/settings/users/email-change.js.map +1 -1
  61. package/dist/pages/settings/users/invite-resend.js +0 -1
  62. package/dist/pages/settings/users/invite-resend.js.map +1 -1
  63. package/dist/pages/settings/users/invites.d.ts +1 -2
  64. package/dist/pages/settings/users/invites.js +21 -19
  65. package/dist/pages/settings/users/invites.js.map +1 -1
  66. package/dist/pages/settings/users/member-invite-batch.js +0 -1
  67. package/dist/pages/settings/users/member-invite-batch.js.map +1 -1
  68. package/dist/pages/settings/users/member-invite-form.js +10 -22
  69. package/dist/pages/settings/users/member-invite-form.js.map +1 -1
  70. package/dist/pages/settings/users/member-role-options.d.ts +6 -4
  71. package/dist/pages/settings/users/member-role-options.js +15 -4
  72. package/dist/pages/settings/users/member-role-options.js.map +1 -1
  73. package/dist/pages/settings/users/members.d.ts +2 -3
  74. package/dist/pages/settings/users/members.js +7 -12
  75. package/dist/pages/settings/users/members.js.map +1 -1
  76. package/dist/pages/settings/users/notifications.d.ts +1 -8
  77. package/dist/pages/settings/users/notifications.js +6 -38
  78. package/dist/pages/settings/users/notifications.js.map +1 -1
  79. package/dist/pages/settings/users/permission-tree-nodes.d.ts +1 -1
  80. package/dist/pages/settings/users/permission-tree-nodes.js +23 -9
  81. package/dist/pages/settings/users/permission-tree-nodes.js.map +1 -1
  82. package/dist/pages/settings/users/permission-warnings.d.ts +7 -0
  83. package/dist/pages/settings/users/permission-warnings.js +42 -0
  84. package/dist/pages/settings/users/permission-warnings.js.map +1 -0
  85. package/dist/pages/settings/users/profile-helpers.d.ts +1 -3
  86. package/dist/pages/settings/users/profile-helpers.js +0 -16
  87. package/dist/pages/settings/users/profile-helpers.js.map +1 -1
  88. package/dist/pages/settings/users/role-editor-store.js +6 -3
  89. package/dist/pages/settings/users/role-editor-store.js.map +1 -1
  90. package/dist/pages/settings/users/role-editor.d.ts +2 -1
  91. package/dist/pages/settings/users/role-editor.js +8 -4
  92. package/dist/pages/settings/users/role-editor.js.map +1 -1
  93. package/dist/pages/settings/users/role-preview.js +2 -1
  94. package/dist/pages/settings/users/role-preview.js.map +1 -1
  95. package/dist/pages/settings/users/roles.js +5 -1
  96. package/dist/pages/settings/users/roles.js.map +1 -1
  97. package/dist/pages/settings/users/security-attention.d.ts +4 -0
  98. package/dist/pages/settings/users/security-attention.js +23 -7
  99. package/dist/pages/settings/users/security-attention.js.map +1 -1
  100. package/dist/pages/settings/users/security.d.ts +2 -1
  101. package/dist/pages/settings/users/security.js +13 -2
  102. package/dist/pages/settings/users/security.js.map +1 -1
  103. package/dist/pages/settings/users/two-factor-operations.d.ts +2 -1
  104. package/dist/pages/settings/users/two-factor-operations.js +28 -29
  105. package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
  106. package/dist/routes/auth/forgot-password.js +3 -0
  107. package/dist/routes/auth/forgot-password.js.map +1 -1
  108. package/dist/routes/auth/index.d.ts +1 -0
  109. package/dist/routes/auth/index.js +1 -0
  110. package/dist/routes/auth/index.js.map +1 -1
  111. package/dist/routes/auth/invite.js +28 -4
  112. package/dist/routes/auth/invite.js.map +1 -1
  113. package/dist/routes/auth/login-throttle.d.ts +2 -0
  114. package/dist/routes/auth/login-throttle.js +5 -4
  115. package/dist/routes/auth/login-throttle.js.map +1 -1
  116. package/dist/routes/auth/request-2fa-email.js +6 -18
  117. package/dist/routes/auth/request-2fa-email.js.map +1 -1
  118. package/dist/routes/auth/reset-code.d.ts +3 -0
  119. package/dist/routes/auth/reset-code.js +37 -0
  120. package/dist/routes/auth/reset-code.js.map +1 -0
  121. package/dist/routes/auth/reset-password.d.ts +2 -2
  122. package/dist/routes/auth/reset-password.js +5 -10
  123. package/dist/routes/auth/reset-password.js.map +1 -1
  124. package/dist/routes/auth/signup.js +10 -32
  125. package/dist/routes/auth/signup.js.map +1 -1
  126. package/dist/routes/auth/two-factor-throttle.d.ts +5 -0
  127. package/dist/routes/auth/two-factor-throttle.js +81 -0
  128. package/dist/routes/auth/two-factor-throttle.js.map +1 -0
  129. package/dist/routes/auth/validate-forgot-password-token.js +2 -8
  130. package/dist/routes/auth/validate-forgot-password-token.js.map +1 -1
  131. package/dist/routes/auth/validate-invite-token.d.ts +1 -0
  132. package/dist/routes/auth/validate-invite-token.js +11 -0
  133. package/dist/routes/auth/validate-invite-token.js.map +1 -0
  134. package/dist/routes/auth/verify-2fa.js +10 -13
  135. package/dist/routes/auth/verify-2fa.js.map +1 -1
  136. package/dist/routes/auth.d.ts +1 -0
  137. package/dist/routes/auth.js +11 -1
  138. package/dist/routes/auth.js.map +1 -1
  139. package/dist/test/helpers/auth.d.ts +0 -1
  140. package/dist/test/helpers/auth.js +0 -1
  141. package/dist/test/helpers/auth.js.map +1 -1
  142. package/dist/test/helpers/emails.d.ts +10 -0
  143. package/dist/test/helpers/emails.js +36 -0
  144. package/dist/test/helpers/emails.js.map +1 -0
  145. package/dist/test/helpers/fixtures.d.ts +0 -1
  146. package/dist/test/helpers/fixtures.js +1 -2
  147. package/dist/test/helpers/fixtures.js.map +1 -1
  148. package/dist/test/helpers/page-access.d.ts +1 -0
  149. package/dist/test/helpers/page-access.js +6 -1
  150. package/dist/test/helpers/page-access.js.map +1 -1
  151. package/dist/test/integration/auth/current-password.test.d.ts +1 -0
  152. package/dist/test/integration/auth/current-password.test.js +65 -0
  153. package/dist/test/integration/auth/current-password.test.js.map +1 -0
  154. package/dist/test/integration/auth/password-reset.test.d.ts +1 -0
  155. package/dist/test/integration/auth/password-reset.test.js +126 -0
  156. package/dist/test/integration/auth/password-reset.test.js.map +1 -0
  157. package/dist/test/integration/auth/session-revocation.test.d.ts +1 -0
  158. package/dist/test/integration/auth/session-revocation.test.js +45 -0
  159. package/dist/test/integration/auth/session-revocation.test.js.map +1 -0
  160. package/dist/test/integration/auth/two-factor-codes.test.d.ts +1 -0
  161. package/dist/test/integration/auth/two-factor-codes.test.js +335 -0
  162. package/dist/test/integration/auth/two-factor-codes.test.js.map +1 -0
  163. package/dist/test/integration/auth/two-factor-password.test.js +5 -1
  164. package/dist/test/integration/auth/two-factor-password.test.js.map +1 -1
  165. package/dist/test/integration/auth/two-factor-token.test.d.ts +1 -0
  166. package/dist/test/integration/auth/two-factor-token.test.js +92 -0
  167. package/dist/test/integration/auth/two-factor-token.test.js.map +1 -0
  168. package/dist/test/integration/email-change.test.js +36 -0
  169. package/dist/test/integration/email-change.test.js.map +1 -1
  170. package/dist/test/integration/invite-extension-edit.test.js +0 -1
  171. package/dist/test/integration/invite-extension-edit.test.js.map +1 -1
  172. package/dist/test/integration/invite-link-status.test.d.ts +1 -0
  173. package/dist/test/integration/invite-link-status.test.js +110 -0
  174. package/dist/test/integration/invite-link-status.test.js.map +1 -0
  175. package/dist/test/integration/invite-resolution.test.js +0 -3
  176. package/dist/test/integration/invite-resolution.test.js.map +1 -1
  177. package/dist/test/integration/member-settings-access.test.js +17 -0
  178. package/dist/test/integration/member-settings-access.test.js.map +1 -1
  179. package/dist/test/integration/notification-unread-badge.test.d.ts +1 -0
  180. package/dist/test/integration/notification-unread-badge.test.js +92 -0
  181. package/dist/test/integration/notification-unread-badge.test.js.map +1 -0
  182. package/dist/test/integration/permission-warnings.test.d.ts +1 -0
  183. package/dist/test/integration/permission-warnings.test.js +71 -0
  184. package/dist/test/integration/permission-warnings.test.js.map +1 -0
  185. package/dist/test/integration/removed-member-notifications.test.d.ts +1 -0
  186. package/dist/test/integration/removed-member-notifications.test.js +80 -0
  187. package/dist/test/integration/removed-member-notifications.test.js.map +1 -0
  188. package/dist/test/integration/role-permission-ancestors.test.d.ts +1 -0
  189. package/dist/test/integration/role-permission-ancestors.test.js +146 -0
  190. package/dist/test/integration/role-permission-ancestors.test.js.map +1 -0
  191. package/dist/test/integration/tenant-lifecycle.test.js +0 -4
  192. package/dist/test/integration/tenant-lifecycle.test.js.map +1 -1
  193. package/dist/test/unit/auth-session-revocation.test.d.ts +1 -0
  194. package/dist/test/unit/auth-session-revocation.test.js +105 -0
  195. package/dist/test/unit/auth-session-revocation.test.js.map +1 -0
  196. package/dist/test/unit/db/email-normalization.test.js +0 -1
  197. package/dist/test/unit/db/email-normalization.test.js.map +1 -1
  198. package/dist/test/unit/db/notification-feed-filter.test.js +0 -16
  199. package/dist/test/unit/db/notification-feed-filter.test.js.map +1 -1
  200. package/dist/test/unit/db/notification-inbox.test.js +63 -13
  201. package/dist/test/unit/db/notification-inbox.test.js.map +1 -1
  202. package/dist/test/unit/db/notification-preferences.test.js +0 -17
  203. package/dist/test/unit/db/notification-preferences.test.js.map +1 -1
  204. package/dist/test/unit/implementations/dms/empty-menu-group.test.d.ts +1 -0
  205. package/dist/test/unit/implementations/dms/empty-menu-group.test.js +133 -0
  206. package/dist/test/unit/implementations/dms/empty-menu-group.test.js.map +1 -0
  207. package/dist/test/unit/implementations/dms/layout-banners.test.js +2 -1
  208. package/dist/test/unit/implementations/dms/layout-banners.test.js.map +1 -1
  209. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.d.ts +1 -0
  210. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js +149 -0
  211. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js.map +1 -0
  212. package/dist/test/unit/implementations/dms/nav-badges.test.js +55 -4
  213. package/dist/test/unit/implementations/dms/nav-badges.test.js.map +1 -1
  214. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.d.ts +1 -0
  215. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js +118 -0
  216. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js.map +1 -0
  217. package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js +16 -0
  218. package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js.map +1 -1
  219. package/dist/test/unit/implementations/dms/permission-preview-cost.test.js +5 -3
  220. package/dist/test/unit/implementations/dms/permission-preview-cost.test.js.map +1 -1
  221. package/dist/test/unit/implementations/dms/permission-preview-menu.test.js +29 -3
  222. package/dist/test/unit/implementations/dms/permission-preview-menu.test.js.map +1 -1
  223. package/dist/test/unit/implementations/dms/quick-actions-button.test.js +4 -2
  224. package/dist/test/unit/implementations/dms/quick-actions-button.test.js.map +1 -1
  225. package/dist/test/unit/implementations/dms/user-permissions-gate.test.js +2 -1
  226. package/dist/test/unit/implementations/dms/user-permissions-gate.test.js.map +1 -1
  227. package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js +2 -1
  228. package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js.map +1 -1
  229. package/dist/test/unit/interfaces/dms/component-children-permissions.test.js +7 -2
  230. package/dist/test/unit/interfaces/dms/component-children-permissions.test.js.map +1 -1
  231. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.d.ts +1 -0
  232. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js +133 -0
  233. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js.map +1 -0
  234. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.d.ts +1 -0
  235. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js +149 -0
  236. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js.map +1 -0
  237. package/dist/test/unit/interfaces/dms/invite-extension.test.js +13 -0
  238. package/dist/test/unit/interfaces/dms/invite-extension.test.js.map +1 -1
  239. package/dist/test/unit/interfaces/dms/member-access.test.js +27 -1
  240. package/dist/test/unit/interfaces/dms/member-access.test.js.map +1 -1
  241. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.d.ts +1 -0
  242. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js +31 -0
  243. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js.map +1 -0
  244. package/dist/test/unit/interfaces/dms/page-extension.test.js +4 -1
  245. package/dist/test/unit/interfaces/dms/page-extension.test.js.map +1 -1
  246. package/dist/test/unit/interfaces/dms/permission-requirements.test.d.ts +1 -0
  247. package/dist/test/unit/interfaces/dms/permission-requirements.test.js +144 -0
  248. package/dist/test/unit/interfaces/dms/permission-requirements.test.js.map +1 -0
  249. package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js +6 -2
  250. package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js.map +1 -1
  251. package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js +1 -1
  252. package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js.map +1 -1
  253. package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js +2 -1
  254. package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js.map +1 -1
  255. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js +2 -1
  256. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js.map +1 -1
  257. package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js +2 -1
  258. package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js.map +1 -1
  259. package/dist/test/unit/pages/settings/account-activity-feed.test.js +2 -2
  260. package/dist/test/unit/pages/settings/account-activity-feed.test.js.map +1 -1
  261. package/dist/test/unit/pages/settings/account-activity.test.js +11 -2
  262. package/dist/test/unit/pages/settings/account-activity.test.js.map +1 -1
  263. package/dist/test/unit/pages/settings/invite-email-delivery.test.js +0 -1
  264. package/dist/test/unit/pages/settings/invite-email-delivery.test.js.map +1 -1
  265. package/dist/test/unit/pages/settings/invite-email-validation-option.test.d.ts +1 -0
  266. package/dist/test/unit/pages/settings/invite-email-validation-option.test.js +33 -0
  267. package/dist/test/unit/pages/settings/invite-email-validation-option.test.js.map +1 -0
  268. package/dist/test/unit/pages/settings/member-lists-page-size.test.d.ts +1 -0
  269. package/dist/test/unit/pages/settings/member-lists-page-size.test.js +22 -0
  270. package/dist/test/unit/pages/settings/member-lists-page-size.test.js.map +1 -0
  271. package/dist/test/unit/pages/settings/member-table-widths.test.js +2 -2
  272. package/dist/test/unit/pages/settings/member-table-widths.test.js.map +1 -1
  273. package/dist/test/unit/pages/settings/members-page.test.js +7 -10
  274. package/dist/test/unit/pages/settings/members-page.test.js.map +1 -1
  275. package/dist/test/unit/pages/settings/notifications-access-gate.test.js +3 -10
  276. package/dist/test/unit/pages/settings/notifications-access-gate.test.js.map +1 -1
  277. package/dist/test/unit/pages/settings/permission-tree-nodes.test.js +57 -0
  278. package/dist/test/unit/pages/settings/permission-tree-nodes.test.js.map +1 -1
  279. package/dist/test/unit/pages/settings/permission-warnings.test.d.ts +1 -0
  280. package/dist/test/unit/pages/settings/permission-warnings.test.js +49 -0
  281. package/dist/test/unit/pages/settings/permission-warnings.test.js.map +1 -0
  282. package/dist/test/unit/pages/settings/role-editor.test.js +16 -0
  283. package/dist/test/unit/pages/settings/role-editor.test.js.map +1 -1
  284. package/dist/test/unit/pages/settings/role-preview.test.js +7 -0
  285. package/dist/test/unit/pages/settings/role-preview.test.js.map +1 -1
  286. package/dist/test/unit/pages/settings/security-attention.test.d.ts +1 -0
  287. package/dist/test/unit/pages/settings/security-attention.test.js +74 -0
  288. package/dist/test/unit/pages/settings/security-attention.test.js.map +1 -0
  289. package/dist/test/unit/sanitize-user.test.d.ts +1 -0
  290. package/dist/test/unit/sanitize-user.test.js +21 -0
  291. package/dist/test/unit/sanitize-user.test.js.map +1 -0
  292. package/dist/test/unit/signup-email-validation.test.d.ts +1 -0
  293. package/dist/test/unit/signup-email-validation.test.js +79 -0
  294. package/dist/test/unit/signup-email-validation.test.js.map +1 -0
  295. package/dist/test/unit/validation/member-invite.schema.test.js +14 -52
  296. package/dist/test/unit/validation/member-invite.schema.test.js.map +1 -1
  297. package/dist/utils/account-notifications.d.ts +5 -0
  298. package/dist/utils/account-notifications.js +8 -0
  299. package/dist/utils/account-notifications.js.map +1 -1
  300. package/dist/utils/notification-emitter.d.ts +1 -1
  301. package/dist/utils/notification-emitter.js +1 -1
  302. package/dist/utils/notification-emitter.js.map +1 -1
  303. package/dist/utils/notification-tones.d.ts +2 -1
  304. package/dist/utils/notification-tones.js +5 -1
  305. package/dist/utils/notification-tones.js.map +1 -1
  306. package/dist/utils/one-time-code.d.ts +3 -0
  307. package/dist/utils/one-time-code.js +21 -0
  308. package/dist/utils/one-time-code.js.map +1 -0
  309. package/dist/utils/sign-in-monitor.d.ts +1 -0
  310. package/dist/utils/sign-in-monitor.js +3 -2
  311. package/dist/utils/sign-in-monitor.js.map +1 -1
  312. package/dist/utils/two-factor-codes.d.ts +10 -0
  313. package/dist/utils/two-factor-codes.js +76 -0
  314. package/dist/utils/two-factor-codes.js.map +1 -0
  315. package/dist/validation/auth.schema.d.ts +17 -0
  316. package/dist/validation/auth.schema.js +17 -6
  317. package/dist/validation/auth.schema.js.map +1 -1
  318. package/dist/validation/issue-message.d.ts +1 -0
  319. package/dist/validation/issue-message.js +9 -0
  320. package/dist/validation/issue-message.js.map +1 -0
  321. package/dist/validation/member-invite.schema.d.ts +1 -25
  322. package/dist/validation/member-invite.schema.js +2 -23
  323. package/dist/validation/member-invite.schema.js.map +1 -1
  324. package/frontend-vue/dms.frontend.ts +2 -0
  325. package/frontend-vue/layers/dms-auth/app/custom-pages/auth/forgot-validation.vue +3 -0
  326. package/frontend-vue/layers/dms-auth/app/custom-pages/auth/signup.vue +105 -5
  327. package/frontend-vue/layers/dms-auth/i18n/locales/auth-en-GB.json +20 -4
  328. package/frontend-vue/layers/dms-auth/i18n/locales/auth-fr-FR.json +20 -4
  329. package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +3 -2
  330. package/frontend-vue/layers/dms-core/app/types/menu.ts +15 -0
  331. package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +4 -1
  332. package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +4 -1
  333. package/frontend-vue/layers/dms-layout/app/assets/css/main.css +20 -0
  334. package/frontend-vue/layers/dms-layout/app/build/components/layout/CommandPaletteAssistantAnswer.vue +75 -0
  335. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardFrame.vue +22 -0
  336. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +24 -10
  337. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidePanel.vue +139 -0
  338. package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +4 -2
  339. package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +90 -0
  340. package/frontend-vue/layers/dms-layout/app/build/components/layout/SidePanelHost.vue +17 -0
  341. package/frontend-vue/layers/dms-layout/app/build/components/notification/NotificationPopover.vue +25 -43
  342. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/members/MemberRolePicker.vue +24 -2
  343. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationMatrixCategory.vue +70 -25
  344. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationPreferencesForm.vue +25 -10
  345. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/notificationDisplay.ts +41 -5
  346. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfilePreferencesSummary.vue +2 -1
  347. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfileSecuritySummary.vue +20 -4
  348. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RoleEditor.vue +21 -0
  349. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionArea.vue +16 -2
  350. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionBranch.vue +1 -0
  351. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionLeaf.vue +13 -1
  352. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionTree.vue +9 -0
  353. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionWarning.vue +46 -0
  354. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +108 -29
  355. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-types.ts +2 -0
  356. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityDialogFrame.vue +6 -6
  357. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityEmail.vue +7 -1
  358. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecuritySessions.vue +5 -4
  359. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityStatus.vue +4 -3
  360. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityTwoFactor.vue +54 -18
  361. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/shell/SettingsNav.vue +13 -8
  362. package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/assistantGroups.ts +143 -0
  363. package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/useCommandPaletteAssistantMode.ts +249 -0
  364. package/frontend-vue/layers/dms-layout/app/build/composables/general/useGithubStarPrompt.ts +178 -0
  365. package/frontend-vue/layers/dms-layout/app/build/composables/layout/sidePanelState.ts +191 -0
  366. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useHeaderActionControls.ts +51 -0
  367. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +113 -0
  368. package/frontend-vue/layers/dms-layout/app/build/composables/navigation/useCategoryNavCards.ts +17 -10
  369. package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +45 -0
  370. package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/useProfilePreferences.ts +8 -1
  371. package/frontend-vue/layers/dms-layout/app/build/composables/settings/security/useSecurityOverview.ts +50 -3
  372. package/frontend-vue/layers/dms-layout/app/build/composables/settings/useSettingsNavigation.ts +3 -0
  373. package/frontend-vue/layers/dms-layout/app/build/utils/categoryPages.ts +1 -2
  374. package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +5 -0
  375. package/frontend-vue/layers/dms-layout/app/components/layout/DashboardSearch.vue +109 -7
  376. package/frontend-vue/layers/dms-layout/app/components/navigation/NavigationMenu.vue +19 -9
  377. package/frontend-vue/layers/dms-layout/app/composables/notification/useNotifications.ts +22 -40
  378. package/frontend-vue/layers/dms-layout/app/composables/useAppSidePanels.ts +96 -0
  379. package/frontend-vue/layers/dms-layout/app/composables/useCommandPaletteAssistant.ts +129 -0
  380. package/frontend-vue/layers/dms-layout/app/composables/useHeaderActions.ts +33 -11
  381. package/frontend-vue/layers/dms-layout/app/composables/useSidePanel.ts +41 -0
  382. package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +15 -0
  383. package/frontend-vue/layers/dms-layout/app/plugins/notification-stream.client.ts +1 -7
  384. package/frontend-vue/layers/dms-layout/app/plugins/side-panel-host.ts +13 -0
  385. package/frontend-vue/layers/dms-layout/app/types/page.ts +4 -0
  386. package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +43 -13
  387. package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +43 -13
  388. package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +45 -0
  389. package/frontend-vue/layers/dms-ui/app/build/components/modal/ModalEscHint.vue +28 -0
  390. package/frontend-vue/layers/dms-ui/app/build/composables/form/floatingSaveBars.ts +38 -0
  391. package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +66 -0
  392. package/frontend-vue/layers/dms-ui/app/build/composables/navigation/useNavBadges.ts +50 -9
  393. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +7 -1
  394. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/chrome.ts +2 -2
  395. package/frontend-vue/layers/dms-ui/app/build/types/tree.ts +14 -10
  396. package/frontend-vue/layers/dms-ui/app/build/utils/navBadge.ts +12 -0
  397. package/frontend-vue/layers/dms-ui/app/build/utils/tone.ts +22 -0
  398. package/frontend-vue/layers/dms-ui/app/components/activity-feed/ActivityFeed.vue +117 -82
  399. package/frontend-vue/layers/dms-ui/app/components/blocks/NavCardGridBlock.vue +12 -1
  400. package/frontend-vue/layers/dms-ui/app/components/card/NavCard.vue +16 -1
  401. package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +7 -8
  402. package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +28 -6
  403. package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +5 -1
  404. package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +4 -0
  405. package/frontend-vue/layers/dms-ui/app/components/status-pill/StatusPill.vue +7 -2
  406. package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +7 -2
  407. package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +48 -34
  408. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +13 -3
  409. package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -14
  410. package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -14
  411. package/frontend-vue/package.json +2 -2
  412. package/frontend-vue/pnpm-lock.yaml +5 -5
  413. package/frontend-vue/tests/activity-feed-fill-height.test.ts +107 -0
  414. package/frontend-vue/tests/category-nav-cards.test.ts +21 -13
  415. package/frontend-vue/tests/command-palette-assistant.test.ts +344 -0
  416. package/frontend-vue/tests/fixtures/dashboard-search-stub.ts +91 -0
  417. package/frontend-vue/tests/forgot-validation-resend.test.ts +234 -0
  418. package/frontend-vue/tests/form-display-options.test.ts +64 -0
  419. package/frontend-vue/tests/form-load-error.test.ts +160 -0
  420. package/frontend-vue/tests/form-saved-before-success.test.ts +110 -0
  421. package/frontend-vue/tests/github-star-prompt.test.ts +328 -0
  422. package/frontend-vue/tests/header-actions.test.ts +191 -0
  423. package/frontend-vue/tests/invites-edit-modal.test.ts +157 -0
  424. package/frontend-vue/tests/member-role-picker.test.ts +26 -0
  425. package/frontend-vue/tests/menu-hidden-page.test.ts +93 -0
  426. package/frontend-vue/tests/nav-badge-tones.test.ts +274 -0
  427. package/frontend-vue/tests/nav-card-badge.test.ts +69 -0
  428. package/frontend-vue/tests/nav-card-grid-empty-category.test.ts +163 -0
  429. package/frontend-vue/tests/notification-popover-errors.test.ts +71 -37
  430. package/frontend-vue/tests/notification-preferences-groups.test.ts +268 -0
  431. package/frontend-vue/tests/notification-tone-contract.test.ts +70 -0
  432. package/frontend-vue/tests/page-fill-height.test.ts +9 -1
  433. package/frontend-vue/tests/page-no-visible-blocks.test.ts +202 -0
  434. package/frontend-vue/tests/profile-preferences-summary.test.ts +26 -2
  435. package/frontend-vue/tests/profile-security-summary.test.ts +121 -0
  436. package/frontend-vue/tests/role-permission-tree.test.ts +102 -8
  437. package/frontend-vue/tests/role-permissions.test.ts +178 -56
  438. package/frontend-vue/tests/side-panels.test.ts +470 -0
  439. package/frontend-vue/tests/signup-invitation-link.test.ts +71 -2
  440. package/frontend-vue/tests/table-actions-column-width.test.ts +51 -1
  441. package/frontend-vue/tests/table-view-chrome.test.ts +2 -2
  442. package/frontend-vue/tests/vue-inventory.test.ts +1 -1
  443. package/package.json +1 -1
  444. package/skills/dms/REFERENCE.md +1 -1
@@ -3,8 +3,13 @@ import Container from "./Container.vue";
3
3
  import DashboardSidebar from "./DashboardSidebar.vue";
4
4
  import DashboardHeader from "./DashboardHeader.vue";
5
5
  import DashboardBanners from "./DashboardBanners.vue";
6
+ import GithubStarPrompt from "./GithubStarPrompt.vue";
6
7
  import RolePreviewBar from "./RolePreviewBar.vue";
7
8
  import { useAppWidgets } from "../../../composables/useAppWidgets";
9
+ import {
10
+ sidePanelWidthStyle,
11
+ useActiveSidePanel,
12
+ } from "../../composables/layout/sidePanelState";
8
13
 
9
14
  // Sidebar sizes are in px (the v2 240px sidebar). The storage key changed with
10
15
  // the unit, so a width saved in % is not read back as px.
@@ -23,6 +28,9 @@ const DOCK_CLEARANCE_CLASS =
23
28
  // One 40px chip plus its 8px gap per widget, the 10px inset and a 12px margin.
24
29
  const DOCK_CHIP_REM = 3;
25
30
  const DOCK_EDGE_REM = 1.375;
31
+ // The open side panel is rendered once for the app (`SidePanelHost`), fixed on
32
+ // the right; from `lg` the frame keeps its width free so the page shrinks.
33
+ const SIDE_PANEL_ROOM_CLASS = "lg:end-[min(var(--dms-side-panel-width),60vw)]";
26
34
  const dockHeight = (chips: number): string =>
27
35
  `${chips * DOCK_CHIP_REM + DOCK_EDGE_REM}rem`;
28
36
 
@@ -60,6 +68,17 @@ const regionAttrs = computed(() =>
60
68
  }
61
69
  : {},
62
70
  );
71
+
72
+ const { panel: sidePanel, width: sidePanelWidth } = useActiveSidePanel();
73
+ // Bound as attributes so a frame without a panel renders no empty `style`.
74
+ const groupAttrs = computed(() =>
75
+ sidePanel.value
76
+ ? {
77
+ class: SIDE_PANEL_ROOM_CLASS,
78
+ style: sidePanelWidthStyle(sidePanelWidth.value),
79
+ }
80
+ : {},
81
+ );
63
82
  </script>
64
83
 
65
84
  <template>
@@ -67,6 +86,7 @@ const regionAttrs = computed(() =>
67
86
  data-dms-persistent-shell
68
87
  :storage-key="DASHBOARD_STORAGE_KEY"
69
88
  :unit="DASHBOARD_SIZE_UNIT"
89
+ v-bind="groupAttrs"
70
90
  >
71
91
  <DashboardSidebar />
72
92
 
@@ -93,5 +113,7 @@ const regionAttrs = computed(() =>
93
113
  <DmsAppWidgetsDock />
94
114
  </template>
95
115
  </UDashboardPanel>
116
+
117
+ <GithubStarPrompt />
96
118
  </UDashboardGroup>
97
119
  </template>
@@ -3,6 +3,7 @@ import type { BreadcrumbItem, DropdownMenuItem } from "@nuxt/ui";
3
3
  import NotificationPopover from "../notification/NotificationPopover.vue";
4
4
  import QuickActionsPopover from "./QuickActionsPopover.vue";
5
5
  import { useSidebarState } from "./sidebarState";
6
+ import { useHeaderActionControls } from "../../composables/layout/useHeaderActionControls";
6
7
  import { usePageRecordLabel } from "#dms-core/app/build/composables/page/usePageRecordLabel";
7
8
 
8
9
  const HOME_ICON = "i-ph-house-light";
@@ -37,6 +38,11 @@ const builderAction = computed(() =>
37
38
  const headerActions = computed(() =>
38
39
  registeredActions.value.filter((action) => action.id !== BUILDER_ACTION_ID),
39
40
  );
41
+ const {
42
+ isToggle: isActionToggle,
43
+ isActive: isActionActive,
44
+ select: selectAction,
45
+ } = useHeaderActionControls();
40
46
 
41
47
  const sidebarToggleLabel = computed(() =>
42
48
  sidebarCollapsed.value
@@ -233,36 +239,44 @@ const mobileBreadcrumb = computed(
233
239
  <template #right>
234
240
  <UTooltip
235
241
  v-if="builderAction"
236
- :text="builderAction.label"
242
+ :text="processI18n(builderAction.label)"
237
243
  :content="TOOLTIP_CONTENT"
238
244
  >
239
245
  <UButton
240
246
  :icon="builderAction.icon || 'i-ph-hammer-light'"
241
247
  variant="ghost"
242
- :color="builderAction.isActive?.() ? 'primary' : 'neutral'"
248
+ :color="isActionActive(builderAction) ? 'primary' : 'neutral'"
243
249
  :class="
244
- builderAction.isActive?.() ? undefined : TOOLBAR_BUTTON_CLASS
250
+ isActionActive(builderAction) ? undefined : TOOLBAR_BUTTON_CLASS
251
+ "
252
+ :aria-label="processI18n(builderAction.label)"
253
+ :aria-pressed="
254
+ isActionToggle(builderAction)
255
+ ? isActionActive(builderAction)
256
+ : undefined
245
257
  "
246
- :aria-label="builderAction.label"
247
258
  :ui="{ leadingIcon: 'size-[18px]' }"
248
- @click="builderAction.onSelect()"
259
+ @click="selectAction(builderAction)"
249
260
  />
250
261
  </UTooltip>
251
262
 
252
263
  <UTooltip
253
264
  v-for="action in headerActions"
254
265
  :key="action.id"
255
- :text="action.label"
266
+ :text="processI18n(action.label)"
256
267
  :content="TOOLTIP_CONTENT"
257
268
  >
258
269
  <UButton
259
270
  :icon="action.icon"
260
271
  variant="ghost"
261
- color="neutral"
262
- :class="TOOLBAR_BUTTON_CLASS"
263
- :aria-label="action.label"
272
+ :color="isActionActive(action) ? 'primary' : 'neutral'"
273
+ :class="isActionActive(action) ? undefined : TOOLBAR_BUTTON_CLASS"
274
+ :aria-label="processI18n(action.label)"
275
+ :aria-pressed="
276
+ isActionToggle(action) ? isActionActive(action) : undefined
277
+ "
264
278
  :ui="{ leadingIcon: 'size-[18px]' }"
265
- @click="action.onSelect?.()"
279
+ @click="selectAction(action)"
266
280
  />
267
281
  </UTooltip>
268
282
 
@@ -0,0 +1,139 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * One side panel (see `useAppSidePanels`), fixed on the right of the window.
4
+ * From `lg` it is docked: every dashboard frame keeps that width free on its
5
+ * right, so the page shrinks next to it, and a resize handle sits on its inner
6
+ * edge. Below `lg` the same element is a sheet over the page, above a
7
+ * backdrop: the switch is CSS only, so crossing the breakpoint never remounts
8
+ * the panel's component.
9
+ */
10
+ import { useMediaQuery } from "@vueuse/core";
11
+ import type { SidePanel } from "../../../composables/useAppSidePanels";
12
+ import { useSidePanel } from "../../../composables/useSidePanel";
13
+ import { sidePanelWidthStyle } from "../../composables/layout/sidePanelState";
14
+ import { useSidePanelWidth } from "../../composables/layout/useSidePanelWidth";
15
+
16
+ interface Props {
17
+ panel: SidePanel;
18
+ }
19
+
20
+ const props = defineProps<Props>();
21
+
22
+ // The panel belongs to the dashboard: a page without its shell (onboarding,
23
+ // an error page) hides it, and keeps it mounted for the way back.
24
+ const HOST_CLASS =
25
+ "contents [body:not(:has([data-dms-persistent-shell]))_&]:hidden";
26
+ const DESKTOP_QUERY = "(min-width: 1024px)";
27
+ const ESCAPE_KEY = "Escape";
28
+ const PANEL_DOM_ID_PREFIX = "dms-side-panel-";
29
+
30
+ const { t } = useI18n();
31
+ const { processI18n } = useTranslation();
32
+ const isDocked = useMediaQuery(DESKTOP_QUERY);
33
+ const { close } = useSidePanel(props.panel.id);
34
+ const panelEl = ref<HTMLElement | null>(null);
35
+ const {
36
+ width,
37
+ bounds,
38
+ isDragging,
39
+ startDrag,
40
+ drag,
41
+ endDrag,
42
+ resizeFromKey,
43
+ reset,
44
+ } = useSidePanelWidth(props.panel);
45
+
46
+ const panelDomId = `${PANEL_DOM_ID_PREFIX}${props.panel.id}`;
47
+ const ariaLabel = computed(() =>
48
+ props.panel.ariaLabel ? processI18n(props.panel.ariaLabel) : undefined,
49
+ );
50
+ const panelStyle = computed(() => sidePanelWidthStyle(width.value));
51
+ const panelComponent = computed(
52
+ () => resolveDmsComponent(props.panel.component) ?? props.panel.component,
53
+ );
54
+
55
+ // Escape dismisses the sheet only: docked, the panel is part of the page and
56
+ // its component may give the key a meaning of its own.
57
+ function closeSheetOnEscape(event: KeyboardEvent): void {
58
+ if (event.key !== ESCAPE_KEY || isDocked.value) return;
59
+ close();
60
+ }
61
+
62
+ function startHandleDrag(event: PointerEvent): void {
63
+ (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
64
+ const renderedWidth = panelEl.value?.getBoundingClientRect().width;
65
+ startDrag(event, renderedWidth || width.value);
66
+ }
67
+
68
+ let focusBeforeOpen: HTMLElement | null = null;
69
+
70
+ function isFocusInside(): boolean {
71
+ return panelEl.value?.contains(document.activeElement) ?? false;
72
+ }
73
+
74
+ // The sheet covers the page, so focus moves into it unless the panel's own
75
+ // component already took it; closing gives focus back to where it came from.
76
+ onMounted(() => {
77
+ const active = document.activeElement;
78
+ focusBeforeOpen = active instanceof HTMLElement ? active : null;
79
+ if (isDocked.value || isFocusInside()) return;
80
+ panelEl.value?.focus();
81
+ });
82
+
83
+ onBeforeUnmount(() => {
84
+ if (isFocusInside()) focusBeforeOpen?.focus();
85
+ });
86
+ </script>
87
+
88
+ <template>
89
+ <div data-dms-side-panel-host :class="HOST_CLASS">
90
+ <button
91
+ type="button"
92
+ aria-hidden="true"
93
+ tabindex="-1"
94
+ data-dms-side-panel-backdrop
95
+ class="bg-elevated/75 fixed inset-0 z-40 lg:hidden"
96
+ @click="close"
97
+ />
98
+
99
+ <aside
100
+ :id="panelDomId"
101
+ ref="panelEl"
102
+ data-dms-side-panel
103
+ :data-dragging="isDragging || undefined"
104
+ :aria-label="ariaLabel"
105
+ tabindex="-1"
106
+ class="border-default fixed inset-y-0 end-0 flex w-(--dms-side-panel-width) max-w-full min-w-0 flex-col border-s bg-(--dms-bg-sidebar) outline-none max-lg:z-50 max-lg:shadow-xl lg:max-w-[60vw]"
107
+ :style="panelStyle"
108
+ @keydown="closeSheetOnEscape"
109
+ >
110
+ <div
111
+ role="separator"
112
+ aria-orientation="vertical"
113
+ tabindex="0"
114
+ data-dms-side-panel-handle
115
+ :aria-controls="panelDomId"
116
+ :aria-label="t('side_panel.resize')"
117
+ :aria-valuenow="width"
118
+ :aria-valuemin="bounds.minWidth"
119
+ :aria-valuemax="bounds.maxWidth"
120
+ class="group/handle absolute inset-y-0 -start-1 z-10 hidden w-2 cursor-ew-resize touch-none outline-none select-none lg:block"
121
+ @pointerdown="startHandleDrag"
122
+ @pointermove="drag"
123
+ @pointerup="endDrag"
124
+ @pointercancel="endDrag"
125
+ @lostpointercapture="endDrag"
126
+ @keydown="resizeFromKey"
127
+ @dblclick="reset"
128
+ >
129
+ <span
130
+ aria-hidden="true"
131
+ class="group-hover/handle:bg-primary group-focus-visible/handle:bg-primary absolute inset-y-0 start-1/2 w-0.5 -translate-x-1/2 transition-colors motion-reduce:transition-none"
132
+ :class="{ 'bg-primary': isDragging }"
133
+ />
134
+ </div>
135
+
136
+ <component :is="panelComponent" class="min-h-0 flex-1" />
137
+ </aside>
138
+ </div>
139
+ </template>
@@ -1,9 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import type { SelectItem } from "@nuxt/ui";
3
+ import {
4
+ GITHUB_REPOSITORY,
5
+ GITHUB_REPOSITORY_URL,
6
+ } from "../../utils/github-repository";
3
7
 
4
8
  const EXTERNAL_LINK_PATTERN = /^https?:\/\//;
5
- const GITHUB_REPOSITORY = "AntelopeJS/dms";
6
- const GITHUB_REPOSITORY_URL = `https://github.com/${GITHUB_REPOSITORY}`;
7
9
  const GITHUB_REPOSITORY_API = `https://api.github.com/repos/${GITHUB_REPOSITORY}`;
8
10
  const GITHUB_STARS_CACHE_KEY = "dms-github-stars";
9
11
  // GitHub allows 60 anonymous API calls an hour per visitor: the count is
@@ -0,0 +1,90 @@
1
+ <script setup lang="ts">
2
+ import { computed } from "vue";
3
+ import { isFloatingSaveBarShown } from "#dms-ui/app/build/composables/form/floatingSaveBars";
4
+ import { useGithubStarPrompt } from "../../composables/general/useGithubStarPrompt";
5
+
6
+ const TITLE_ID = "dms-github-star-prompt-title";
7
+ const DESCRIPTION_ID = "dms-github-star-prompt-description";
8
+
9
+ const { t } = useI18n();
10
+ const { user } = useCurrentUser();
11
+ const toast = useToast();
12
+
13
+ // Developers only: a production build, a client's dashboard included, never
14
+ // counts, stores or shows anything. The same flag gates the dev reload.
15
+ const { isDue, snooze, star, dismiss } = useGithubStarPrompt(
16
+ import.meta.env.DEV,
17
+ );
18
+
19
+ // The toaster stacks in the same corner, and a floating save bar sticks to
20
+ // the bottom of the panel: the prompt steps aside while either is up rather
21
+ // than cover it.
22
+ const isShown = computed(
23
+ () =>
24
+ isDue.value &&
25
+ !!user.value &&
26
+ toast.toasts.value.length === 0 &&
27
+ !isFloatingSaveBarShown.value,
28
+ );
29
+ </script>
30
+
31
+ <template>
32
+ <!-- A non-modal dialog that takes no focus: it waits at the end of the tab
33
+ order. Toast look (theme/surfaces.ts), in the toaster's corner and
34
+ width, rising into place like a toast. The buttons take the card's
35
+ full width, so the longer French label still fits beside "Later".
36
+ On a phone it tightens and drops the icon, so the text runs the full
37
+ width and covers less of the page. From `lg` it stays clear of an
38
+ open side panel, whose width the dashboard frame sets. -->
39
+ <div
40
+ v-if="isShown"
41
+ role="dialog"
42
+ :aria-labelledby="TITLE_ID"
43
+ :aria-describedby="DESCRIPTION_ID"
44
+ class="bg-default ring-accented fixed inset-x-3 bottom-3 z-50 rounded-(--dms-radius-card) p-3 shadow-(--dms-shadow-pop) ring transition duration-300 ease-out motion-reduce:transition-none sm:inset-x-auto sm:right-5 sm:bottom-5 sm:w-[380px] sm:p-3.5 sm:ps-4 lg:right-[calc(min(var(--dms-side-panel-width,0px),60vw)+1.25rem)] starting:translate-y-4 starting:opacity-0"
45
+ >
46
+ <div class="flex items-start gap-3 pe-6">
47
+ <DmsIconWell icon="i-ph-star" size="sm" class="max-sm:hidden" />
48
+ <div class="min-w-0 flex-1">
49
+ <h2
50
+ :id="TITLE_ID"
51
+ class="text-highlighted text-[13px]/[1.35] font-semibold"
52
+ >
53
+ {{ t("github_star_prompt.title") }}
54
+ </h2>
55
+ <p :id="DESCRIPTION_ID" class="text-muted mt-0.5 text-[13px]/[1.45]">
56
+ {{ t("github_star_prompt.description") }}
57
+ </p>
58
+ </div>
59
+ </div>
60
+ <div class="mt-2.5 flex flex-wrap justify-end gap-1.5 sm:mt-3">
61
+ <UButton
62
+ size="sm"
63
+ color="neutral"
64
+ variant="outline"
65
+ :label="t('github_star_prompt.later')"
66
+ data-action="later"
67
+ @click="snooze"
68
+ />
69
+ <UButton
70
+ size="sm"
71
+ icon="i-ph-star"
72
+ :label="t('github_star_prompt.star')"
73
+ data-action="star"
74
+ @click="star"
75
+ />
76
+ </div>
77
+ <UButton
78
+ size="xs"
79
+ color="neutral"
80
+ variant="ghost"
81
+ square
82
+ icon="i-ph-x"
83
+ class="text-dimmed hover:text-highlighted absolute top-2.5 right-2.5"
84
+ :aria-label="t('github_star_prompt.close')"
85
+ :title="t('github_star_prompt.close')"
86
+ data-action="close"
87
+ @click="dismiss"
88
+ />
89
+ </div>
90
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Renders the open side panel (see `useSidePanel`) once for the whole app,
4
+ * registered as an app overlay: outside the routed layouts, so moving between
5
+ * the default and settings layouts keeps the panel's component mounted. The
6
+ * server renders it from the side panel cookie, in place on the first paint.
7
+ * Keyed by panel id, so each panel keeps its own focus bookkeeping.
8
+ */
9
+ import DashboardSidePanel from "./DashboardSidePanel.vue";
10
+ import { useActiveSidePanel } from "../../composables/layout/sidePanelState";
11
+
12
+ const { panel } = useActiveSidePanel();
13
+ </script>
14
+
15
+ <template>
16
+ <DashboardSidePanel v-if="panel" :key="panel.id" :panel="panel" />
17
+ </template>
@@ -5,6 +5,7 @@ import { useNavBadges } from "#dms-ui/app/build/composables/navigation/useNavBad
5
5
  import { settleWidgetRequest } from "./widgetRequest";
6
6
  import type { UserNotification } from "../../../composables/notification/useNotifications";
7
7
  import { resolveNotificationTone } from "../pages/settings/notification/notificationDisplay";
8
+ import { DMS_TONE_SOLID, iconWellToneOf } from "#dms-ui/app/build/utils/tone";
8
9
  import DmsRowSkeleton from "#dms-ui/app/build/components/skeleton/RowSkeleton.vue";
9
10
 
10
11
  const MAX_DISPLAYED_COUNT = 99;
@@ -23,13 +24,12 @@ const { loggedIn } = useUserSession();
23
24
  const { processI18n } = useTranslation();
24
25
  const {
25
26
  unreadCount,
26
- unseenCount,
27
+ unreadTone,
27
28
  notifications,
28
29
  hasMore,
29
30
  fetchBellCounts,
30
31
  fetchNotifications,
31
32
  markAsRead,
32
- markAllSeen,
33
33
  } = useNotifications();
34
34
  const { setNavBadge } = useNavBadges();
35
35
  const isOpen = ref(false);
@@ -46,37 +46,36 @@ const { isLoadingMore, setupObserver, disconnectObserver } = useInfiniteScroll(
46
46
 
47
47
  // The sender's tone (a warning, a success) colours the icon well, as in the
48
48
  // inbox; untoned notifications keep the accent until read.
49
- const iconWellTone = (notification: UserNotification) => {
50
- const tone = resolveNotificationTone(notification);
51
- return tone === "neutral" ? "muted" : tone;
52
- };
49
+ const iconWellTone = (notification: UserNotification) =>
50
+ iconWellToneOf(resolveNotificationTone(notification));
53
51
 
54
52
  const formatCount = (count: number) =>
55
53
  count > MAX_DISPLAYED_COUNT ? `${MAX_DISPLAYED_COUNT}+` : String(count);
56
54
 
57
- // The bell's badge counts what arrived since it was last opened (unseen);
58
- // opening it resets the badge but leaves the notifications unread.
59
- const displayedCount = computed(() => formatCount(unseenCount.value));
55
+ // The bell's badge counts what is unread, in the tone of the most important
56
+ // unread notification; opening the bell changes neither.
57
+ const displayedCount = computed(() => formatCount(unreadCount.value));
58
+ const badgeToneClass = computed(
59
+ () => DMS_TONE_SOLID[unreadTone.value ?? "neutral"],
60
+ );
60
61
 
61
- // The bell is on every page, so it keeps the unread badge of the
62
- // Notifications entry in the navigation current between two menu loads:
63
- // that one counts what is still unread, seen or not.
64
- watch(unreadCount, (count) => {
65
- setNavBadge(NOTIFICATIONS_SETTINGS_PAGE, count > 0 ? formatCount(count) : "");
62
+ // The bell is on every page, so it keeps the badge of the Notifications
63
+ // entry in the navigation current between two menu loads: the same count,
64
+ // in the same tone.
65
+ watch([unreadCount, unreadTone], ([count, tone]) => {
66
+ setNavBadge(
67
+ NOTIFICATIONS_SETTINGS_PAGE,
68
+ count > 0 ? formatCount(count) : "",
69
+ tone,
70
+ );
66
71
  });
67
72
 
68
73
  const refreshCounts = () =>
69
74
  settleWidgetRequest(fetchBellCounts, () => {
70
75
  unreadCount.value = 0;
71
- unseenCount.value = 0;
76
+ unreadTone.value = undefined;
72
77
  });
73
78
 
74
- const handleNotificationEvent = async () => {
75
- if (!isOpen.value) {
76
- await refreshCounts();
77
- }
78
- };
79
-
80
79
  const handleFormSubmitSuccess = async (event: Event) => {
81
80
  const customEvent = event as CustomEvent;
82
81
  const submitUrl = customEvent.detail?.data?.submitUrl;
@@ -88,20 +87,10 @@ const handleFormSubmitSuccess = async (event: Event) => {
88
87
  }
89
88
  };
90
89
 
91
- // Seeing is not reading: the notifications stay unread until opened or
92
- // marked read, in the popover or the inbox.
93
- const markSeen = async () => {
94
- if (unseenCount.value > 0) await settleWidgetRequest(markAllSeen);
95
- };
96
-
97
90
  onMounted(async () => {
98
91
  if (!loggedIn.value) return;
99
92
  await refreshCounts();
100
93
 
101
- window.addEventListener(
102
- NotificationEvents.NOTIFICATION_RECEIVED,
103
- handleNotificationEvent as EventListener,
104
- );
105
94
  window.addEventListener(
106
95
  FormEvents.SUBMIT_SUCCESS,
107
96
  handleFormSubmitSuccess as EventListener,
@@ -111,10 +100,6 @@ onMounted(async () => {
111
100
  onUnmounted(() => {
112
101
  disconnectObserver();
113
102
 
114
- window.removeEventListener(
115
- NotificationEvents.NOTIFICATION_RECEIVED,
116
- handleNotificationEvent as EventListener,
117
- );
118
103
  window.removeEventListener(
119
104
  FormEvents.SUBMIT_SUCCESS,
120
105
  handleFormSubmitSuccess as EventListener,
@@ -124,17 +109,12 @@ onUnmounted(() => {
124
109
  watch(isOpen, async (isNowOpen) => {
125
110
  if (isNowOpen) {
126
111
  isListLoading.value = true;
127
- await Promise.all([
128
- markSeen(),
129
- settleWidgetRequest(() => fetchNotifications(true)),
130
- ]);
112
+ await settleWidgetRequest(() => fetchNotifications(true));
131
113
  isListLoading.value = false;
132
114
  await nextTick();
133
115
  setupObserver();
134
116
  } else {
135
117
  disconnectObserver();
136
- // What arrived while the list was open showed at its top: seen too.
137
- await markSeen();
138
118
  }
139
119
  });
140
120
 
@@ -175,8 +155,10 @@ const goToNotifications = () => {
175
155
  <!-- Floats over the button's corner (nothing moves) and fades in
176
156
  (starting style) once the count, fetched after mount, is back. -->
177
157
  <span
178
- v-if="unseenCount > 0"
179
- class="absolute -top-0.5 -right-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-(--dms-accent-fill) px-1 text-[10px] leading-none font-semibold text-(--dms-accent-on-fill) ring-2 ring-(--ui-bg-muted) transition-opacity duration-200 starting:opacity-0"
158
+ v-if="unreadCount > 0"
159
+ data-bell-badge
160
+ :class="badgeToneClass"
161
+ class="absolute -top-0.5 -right-0.5 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] leading-none font-semibold ring-2 ring-(--ui-bg-muted) transition-opacity duration-200 starting:opacity-0"
180
162
  >
181
163
  {{ displayedCount }}
182
164
  </span>
@@ -20,6 +20,8 @@ interface RoleOption {
20
20
  _id: string;
21
21
  name: string;
22
22
  permissionIds: string[];
23
+ /** Set when what the role grants amounts to owner-level access. */
24
+ warnings?: string[];
23
25
  }
24
26
 
25
27
  interface RoleOptionsResponse {
@@ -77,8 +79,7 @@ const isOwner = computed(
77
79
  () => !!props.ownerField && formState?.value?.[props.ownerField] === true,
78
80
  );
79
81
  const isInert = computed(() => props.disabled || isOwner.value);
80
- // Without an owner field (the invite form), the form disables the roles for
81
- // an owner only.
82
+ // Without an owner field, the form disables the roles for an owner only.
82
83
  const showsOwnerHint = computed(() =>
83
84
  props.ownerField ? isOwner.value : props.disabled,
84
85
  );
@@ -102,6 +103,19 @@ const roleItems = computed<ChipGroupItem[]>(() =>
102
103
  const selectedRoles = computed(() =>
103
104
  options.value.roles.filter((role) => selectedIds.value.has(role._id)),
104
105
  );
106
+ // An owner holds every permission anyway: no warning then.
107
+ const ownerLevelWarning = computed(() => {
108
+ if (isOwner.value) return undefined;
109
+ const names = selectedRoles.value
110
+ .filter((role) => (role.warnings?.length ?? 0) > 0)
111
+ .map((role) => role.name);
112
+ if (names.length === 0) return undefined;
113
+ return t(
114
+ "page.settings.members.invite.roles_owner_level",
115
+ { roles: names.join(" + ") },
116
+ names.length,
117
+ );
118
+ });
105
119
  const grantedCount = computed(
106
120
  () => new Set(selectedRoles.value.flatMap((role) => role.permissionIds)).size,
107
121
  );
@@ -180,5 +194,13 @@ function toggle(roleId: string) {
180
194
  {{ t("page.settings.members.invite.compare_roles") }}
181
195
  </ULink>
182
196
  </p>
197
+ <p
198
+ v-if="ownerLevelWarning"
199
+ class="text-warning flex items-start gap-1.5 text-xs"
200
+ data-role-owner-level
201
+ >
202
+ <UIcon name="i-ph-warning" class="mt-px size-3.5 shrink-0" />
203
+ <span>{{ ownerLevelWarning }}</span>
204
+ </p>
183
205
  </div>
184
206
  </template>