@abyss-project/commons-front-core 14.0.0 → 15.0.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 (146) hide show
  1. package/README.md +1 -1
  2. package/dist/{CookieConsentSettings-DyJGEnVA.js → CookieConsentSettings-B7NfjgaI.js} +1 -1
  3. package/dist/{Surface-B_J_I_1i.js → Surface-BEhoEhyC.js} +214 -84
  4. package/dist/{Tabs-_TzugjHZ.js → Tabs-DJ9_ZFjM.js} +649 -644
  5. package/dist/auth/components/AuthFlow/auth-flow.types.d.ts +2 -0
  6. package/dist/auth/components/AuthFlow/steps/MfaEnrollmentStep.component.d.ts +2 -0
  7. package/dist/auth/components/AuthFlow/steps/MfaStep.component.d.ts +10 -4
  8. package/dist/auth/components/AuthFlow/steps/PasskeyNudgeStep.component.d.ts +3 -1
  9. package/dist/auth/components/MfaRequirementBanner/MfaRequirementBanner.component.d.ts +3 -1
  10. package/dist/auth/components/SecuritySettings/SecuritySettings.component.d.ts +1 -1
  11. package/dist/auth/components/SecuritySettings/sections/PasskeysSection.component.d.ts +6 -1
  12. package/dist/auth/components/SecuritySettings/sections/RecoveryCodesSection.component.d.ts +3 -1
  13. package/dist/auth/components/SecuritySettings/sections/TrustedDevicesSection.component.d.ts +6 -0
  14. package/dist/auth/components/index.d.ts +1 -0
  15. package/dist/auth/components/shared/SingleDevicePasskeyAdvice.component.d.ts +13 -0
  16. package/dist/auth/components/shared/passkey-ceremonies.d.ts +6 -1
  17. package/dist/auth/components/shared/support-contact.d.ts +2 -0
  18. package/dist/auth/components/test-support/auth-sdk.mock.d.ts +5 -0
  19. package/dist/auth/components/test-support/auth-test-harness.d.ts +3 -0
  20. package/dist/clsx-OuTLNxxd.js +16 -0
  21. package/dist/components/business/Support/AbyssServiceSelect.component.d.ts +26 -0
  22. package/dist/components/business/Support/SupportActionButtons.component.d.ts +7 -0
  23. package/dist/components/business/Support/SupportActivityLog.component.d.ts +7 -0
  24. package/dist/components/business/Support/SupportAttachmentsPanel.component.d.ts +7 -0
  25. package/dist/components/business/Support/SupportCategoryChip.component.d.ts +12 -0
  26. package/dist/components/business/Support/SupportCategoryGroupCards.component.d.ts +2 -0
  27. package/dist/components/business/Support/SupportCategorySelect.component.d.ts +21 -0
  28. package/dist/components/business/Support/SupportCreateTextField.d.ts +17 -0
  29. package/dist/components/business/Support/SupportMessageAttachment.component.d.ts +9 -0
  30. package/dist/components/business/Support/SupportMessageInput.component.d.ts +7 -0
  31. package/dist/components/business/Support/SupportMessageLink.component.d.ts +8 -0
  32. package/dist/components/business/Support/SupportMessageThread.component.d.ts +8 -0
  33. package/dist/components/business/Support/SupportPill.d.ts +18 -0
  34. package/dist/components/business/Support/SupportPriorityChip.component.d.ts +3 -0
  35. package/dist/components/business/Support/SupportSidebar.component.d.ts +7 -0
  36. package/dist/components/business/Support/SupportStatusBadge.component.d.ts +3 -0
  37. package/dist/components/business/Support/SupportStatusTimeline.component.d.ts +15 -0
  38. package/dist/components/business/Support/SupportSystemMessage.component.d.ts +11 -0
  39. package/dist/components/business/Support/SupportSystemMessage.component.spec.d.ts +1 -0
  40. package/dist/components/business/Support/SupportTagEditor.d.ts +15 -0
  41. package/dist/components/business/Support/SupportTicketCreateForm.component.d.ts +2 -0
  42. package/dist/components/business/Support/SupportTicketCreateForm.component.spec.d.ts +1 -0
  43. package/dist/components/business/Support/SupportTicketCreateStepper.component.d.ts +2 -0
  44. package/dist/components/business/Support/SupportTicketCreateStepper.component.spec.d.ts +1 -0
  45. package/dist/components/business/Support/SupportTicketDetail.component.d.ts +8 -0
  46. package/dist/components/business/Support/SupportTicketDetail.component.spec.d.ts +1 -0
  47. package/dist/components/business/Support/SupportTicketDetail.mobile-layout.spec.d.ts +1 -0
  48. package/dist/components/business/Support/SupportTicketList.component.spec.d.ts +1 -0
  49. package/dist/components/business/Support/SupportTicketList.week-preset.spec.d.ts +1 -0
  50. package/dist/components/business/Support/SupportTicketListFilterBar.d.ts +15 -0
  51. package/dist/components/business/Support/SupportTopBar.component.d.ts +7 -0
  52. package/dist/components/business/Support/support-action.d.ts +17 -0
  53. package/dist/components/business/Support/support-action.logic.d.ts +12 -0
  54. package/dist/components/business/Support/support-action.logic.spec.d.ts +1 -0
  55. package/dist/components/business/Support/support-attachment.logic.spec.d.ts +1 -0
  56. package/dist/components/business/Support/support-author.logic.spec.d.ts +1 -0
  57. package/dist/components/business/Support/support-create-stepper.logic.spec.d.ts +1 -0
  58. package/dist/components/business/Support/support-create.logic.d.ts +28 -0
  59. package/dist/components/business/Support/support-create.logic.spec.d.ts +1 -0
  60. package/dist/components/business/Support/support-message-anchor.d.ts +4 -0
  61. package/dist/components/business/Support/support-message-input.logic.spec.d.ts +1 -0
  62. package/dist/components/business/Support/support-service.logic.spec.d.ts +1 -0
  63. package/dist/components/business/Support/support-status-timeline.logic.spec.d.ts +1 -0
  64. package/dist/components/business/Support/support-tone.d.ts +11 -0
  65. package/dist/components/business/Support/test-support/support-detail.fixtures.d.ts +7 -0
  66. package/dist/components/business/Support/test-support/support-thread.fixtures.d.ts +9 -0
  67. package/dist/{legacy/components → components/business}/Support/types.d.ts +13 -4
  68. package/dist/components/business/Support/use-support-create-error-message.hook.d.ts +4 -0
  69. package/dist/components/business/index.d.ts +20 -0
  70. package/dist/components/inputs/ExpressionSearch/ExpressionSearch.d.ts +6 -1
  71. package/dist/components/inputs/SegmentedControl/SegmentedControl.d.ts +9 -1
  72. package/dist/cookie-consent.js +2 -2
  73. package/dist/design-theme-N9jJSXdK.js +27605 -0
  74. package/dist/{editors-C6Rocm6M.js → editors-QM76tqZI.js} +29 -29
  75. package/dist/editors.js +1 -1
  76. package/dist/hooks/use-rich-intl.hook.d.ts +130 -0
  77. package/dist/{index-DGoR-pBV.js → index-3-SmpH5N.js} +4 -4
  78. package/dist/{index-CuYK_i3Q.js → index-4b2f7sdW.js} +2 -2
  79. package/dist/{index-C1I7MW-q.js → index-5OVR3WNo.js} +3 -3
  80. package/dist/{index-CDWJlhuZ.js → index-BKAfoA1a.js} +2 -2
  81. package/dist/{AbyssCloud-B3rMelRi.js → index-C27b790L.js} +1448 -1017
  82. package/dist/{index-u-EAOYOb.js → index-C6jhogFt.js} +2 -2
  83. package/dist/{index-BI4ooqu1.js → index-CM5COMvb.js} +2 -2
  84. package/dist/{index-5AavH8Oo.js → index-COUUAr5G.js} +1 -1
  85. package/dist/{index-CKJMsjnV.js → index-CQU0eEXk.js} +4 -4
  86. package/dist/{index-DjAZPCEQ.js → index-Ce0rv5wr.js} +3 -3
  87. package/dist/{index-C1GCQ2Ke.js → index-D1M_muSg.js} +2 -2
  88. package/dist/{index-Cskjr11h.js → index-D8ncJrf1.js} +2 -2
  89. package/dist/{index-BElPTqLa.js → index-DA-HUFp6.js} +2 -2
  90. package/dist/{index-UjGNADrL.js → index-DCk0q3d7.js} +3 -3
  91. package/dist/{index-B58_3EoW.js → index-DW3SBSsW.js} +2 -2
  92. package/dist/{index-TshVV9T4.js → index-DYXAfA_s.js} +2 -2
  93. package/dist/{index-CDI4_t7D.js → index-DmAoL9-1.js} +4 -4
  94. package/dist/{index-Czhx2OUB.js → index-Taee9VIc.js} +2 -2
  95. package/dist/{index-Cwgj3j50.js → index-jZGexiyT.js} +3 -3
  96. package/dist/{index-Dutd4cJm.js → index-mmrA4ErC.js} +2 -2
  97. package/dist/{index-BYDMmzla.js → index-nKbvjf2P.js} +2 -2
  98. package/dist/{index-Dym_r-do.js → index-pX3CTxFd.js} +2 -2
  99. package/dist/index.js +13954 -9324
  100. package/dist/legacy/components/index.d.ts +0 -1
  101. package/dist/legacy/legacy-support-removed.spec.d.ts +1 -0
  102. package/dist/legacy.js +5634 -11703
  103. package/dist/theme/index.d.ts +1 -1
  104. package/dist/translations/en.d.ts +65 -0
  105. package/dist/translations/fr.d.ts +65 -0
  106. package/package.json +3 -3
  107. package/dist/clsx-D8ItxkrZ.js +0 -446
  108. package/dist/design-theme-D5L0JNbX.js +0 -26599
  109. package/dist/legacy/components/Support/AbyssServiceSelect.component.d.ts +0 -37
  110. package/dist/legacy/components/Support/SupportActionButtons.component.d.ts +0 -3
  111. package/dist/legacy/components/Support/SupportActivityLog.component.d.ts +0 -3
  112. package/dist/legacy/components/Support/SupportAttachmentsPanel.component.d.ts +0 -3
  113. package/dist/legacy/components/Support/SupportCategoryChip.component.d.ts +0 -9
  114. package/dist/legacy/components/Support/SupportCategoryGroupCards.component.d.ts +0 -3
  115. package/dist/legacy/components/Support/SupportCategorySelect.component.d.ts +0 -22
  116. package/dist/legacy/components/Support/SupportMessageInput.component.d.ts +0 -3
  117. package/dist/legacy/components/Support/SupportMessageThread.component.d.ts +0 -3
  118. package/dist/legacy/components/Support/SupportPriorityChip.component.d.ts +0 -3
  119. package/dist/legacy/components/Support/SupportSidebar.component.d.ts +0 -3
  120. package/dist/legacy/components/Support/SupportStatusBadge.component.d.ts +0 -3
  121. package/dist/legacy/components/Support/SupportStatusTimeline.component.d.ts +0 -10
  122. package/dist/legacy/components/Support/SupportTicketCreateForm.component.d.ts +0 -3
  123. package/dist/legacy/components/Support/SupportTicketCreateStepper.component.d.ts +0 -3
  124. package/dist/legacy/components/Support/SupportTicketDetail.component.d.ts +0 -3
  125. package/dist/legacy/components/Support/SupportTopBar.component.d.ts +0 -3
  126. package/dist/legacy/components/Support/index.d.ts +0 -18
  127. /package/dist/{legacy/components/Support/SupportCategoryPick.component.spec.d.ts → auth/components/AuthFlow/steps/MfaStep.component.spec.d.ts} +0 -0
  128. /package/dist/{legacy/components/Support/SupportMessageLink.component.spec.d.ts → components/business/Support/AbyssServiceSelect.component.spec.d.ts} +0 -0
  129. /package/dist/{legacy/components/Support/SupportSystemMessage.component.spec.d.ts → components/business/Support/SupportActivityLog.component.spec.d.ts} +0 -0
  130. /package/dist/{legacy/components/Support/SupportTicketDetail.mobile-layout.spec.d.ts → components/business/Support/SupportAttachmentsPanel.component.spec.d.ts} +0 -0
  131. /package/dist/{legacy/components/Support/SupportTicketList.week-preset.spec.d.ts → components/business/Support/SupportBadges.spec.d.ts} +0 -0
  132. /package/dist/{legacy/components/Support/support-attachment.logic.spec.d.ts → components/business/Support/SupportCategoryGroupCards.component.spec.d.ts} +0 -0
  133. /package/dist/{legacy/components/Support/support-author.logic.spec.d.ts → components/business/Support/SupportCategorySelect.component.spec.d.ts} +0 -0
  134. /package/dist/{legacy/components/Support/support-create-stepper.logic.spec.d.ts → components/business/Support/SupportMessageInput.component.spec.d.ts} +0 -0
  135. /package/dist/{legacy/components/Support/support-message-input.logic.spec.d.ts → components/business/Support/SupportMessageLink.component.spec.d.ts} +0 -0
  136. /package/dist/{legacy/components/Support/support-service.logic.spec.d.ts → components/business/Support/SupportMessageThread.component.spec.d.ts} +0 -0
  137. /package/dist/{legacy/components/Support/support-status-timeline.logic.spec.d.ts → components/business/Support/SupportSidebar.component.spec.d.ts} +0 -0
  138. /package/dist/{legacy/components → components/business}/Support/SupportTicketList.component.d.ts +0 -0
  139. /package/dist/{legacy/components → components/business}/Support/support-attachment.logic.d.ts +0 -0
  140. /package/dist/{legacy/components → components/business}/Support/support-author.logic.d.ts +0 -0
  141. /package/dist/{legacy/components → components/business}/Support/support-category.logic.d.ts +0 -0
  142. /package/dist/{legacy/components → components/business}/Support/support-create-stepper.logic.d.ts +0 -0
  143. /package/dist/{legacy/components → components/business}/Support/support-message-input.logic.d.ts +0 -0
  144. /package/dist/{legacy/components → components/business}/Support/support-service.logic.d.ts +0 -0
  145. /package/dist/{legacy/components → components/business}/Support/support-status-timeline.logic.d.ts +0 -0
  146. /package/dist/{legacy/components → components/business}/Support/support-system-message.logic.d.ts +0 -0
@@ -52,6 +52,8 @@ export type AuthFlowStep = {
52
52
  kind: AuthFlowStepKind.MFA;
53
53
  challengeToken: string;
54
54
  factors: MfaFactorType[];
55
+ /** The second-factor step may offer "trust this browser for 30 days". */
56
+ trustDeviceAllowed: boolean;
55
57
  } | {
56
58
  kind: AuthFlowStepKind.ENROLLMENT;
57
59
  user: IUser;
@@ -9,5 +9,7 @@ export type MfaEnrollmentStepProps = {
9
9
  * Mandatory set-up of a second factor (an administrator without one, Q6): no skip. Once the factor
10
10
  * exists, the session is re-proven with it — a session only counts as MFA once a second factor was
11
11
  * presented on it — so the admin token is granted right after this step, without signing in again.
12
+ * A passkey that cannot leave its device is followed by a proposal to add an authenticator app,
13
+ * which "Later" declines.
12
14
  */
13
15
  export declare const MfaEnrollmentStep: ({ passkeySupported, onEnrolled, onSignOut, }: MfaEnrollmentStepProps) => import("react/jsx-runtime").JSX.Element;
@@ -8,13 +8,19 @@ export type MfaStepProps = {
8
8
  error: AuthErrorKind | null;
9
9
  /** The passkey sheet was dismissed: the user may try again or pick another factor. */
10
10
  passkeyCancelled: boolean;
11
- onSubmitCode: (factor: MfaFactorType.TOTP | MfaFactorType.RECOVERY_CODE, code: string) => void;
12
- onPasskey: () => void;
11
+ /**
12
+ * The challenge allows "trust this browser for 30 days" (#769): false for an administrator and
13
+ * outside a web browser, where the checkbox is not shown.
14
+ */
15
+ trustDeviceAllowed: boolean;
16
+ onSubmitCode: (factor: MfaFactorType.TOTP | MfaFactorType.RECOVERY_CODE, code: string, trustDevice: boolean) => void;
17
+ onPasskey: (trustDevice: boolean) => void;
13
18
  /** The challenge expired (5 min): back to the e-mail step. */
14
19
  onRestart: () => void;
15
20
  };
16
21
  /**
17
22
  * Second factor of a sign-in proven by password, e-mail code, Google or Apple (D6): authenticator
18
- * code, passkey, or one of the recovery codes (each usable once).
23
+ * code, passkey, or one of the recovery codes (each usable once). A help block, folded until a
24
+ * passkey ceremony is cancelled, tells what to do when the factor is out of reach here.
19
25
  */
20
- export declare const MfaStep: ({ factors, passkeySupported, busy, error, passkeyCancelled, onSubmitCode, onPasskey, onRestart, }: MfaStepProps) => import("react/jsx-runtime").JSX.Element;
26
+ export declare const MfaStep: ({ factors, passkeySupported, busy, error, passkeyCancelled, trustDeviceAllowed, onSubmitCode, onPasskey, onRestart, }: MfaStepProps) => import("react/jsx-runtime").JSX.Element;
@@ -6,6 +6,8 @@ export type PasskeyNudgeStepProps = {
6
6
  };
7
7
  /**
8
8
  * After a sign-in without passkey, on a device that can hold one (5.1, 7): a proposal to create
9
- * one, never a requirement. "Later" is remembered for this user on this device.
9
+ * one, never a requirement. "Later" is remembered for this user on this device. When the passkey
10
+ * created cannot leave this device and no authenticator app backs it up, an authenticator app is
11
+ * proposed next; "Later" there ends the step like everywhere else.
10
12
  */
11
13
  export declare const PasskeyNudgeStep: ({ user, onDone }: PasskeyNudgeStepProps) => import("react/jsx-runtime").JSX.Element;
@@ -6,7 +6,9 @@ export type MfaRequirementBannerProps = {
6
6
  * Says why a second factor is required while the user has none (`GET /user/me/mfa`): an
7
7
  * administrator account, or an organisation requiring it (Q1: 7 days of grace, then no access to
8
8
  * its projects — the personal account stays intact). Disappears once a factor exists, including
9
- * one added in this tab. Renders nothing for a signed-out user, while loading, or if the status
9
+ * one added in this tab. An enrolled account whose factors all stay on one device (a passkey that
10
+ * is not synced, no authenticator app) gets a warning instead: a sign-in from another browser
11
+ * would lock it out (#769). The requirement keeps priority over that warning. Renders nothing for a signed-out user, while loading, or if the status
10
12
  * cannot be read: the server enforces the requirement either way, the banner only announces it.
11
13
  */
12
14
  export declare const MfaRequirementBanner: ({ onConfigure, }: MfaRequirementBannerProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The Security page of every Abyss front (5.2, 5.3): connected devices, passkeys, authenticator
2
+ * The Security page of every Abyss front (5.2, 5.3): connected devices, trusted devices, passkeys, authenticator
3
3
  * app, recovery codes, e-mail address, password. Must be rendered inside `<AuthProvider>`;
4
4
  * sensitive actions open the re-authentication dialog through the client (mount
5
5
  * `<AuthReauthHost />` once).
@@ -1,10 +1,15 @@
1
1
  type Props = {
2
2
  /** Whether this device can create a passkey (the list is shown either way). */
3
3
  passkeySupported: boolean;
4
+ /**
5
+ * Every factor of the account stays on one device (a passkey that is not synced, no
6
+ * authenticator app): a warning opens the section.
7
+ */
8
+ deviceBound: boolean;
4
9
  };
5
10
  /**
6
11
  * The account's passkeys: add one from this device, rename, remove. Adding and removing need a
7
12
  * proof of less than 5 minutes: the re-authentication dialog opens when it is older.
8
13
  */
9
- export declare const PasskeysSection: ({ passkeySupported }: Props) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const PasskeysSection: ({ passkeySupported, deviceBound }: Props) => import("react/jsx-runtime").JSX.Element;
10
15
  export {};
@@ -4,7 +4,9 @@ type Props = {
4
4
  };
5
5
  /**
6
6
  * The recovery codes (5.3): how many are left, and a new set of ten — replacing every previous
7
- * code — shown once. They stand in for a factor, so they exist only once one is enrolled.
7
+ * code — shown once. They stand in for a factor, so they exist only once one is enrolled. At two
8
+ * codes or fewer a callout carries the regenerate action (in danger at zero: nothing is left to
9
+ * fall back on).
8
10
  */
9
11
  export declare const RecoveryCodesSection: ({ status }: Props) => import("react/jsx-runtime").JSX.Element;
10
12
  export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The browsers trusted for 30 days (#769, ADR-0240): signing in there asks no second factor.
3
+ * Label, addition date, last use and expiry; removing one — or all — makes the second factor
4
+ * required again at once. Any row can be removed, the current browser's included.
5
+ */
6
+ export declare const TrustedDevicesSection: () => import("react/jsx-runtime").JSX.Element;
@@ -19,3 +19,4 @@ export { RequireSession } from './RequireSession/RequireSession.component';
19
19
  export type { RequireSessionProps } from './RequireSession/RequireSession.component';
20
20
  export { SessionErrorReason, SessionErrorScreen, } from './SessionErrorScreen/SessionErrorScreen.component';
21
21
  export type { SessionErrorScreenProps } from './SessionErrorScreen/SessionErrorScreen.component';
22
+ export { SUPPORT_CONTACT_EMAIL } from './shared/support-contact';
@@ -0,0 +1,13 @@
1
+ type Props = {
2
+ /** Opens the set-up of another method (authenticator app). */
3
+ onAdd: () => void;
4
+ /** Declines: the sign-in goes on, nothing is blocked. */
5
+ onLater: () => void;
6
+ busy?: boolean;
7
+ };
8
+ /**
9
+ * Shown right after a passkey bound to one device became the account's only second factor: it
10
+ * will not work from another browser, so a portable method is proposed — never imposed.
11
+ */
12
+ export declare const SingleDevicePasskeyAdvice: ({ onAdd, onLater, busy }: Props) => import("react/jsx-runtime").JSX.Element;
13
+ export {};
@@ -1,4 +1,4 @@
1
- import { IRegistrationVerifyPasskeyUserData } from '@abyss-project/main';
1
+ import { IPasskey, IRegistrationVerifyPasskeyUserData } from '@abyss-project/main';
2
2
  import { AuthClient } from '../../client/auth-client';
3
3
  /**
4
4
  * Creates a passkey for the signed-in user: options from abyss-main, the platform ceremony, then
@@ -7,6 +7,11 @@ import { AuthClient } from '../../client/auth-client';
7
7
  * account's first second factor, to be shown once.
8
8
  */
9
9
  export declare const registerPasskey: (client: AuthClient, name: string) => Promise<IRegistrationVerifyPasskeyUserData>;
10
+ /**
11
+ * A passkey the provider does not sync (`deviceType` of the WebAuthn credential): it only works
12
+ * on the device that holds it.
13
+ */
14
+ export declare const isSingleDevicePasskey: (passkey: IPasskey) => boolean;
10
15
  /**
11
16
  * Re-proves the current session with one of the user's passkeys. The new session (fresh proof,
12
17
  * `mfa` from then on, rotated refresh token) goes through `handleResult`.
@@ -0,0 +1,2 @@
1
+ /** Where a user who lost every second factor writes: there is no self-service recovery. */
2
+ export declare const SUPPORT_CONTACT_EMAIL = "contact@abyss-project.fr";
@@ -47,6 +47,11 @@ export declare const sdkMock: {
47
47
  revoke: Mock<(...args: any[]) => any>;
48
48
  revokeOthers: Mock<(...args: any[]) => any>;
49
49
  };
50
+ trustedDevice: {
51
+ list: Mock<(...args: any[]) => any>;
52
+ revoke: Mock<(...args: any[]) => any>;
53
+ revokeAll: Mock<(...args: any[]) => any>;
54
+ };
50
55
  user: {
51
56
  me: Mock<(...args: any[]) => any>;
52
57
  updatePassword: Mock<(...args: any[]) => any>;
@@ -3,6 +3,7 @@ import { vi } from 'vitest';
3
3
  import { ISessionAuthData, IUser, SessionPlatform, UserLanguage } from '@abyss-project/main';
4
4
  import { AuthBridge } from '../../client/auth-bridge';
5
5
  import { AuthClient } from '../../client/auth-client';
6
+ import { TokenStorage } from '../../client/token-storage';
6
7
  export declare const testUser: IUser;
7
8
  export declare const sessionOf: (user?: IUser, overrides?: Partial<ISessionAuthData>) => ISessionAuthData;
8
9
  /** The rejection axios produces for an HTTP answer carrying an API error. */
@@ -34,6 +35,8 @@ export interface RenderWithAuthOptions {
34
35
  bridge?: MockBridge;
35
36
  /** Signed in at launch with this session; signed out (refresh refused) when absent. */
36
37
  session?: ISessionAuthData;
38
+ /** The refresh token store: the web one (cookie, nothing kept) when absent. A native bridge needs a token in it to restore a session. */
39
+ storage?: TokenStorage;
37
40
  language?: UserLanguage;
38
41
  }
39
42
  export interface RenderedWithAuth {
@@ -0,0 +1,16 @@
1
+ function a(r) {
2
+ var f, n, t = "";
3
+ if (typeof r == "string" || typeof r == "number") t += r;
4
+ else if (typeof r == "object") if (Array.isArray(r)) {
5
+ var o = r.length;
6
+ for (f = 0; f < o; f++) r[f] && (n = a(r[f])) && (t && (t += " "), t += n);
7
+ } else for (n in r) r[n] && (t && (t += " "), t += n);
8
+ return t;
9
+ }
10
+ function i() {
11
+ for (var r, f, n = 0, t = "", o = arguments.length; n < o; n++) (r = arguments[n]) && (f = a(r)) && (t && (t += " "), t += f);
12
+ return t;
13
+ }
14
+ export {
15
+ i as c
16
+ };
@@ -0,0 +1,26 @@
1
+ import { ActivatableService } from '@abyss-project/main';
2
+ import { SupportPillSize } from './SupportPill';
3
+ /** The name of a service or of a game as a ticket shows it. */
4
+ export declare const getSupportServiceName: (service: ActivatableService) => string;
5
+ export interface AbyssServiceChipProps {
6
+ service: ActivatableService;
7
+ size?: SupportPillSize;
8
+ }
9
+ /** A service (or the game Odyssey): its mark and its name on a pill. */
10
+ export declare const AbyssServiceChip: ({ service, size, }: AbyssServiceChipProps) => import("react/jsx-runtime").JSX.Element;
11
+ export interface AbyssServiceSelectProps {
12
+ value: ActivatableService[];
13
+ onChange: (value: ActivatableService[]) => void;
14
+ /** Defaults to « Service ». */
15
+ label?: string;
16
+ }
17
+ /** The services a ticket can be about, several at a time (the list filter). */
18
+ export declare const AbyssServiceSelect: ({ value, onChange, label, }: AbyssServiceSelectProps) => import("react/jsx-runtime").JSX.Element;
19
+ export interface AbyssServiceSingleSelectProps {
20
+ value: ActivatableService | null;
21
+ onChange: (value: ActivatableService | null) => void;
22
+ /** Defaults to « Service ». */
23
+ label?: string;
24
+ }
25
+ /** The service a ticket is about: one, or none (the « Aucun service » option clears it). */
26
+ export declare const AbyssServiceSingleSelect: ({ value, onChange, label, }: AbyssServiceSingleSelectProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { SupportActionButtonsProps } from './types';
2
+ /**
3
+ * The actions open to the reader on a ticket, as a row of buttons. Taking over and resolving are
4
+ * the forward moves and are filled; each action asks for its confirmation first. Renders nothing
5
+ * when no action is open.
6
+ */
7
+ export declare const SupportActionButtons: ({ ticket, isAdmin, onExecuteAction, isExecuting, }: SupportActionButtonsProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,7 @@
1
+ import { SupportActivityLogProps } from './types';
2
+ /**
3
+ * The history of a ticket as a timeline: one entry per action (what happened, its reason when
4
+ * there is one, who did it and when), a dot in the tone of the action on a vertical rail. Renders
5
+ * nothing without entries.
6
+ */
7
+ export declare const SupportActivityLog: ({ activities, publicUsers, getProfilePictureUrl, }: SupportActivityLogProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,7 @@
1
+ import { SupportAttachmentsPanelProps } from './types';
2
+ /**
3
+ * The attachments of a ticket: one row per file (preview, name, scan badge, size, open, download,
4
+ * delete with a confirmation) and, while the limit is not reached, an upload entry. Download is
5
+ * never disabled by the scan status: the host wraps its handler with the antivirus warning.
6
+ */
7
+ export declare const SupportAttachmentsPanel: ({ attachments, onUpload, onDelete, onDownload, onOpenAttachment, getAttachmentPreviewUrl, isUploading, maxAttachments, renderScanStatusBadge, getFileThumbnailUrl, cloudImport, }: SupportAttachmentsPanelProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { ElementType } from 'react';
2
+ import { SupportTicketCategory, SupportTicketCategoryGroup } from '@abyss-project/main';
3
+ import { StatusTone } from '../../meaning/StatusBadge/StatusBadge';
4
+ import { SupportCategoryChipProps } from './types';
5
+ export declare const getCategoryGroup: (category: SupportTicketCategory) => SupportTicketCategoryGroup;
6
+ /** The tone and the icon of the group a category belongs to. */
7
+ export declare const getCategoryConfig: (category: SupportTicketCategory) => {
8
+ tone: StatusTone;
9
+ icon: ElementType;
10
+ };
11
+ /** The category of a support ticket: its name on a pill, a dot of its group's tone before it. */
12
+ export declare const SupportCategoryChip: ({ category, size, }: SupportCategoryChipProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { SupportCategoryGroupCardsProps } from './types';
2
+ export declare const SupportCategoryGroupCards: ({ value, onChange, service, onServiceChange, }: SupportCategoryGroupCardsProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { SupportTicketCategory } from '@abyss-project/main';
2
+ import { RichSelectSize } from '../../inputs/RichSelect/RichSelect';
3
+ export interface SupportCategorySelectProps {
4
+ /** Single value mode (create form): the platform-owned categories are not offered. */
5
+ value?: SupportTicketCategory | null;
6
+ onChange?: (value: SupportTicketCategory | null) => void;
7
+ /** Multiple value mode (filter): every category, platform-owned ones included. */
8
+ multiple?: boolean;
9
+ multipleValue?: SupportTicketCategory[];
10
+ onMultipleChange?: (value: SupportTicketCategory[]) => void;
11
+ /** Defaults to « Catégorie ». */
12
+ label?: string;
13
+ /** The message under the field; its presence puts the field in error. */
14
+ error?: string;
15
+ size?: RichSelectSize;
16
+ }
17
+ /**
18
+ * The category of a ticket. Each option carries the icon of its group, in the group's tone, and
19
+ * the group's name under its own, the list being ordered by group.
20
+ */
21
+ export declare const SupportCategorySelect: ({ value, onChange, multiple, multipleValue, onMultipleChange, label, error, size, }: SupportCategorySelectProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { ChangeEvent, FocusEvent } from 'react';
2
+ export interface SupportCreateTextFieldProps {
3
+ name: string;
4
+ label: string;
5
+ value: string;
6
+ onChange: (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
7
+ onBlur: (event: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
8
+ placeholder?: string;
9
+ /** The message under the field; its presence puts the field in error. */
10
+ error?: string;
11
+ required?: boolean;
12
+ /** A text area of this many rows instead of a single line. */
13
+ rows?: number;
14
+ maxLength?: number;
15
+ }
16
+ /** A text field of the ticket-creation components: label above, message under, on `FormField`. */
17
+ export declare const SupportCreateTextField: ({ name, label, value, onChange, onBlur, placeholder, error, required, rows, maxLength, }: SupportCreateTextFieldProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { ISupportTicketAttachment } from '@abyss-project/main';
2
+ import { ReactNode } from 'react';
3
+ export interface SupportMessageAttachmentProps {
4
+ attachment: ISupportTicketAttachment;
5
+ getFileThumbnailUrl?: (id: string) => string;
6
+ renderScanStatusBadge?: (attachment: ISupportTicketAttachment) => ReactNode;
7
+ }
8
+ /** An attachment of a message: its thumbnail or the icon of its type, its name and its size. */
9
+ export declare const SupportMessageAttachment: ({ attachment, getFileThumbnailUrl, renderScanStatusBadge, }: SupportMessageAttachmentProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { SupportMessageInputProps } from './types';
2
+ /**
3
+ * The composer of a ticket reply: a multiline field sent with Ctrl/Cmd+Enter or the send button,
4
+ * an attachment menu when the host takes files, and, for an admin, a switch to write an internal
5
+ * note instead. Renders nothing once the ticket is terminal.
6
+ */
7
+ export declare const SupportMessageInput: ({ onSendMessage, onSendAdminNote, onAttachFile, isAdmin, isSending, isTerminal, cloudImport, }: SupportMessageInputProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,8 @@
1
+ export interface SupportMessageLinkProps {
2
+ messageId: string;
3
+ }
4
+ /**
5
+ * The « copy link » button of a ticket message: it copies the page address carrying
6
+ * `?messageId=<id>` and confirms with a toast, or reports the failure.
7
+ */
8
+ export declare const SupportMessageLink: ({ messageId }: SupportMessageLinkProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { SupportMessageThreadProps } from './types';
2
+ /**
3
+ * The conversation of a support ticket: the description of the request, then the messages grouped
4
+ * by author under date separators, admin notes (for admins only) and platform notices in between.
5
+ * It follows the bottom of the thread, signals a message arriving while the reader is higher up,
6
+ * and scrolls to and highlights the message a link points to.
7
+ */
8
+ export declare const SupportMessageThread: ({ messages, currentUserId, isAdmin, publicUsers, getProfilePictureUrl, getFileThumbnailUrl, ticket, renderScanStatusBadge, targetMessageId, }: SupportMessageThreadProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ import { StatusTone } from '../../meaning/StatusBadge/StatusBadge';
3
+ export type SupportPillSize = 'small' | 'medium';
4
+ export interface SupportPillProps {
5
+ size?: SupportPillSize;
6
+ /** The tone of the dot before the label. */
7
+ tone?: StatusTone;
8
+ /** A mark drawn before the label, in place of the dot. */
9
+ mark?: ReactNode;
10
+ testId?: string;
11
+ children: ReactNode;
12
+ }
13
+ /**
14
+ * The pill of the ticket lists (a category, a priority, a tag): its name on a token pill, a dot of
15
+ * its tone before it, or a `mark` of the host's own (a dot in a colour stored with the data). Shared
16
+ * by the support chips and the internal ticket lists.
17
+ */
18
+ export declare const SupportPill: ({ size, tone, mark, testId, children, }: SupportPillProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { SupportPriorityChipProps } from './types';
2
+ /** The priority of a support ticket: its name on a pill, a dot of its tone before it. */
3
+ export declare const SupportPriorityChip: ({ priority, size, }: SupportPriorityChipProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { SupportSidebarProps } from './types';
2
+ /**
3
+ * The column beside a ticket: its actions, its place in the life cycle, priority and
4
+ * classification (editable by the back office, read-only for the requester), the people and
5
+ * organization behind it, tags, dates, attachments and the journal of what happened to it.
6
+ */
7
+ export declare const SupportSidebar: ({ ticket, isAdmin, currentUserId, onChangePriority, onChangeCategory, onChangeService, onAssign, onExecuteAction, isExecuting, adminUsers, activities, attachments, onUploadAttachment, onDeleteAttachment, onDownloadAttachment, onOpenAttachment, getAttachmentPreviewUrl, isUploadingAttachment, publicUsers, getProfilePictureUrl, tags, availableTags, onAddTag, onRemoveTag, organization, getOrgLogoUrl, project, onNavigateToUser, onNavigateToOrganization, onViewContext, renderScanStatusBadge, getFileThumbnailUrl, cloudImport, }: SupportSidebarProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { SupportStatusBadgeProps } from './types';
2
+ /** The status of a support ticket, in the tone `SUPPORT_STATUS_TONE` gives it. */
3
+ export declare const SupportStatusBadge: ({ status }: SupportStatusBadgeProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { SupportTicketStatus } from '@abyss-project/main';
2
+ export interface SupportStatusTimelineProps {
3
+ status: SupportTicketStatus;
4
+ /**
5
+ * The exact label of the current status, written above the rail: the rail has four phases, and
6
+ * waiting, escalated and archived tickets would otherwise read as their neighbour.
7
+ */
8
+ currentStatusLabel: string;
9
+ }
10
+ /**
11
+ * Where a support ticket is in its life: four phases on a rail, the reached ones filled. The exact
12
+ * status is written above the rail; a waiting, escalated or archived ticket also tints the rail and
13
+ * marks its active node with a glyph, so the difference is not told by colour alone.
14
+ */
15
+ export declare const SupportStatusTimeline: ({ status, currentStatusLabel, }: SupportStatusTimelineProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { ISupportTicketMessage } from '@abyss-project/main';
2
+ export interface SupportSystemMessageProps {
3
+ message: ISupportTicketMessage;
4
+ /** The platform event the message tells; the caller checked it is set. */
5
+ systemEvent: NonNullable<ISupportTicketMessage['systemEvent']>;
6
+ }
7
+ /**
8
+ * A notice written by the platform (a funding programme event): centered, with no author. Its text
9
+ * is resolved from the event in the language of the viewer; an admin-only one is flagged as a note.
10
+ */
11
+ export declare const SupportSystemMessage: ({ message, systemEvent, }: SupportSystemMessageProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { ISupportTicketTag } from '@abyss-project/main';
2
+ export interface SupportTagEditorProps {
3
+ /** The tags of the ticket. */
4
+ tags: ISupportTicketTag[];
5
+ /** Every tag that exists, the ones of the ticket included. */
6
+ availableTags: ISupportTicketTag[];
7
+ /** Adds an existing tag by its id, or creates one by its name (`isNew`). */
8
+ onAddTag: (tagIdOrName: string, isNew?: boolean) => void;
9
+ onRemoveTag?: (tagId: string) => void;
10
+ }
11
+ /**
12
+ * The tags of a ticket as pills, each removable when the host allows it, and a button that opens a
13
+ * panel to add one: search the existing tags, pick one, or type a new name and create it.
14
+ */
15
+ export declare const SupportTagEditor: ({ tags, availableTags, onAddTag, onRemoveTag, }: SupportTagEditorProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { SupportTicketCreateFormProps } from './types';
2
+ export declare const SupportTicketCreateForm: ({ onSubmit, isSubmitting, onBack, }: SupportTicketCreateFormProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { SupportTicketCreateStepperProps } from './types';
2
+ export declare const SupportTicketCreateStepper: ({ onSubmit, isSubmitting, isAdmin, onCancel, initialValues, renderForWhoStep, renderProjectSelect, onRedirectedCategory, }: SupportTicketCreateStepperProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { SupportTicketDetailProps } from './types';
2
+ /**
3
+ * A support ticket as one screen: the header with the actions, the conversation in the middle and
4
+ * the sidebar of information beside it (under it on a phone). While the ticket loads, fails to
5
+ * load (`error`, while there is no ticket to show) or does not exist, the screen shows that state
6
+ * under the way back.
7
+ */
8
+ export declare const SupportTicketDetail: ({ ticket, messages, currentUserId, targetMessageId, isAdmin, isLoading, error, onNavigateBack, onSendMessage, onSendAdminNote, isSending, onExecuteAction, isExecuting, onChangePriority, onChangeCategory, onChangeService, onAssign, adminUsers, activities, attachments, onUploadAttachment, onDeleteAttachment, onDownloadAttachment, onOpenAttachment, getAttachmentPreviewUrl, isUploadingAttachment, publicUsers, getProfilePictureUrl, tags, availableTags, onAddTag, onRemoveTag, organization, getOrgLogoUrl, project, onUploadMessageAttachment, onNavigateToUser, onNavigateToOrganization, onViewContext, renderScanStatusBadge, getFileThumbnailUrl, cloudImport, }: SupportTicketDetailProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+ import { ISupportTicketTag } from '@abyss-project/main';
3
+ import { SupportTicketListFilters } from './types';
4
+ export interface SupportTicketListFilterBarProps {
5
+ filters: SupportTicketListFilters;
6
+ onFiltersChange: (filters: SupportTicketListFilters) => void;
7
+ isAdmin?: boolean;
8
+ availableTags?: ISupportTicketTag[];
9
+ renderExtraFilters?: () => ReactNode;
10
+ }
11
+ /**
12
+ * The search field, the filters and the chips of the active ones above the support ticket list.
13
+ * The search waits for a pause in the typing before it filters: the host fetches on every change.
14
+ */
15
+ export declare const SupportTicketListFilterBar: ({ filters, onFiltersChange, isAdmin, availableTags, renderExtraFilters, }: SupportTicketListFilterBarProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { SupportTopBarProps } from './types';
2
+ /**
3
+ * The header of a ticket: the way back, the title, the status and the project, then the actions
4
+ * open to the reader. Forward moves are buttons; the rest sit in an overflow menu. Priority and
5
+ * category live in the sidebar, so the header does not say them twice.
6
+ */
7
+ export declare const SupportTopBar: ({ ticket, isAdmin, onNavigateBack, onExecuteAction, isExecuting, project, }: SupportTopBarProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { ReactElement } from 'react';
2
+ import { SupportTicketAction } from '@abyss-project/main';
3
+ /** The MUI palette color a button of the action is painted with. */
4
+ export type SupportActionColor = 'primary' | 'success' | 'error' | 'warning';
5
+ export interface SupportActionConfig {
6
+ icon: ReactElement;
7
+ color: SupportActionColor;
8
+ /** The action asks the reason for it in its confirmation. */
9
+ reasonRequired?: boolean;
10
+ }
11
+ export declare const SUPPORT_ACTION_CONFIG: Record<SupportTicketAction, SupportActionConfig>;
12
+ /**
13
+ * Runs an action of the lifecycle of a ticket once the reader confirmed it. The confirmation says
14
+ * what the action does and, for resolving and closing, takes the reason; the callback gets the
15
+ * action and the reason, left out when empty.
16
+ */
17
+ export declare const useSupportActionRunner: (onExecuteAction?: (action: SupportTicketAction, reason?: string) => void) => ((action: SupportTicketAction) => Promise<void>);
@@ -0,0 +1,12 @@
1
+ import { SupportTicketAction, SupportTicketStatus } from '@abyss-project/main';
2
+ export interface SupportAvailableActions {
3
+ /** Shown as buttons. */
4
+ primary: SupportTicketAction[];
5
+ /** Kept in the overflow menu. */
6
+ secondary: SupportTicketAction[];
7
+ }
8
+ /**
9
+ * The actions open to the reader on a ticket in `status`: the transitions the lifecycle allows
10
+ * from there, narrowed to closing and reopening for a requester.
11
+ */
12
+ export declare const getAvailableActions: (status: SupportTicketStatus, isAdmin: boolean) => SupportAvailableActions;
@@ -0,0 +1,28 @@
1
+ import { SupportTicketCategory, SupportTicketPriority } from '@abyss-project/main';
2
+ /**
3
+ * Pure rules shared by the two ticket-creation components (the single form and the stepper): what a
4
+ * valid ticket is, which categories ask for a service, which priorities ask for a reason.
5
+ */
6
+ export declare const TITLE_MIN_LENGTH = 3;
7
+ export declare const TITLE_MAX_LENGTH = 255;
8
+ export declare const DESCRIPTION_MIN_LENGTH = 10;
9
+ /** Whether a ticket of this category can name the service it is about. */
10
+ export declare const isServiceCategory: (category: SupportTicketCategory | "") => boolean;
11
+ /** Whether this priority must be justified. */
12
+ export declare const isReasonedPriority: (priority: SupportTicketPriority) => boolean;
13
+ export declare enum SupportCreateError {
14
+ Title = "title",
15
+ Description = "description",
16
+ Category = "category",
17
+ PriorityReason = "priority-reason"
18
+ }
19
+ export interface SupportCreateCheckedValues {
20
+ title: string;
21
+ description: string;
22
+ category: SupportTicketCategory | '';
23
+ priority: SupportTicketPriority;
24
+ priorityReason?: string;
25
+ }
26
+ export type SupportCreateErrors = Partial<Record<'title' | 'description' | 'category' | 'priorityReason', SupportCreateError>>;
27
+ /** The first problem of each field of a ticket about to be created; empty when it is valid. */
28
+ export declare const validateSupportCreate: (values: SupportCreateCheckedValues) => SupportCreateErrors;
@@ -0,0 +1,4 @@
1
+ /** Id of the row of a ticket message: the target of a link to that message. */
2
+ export declare const messageAnchorId: (messageId: string) => string;
3
+ /** Id of the bubble of a ticket message: the element a link to that message highlights. */
4
+ export declare const messageBubbleId: (messageId: string) => string;