@wssto2/vue-core 0.9.4 → 0.11.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 (169) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/ActionRow.vue_vue_type_script_setup_true_lang-DybAIOHS.js +64 -0
  3. package/dist/Activity-CdkJW68R.js +169 -0
  4. package/dist/{AdaptivePageShell.vue_vue_type_script_setup_true_lang-DdJOodn8.js → AdaptivePageShell.vue_vue_type_script_setup_true_lang-D5i77H6S.js} +147 -159
  5. package/dist/{AsyncSection.vue_vue_type_script_setup_true_lang-BdeOKqz_.js → AsyncSection.vue_vue_type_script_setup_true_lang-DGzQ-Snp.js} +1 -1
  6. package/dist/BottomDockPortal.vue_vue_type_script_setup_true_lang-DmwR-2SP.js +17 -0
  7. package/dist/Button.vue_vue_type_script_setup_true_lang-C74hcb0N.js +123 -0
  8. package/dist/Changes-DxK_QfiB.js +69 -0
  9. package/dist/{CollectionPage.vue_vue_type_script_setup_true_lang-DHcekGNn.js → CollectionPage.vue_vue_type_script_setup_true_lang-x0jyJ01f.js} +19 -18
  10. package/dist/{DataTable.vue_vue_type_script_setup_true_lang-8kBsNRuq.js → DataTable.vue_vue_type_script_setup_true_lang-C_ZytnW-.js} +1 -1
  11. package/dist/{DateField.vue_vue_type_script_setup_true_lang-BhKdCVFn.js → DateField.vue_vue_type_script_setup_true_lang-CeNwBbJT.js} +1 -1
  12. package/dist/{DeadLetters-Bb5pPlOY.js → DeadLetters-DnA7LP1w.js} +5 -6
  13. package/dist/DrawnCheck.vue_vue_type_script_setup_true_lang-9DzDJlIA.js +38 -0
  14. package/dist/FormGroup.vue_vue_type_script_setup_true_lang-D6jYfNjW.js +427 -0
  15. package/dist/{FormView.vue_vue_type_script_setup_true_lang-aaNnMIOi.js → FormView.vue_vue_type_script_setup_true_lang-DvbPEiNQ.js} +2 -2
  16. package/dist/{General-BAG7S6wV.js → General-2matxl2Y.js} +23 -24
  17. package/dist/Highlight.vue_vue_type_script_setup_true_lang-DZGBmwcX.js +29 -0
  18. package/dist/{IncidentRecord-D8aOpNHo.js → IncidentRecord-Bt3G4HlX.js} +14 -15
  19. package/dist/{IncidentsList-C0cFl0Db.js → IncidentsList-2iwgqp9J.js} +3 -3
  20. package/dist/{Modal.vue_vue_type_script_setup_true_lang-BlHhdmMy.js → Modal.vue_vue_type_script_setup_true_lang-DDS0iEnn.js} +9 -8
  21. package/dist/{NewRolePage-C6Iu-EQJ.js → NewRolePage-DhGFwvk3.js} +4 -4
  22. package/dist/{NumberField.vue_vue_type_script_setup_true_lang-TGGAq8J-.js → NumberField.vue_vue_type_script_setup_true_lang-B3UrXNqH.js} +1 -1
  23. package/dist/{PersonAccess.vue_vue_type_script_setup_true_lang-qz1tmYpF.js → PersonAccess.vue_vue_type_script_setup_true_lang-DbGZSNQc.js} +56 -56
  24. package/dist/ProfilePage-CpuyDBAv.js +685 -0
  25. package/dist/ProgressTrack.vue_vue_type_script_setup_true_lang-DrOm8k--.js +30 -0
  26. package/dist/{RecordHeader.vue_vue_type_script_setup_true_lang-B9mN7UxZ.js → RecordHeader.vue_vue_type_script_setup_true_lang-DqGc3Jyo.js} +1 -1
  27. package/dist/{ResourcePage.vue_vue_type_script_setup_true_lang-Cw8mGf_B.js → ResourcePage.vue_vue_type_script_setup_true_lang-DljhsTU4.js} +3 -3
  28. package/dist/{RoleEditor.vue_vue_type_script_setup_true_lang-CJPvOVDV.js → RoleEditor.vue_vue_type_script_setup_true_lang-C0FIotFA.js} +11 -12
  29. package/dist/{RolePage-Dj_ocMnM.js → RolePage-DaNv049g.js} +10 -10
  30. package/dist/{RolesPage-PXrs4O-1.js → RolesPage-6hlzJes_.js} +6 -6
  31. package/dist/SearchInput.vue_vue_type_script_setup_true_lang-w4eAqyZ9.js +32 -0
  32. package/dist/{SectionList.vue_vue_type_script_setup_true_lang-CtdF1zuv.js → SectionList.vue_vue_type_script_setup_true_lang-DR0_NsqC.js} +1 -1
  33. package/dist/{SectionNavigator.vue_vue_type_script_setup_true_lang-B5ove3rM.js → SectionNavigator.vue_vue_type_script_setup_true_lang-Dh3sXUt_.js} +2 -2
  34. package/dist/{SegmentedField.vue_vue_type_script_setup_true_lang-ChfDFAA2.js → SegmentedField.vue_vue_type_script_setup_true_lang-zv_AxpBn.js} +1 -1
  35. package/dist/{SelectField.vue_vue_type_script_setup_true_lang-BP8nAQwo.js → SelectField.vue_vue_type_script_setup_true_lang-BZwdANL3.js} +3 -3
  36. package/dist/{ServiceAccountDialog.vue_vue_type_script_setup_true_lang-aWkKwxNe.js → ServiceAccountDialog.vue_vue_type_script_setup_true_lang-FJbWxME_.js} +20 -20
  37. package/dist/{ServiceAccountRecord-bxX9yQkC.js → ServiceAccountRecord-0-JF5lRx.js} +24 -24
  38. package/dist/{ServiceAccountsList-BXE6htxk.js → ServiceAccountsList-DcsnOcf-.js} +32 -32
  39. package/dist/{Sessions--Gvc0kxw.js → Sessions-DgWhpk-i.js} +23 -24
  40. package/dist/{SettingsPage-DzDC7gD-.js → SettingsPage-BXPWATYU.js} +28 -30
  41. package/dist/{SignIn-CTI_699e.js → SignIn-DPoUwHZd.js} +9 -10
  42. package/dist/{SignInPage-HKC1bm2E.js → SignInPage-OyrVemro.js} +4 -4
  43. package/dist/SignIns-BMDrZVVp.js +64 -0
  44. package/dist/StatusLine.vue_vue_type_script_setup_true_lang-DsdQmLq6.js +56 -0
  45. package/dist/{SwitchField.vue_vue_type_script_setup_true_lang-BMA2YXTZ.js → SwitchField.vue_vue_type_script_setup_true_lang-Ds4q0bbl.js} +1 -1
  46. package/dist/{TextField.vue_vue_type_script_setup_true_lang-BFVsqcBX.js → TextField.vue_vue_type_script_setup_true_lang-CWIeeZRE.js} +2 -2
  47. package/dist/{TextareaField.vue_vue_type_script_setup_true_lang-Dyh4Hhyl.js → TextareaField.vue_vue_type_script_setup_true_lang-D2j4s96s.js} +1 -1
  48. package/dist/{TimeField.vue_vue_type_script_setup_true_lang-gGFfQLuK.js → TimeField.vue_vue_type_script_setup_true_lang-D-Em4glH.js} +1 -1
  49. package/dist/UserRecord-BW-gdCqi.js +202 -0
  50. package/dist/UsersList-B3ZF_1Dj.js +74 -0
  51. package/dist/access/index.js +4 -4
  52. package/dist/app/index.d.ts +1 -0
  53. package/dist/app/index.js +11 -10
  54. package/dist/app/languages.d.ts +8 -0
  55. package/dist/{application-BmXW6iW_.js → application-CuzT-0vW.js} +1 -1
  56. package/dist/button/index.js +6 -5
  57. package/dist/collection/Highlight.vue.d.ts +12 -0
  58. package/dist/collection/PickerModal.vue.d.ts +26 -0
  59. package/dist/collection/definition.d.ts +6 -6
  60. package/dist/collection/http.d.ts +6 -6
  61. package/dist/collection/index.d.ts +6 -1
  62. package/dist/collection/index.js +145 -85
  63. package/dist/collection/picker.d.ts +39 -0
  64. package/dist/collection/types.d.ts +9 -4
  65. package/dist/collection/useCollection.d.ts +5 -5
  66. package/dist/content/ActivityStream.vue.d.ts +62 -0
  67. package/dist/content/CommentThread.vue.d.ts +52 -0
  68. package/dist/content/Composer.vue.d.ts +36 -0
  69. package/dist/content/index.d.ts +3 -0
  70. package/dist/content/index.js +321 -56
  71. package/dist/controls/index.js +28 -54
  72. package/dist/form/index.js +132 -134
  73. package/dist/format/index.d.ts +1 -0
  74. package/dist/format/index.js +10 -6
  75. package/dist/format/slug.d.ts +8 -0
  76. package/dist/http-Dm0uXY9O.js +95 -0
  77. package/dist/i18n/index.d.ts +15 -0
  78. package/dist/i18n/index.js +89 -63
  79. package/dist/i18n/plural.d.ts +23 -0
  80. package/dist/i18n/serverMessages.d.ts +16 -0
  81. package/dist/identity/embed.d.ts +39 -0
  82. package/dist/identity/index.d.ts +22 -1
  83. package/dist/identity/index.js +40 -21
  84. package/dist/identity/session.d.ts +9 -1
  85. package/dist/identity/shared/ChangeFeed.vue.d.ts +6 -3
  86. package/dist/identity/users/context.d.ts +11 -0
  87. package/dist/identity/users/dialogs.d.ts +10 -0
  88. package/dist/identity/users/ext.d.ts +8 -0
  89. package/dist/identity/users/feature.d.ts +22 -1
  90. package/dist/identity/users/list.d.ts +12 -1
  91. package/dist/identity/users/personSections.d.ts +15 -6
  92. package/dist/identity/users/replace.d.ts +45 -0
  93. package/dist/identity/users/words.d.ts +28 -0
  94. package/dist/incidents/api.d.ts +1 -1
  95. package/dist/incidents/index.js +1 -1
  96. package/dist/{index-Dz0LkLM8.js → index-ClJeyW3F.js} +4 -4
  97. package/dist/index-Cq9TuOqH.js +1264 -0
  98. package/dist/{index-Dm-sdJJr.js → index-kEHY7hcG.js} +31 -32
  99. package/dist/index.d.ts +1 -1
  100. package/dist/index.js +1 -1
  101. package/dist/keepAlive-ClGnsIzT.js +55 -0
  102. package/dist/modal/index.js +3 -3
  103. package/dist/modules/identity/entities.d.ts +7 -0
  104. package/dist/modules/identity/routes.d.ts +8 -4
  105. package/dist/modules/identity/schemas.d.ts +16 -0
  106. package/dist/{neighbors-DVfU9T0o.js → neighbors-OyvGi233.js} +2 -2
  107. package/dist/notifications/deadletters/list.d.ts +1 -1
  108. package/dist/notifications/index.js +1 -1
  109. package/dist/{options-QuOkMKVZ.js → options-B48UiYsG.js} +2 -2
  110. package/dist/page/index.js +11 -11
  111. package/dist/phone/index.js +1 -1
  112. package/dist/pwa/AndroidInstallBanner.vue.d.ts +18 -0
  113. package/dist/pwa/InstallQrSheet.vue.d.ts +21 -0
  114. package/dist/pwa/IosInstallGuide.vue.d.ts +19 -0
  115. package/dist/pwa/QrCode.vue.d.ts +16 -0
  116. package/dist/pwa/index.d.ts +4 -0
  117. package/dist/pwa/index.js +244 -24
  118. package/dist/resource/index.js +1 -1
  119. package/dist/rowLayout-BsKEzEME.js +650 -0
  120. package/dist/shell/DarkModeRow.vue.d.ts +15 -0
  121. package/dist/shell/OfflineNotice.vue.d.ts +2 -0
  122. package/dist/shell/QuickSearchButton.vue.d.ts +2 -0
  123. package/dist/shell/QuickSearchPalette.vue.d.ts +12 -0
  124. package/dist/shell/darkMode.d.ts +26 -0
  125. package/dist/shell/index.d.ts +10 -0
  126. package/dist/shell/index.js +954 -579
  127. package/dist/shell/offlineNotice.d.ts +3 -0
  128. package/dist/shell/quickSearch.d.ts +14 -0
  129. package/dist/shell/quickSearchControl.d.ts +69 -0
  130. package/dist/shortcut-DUR6yPWA.js +93 -0
  131. package/dist/state/BackgroundTaskCapsule.vue.d.ts +18 -0
  132. package/dist/state/backgroundTasks.d.ts +58 -0
  133. package/dist/state/index.d.ts +4 -0
  134. package/dist/state/index.js +194 -80
  135. package/dist/state/useCountUp.d.ts +9 -0
  136. package/dist/styles.css +1 -1
  137. package/dist/{suggestions-BVQhoXzS.js → suggestions-q_v3M7G6.js} +1 -1
  138. package/dist/testing/collection.d.ts +1 -1
  139. package/dist/{useCommand-Dc8Lgs9h.js → useCommand-Ch_nx1AQ.js} +4 -4
  140. package/dist/{useGroupSheet-DQ6cVG-z.js → useGroupSheet-CPjHydQV.js} +14 -15
  141. package/dist/{useRecordDialog-BTsbHY38.js → useRecordDialog-DdkauXnU.js} +1 -1
  142. package/dist/{useResourceForm-DJ4Q75pq.js → useResourceForm-Dl6YFYyz.js} +1 -1
  143. package/package.json +3 -2
  144. package/dist/ActionRow.vue_vue_type_script_setup_true_lang-Cg1lhpcA.js +0 -45
  145. package/dist/Activity-29hsZ28j.js +0 -156
  146. package/dist/Button.vue_vue_type_script_setup_true_lang-Dp7OB-eF.js +0 -192
  147. package/dist/Changes-Dxjdkd_5.js +0 -129
  148. package/dist/FormErrors.vue_vue_type_script_setup_true_lang-CIggKPtq.js +0 -295
  149. package/dist/FormGroup.vue_vue_type_script_setup_true_lang-B37dixvJ.js +0 -137
  150. package/dist/PageBar.vue_vue_type_script_setup_true_lang-qI94fjJv.js +0 -47
  151. package/dist/ProfilePage-BnohZIEg.js +0 -764
  152. package/dist/ProgressTrack.vue_vue_type_script_setup_true_lang-B6Prw9hi.js +0 -64
  153. package/dist/SectionIntro.vue_vue_type_script_setup_true_lang-CZtPrmXD.js +0 -23
  154. package/dist/SessionList.vue_vue_type_script_setup_true_lang-Cnyt5V8T.js +0 -133
  155. package/dist/SignIns-BcqBgWgN.js +0 -121
  156. package/dist/UserRecord-CtUPpbCt.js +0 -267
  157. package/dist/UsersList-BMkIgIg8.js +0 -155
  158. package/dist/definition-C7QuyV3i.js +0 -54
  159. package/dist/http-nz92KjdS.js +0 -42
  160. package/dist/identity/fieldMessages.d.ts +0 -15
  161. package/dist/identity/users/languages.d.ts +0 -4
  162. package/dist/index-CdtofdcJ.js +0 -501
  163. package/dist/keepAlive-z3IRFkQq.js +0 -46
  164. package/dist/languages-BShG9LpE.js +0 -10
  165. package/dist/rowLayout-CT8vWYgI.js +0 -663
  166. package/dist/signInEvents-DWShrJox.js +0 -30
  167. package/dist/status-BRA14qwX.js +0 -34
  168. package/dist/useWaitStatus-fsacMl4W.js +0 -24
  169. /package/dist/{fieldMessages-B6GHgi40.js → serverMessages-B6GHgi40.js} +0 -0
@@ -0,0 +1,23 @@
1
+ import type { PluralizationRule } from "vue-i18n";
2
+ /**
3
+ * Plural rules for the Slavic locales the library ships, ready for `pluralRules` of `createApplication`
4
+ * (or of `createI18n`). vue-i18n picks the form of `t("key", { count })` by the index a rule returns
5
+ * for the number of forms the message has, so the message is written in the order of its layout:
6
+ *
7
+ * | forms | layout | hr, bs, sr-Latn | sl |
8
+ * |-------|-----------------------------------|----------------------------------|-------------------------------|
9
+ * | 2 | one \| other | 1, 21, 101 … / the rest | 1, 101 … / the rest |
10
+ * | 3 | none \| one \| other | 0 / 1, 21 … / the rest | the same |
11
+ * | 4 | none \| one \| few \| other | + 2-4, 22-24 … (not 12-14) | + 2-4, 102-104 … (two is few) |
12
+ * | 5 | none \| one \| two \| few \| other | as 4 (no dual: two is few) | + 2, 102 … / 3-4, 103 … |
13
+ *
14
+ * "{count} osoba | {count} osoba | {count} osobe | {count} osoba" // hr: none | one | few | other
15
+ * createApplication({ pluralRules: slavicPluralRules, … })
16
+ */
17
+ export type PluralCategory = "none" | "one" | "two" | "few" | "other";
18
+ /** Croatian, Bosnian and Serbian: one (1, 21, 101 …), few (2-4, 22-24 …), other (5-20, 25 …; 111-114 …). */
19
+ export declare const slavicPluralRule: PluralizationRule;
20
+ /** Slovenian: one (1, 101 …), two (2, 102 …), few (3-4, 103-104 …), other (5-100 …); without a dual form two is few. */
21
+ export declare const slovenianPluralRule: PluralizationRule;
22
+ /** The rules of every locale the library ships a Slavic language for, by vue-i18n locale code. */
23
+ export declare const slavicPluralRules: Readonly<Record<"hr" | "bs" | "sr-Latn" | "sl", PluralizationRule>>;
@@ -0,0 +1,16 @@
1
+ import type { FormFailureKind } from "../form";
2
+ /**
3
+ * What a form needs to speak any go-core refusal, in the app's language (an app's `errors.<reason>` first, then
4
+ * `core.errors.<reason>`): the reason of a field (`identity.email.taken`) becomes a sentence (`describeFieldError`); a refusal of
5
+ * the whole action (a veto of the application's hook, a lock) says its reason instead of the generic line (`failureMessage`); a
6
+ * time a lock ends (`locked_until`) reads as a time of day. Spread into `useForm` / `useCommand`, or call `failureMessage(kind, error)`
7
+ * inside an `failureMessage` of your own to put the application's refusals first; `sentence` is the same for a toast or a line of your own:
8
+ *
9
+ * const messages = useServerMessages();
10
+ * useForm({ ...messages, failureMessage: (kind, error) => myRefusal(error) ?? messages.failureMessage(kind, error), defaults, validator });
11
+ */
12
+ export declare function useServerMessages(): {
13
+ sentence: (error: unknown, fallback?: string) => string;
14
+ describeFieldError: (message: string) => string;
15
+ failureMessage: (kind: FormFailureKind, error: unknown) => string | undefined;
16
+ };
@@ -0,0 +1,39 @@
1
+ import { type HttpClient } from "../client";
2
+ import { type SessionAdapter, type SessionUser, type UserParser } from "../platform";
3
+ /** Where an embed session keeps its token: the part of `Storage` it uses. */
4
+ export type EmbedStorage = Pick<Storage, "getItem" | "setItem" | "removeItem">;
5
+ export interface EmbedSessionOptions {
6
+ /** Default `sessionStorage`: tab-scoped and same-origin, which a cross-origin iframe's browser (Safari's tracking prevention) still allows where cookies and `localStorage` are blocked. */
7
+ storage?: EmbedStorage;
8
+ /** The storage key of the token. Default `embed_access_token`. */
9
+ tokenKey?: string;
10
+ /** The storage key of the moment the token ends (an ISO date). Default `embed_expires_at`. */
11
+ expiresKey?: string;
12
+ }
13
+ /**
14
+ * A session an iframe's host page hands over as a bearer token (the cookies of an embedded page are blocked): kept in
15
+ * the tab's storage, sent as `Authorization: Bearer`, and not renewable, as there is no refresh token. The page that
16
+ * receives the token calls `start`; everything else is wired by `identityPlatform({ embed })`.
17
+ */
18
+ export interface EmbedSession {
19
+ /** Keeps the token the server handed out, and the moment it ends. */
20
+ start(token: string, expiresAt: string): void;
21
+ /** Forgets the token: the page goes back to the cookie session, if there is one. */
22
+ end(): void;
23
+ /** The token, or null when there is none (or the storage is not available). */
24
+ token(): string | null;
25
+ /** Whether an embed token is held; the session then cannot be renewed. */
26
+ active(): boolean;
27
+ /** Whether the held token has run out (a missing end counts as run out). */
28
+ expired(): boolean;
29
+ }
30
+ /** The embed session over the tab's storage; a storage that throws (blocked, private mode) reads as no session and keeps nothing. */
31
+ export declare function embedSession(options?: EmbedSessionOptions): EmbedSession;
32
+ /** The headers every request carries for an embed session: the bearer token, or none. */
33
+ export declare const embedHeaders: (embed: EmbedSession) => () => Record<string, string>;
34
+ /**
35
+ * The session adapter while an embed token is held: read with the bearer token (`/auth/me`, no refresh), none when the
36
+ * token ran out or is refused (and then forgotten); sign-out ends the server's session and forgets the token. Without a
37
+ * token it is the cookie session `inner`.
38
+ */
39
+ export declare function embeddedSessionAdapter<U extends SessionUser>(inner: SessionAdapter<U>, http: HttpClient, parseUser: UserParser<U>, embed: EmbedSession): SessionAdapter<U>;
@@ -5,9 +5,30 @@ export { identityFeature } from "./feature";
5
5
  export type { IdentityFeatureOptions } from "./feature";
6
6
  export { identityPlatform, identitySessionAdapter } from "./session";
7
7
  export type { IdentityPlatformOptions } from "./session";
8
+ export { embedHeaders, embedSession } from "./embed";
9
+ export type { EmbedSession, EmbedSessionOptions, EmbedStorage } from "./embed";
8
10
  export { usersFeature } from "./users/feature";
9
11
  export type { UsersFeatureOptions } from "./users/feature";
10
- export type { PersonSection } from "./users/personSections";
12
+ export type { BuiltInPersonSection, PersonSection } from "./users/personSections";
13
+ export type { UsersReplace, NewUserDialogHandle, NewUserDialogEmits, DeactivateDialogProps, DeactivateDialogHandle, DeactivateDialogEmits } from "./users/replace";
14
+ export type { ActivityRecord, ChangeDetail, ChangeWords, ChangeWordsFn, Translate } from "./users/words";
15
+ export type { OpenChangeRow } from "./users/ext";
16
+ export { PERSON, personActionsKey, usePersonActions, usePersonSessions } from "./users/person";
17
+ export type { PersonActions } from "./users/person";
18
+ export { useUsersContext } from "./users/context";
19
+ export type { UsersContext } from "./users/context";
20
+ export { useUserDialogs } from "./users/dialogs";
21
+ export { USER_VIEWS, userList } from "./users/list";
22
+ export type { UsersCollection } from "./users/list";
23
+ export { default as NewUserDialog } from "./users/NewUserDialog.vue";
24
+ export { default as DeactivateDialog } from "./users/DeactivateDialog.vue";
25
+ export { statusTone } from "./users/status";
26
+ export { default as PageBar } from "./shared/PageBar.vue";
27
+ export { default as SectionIntro } from "./shared/SectionIntro.vue";
28
+ export { default as SessionList } from "./shared/SessionList.vue";
29
+ export { default as SignInList } from "./shared/SignInList.vue";
30
+ export { default as SignInTable } from "./shared/SignInTable.vue";
31
+ export { default as ChangeFeed } from "./shared/ChangeFeed.vue";
11
32
  export type { ProfilePanel, ProfileSection } from "./profile/profileSections";
12
33
  export { profileRoutes } from "./profile/routes";
13
34
  export { usersRoutes } from "./users/routes";
@@ -1,23 +1,42 @@
1
- import { _ as t, k as a, l as o, i as n, m as i, d as r, n as u, o as c, q as d, r as A, t as p, s as R, v as f, w as l, x as m, g as y } from "../index-CdtofdcJ.js";
2
- import { _ as v } from "../ActionRow.vue_vue_type_script_setup_true_lang-Cg1lhpcA.js";
3
- import { s as I } from "../routes-Beyr5NQo.js";
1
+ import { m as a, v as t, w as n, P as o, l as i, j as r, _ as u, t as c, k as d, U as S, x as g, y as A, z as l, A as I, i as p, B as R, g as m, C as y, D as U, r as f, E as P, F as v, G as x, p as D, H as E, I as F, s as b, e as w, h as B, b as C, f as L, J as T, K as _, c as h } from "../index-Cq9TuOqH.js";
2
+ import { a as H, _ as K } from "../ActionRow.vue_vue_type_script_setup_true_lang-DybAIOHS.js";
3
+ import { s as O } from "../routes-Beyr5NQo.js";
4
4
  export {
5
- v as ActionRow,
6
- t as SignInAsButton,
7
- a as identityFeature,
8
- o as identityPlatform,
9
- n as identityRoutes,
10
- i as identitySessionAdapter,
11
- r as isSessionEnded,
12
- u as lockedUntil,
13
- c as parseIdentityUser,
14
- d as profileRoutes,
15
- A as returnToOwnAccount,
16
- p as serviceAccountsFeature,
17
- R as serviceAccountsRoutes,
18
- I as serviceaccountRoutes,
19
- f as signIn,
20
- l as signInAs,
21
- m as usersFeature,
22
- y as usersRoutes
5
+ H as ActionRow,
6
+ a as ChangeFeed,
7
+ t as DeactivateDialog,
8
+ n as NewUserDialog,
9
+ o as PERSON,
10
+ i as PageBar,
11
+ K as SectionIntro,
12
+ r as SessionList,
13
+ u as SignInAsButton,
14
+ c as SignInList,
15
+ d as SignInTable,
16
+ S as USER_VIEWS,
17
+ g as embedHeaders,
18
+ A as embedSession,
19
+ l as identityFeature,
20
+ I as identityPlatform,
21
+ p as identityRoutes,
22
+ R as identitySessionAdapter,
23
+ m as isSessionEnded,
24
+ y as lockedUntil,
25
+ U as parseIdentityUser,
26
+ f as personActionsKey,
27
+ P as profileRoutes,
28
+ v as returnToOwnAccount,
29
+ x as serviceAccountsFeature,
30
+ D as serviceAccountsRoutes,
31
+ O as serviceaccountRoutes,
32
+ E as signIn,
33
+ F as signInAs,
34
+ b as statusTone,
35
+ w as usePersonActions,
36
+ B as usePersonSessions,
37
+ C as useUserDialogs,
38
+ L as useUsersContext,
39
+ T as userList,
40
+ _ as usersFeature,
41
+ h as usersRoutes
23
42
  };
@@ -1,6 +1,7 @@
1
1
  import { type HttpClient } from "../client";
2
2
  import { type PlatformOptions, type SessionAdapter, type SessionUser, type UserParser } from "../platform";
3
3
  import type { BootstrapConfig } from "../platform";
4
+ import { type EmbedSession } from "./embed";
4
5
  import { type IdentityUser } from "./user";
5
6
  /**
6
7
  * The session over go-core's identity routes: `GET /v1/auth/me`; when that says 401 (the access token ran
@@ -8,13 +9,20 @@ import { type IdentityUser } from "./user";
8
9
  */
9
10
  export declare function identitySessionAdapter<U extends SessionUser>(http: HttpClient, parseUser: UserParser<U>): SessionAdapter<U>;
10
11
  /** What `createPlatform` is given to run on go-core's identity module. */
11
- export type IdentityPlatformOptions<U extends SessionUser> = Required<Pick<PlatformOptions<U, BootstrapConfig>, "session" | "renewSession">> & Pick<PlatformOptions<U, BootstrapConfig>, "renewable">;
12
+ export type IdentityPlatformOptions<U extends SessionUser> = Required<Pick<PlatformOptions<U, BootstrapConfig>, "session" | "renewSession">> & Pick<PlatformOptions<U, BootstrapConfig>, "renewable" | "headers" | "onSessionExpired">;
12
13
  /** What `identityPlatform` takes. */
13
14
  export interface IdentityPlatformInput<U extends SessionUser> {
14
15
  /** The application's own user projection; see `identityPlatform`. */
15
16
  parseUser?: UserParser<U>;
16
17
  /** False while the session has no refresh token (an embed bearer session): nothing renews it, a 401 ends it. See `PlatformOptions.renewable`. */
17
18
  renewable?: () => boolean;
19
+ /**
20
+ * A session handed over as a bearer token (an iframe whose cookies are blocked): while one is held the requests carry it,
21
+ * the session is read with it and cannot be renewed, a refused or run-out token is forgotten, and signing out forgets
22
+ * it. It sets `headers` and `onSessionExpired` of the platform, so spread `identityPlatform()` first and, when you set
23
+ * either yourself, keep the embed's part (`embed.end()` on expiry, `embedHeaders(embed)`).
24
+ */
25
+ embed?: EmbedSession;
18
26
  }
19
27
  /**
20
28
  * The platform options that wire the session to go-core's identity routes: reading it (`/auth/me`, with one
@@ -1,11 +1,14 @@
1
- import type { ChangeRow } from "../../modules/identity/entities";
1
+ import type { OpenChangeRow } from "../users/ext";
2
+ import type { ChangeWordsFn } from "../users/words";
2
3
  /**
3
4
  * What was changed on a person's account, newest first, one sentence per change ("Details changed", "Password changed"),
4
5
  * with who did it (by the name the row carries, "somebody else" when the person is gone; nothing when it was the person themselves), what changed from what to what, and when. An action or a
5
- * field this version does not know reads as a generic one, never as its key; a password is never shown.
6
+ * field this version does not know reads as a generic one, never as its key; a password is never shown. `words` is the
7
+ * application's own wording (`usersFeature({ changeWords })`): its sentence replaces the library's, its details follow them.
6
8
  */
7
9
  type __VLS_Props = {
8
- rows: readonly ChangeRow[];
10
+ rows: readonly OpenChangeRow[];
11
+ words?: ChangeWordsFn;
9
12
  };
10
13
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
14
  export default _default;
@@ -1,5 +1,8 @@
1
1
  import type { ProfileSection } from "../profile/profileSections";
2
2
  import { type Permission } from "../../platform";
3
+ import type { UsersCollection } from "./list";
4
+ import type { UsersReplace } from "./replace";
5
+ import type { ActivityRecord, ChangeWordsFn } from "./words";
3
6
  /** What the screens of `usersFeature` need from the feature that installed them. */
4
7
  export interface UsersContext {
5
8
  /** The permission that shows "Sign in as" on a person's record; false leaves it out. */
@@ -8,5 +11,13 @@ export interface UsersContext {
8
11
  readonly activityAreas: Readonly<Record<string, string>>;
9
12
  /** The panels the application adds to "My profile". */
10
13
  readonly profileSections: readonly ProfileSection[];
14
+ /** The screens the application swapped for its own (`useUserDialogs()` resolves the dialogs). */
15
+ readonly replace: UsersReplace;
16
+ /** The application's definition of the list, used by the list page and the record's previous / next; without it `userList`. */
17
+ readonly collection: UsersCollection | undefined;
18
+ /** The records the Activity section names and links, by the server's `record_type`. */
19
+ readonly activityRecords: Readonly<Record<string, ActivityRecord>>;
20
+ /** The application's wording of a change; without it the library's. */
21
+ readonly changeWords: ChangeWordsFn | undefined;
11
22
  }
12
23
  export declare const usersContextKey: import("vue").InjectionKey<UsersContext>, useUsersContext: () => UsersContext;
@@ -0,0 +1,10 @@
1
+ import type { Component } from "vue";
2
+ /**
3
+ * The New user and Deactivate dialogs the screens use: the application's (`usersFeature({ replace })`) or the library's. A
4
+ * replaced list or record mounts these, so one replacement of a dialog serves every screen. Use them through a template ref
5
+ * (`NewUserDialogHandle`, `DeactivateDialogHandle`).
6
+ */
7
+ export declare function useUserDialogs(): {
8
+ newUser: Component;
9
+ deactivate: Component;
10
+ };
@@ -0,0 +1,8 @@
1
+ import type { ChangeRow } from "../../modules/identity/entities";
2
+ /**
3
+ * A change as the server's change log writes it: go-core's `ChangeRow` (with its `ext`), except that the `action` can be one
4
+ * go-core does not know (a role granted, a binding changed), which the application words with `changeWords`.
5
+ */
6
+ export type OpenChangeRow = Omit<ChangeRow, "action"> & {
7
+ action: ChangeRow["action"] | (string & {});
8
+ };
@@ -2,7 +2,10 @@ import { type Feature } from "../../app";
2
2
  import type { Permission } from "../../platform";
3
3
  import type { Destination } from "../../router";
4
4
  import type { ProfileSection } from "../profile/profileSections";
5
+ import type { UsersCollection } from "./list";
5
6
  import { type PersonSection } from "./personSections";
7
+ import type { UsersReplace } from "./replace";
8
+ import type { ActivityRecord, ChangeWordsFn } from "./words";
6
9
  export interface UsersFeatureOptions {
7
10
  /** The users list and a person's record (`/users`), for whoever holds `iam.user:view`. Default true. */
8
11
  people?: boolean;
@@ -12,12 +15,30 @@ export interface UsersFeatureOptions {
12
15
  signInAs?: Permission | false;
13
16
  /** Names of the application's areas in a person's Activity: the area key the audit records (`crm`) and the i18n key of its name. `all`, `identity` and `other` are the library's. An area without a key reads as "Other". */
14
17
  activityAreas?: Readonly<Record<string, string>>;
15
- /** Sections the application adds to a person's record after the feature's own (their roles); each is a child route `users.record.<path>`. */
18
+ /** Sections the application adds to a person's record (their roles), at the end or, with `after`, behind a built-in one; each is a child route `users.record.<path>`. */
16
19
  sections?: readonly PersonSection[];
17
20
  /** Panels the application adds to "My profile" (mobile phone, dealer and location, preferences), each placed after or before a built-in panel. */
18
21
  profileSections?: readonly ProfileSection[];
19
22
  /** The destination of the backend's menu that opens the users list. Without it the application binds the list itself. */
20
23
  destination?: Destination;
24
+ /** The base path of the list; a record is `<path>/:id`. Default `/users`. The route names stay (`users.index`, `users.record`), so links by name follow it. */
25
+ path?: `/${string}`;
26
+ /** Whole screens the application swaps for its own, each keeping the contract documented on `UsersReplace`: the list, the details section, the New user and the Deactivate dialogs. */
27
+ replace?: UsersReplace;
28
+ /**
29
+ * The one definition of the people list, for the list page and for the previous / next of a person's record, so both ask the
30
+ * server the same question. Default `userList` (the library's). An application whose list filters people by more than the
31
+ * library knows (a dealer, a role) passes its own collection: the very definition its `replace.list` page calls `useCollection`
32
+ * on, since the record replays the state that page wrote into the link. A definition, not a factory: the application builds it
33
+ * once, with its own client; the library's default is built from the platform's.
34
+ *
35
+ * usersFeature({ collection: peopleList, replace: { list: PeopleList } }) // peopleList = defineCollection({ id: "identity.users", …, query: { filters: ["dealer_id", "role"] } })
36
+ */
37
+ collection?: UsersCollection;
38
+ /** What the Activity section calls and links the records the application knows, by the server's `record_type`; an unknown type reads as the type itself. */
39
+ activityRecords?: Readonly<Record<string, ActivityRecord>>;
40
+ /** The application's wording for a change (sentence and details, with links), asked for every row of the Changes section with its `ext`; the library words what it returns nothing for. */
41
+ changeWords?: ChangeWordsFn;
21
42
  }
22
43
  /**
23
44
  * The screens of go-core's users and profile routes, one feature to install:
@@ -1,8 +1,19 @@
1
1
  import type { HttpClient } from "../../client";
2
+ import { type CollectionDefinition } from "../../collection";
2
3
  /** The views of the list, as go-core's `GET /v1/iam/users` knows them. */
3
4
  export declare const USER_VIEWS: readonly ["active", "locked", "inactive", "all"];
5
+ /**
6
+ * The definition of the people list that `usersFeature({ collection })` takes: any collection of people, with the sorts and
7
+ * filters the application's server accepts. Its rows must carry what the screens read of a `UserRow`.
8
+ */
9
+ export type UsersCollection = CollectionDefinition<any, any, any, any>;
4
10
  /**
5
11
  * The list of people, one definition for the list page and for the previous / next of a person's record, so both ask
6
12
  * the server the same question. The sorts and views are the ones go-core accepts.
7
13
  */
8
- export declare function userList(http: HttpClient): import("../../collection").CollectionDefinition<import("..").UserRow, "name" | "email" | "login" | "created_at", never, "inactive" | "all" | "locked" | "active">;
14
+ export declare function userList(http: HttpClient): CollectionDefinition<import("..").UserRow, "name" | "email" | "login" | "created_at", "last_sign_in", "inactive" | "all" | "locked" | "active", Readonly<Record<string, unknown>>>;
15
+ /**
16
+ * The definition the users screens ask the list with: the application's (`usersFeature({ collection })`) or `userList`. The list
17
+ * page and the previous / next of a record both call it, so they ask the server the same question.
18
+ */
19
+ export declare function useUserList(): ReturnType<typeof userList>;
@@ -1,16 +1,22 @@
1
1
  import { type Component } from "vue";
2
2
  import type { RouteRecordRaw } from "vue-router";
3
- import type { UserDetail } from "../../modules/identity/entities";
4
3
  import type { AccessRequirement, RouteSection } from "../../router";
4
+ import type { UserDetail } from "../../modules/identity/entities";
5
+ /** The paths of the sections the feature's own record has, in order; what `PersonSection.after` can name. */
6
+ export declare const PERSON_SECTIONS: readonly ["general", "signin", "sessions", "signins", "changes", "activity"];
7
+ export type BuiltInPersonSection = (typeof PERSON_SECTIONS)[number];
5
8
  /**
6
- * A section the application adds to a person's record (their roles, say), listed after the feature's own. The component
7
- * gets what `props` makes of the loaded person; `meta` is the section's route meta (its label, icon and `access`).
9
+ * A section the application adds to a person's record (their roles, say). The component gets what `props` makes of the loaded
10
+ * person; `meta` is the section's route meta (its label, icon and `access`). It is listed after the feature's own, or, with
11
+ * `after`, right behind one of them and in that one's group (`meta.section.groupKey` is then the group's):
8
12
  *
9
- * usersFeature({ sections: [{ path: "roles", component: PersonAccess, props: (p) => ({ subject: { kind: "user", id: p.id }, name: p.name }), meta: personRolesSection }] })
13
+ * usersFeature({ sections: [{ path: "roles", after: "signin", component: PersonAccess, props: (p) => ({ subject: { kind: "user", id: p.id }, name: p.name }), meta: personRolesSection }] })
10
14
  */
11
15
  export interface PersonSection {
12
16
  /** The child route's path under `/users/:id/` and its name suffix (`users.record.<path>`): one lowercase word. */
13
17
  readonly path: string;
18
+ /** Places the section right after this built-in one, in its group (Sign-in is in "Access", so a section after it is too). Several after the same one keep their order. Without it: at the end. */
19
+ readonly after?: BuiltInPersonSection;
14
20
  readonly component: Component;
15
21
  readonly props?: (person: UserDetail) => Record<string, unknown>;
16
22
  readonly meta: {
@@ -18,5 +24,8 @@ export interface PersonSection {
18
24
  readonly section: RouteSection;
19
25
  };
20
26
  }
21
- /** The child route of the record for an extra section. */
22
- export declare function personSectionRoute(section: PersonSection): RouteRecordRaw;
27
+ /**
28
+ * The record's children with the application's sections in place: behind the built-in one they name, in its group, or at the
29
+ * end. A name that is not a built-in section is a start-up error that lists the valid ones.
30
+ */
31
+ export declare function withPersonSections(children: readonly RouteRecordRaw[], sections: readonly PersonSection[]): RouteRecordRaw[];
@@ -0,0 +1,45 @@
1
+ import type { Component } from "vue";
2
+ import type { UserDetail } from "../../modules/identity/entities";
3
+ /**
4
+ * Whole screens of `usersFeature` an application swaps for its own, with the contract each one keeps. A replacement is
5
+ * mounted where the built-in was, with the same props and events, and finds the same context: `usePlatform()`, the record
6
+ * (`useRouteResourceContext(PERSON)`), the actions (`usePersonActions()`), `useUsersContext()`, the collection (`userList`),
7
+ * and the shared pieces exported beside them.
8
+ */
9
+ export interface UsersReplace {
10
+ /** The users list, the page of `users.index`. No props. Open the New user dialog with `useUserDialogs().newUser`. */
11
+ readonly list?: Component;
12
+ /** The "Basic details" section of a person's record (`users.record.general`). No props; reads the person with `useRouteResourceContext(PERSON)`, and its save chrome and rows are its own. */
13
+ readonly general?: Component;
14
+ /** The New user dialog: no props, emits `created` with the new person, exposes `create()` (a `NewUserDialogHandle`). */
15
+ readonly newUser?: Component;
16
+ /** The Deactivate dialog: props `DeactivateDialogProps`, emits `done` after it deactivated, exposes `open()` (a `DeactivateDialogHandle`). */
17
+ readonly deactivate?: Component;
18
+ }
19
+ /** What the users list and any other screen call on the New user dialog (`replace.newUser`), through a template ref. */
20
+ export interface NewUserDialogHandle {
21
+ /** Opens the dialog on an empty form. */
22
+ create(): void;
23
+ }
24
+ /** The events of the New user dialog. */
25
+ export interface NewUserDialogEmits {
26
+ /** The person was created; the list opens their record. */
27
+ created: [user: UserDetail];
28
+ }
29
+ /** The props of the Deactivate dialog (`replace.deactivate`). */
30
+ export interface DeactivateDialogProps {
31
+ readonly id: number;
32
+ readonly name: string;
33
+ /** How many sessions the person has now; null while they are being counted. */
34
+ readonly sessionCount: number | null;
35
+ }
36
+ /** What the record page calls on the Deactivate dialog. */
37
+ export interface DeactivateDialogHandle {
38
+ /** Opens the dialog. */
39
+ open(): void;
40
+ }
41
+ /** The events of the Deactivate dialog. */
42
+ export interface DeactivateDialogEmits {
43
+ /** The person was deactivated; the record reloads. */
44
+ done: [];
45
+ }
@@ -0,0 +1,28 @@
1
+ import type { RouteLocationRaw } from "vue-router";
2
+ import type { OpenChangeRow } from "./ext";
3
+ /** Where the Activity section sends a record the application knows: its name (an i18n key) and, when it has a page, the link. */
4
+ export interface ActivityRecord {
5
+ /** The i18n key of the kind of record ("Lead"); shown instead of the server's `record_type`. */
6
+ readonly labelKey: string;
7
+ /** The page of the record with this id; without it the row names the record and does not link. */
8
+ readonly to?: (id: number) => RouteLocationRaw;
9
+ }
10
+ /** A piece of a change's details: plain text, or text that links (a hand-over recipient, a binding). */
11
+ export type ChangeDetail = string | {
12
+ readonly text: string;
13
+ readonly to: RouteLocationRaw;
14
+ };
15
+ /** What the application says about one change in the Changes section; every part left out keeps the library's wording. */
16
+ export interface ChangeWords {
17
+ /** The sentence ("Role granted"), already translated. */
18
+ readonly sentence?: string;
19
+ /** Details after the library's own ("Dealer: A to B"). */
20
+ readonly details?: readonly ChangeDetail[];
21
+ }
22
+ /** `t` as `useI18n()` gives it. */
23
+ export type Translate = (key: string, named?: Record<string, unknown>) => string;
24
+ /**
25
+ * The application's wording for a change: asked for every row (with its `ext`, as the server's change log wrote it); return
26
+ * `undefined` for a row the library already words well. Used by `usersFeature({ changeWords })`.
27
+ */
28
+ export type ChangeWordsFn = (row: OpenChangeRow, t: Translate) => ChangeWords | undefined;
@@ -4,7 +4,7 @@ import type { CommentRequest, ReportInput, UpdateRequest } from "../modules/inci
4
4
  export type IncidentSort = "title" | "last_seen_at";
5
5
  export type IncidentFilter = "created_at" | "status" | "severity" | "source";
6
6
  /** The incident list: last seen first. Made over the platform's client, in `setup`; the list and the record's previous / next share its id. */
7
- export declare function incidentList(http: HttpClient): import("../collection").CollectionDefinition<Incident, IncidentSort, IncidentFilter, string>;
7
+ export declare function incidentList(http: HttpClient): import("../collection").CollectionDefinition<Incident, IncidentSort, IncidentFilter, string, Readonly<Record<string, unknown>>>;
8
8
  /** An incident's page: the incident, the user reports behind it and its comments, from one read. */
9
9
  export interface IncidentDetail {
10
10
  readonly incident: Incident;
@@ -1,4 +1,4 @@
1
- import { h as t, j as i, k as r, l as n, i as a } from "../index-Dm-sdJJr.js";
1
+ import { h as t, j as i, k as r, l as n, i as a } from "../index-kEHY7hcG.js";
2
2
  export {
3
3
  t as MAX_REPORTS_PER_SESSION,
4
4
  i as clientErrorReporter,
@@ -12,10 +12,10 @@ import { _ as ke } from "./Sheet.vue_vue_type_script_setup_true_lang-B91aRD_y.js
12
12
  import { _ as Se } from "./Popover.vue_vue_type_script_setup_true_lang-C20Hf3Hl.js";
13
13
  import { _ as J } from "./HeaderAction.vue_vue_type_script_setup_true_lang-Da59TLBh.js";
14
14
  import { useRouter as Te } from "vue-router";
15
- import { _ as K } from "./Button.vue_vue_type_script_setup_true_lang-Dp7OB-eF.js";
15
+ import { _ as K } from "./Button.vue_vue_type_script_setup_true_lang-C74hcb0N.js";
16
16
  import { u as Ee } from "./format-D8KUBmbS.js";
17
17
  import { _ as Pe } from "./Icon.vue_vue_type_script_lang-BhhsFYwp.js";
18
- import { _ as Ce } from "./AsyncSection.vue_vue_type_script_setup_true_lang-BdeOKqz_.js";
18
+ import { _ as Ce } from "./AsyncSection.vue_vue_type_script_setup_true_lang-DGzQ-Snp.js";
19
19
  const E = {
20
20
  list: v("GET", "/v1/notifications"),
21
21
  unread: v("GET", "/v1/notifications/unread"),
@@ -135,9 +135,9 @@ function Me(n = ee().http, t = W()) {
135
135
  return { state: $(e), hash: $(i), busy: $(a), inspect: c, enable: u, disable: g };
136
136
  }
137
137
  const Ne = "events.deadletter:view", $t = "events.deadletter:retry", Y = te({
138
- index: { name: "events.deadletters", path: "/events/dead-letters", component: () => import("./DeadLetters-Bb5pPlOY.js"), meta: { access: Ne, titleKey: "core.notifications.dead_letters.title" } }
138
+ index: { name: "events.deadletters", path: "/events/dead-letters", component: () => import("./DeadLetters-DnA7LP1w.js"), meta: { access: Ne, titleKey: "core.notifications.dead_letters.title" } }
139
139
  }), j = te({
140
- index: { name: "notifications.settings", path: "/profile/notifications", component: () => import("./SettingsPage-DzDC7gD-.js"), meta: { titleKey: "core.notifications.settings.title" } }
140
+ index: { name: "notifications.settings", path: "/profile/notifications", component: () => import("./SettingsPage-BXPWATYU.js"), meta: { titleKey: "core.notifications.settings.title" } }
141
141
  }), Oe = /* @__PURE__ */ q({
142
142
  __name: "SettingsMenuItem",
143
143
  setup(n) {