@plumile/backoffice-react 0.1.200 → 0.1.205

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 (202) hide show
  1. package/README.md +4 -4
  2. package/lib/esm/auth/login/LoginFlow.js.map +1 -1
  3. package/lib/esm/auth/pages/AcceptInvitationScreen.js.map +1 -1
  4. package/lib/esm/auth/pages/PasswordResetCompleteScreen.js.map +1 -1
  5. package/lib/esm/auth/pages/PasswordResetRequestScreen.js.map +1 -1
  6. package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js.map +1 -1
  7. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js +28 -28
  8. package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js.map +1 -1
  9. package/lib/esm/components/backoffice/layout/breadcrumb/buildBreadcrumbs.js.map +1 -1
  10. package/lib/esm/components/backoffice/layout/sidebarUtils.js.map +1 -1
  11. package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js +1 -1
  12. package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js.map +1 -1
  13. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +183 -183
  14. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
  15. package/lib/esm/hooks/useAuth.js +56 -56
  16. package/lib/esm/hooks/useAuth.js.map +1 -1
  17. package/lib/esm/hooks/useConditionalSubscription.js +18 -18
  18. package/lib/esm/hooks/useConditionalSubscription.js.map +1 -1
  19. package/lib/esm/index.js +49 -57
  20. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js +1 -1
  21. package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
  22. package/lib/esm/pages/BackofficeEntityDetailPage.helpers.js.map +1 -1
  23. package/lib/esm/pages/BackofficeEntityDetailPage.js +172 -172
  24. package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
  25. package/lib/esm/pages/BackofficeEntityListDataPage.js +1 -1
  26. package/lib/esm/pages/BackofficeEntityListDataPage.js.map +1 -1
  27. package/lib/esm/pages/BackofficeEntityListPage.helpers.js.map +1 -1
  28. package/lib/esm/pages/BackofficeLayoutPage.js +19 -19
  29. package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
  30. package/lib/esm/provider/BackofficeProvider.js +33 -33
  31. package/lib/esm/provider/entityRegistry.js +39 -36
  32. package/lib/esm/provider/entityRegistry.js.map +1 -1
  33. package/lib/esm/provider/useBackofficeAuthRouteGate.js +7 -7
  34. package/lib/esm/provider/useBackofficeAuthRouteGate.js.map +1 -1
  35. package/lib/esm/relay/createInlineReader.js.map +1 -1
  36. package/lib/esm/relay/typedRelayHooks.js +11 -2
  37. package/lib/esm/relay/typedRelayHooks.js.map +1 -1
  38. package/lib/esm/router/createBackofficeRoutes.js +26 -28
  39. package/lib/esm/router/createBackofficeRoutes.js.map +1 -1
  40. package/lib/esm/storybook/relay/RelayStory.js +32 -32
  41. package/lib/esm/storybook/relay/RelayStory.js.map +1 -1
  42. package/lib/esm/storybook/relay/mockResolvers.js.map +1 -1
  43. package/lib/esm/style.css +1 -1
  44. package/lib/types/components/backoffice/actions/BackofficeEntityActionFormDialog.d.ts +2 -2
  45. package/lib/types/components/backoffice/actions/BackofficeEntityActionFormDialog.d.ts.map +1 -1
  46. package/lib/types/components/backoffice/detail/BackofficeEntitySummaryHeader.d.ts +1 -1
  47. package/lib/types/components/backoffice/detail/BackofficeEntitySummaryHeader.d.ts.map +1 -1
  48. package/lib/types/components/backoffice/layout/sidebarUtils.d.ts.map +1 -1
  49. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.d.ts.map +1 -1
  50. package/lib/types/hooks/useAuth.d.ts.map +1 -1
  51. package/lib/types/hooks/useConditionalSubscription.d.ts.map +1 -1
  52. package/lib/types/i18n/locales/en/backofficeReact.d.ts +5 -0
  53. package/lib/types/i18n/locales/fr/backofficeReact.d.ts +5 -0
  54. package/lib/types/index.d.ts +2 -9
  55. package/lib/types/index.d.ts.map +1 -1
  56. package/lib/types/pages/BackofficeEntityDetailPage.d.ts.map +1 -1
  57. package/lib/types/pages/BackofficeEntityDetailPage.helpers.d.ts +3 -3
  58. package/lib/types/pages/BackofficeEntityDetailPage.helpers.d.ts.map +1 -1
  59. package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts +2 -2
  60. package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts.map +1 -1
  61. package/lib/types/pages/BackofficeLayoutPage.d.ts.map +1 -1
  62. package/lib/types/provider/entityRegistry.d.ts.map +1 -1
  63. package/lib/types/provider/types.d.ts +1 -1
  64. package/lib/types/provider/types.d.ts.map +1 -1
  65. package/lib/types/provider/useBackofficeAuthRouteGate.d.ts.map +1 -1
  66. package/lib/types/relay/createInlineReader.d.ts +4 -1
  67. package/lib/types/relay/createInlineReader.d.ts.map +1 -1
  68. package/lib/types/relay/typedRelayHooks.d.ts +15 -5
  69. package/lib/types/relay/typedRelayHooks.d.ts.map +1 -1
  70. package/lib/types/router/createBackofficeRoutes.d.ts +4 -4
  71. package/lib/types/router/createBackofficeRoutes.d.ts.map +1 -1
  72. package/lib/types/storybook/relay/RelayStory.d.ts +1 -1
  73. package/lib/types/storybook/relay/RelayStory.d.ts.map +1 -1
  74. package/lib/types/storybook/relay/mockResolvers.d.ts +9 -1
  75. package/lib/types/storybook/relay/mockResolvers.d.ts.map +1 -1
  76. package/package.json +12 -15
  77. package/lib/esm/_virtual/_rolldown/runtime.js +0 -7
  78. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.js +0 -13
  79. package/lib/esm/components/backoffice/detail/BackofficeDetailFlagTag.js.map +0 -1
  80. package/lib/esm/components/backoffice/detail/BackofficeDetailTaggedValue.js +0 -12
  81. package/lib/esm/components/backoffice/detail/BackofficeDetailTaggedValue.js.map +0 -1
  82. package/lib/esm/components/backoffice/detail/BackofficeEnumLabel.js +0 -16
  83. package/lib/esm/components/backoffice/detail/BackofficeEnumLabel.js.map +0 -1
  84. package/lib/esm/components/backoffice/detail/BackofficeReferenceValue.js +0 -17
  85. package/lib/esm/components/backoffice/detail/BackofficeReferenceValue.js.map +0 -1
  86. package/lib/esm/components/backoffice/detail/BackofficeStatusGroup.js +0 -8
  87. package/lib/esm/components/backoffice/detail/BackofficeStatusGroup.js.map +0 -1
  88. package/lib/esm/components/backoffice/detail/BackofficeStatusMetaBadge.js +0 -16
  89. package/lib/esm/components/backoffice/detail/BackofficeStatusMetaBadge.js.map +0 -1
  90. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +0 -6
  91. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js.map +0 -1
  92. package/lib/esm/components/backoffice/refs/backofficeEntityIdRef.css.js +0 -6
  93. package/lib/esm/components/backoffice/refs/backofficeEntityIdRef.css.js.map +0 -1
  94. package/lib/esm/components/backoffice/routing/BackofficeRoutePendingBar.js +0 -12
  95. package/lib/esm/components/backoffice/routing/BackofficeRoutePendingBar.js.map +0 -1
  96. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js +0 -7
  97. package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js.map +0 -1
  98. package/lib/esm/modules/base64.js +0 -21
  99. package/lib/esm/modules/base64.js.map +0 -1
  100. package/lib/esm/node_modules/@babel/runtime/helpers/arrayLikeToArray.js +0 -15
  101. package/lib/esm/node_modules/@babel/runtime/helpers/arrayLikeToArray.js.map +0 -1
  102. package/lib/esm/node_modules/@babel/runtime/helpers/arrayWithoutHoles.js +0 -15
  103. package/lib/esm/node_modules/@babel/runtime/helpers/arrayWithoutHoles.js.map +0 -1
  104. package/lib/esm/node_modules/@babel/runtime/helpers/defineProperty.js +0 -20
  105. package/lib/esm/node_modules/@babel/runtime/helpers/defineProperty.js.map +0 -1
  106. package/lib/esm/node_modules/@babel/runtime/helpers/interopRequireDefault.js +0 -13
  107. package/lib/esm/node_modules/@babel/runtime/helpers/interopRequireDefault.js.map +0 -1
  108. package/lib/esm/node_modules/@babel/runtime/helpers/iterableToArray.js +0 -13
  109. package/lib/esm/node_modules/@babel/runtime/helpers/iterableToArray.js.map +0 -1
  110. package/lib/esm/node_modules/@babel/runtime/helpers/nonIterableSpread.js +0 -13
  111. package/lib/esm/node_modules/@babel/runtime/helpers/nonIterableSpread.js.map +0 -1
  112. package/lib/esm/node_modules/@babel/runtime/helpers/objectSpread2.js +0 -33
  113. package/lib/esm/node_modules/@babel/runtime/helpers/objectSpread2.js.map +0 -1
  114. package/lib/esm/node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js +0 -19
  115. package/lib/esm/node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js.map +0 -1
  116. package/lib/esm/node_modules/@babel/runtime/helpers/toConsumableArray.js +0 -18
  117. package/lib/esm/node_modules/@babel/runtime/helpers/toConsumableArray.js.map +0 -1
  118. package/lib/esm/node_modules/@babel/runtime/helpers/toPrimitive.js +0 -22
  119. package/lib/esm/node_modules/@babel/runtime/helpers/toPrimitive.js.map +0 -1
  120. package/lib/esm/node_modules/@babel/runtime/helpers/toPropertyKey.js +0 -17
  121. package/lib/esm/node_modules/@babel/runtime/helpers/toPropertyKey.js.map +0 -1
  122. package/lib/esm/node_modules/@babel/runtime/helpers/typeof.js +0 -18
  123. package/lib/esm/node_modules/@babel/runtime/helpers/typeof.js.map +0 -1
  124. package/lib/esm/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js +0 -19
  125. package/lib/esm/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js.map +0 -1
  126. package/lib/esm/node_modules/fbjs/lib/areEqual.js +0 -42
  127. package/lib/esm/node_modules/fbjs/lib/areEqual.js.map +0 -1
  128. package/lib/esm/node_modules/invariant/browser.js +0 -30
  129. package/lib/esm/node_modules/invariant/browser.js.map +0 -1
  130. package/lib/esm/node_modules/relay-test-utils/index.js +0 -11
  131. package/lib/esm/node_modules/relay-test-utils/index.js.map +0 -1
  132. package/lib/esm/node_modules/relay-test-utils/lib/RelayMockPayloadGenerator.js +0 -288
  133. package/lib/esm/node_modules/relay-test-utils/lib/RelayMockPayloadGenerator.js.map +0 -1
  134. package/lib/esm/node_modules/relay-test-utils/lib/RelayModernMockEnvironment.js +0 -183
  135. package/lib/esm/node_modules/relay-test-utils/lib/RelayModernMockEnvironment.js.map +0 -1
  136. package/lib/esm/node_modules/relay-test-utils/lib/RelayResolverTestUtils.js +0 -19
  137. package/lib/esm/node_modules/relay-test-utils/lib/RelayResolverTestUtils.js.map +0 -1
  138. package/lib/esm/node_modules/relay-test-utils/lib/index.js +0 -21
  139. package/lib/esm/node_modules/relay-test-utils/lib/index.js.map +0 -1
  140. package/lib/esm/node_modules/relay-test-utils/lib/unwrapContainer.js +0 -16
  141. package/lib/esm/node_modules/relay-test-utils/lib/unwrapContainer.js.map +0 -1
  142. package/lib/esm/relay/RelayProvider.js +0 -2
  143. package/lib/esm/relay/envHelpers.js +0 -55
  144. package/lib/esm/relay/envHelpers.js.map +0 -1
  145. package/lib/esm/relay/environment.js +0 -2
  146. package/lib/esm/relay/shortAccessTokenEnvironment.js +0 -2
  147. package/lib/esm/relay/useRelayOperationActivity.js +0 -2
  148. package/lib/esm/storybook/relay/relay-test-utils.d.js +0 -0
  149. package/lib/types/auth/AuthFlows.stories.d.ts +0 -19
  150. package/lib/types/auth/AuthFlows.stories.d.ts.map +0 -1
  151. package/lib/types/components/backoffice/billing/BackofficeBillingUsageChart.stories.d.ts +0 -41
  152. package/lib/types/components/backoffice/billing/BackofficeBillingUsageChart.stories.d.ts.map +0 -1
  153. package/lib/types/components/backoffice/detail/BackofficeDetailFlagTag.d.ts +0 -11
  154. package/lib/types/components/backoffice/detail/BackofficeDetailFlagTag.d.ts.map +0 -1
  155. package/lib/types/components/backoffice/detail/BackofficeDetailPrimitives.stories.d.ts +0 -17
  156. package/lib/types/components/backoffice/detail/BackofficeDetailPrimitives.stories.d.ts.map +0 -1
  157. package/lib/types/components/backoffice/detail/BackofficeDetailTaggedValue.d.ts +0 -13
  158. package/lib/types/components/backoffice/detail/BackofficeDetailTaggedValue.d.ts.map +0 -1
  159. package/lib/types/components/backoffice/detail/BackofficeEnumLabel.d.ts +0 -9
  160. package/lib/types/components/backoffice/detail/BackofficeEnumLabel.d.ts.map +0 -1
  161. package/lib/types/components/backoffice/detail/BackofficeReferenceValue.d.ts +0 -10
  162. package/lib/types/components/backoffice/detail/BackofficeReferenceValue.d.ts.map +0 -1
  163. package/lib/types/components/backoffice/detail/BackofficeStatusGroup.d.ts +0 -8
  164. package/lib/types/components/backoffice/detail/BackofficeStatusGroup.d.ts.map +0 -1
  165. package/lib/types/components/backoffice/detail/BackofficeStatusMetaBadge.d.ts +0 -11
  166. package/lib/types/components/backoffice/detail/BackofficeStatusMetaBadge.d.ts.map +0 -1
  167. package/lib/types/components/backoffice/detail/backofficeDetailRelationLink.css.d.ts +0 -6
  168. package/lib/types/components/backoffice/detail/backofficeDetailRelationLink.css.d.ts.map +0 -1
  169. package/lib/types/components/backoffice/errors/BackofficeErrorBoundary.stories.d.ts +0 -12
  170. package/lib/types/components/backoffice/errors/BackofficeErrorBoundary.stories.d.ts.map +0 -1
  171. package/lib/types/components/backoffice/filters/EntityIdFilterField.stories.d.ts +0 -12
  172. package/lib/types/components/backoffice/filters/EntityIdFilterField.stories.d.ts.map +0 -1
  173. package/lib/types/components/backoffice/hub/BackofficeHubTemplate.stories.d.ts +0 -49
  174. package/lib/types/components/backoffice/hub/BackofficeHubTemplate.stories.d.ts.map +0 -1
  175. package/lib/types/components/backoffice/overview/BackofficeOverviewLayout.stories.d.ts +0 -11
  176. package/lib/types/components/backoffice/overview/BackofficeOverviewLayout.stories.d.ts.map +0 -1
  177. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.stories.d.ts +0 -12
  178. package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.stories.d.ts.map +0 -1
  179. package/lib/types/components/backoffice/refs/backofficeEntityIdRef.css.d.ts +0 -2
  180. package/lib/types/components/backoffice/refs/backofficeEntityIdRef.css.d.ts.map +0 -1
  181. package/lib/types/components/backoffice/routing/BackofficeRoutePendingBar.d.ts +0 -4
  182. package/lib/types/components/backoffice/routing/BackofficeRoutePendingBar.d.ts.map +0 -1
  183. package/lib/types/components/backoffice/routing/backofficeRoutePendingBar.css.d.ts +0 -3
  184. package/lib/types/components/backoffice/routing/backofficeRoutePendingBar.css.d.ts.map +0 -1
  185. package/lib/types/components/backoffice/scaffolds/BackofficeTabbedDetailShell.stories.d.ts +0 -11
  186. package/lib/types/components/backoffice/scaffolds/BackofficeTabbedDetailShell.stories.d.ts.map +0 -1
  187. package/lib/types/components/backoffice/tools/BackofficeTools.stories.d.ts +0 -17
  188. package/lib/types/components/backoffice/tools/BackofficeTools.stories.d.ts.map +0 -1
  189. package/lib/types/modules/base64.d.ts +0 -3
  190. package/lib/types/modules/base64.d.ts.map +0 -1
  191. package/lib/types/pages/BackofficeDashboardPage.stories.d.ts +0 -9
  192. package/lib/types/pages/BackofficeDashboardPage.stories.d.ts.map +0 -1
  193. package/lib/types/relay/RelayProvider.d.ts +0 -2
  194. package/lib/types/relay/RelayProvider.d.ts.map +0 -1
  195. package/lib/types/relay/envHelpers.d.ts +0 -25
  196. package/lib/types/relay/envHelpers.d.ts.map +0 -1
  197. package/lib/types/relay/environment.d.ts +0 -2
  198. package/lib/types/relay/environment.d.ts.map +0 -1
  199. package/lib/types/relay/shortAccessTokenEnvironment.d.ts +0 -5
  200. package/lib/types/relay/shortAccessTokenEnvironment.d.ts.map +0 -1
  201. package/lib/types/relay/useRelayOperationActivity.d.ts +0 -2
  202. package/lib/types/relay/useRelayOperationActivity.d.ts.map +0 -1
package/README.md CHANGED
@@ -91,15 +91,15 @@ without loading the list facet.
91
91
 
92
92
  ### Relay and mutation helpers
93
93
 
94
- - `RelayProvider`
95
- - `configureRelayEnvironment`
96
- - `getEnvironment`
97
- - `resetRelayStore`
98
94
  - `resolveMutationOutcome`
99
95
  - `resolveAgentStartOutcome`
100
96
  - `requireField`
101
97
  - `requireLinkedRecordId`
102
98
 
99
+ Generic Relay environment, provider, transport, and operation-activity helpers
100
+ are owned by `@plumile/relay`. Import them from that package; this package keeps
101
+ only helpers tied to backoffice mutations, connections, and typed data.
102
+
103
103
  ### Backoffice-specific UI scaffolds
104
104
 
105
105
  - `BackofficeOverviewLayout`
@@ -1 +1 @@
1
- {"version":3,"file":"LoginFlow.js","names":[],"sources":["../../../../src/auth/login/LoginFlow.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n type JSX,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport type {\n AuthMethod,\n OidcProviderKind,\n} from '../../modules/sharedSchemaTypes.js';\nimport type { UseAuthReturn } from '../../hooks/useAuth.js';\n\nimport { MfaChallengeForm } from './MfaChallengeForm.js';\nimport { PasskeyLoginForm } from './PasskeyLoginForm.js';\nimport { MethodChooser } from './MethodChooser.js';\nimport AuthPanel from './AuthPanel.js';\nimport { EmailCapturePanel } from './EmailCapturePanel.js';\nimport { PasswordLoginPanel } from './PasswordLoginPanel.js';\n\nexport type LoginFlowProps = {\n auth: UseAuthReturn;\n oidcProviders: readonly OidcProviderKind[];\n onLoginSuccess: () => void;\n onForgotPassword: () => void;\n};\n\ntype View = 'email' | 'passkey' | 'methods' | 'password' | 'mfa';\n\nexport const LoginFlow = ({\n auth,\n oidcProviders,\n onLoginSuccess,\n onForgotPassword,\n}: LoginFlowProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [methods, setMethods] = useState<readonly AuthMethod[]>([]);\n const [lockedUntil, setLockedUntil] = useState<string | null>(null);\n const [view, setView] = useState<View>('email');\n const [hasTriedPasskey, setHasTriedPasskey] = useState(false);\n const [localError, setLocalError] = useState<string | null>(null);\n const passkeyAttemptActive = useRef(true);\n\n const loginAdapter = useMemo(() => {\n return {\n ...auth,\n beginAuthentication: async (inputEmail: string) => {\n const result = await auth.beginAuthentication(inputEmail);\n setEmail(inputEmail);\n setMethods(result.methods);\n setLockedUntil(result.lockedUntil);\n return result;\n },\n };\n }, [auth]);\n\n const handleLoginSuccess = useCallback(\n ({ force } = { force: false }) => {\n if (!force && auth.nextStep === 'TOTP') {\n return;\n }\n onLoginSuccess();\n },\n [auth.nextStep, onLoginSuccess],\n );\n\n const isMfaStep = auth.nextStep === 'TOTP' || view === 'mfa';\n const title = isMfaStep\n ? t('auth.loginFlow.title.mfa')\n : t('auth.loginFlow.title.default');\n const subtitle = isMfaStep\n ? t('auth.loginFlow.subtitle.mfa')\n : t('auth.loginFlow.subtitle.default');\n\n const startFlowForEmail = useCallback(\n async (inputEmail: string) => {\n setLocalError(null);\n try {\n const trimmed = inputEmail.trim();\n const result = await auth.beginAuthentication(trimmed);\n setEmail(trimmed);\n setMethods(result.methods);\n setLockedUntil(result.lockedUntil);\n const hasPasskey = result.methods.some((method) => {\n return method === 'PASSKEY';\n });\n\n if (hasPasskey) {\n setView('passkey');\n } else if (result.methods.includes('PASSWORD')) {\n setView('password');\n } else {\n setView('methods');\n }\n } catch {\n setLocalError(t('auth.loginFlow.errors.tryAgain'));\n }\n },\n [auth, t],\n );\n\n useEffect(() => {\n passkeyAttemptActive.current = true;\n const trimmedEmail = email.trim();\n const shouldAttempt =\n view === 'passkey' && !hasTriedPasskey && trimmedEmail !== '';\n\n if (shouldAttempt) {\n setHasTriedPasskey(true);\n const runPasskeyLogin = async () => {\n try {\n const status = await loginAdapter.loginWithPasskey({\n email: trimmedEmail,\n });\n\n if (!passkeyAttemptActive.current) {\n return;\n }\n\n if (status === 'success') {\n handleLoginSuccess();\n return;\n }\n\n if (status === 'mfa-required') {\n setView('mfa');\n return;\n }\n\n setView('methods');\n setLocalError(t('auth.loginFlow.errors.passkeyUnavailable'));\n } catch {\n if (!passkeyAttemptActive.current) {\n return;\n }\n\n setLocalError(t('auth.loginFlow.errors.passkeyUnavailable'));\n setView('methods');\n }\n };\n runPasskeyLogin().catch(() => {\n // Errors are handled inside runPasskeyLogin; ignore any unexpected rethrow.\n });\n }\n\n return () => {\n passkeyAttemptActive.current = false;\n };\n }, [email, handleLoginSuccess, hasTriedPasskey, loginAdapter, t, view]);\n\n let content: JSX.Element;\n\n if (isMfaStep) {\n content = (\n <AuthPanel>\n <MfaChallengeForm\n auth={auth}\n onSuccess={() => {\n handleLoginSuccess({ force: true });\n }}\n onBack={() => {\n auth.reset();\n setView('email');\n }}\n />\n </AuthPanel>\n );\n } else if (view === 'passkey') {\n content = (\n <AuthPanel\n title={t('auth.loginFlow.passkey.title')}\n description={t('auth.loginFlow.passkey.description', { email })}\n >\n <PasskeyLoginForm\n auth={loginAdapter}\n onSuccess={handleLoginSuccess}\n onShowMethods={() => {\n setView('methods');\n }}\n defaultEmail={email}\n isAttemptingPasskey={auth.isLoading}\n />\n </AuthPanel>\n );\n } else if (view === 'methods') {\n content = (\n <AuthPanel title={t('auth.loginFlow.methods.title')}>\n <MethodChooser\n email={email}\n methods={methods}\n lockedUntil={lockedUntil}\n onSelect={(method) => {\n if (method === 'PASSKEY') {\n setView('passkey');\n return;\n }\n if (method === 'PASSWORD') {\n setView('password');\n }\n }}\n onBack={() => {\n setView('email');\n }}\n />\n </AuthPanel>\n );\n } else if (view === 'password') {\n content = (\n <PasswordLoginPanel\n auth={loginAdapter}\n defaultEmail={email}\n onForgotPassword={onForgotPassword}\n onSuccess={handleLoginSuccess}\n providers={oidcProviders}\n />\n );\n } else {\n // email capture only\n content = (\n <EmailCapturePanel\n email={email}\n errorMessage={localError}\n isLoading={auth.isLoading}\n onEmailChange={(value) => {\n setEmail(value);\n setLocalError(null);\n }}\n onContinue={() => {\n const trimmed = email.trim();\n if (trimmed === '') {\n setLocalError(t('auth.loginFlow.errors.emailRequired'));\n return;\n }\n startFlowForEmail(trimmed).catch(() => {\n // startFlowForEmail handles its own errors.\n });\n }}\n onForgotPassword={onForgotPassword}\n />\n );\n }\n\n return (\n <AuthLayout title={title} subtitle={subtitle}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"LoginFlow.js","names":[],"sources":["../../../../src/auth/login/LoginFlow.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n type JSX,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport type {\n AuthMethod,\n OidcProviderKind,\n} from '../../modules/sharedSchemaTypes.js';\nimport type { UseAuthReturn } from '../../hooks/useAuth.js';\n\nimport { MfaChallengeForm } from './MfaChallengeForm.js';\nimport { PasskeyLoginForm } from './PasskeyLoginForm.js';\nimport { MethodChooser } from './MethodChooser.js';\nimport { AuthPanel } from './AuthPanel.js';\nimport { EmailCapturePanel } from './EmailCapturePanel.js';\nimport { PasswordLoginPanel } from './PasswordLoginPanel.js';\n\nexport type LoginFlowProps = {\n auth: UseAuthReturn;\n oidcProviders: readonly OidcProviderKind[];\n onLoginSuccess: () => void;\n onForgotPassword: () => void;\n};\n\ntype View = 'email' | 'passkey' | 'methods' | 'password' | 'mfa';\n\nexport const LoginFlow = ({\n auth,\n oidcProviders,\n onLoginSuccess,\n onForgotPassword,\n}: LoginFlowProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [methods, setMethods] = useState<readonly AuthMethod[]>([]);\n const [lockedUntil, setLockedUntil] = useState<string | null>(null);\n const [view, setView] = useState<View>('email');\n const [hasTriedPasskey, setHasTriedPasskey] = useState(false);\n const [localError, setLocalError] = useState<string | null>(null);\n const passkeyAttemptActive = useRef(true);\n\n const loginAdapter = useMemo(() => {\n return {\n ...auth,\n beginAuthentication: async (inputEmail: string) => {\n const result = await auth.beginAuthentication(inputEmail);\n setEmail(inputEmail);\n setMethods(result.methods);\n setLockedUntil(result.lockedUntil);\n return result;\n },\n };\n }, [auth]);\n\n const handleLoginSuccess = useCallback(\n ({ force } = { force: false }) => {\n if (!force && auth.nextStep === 'TOTP') {\n return;\n }\n onLoginSuccess();\n },\n [auth.nextStep, onLoginSuccess],\n );\n\n const isMfaStep = auth.nextStep === 'TOTP' || view === 'mfa';\n const title = isMfaStep\n ? t('auth.loginFlow.title.mfa')\n : t('auth.loginFlow.title.default');\n const subtitle = isMfaStep\n ? t('auth.loginFlow.subtitle.mfa')\n : t('auth.loginFlow.subtitle.default');\n\n const startFlowForEmail = useCallback(\n async (inputEmail: string) => {\n setLocalError(null);\n try {\n const trimmed = inputEmail.trim();\n const result = await auth.beginAuthentication(trimmed);\n setEmail(trimmed);\n setMethods(result.methods);\n setLockedUntil(result.lockedUntil);\n const hasPasskey = result.methods.some((method) => {\n return method === 'PASSKEY';\n });\n\n if (hasPasskey) {\n setView('passkey');\n } else if (result.methods.includes('PASSWORD')) {\n setView('password');\n } else {\n setView('methods');\n }\n } catch {\n setLocalError(t('auth.loginFlow.errors.tryAgain'));\n }\n },\n [auth, t],\n );\n\n useEffect(() => {\n passkeyAttemptActive.current = true;\n const trimmedEmail = email.trim();\n const shouldAttempt =\n view === 'passkey' && !hasTriedPasskey && trimmedEmail !== '';\n\n if (shouldAttempt) {\n setHasTriedPasskey(true);\n const runPasskeyLogin = async () => {\n try {\n const status = await loginAdapter.loginWithPasskey({\n email: trimmedEmail,\n });\n\n if (!passkeyAttemptActive.current) {\n return;\n }\n\n if (status === 'success') {\n handleLoginSuccess();\n return;\n }\n\n if (status === 'mfa-required') {\n setView('mfa');\n return;\n }\n\n setView('methods');\n setLocalError(t('auth.loginFlow.errors.passkeyUnavailable'));\n } catch {\n if (!passkeyAttemptActive.current) {\n return;\n }\n\n setLocalError(t('auth.loginFlow.errors.passkeyUnavailable'));\n setView('methods');\n }\n };\n runPasskeyLogin().catch(() => {\n // Errors are handled inside runPasskeyLogin; ignore any unexpected rethrow.\n });\n }\n\n return () => {\n passkeyAttemptActive.current = false;\n };\n }, [email, handleLoginSuccess, hasTriedPasskey, loginAdapter, t, view]);\n\n let content: JSX.Element;\n\n if (isMfaStep) {\n content = (\n <AuthPanel>\n <MfaChallengeForm\n auth={auth}\n onSuccess={() => {\n handleLoginSuccess({ force: true });\n }}\n onBack={() => {\n auth.reset();\n setView('email');\n }}\n />\n </AuthPanel>\n );\n } else if (view === 'passkey') {\n content = (\n <AuthPanel\n title={t('auth.loginFlow.passkey.title')}\n description={t('auth.loginFlow.passkey.description', { email })}\n >\n <PasskeyLoginForm\n auth={loginAdapter}\n onSuccess={handleLoginSuccess}\n onShowMethods={() => {\n setView('methods');\n }}\n defaultEmail={email}\n isAttemptingPasskey={auth.isLoading}\n />\n </AuthPanel>\n );\n } else if (view === 'methods') {\n content = (\n <AuthPanel title={t('auth.loginFlow.methods.title')}>\n <MethodChooser\n email={email}\n methods={methods}\n lockedUntil={lockedUntil}\n onSelect={(method) => {\n if (method === 'PASSKEY') {\n setView('passkey');\n return;\n }\n if (method === 'PASSWORD') {\n setView('password');\n }\n }}\n onBack={() => {\n setView('email');\n }}\n />\n </AuthPanel>\n );\n } else if (view === 'password') {\n content = (\n <PasswordLoginPanel\n auth={loginAdapter}\n defaultEmail={email}\n onForgotPassword={onForgotPassword}\n onSuccess={handleLoginSuccess}\n providers={oidcProviders}\n />\n );\n } else {\n // email capture only\n content = (\n <EmailCapturePanel\n email={email}\n errorMessage={localError}\n isLoading={auth.isLoading}\n onEmailChange={(value) => {\n setEmail(value);\n setLocalError(null);\n }}\n onContinue={() => {\n const trimmed = email.trim();\n if (trimmed === '') {\n setLocalError(t('auth.loginFlow.errors.emailRequired'));\n return;\n }\n startFlowForEmail(trimmed).catch(() => {\n // startFlowForEmail handles its own errors.\n });\n }}\n onForgotPassword={onForgotPassword}\n />\n );\n }\n\n return (\n <AuthLayout title={title} subtitle={subtitle}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AcceptInvitationScreen.js","names":[],"sources":["../../../../src/auth/pages/AcceptInvitationScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormField } from '@plumile/ui/atomic/molecules/form_field/FormField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport type { UseAuthReturn } from '../../hooks/useAuth.js';\nimport { MfaChallengeForm } from '../login/MfaChallengeForm.js';\nimport AuthPanel from '../login/AuthPanel.js';\nimport * as styles from '../login/loginPage.css.js';\n\ntype AcceptanceState = 'pending' | 'mfa' | 'completed' | 'error' | 'idle';\n\ntype Props = {\n auth: UseAuthReturn;\n onSuccessRedirect: () => void;\n onBackToLogin: () => void;\n token?: string;\n};\n\nexport const AcceptInvitationScreen = ({\n auth,\n onSuccessRedirect,\n onBackToLogin,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const { acceptInvitation } = auth;\n const [status, setStatus] = useState<AcceptanceState>('idle');\n const [password, setPassword] = useState('');\n const [passwordConfirmation, setPasswordConfirmation] = useState('');\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (resolvedToken === '') {\n setErrorMessage(t('auth.acceptInvitation.errors.missingToken'));\n setStatus('error');\n return;\n }\n\n if (password !== passwordConfirmation) {\n setErrorMessage(t('auth.acceptInvitation.errors.passwordMismatch'));\n setStatus('error');\n return;\n }\n\n setStatus('pending');\n setErrorMessage(null);\n setIsSubmitting(true);\n\n // eslint-disable-next-line no-void\n void acceptInvitation({\n token: resolvedToken,\n password,\n passwordConfirmation,\n })\n .then((result) => {\n if (result === 'mfa-required') {\n setStatus('mfa');\n return;\n }\n setStatus('completed');\n onSuccessRedirect();\n })\n .catch(() => {\n setStatus('error');\n setErrorMessage(t('auth.acceptInvitation.errors.default'));\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [\n acceptInvitation,\n onSuccessRedirect,\n password,\n passwordConfirmation,\n resolvedToken,\n t,\n ],\n );\n\n const handleMfaSuccess = useCallback(() => {\n setStatus('completed');\n onSuccessRedirect();\n }, [onSuccessRedirect]);\n\n const handleRetry = useCallback(() => {\n setStatus('idle');\n setErrorMessage(null);\n setIsSubmitting(false);\n }, []);\n\n if (status === 'mfa') {\n return (\n <AuthLayout\n title={t('auth.acceptInvitation.mfaTitle')}\n subtitle={t('auth.acceptInvitation.mfaSubtitle')}\n >\n <MfaChallengeForm\n auth={auth}\n onSuccess={handleMfaSuccess}\n onBack={() => {\n auth.reset();\n handleRetry();\n }}\n />\n </AuthLayout>\n );\n }\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <div className={styles.stack}>\n <p className={styles.helper}>\n {t('auth.acceptInvitation.status.success')}\n </p>\n </div>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.acceptInvitation.subtitle')}>\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {errorMessage != null ? <FormError>{errorMessage}</FormError> : null}\n <FormField\n label={t('auth.acceptInvitation.form.passwordLabel')}\n name=\"password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setErrorMessage(null);\n if (status === 'error') {\n setStatus('idle');\n }\n }}\n placeholder={t('auth.acceptInvitation.form.passwordPlaceholder')}\n autoComplete=\"new-password\"\n required\n />\n <FormField\n label={t('auth.acceptInvitation.form.confirmLabel')}\n name=\"password-confirmation\"\n type=\"password\"\n value={passwordConfirmation}\n onChange={(event) => {\n setPasswordConfirmation(event.target.value);\n setErrorMessage(null);\n if (status === 'error') {\n setStatus('idle');\n }\n }}\n placeholder={t('auth.acceptInvitation.form.confirmPlaceholder')}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {status === 'pending'\n ? t('auth.acceptInvitation.status.workingButton')\n : t('auth.acceptInvitation.form.submit')}\n </Button>\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\n {t('auth.acceptInvitation.actions.backToLogin')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.acceptInvitation.title')}>{content}</AuthLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AcceptInvitationScreen.js","names":[],"sources":["../../../../src/auth/pages/AcceptInvitationScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormField } from '@plumile/ui/atomic/molecules/form_field/FormField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport type { UseAuthReturn } from '../../hooks/useAuth.js';\nimport { MfaChallengeForm } from '../login/MfaChallengeForm.js';\nimport { AuthPanel } from '../login/AuthPanel.js';\nimport * as styles from '../login/loginPage.css.js';\n\ntype AcceptanceState = 'pending' | 'mfa' | 'completed' | 'error' | 'idle';\n\ntype Props = {\n auth: UseAuthReturn;\n onSuccessRedirect: () => void;\n onBackToLogin: () => void;\n token?: string;\n};\n\nexport const AcceptInvitationScreen = ({\n auth,\n onSuccessRedirect,\n onBackToLogin,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const { acceptInvitation } = auth;\n const [status, setStatus] = useState<AcceptanceState>('idle');\n const [password, setPassword] = useState('');\n const [passwordConfirmation, setPasswordConfirmation] = useState('');\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (resolvedToken === '') {\n setErrorMessage(t('auth.acceptInvitation.errors.missingToken'));\n setStatus('error');\n return;\n }\n\n if (password !== passwordConfirmation) {\n setErrorMessage(t('auth.acceptInvitation.errors.passwordMismatch'));\n setStatus('error');\n return;\n }\n\n setStatus('pending');\n setErrorMessage(null);\n setIsSubmitting(true);\n\n // eslint-disable-next-line no-void\n void acceptInvitation({\n token: resolvedToken,\n password,\n passwordConfirmation,\n })\n .then((result) => {\n if (result === 'mfa-required') {\n setStatus('mfa');\n return;\n }\n setStatus('completed');\n onSuccessRedirect();\n })\n .catch(() => {\n setStatus('error');\n setErrorMessage(t('auth.acceptInvitation.errors.default'));\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [\n acceptInvitation,\n onSuccessRedirect,\n password,\n passwordConfirmation,\n resolvedToken,\n t,\n ],\n );\n\n const handleMfaSuccess = useCallback(() => {\n setStatus('completed');\n onSuccessRedirect();\n }, [onSuccessRedirect]);\n\n const handleRetry = useCallback(() => {\n setStatus('idle');\n setErrorMessage(null);\n setIsSubmitting(false);\n }, []);\n\n if (status === 'mfa') {\n return (\n <AuthLayout\n title={t('auth.acceptInvitation.mfaTitle')}\n subtitle={t('auth.acceptInvitation.mfaSubtitle')}\n >\n <MfaChallengeForm\n auth={auth}\n onSuccess={handleMfaSuccess}\n onBack={() => {\n auth.reset();\n handleRetry();\n }}\n />\n </AuthLayout>\n );\n }\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <div className={styles.stack}>\n <p className={styles.helper}>\n {t('auth.acceptInvitation.status.success')}\n </p>\n </div>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.acceptInvitation.subtitle')}>\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {errorMessage != null ? <FormError>{errorMessage}</FormError> : null}\n <FormField\n label={t('auth.acceptInvitation.form.passwordLabel')}\n name=\"password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setErrorMessage(null);\n if (status === 'error') {\n setStatus('idle');\n }\n }}\n placeholder={t('auth.acceptInvitation.form.passwordPlaceholder')}\n autoComplete=\"new-password\"\n required\n />\n <FormField\n label={t('auth.acceptInvitation.form.confirmLabel')}\n name=\"password-confirmation\"\n type=\"password\"\n value={passwordConfirmation}\n onChange={(event) => {\n setPasswordConfirmation(event.target.value);\n setErrorMessage(null);\n if (status === 'error') {\n setStatus('idle');\n }\n }}\n placeholder={t('auth.acceptInvitation.form.confirmPlaceholder')}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {status === 'pending'\n ? t('auth.acceptInvitation.status.workingButton')\n : t('auth.acceptInvitation.form.submit')}\n </Button>\n <Button type=\"button\" variant=\"secondary\" onClick={onBackToLogin}>\n {t('auth.acceptInvitation.actions.backToLogin')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.acceptInvitation.title')}>{content}</AuthLayout>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordResetCompleteScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetCompleteScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormField } from '@plumile/ui/atomic/molecules/form_field/FormField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport * as styles from '../login/loginPage.css.js';\nimport AuthPanel from '../login/AuthPanel.js';\n\nconst MIN_PASSWORD_LENGTH = 8;\n\ntype Props = {\n onBackToLogin: () => void;\n onCompletePasswordReset: (input: {\n newPassword: string;\n token: string;\n }) => Promise<boolean>;\n token?: string;\n};\n\nexport const PasswordResetCompleteScreen = ({\n onBackToLogin,\n onCompletePasswordReset,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [password, setPassword] = useState('');\n const [passwordConfirm, setPasswordConfirm] = useState('');\n const [status, setStatus] = useState<'idle' | 'completed'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (resolvedToken === '') {\n setError(t('auth.passwordResetComplete.errors.missingToken'));\n return;\n }\n\n if (password.length < MIN_PASSWORD_LENGTH) {\n setError(\n t('auth.passwordResetComplete.errors.minLength', {\n minLength: MIN_PASSWORD_LENGTH,\n }),\n );\n return;\n }\n\n if (password !== passwordConfirm) {\n setError(t('auth.passwordResetComplete.errors.mismatch'));\n return;\n }\n\n setIsSubmitting(true);\n\n const completePasswordReset = async (): Promise<void> => {\n try {\n const success = await onCompletePasswordReset({\n newPassword: password,\n token: resolvedToken,\n });\n if (success) {\n setStatus('completed');\n } else {\n setError(t('auth.passwordResetComplete.errors.invalid'));\n }\n } catch (mutationError) {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetComplete.errors.invalid'),\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n completePasswordReset().catch(() => {\n return undefined;\n });\n },\n [onCompletePasswordReset, password, passwordConfirm, resolvedToken, t],\n );\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.success.title')}\n description={t('auth.passwordResetComplete.success.description')}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n className={styles.brandGhostButton}\n onClick={onBackToLogin}\n >\n {t('auth.passwordResetComplete.success.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetComplete.success.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.form.title')}\n description={t('auth.passwordResetComplete.form.description')}\n >\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetComplete.form.passwordLabel')}\n name=\"new-password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.passwordPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <FormField\n label={t('auth.passwordResetComplete.form.confirmLabel')}\n name=\"confirm-password\"\n type=\"password\"\n value={passwordConfirm}\n onChange={(event) => {\n setPasswordConfirm(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.confirmPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetComplete.form.submit')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout\n title={t('auth.passwordResetComplete.title')}\n subtitle={t('auth.passwordResetComplete.subtitle')}\n >\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;AAmBA,IAAM,IAAsB,GAWf,KAA+B,EAC1C,kBACA,4BACA,eACwB;CACxB,IAAM,EAAE,SAAM,EAA8B,GACtC,CAAC,GAAU,KAAe,EAAS,EAAE,GACrC,CAAC,GAAiB,KAAsB,EAAS,EAAE,GACnD,CAAC,GAAQ,KAAa,EAA+B,MAAM,GAC3D,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAEhD,IAAgB,QAChB,MAGA,OAAO,SAAW,MACb,KAGF,IADY,gBAAgB,OAAO,SAAS,MAC5C,CAAA,CAAO,IAAI,OAAO,KAAK,KAC7B,CAAC,CAAK,CAAC,GAEJ,IAAe,GAClB,MAAsC;EAIrC,IAHA,EAAM,eAAe,GACrB,EAAS,IAAI,GAET,MAAkB,IAAI;GACxB,EAAS,EAAE,gDAAgD,CAAC;GAC5D;EACF;EAEA,IAAI,EAAS,SAAS,GAAqB;GACzC,EACE,EAAE,+CAA+C,EAC/C,WAAW,EACb,CAAC,CACH;GACA;EACF;EAEA,IAAI,MAAa,GAAiB;GAChC,EAAS,EAAE,4CAA4C,CAAC;GACxD;EACF;EA0BA,AAxBA,EAAgB,EAAI,IAwBpB,YAtByD;GACvD,IAAI;IAKF,AAAI,MAJkB,EAAwB;KAC5C,aAAa;KACb,OAAO;IACT,CAAC,IAEC,EAAU,WAAW,IAErB,EAAS,EAAE,2CAA2C,CAAC;GAE3D,SAAS,GAAe;IACtB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,2CAA2C,CACnD;GACF,UAAU;IACR,EAAgB,EAAK;GACvB;EACF,EAEA,CAAsB,CAAC,CAAC,YAAY,CAEpC,CAAC;CACH,GACA;EAAC;EAAyB;EAAU;EAAiB;EAAe;CAAC,CACvE,GAEI;CAyEJ,OAxEA,AAsBE,IAtBE,MAAW,cAEX,kBAAC,GAAD;EACE,OAAO,EAAE,0CAA0C;EACnD,aAAa,EAAE,gDAAgD;EAC/D,QACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,WAAW;GACX,SAAS;GAER,UAAA,EAAE,2CAA2C;EACxC,CAAA;EAGV,UAAA,kBAAC,KAAD;GAAG,WAAW;GACX,UAAA,EAAE,2CAA2C;EAC7C,CAAA;CACM,CAAA,IAIX,kBAAC,GAAD;EACE,OAAO,EAAE,uCAAuC;EAChD,aAAa,EAAE,6CAA6C;EAE5D,UAAA,kBAAC,GAAD;GACE,WAAW;GACX,UAAU;GACV,YAAA;GACA,cAAa;GAJf,UAAA;IAMG,KAAS,OAAwC,OAAjC,kBAAC,GAAD,EAAA,UAAY,EAAiB,CAAA;IAC9C,kBAAC,GAAD;KACE,OAAO,EAAE,+CAA+C;KACxD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAY,EAAM,OAAO,KAAK,GAC9B,EAAS,IAAI;KACf;KACA,aAAa,EACX,qDACF;KACA,cAAa;KACb,UAAA;IACD,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAE,8CAA8C;KACvD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAmB,EAAM,OAAO,KAAK,GACrC,EAAS,IAAI;KACf;KACA,aAAa,EACX,oDACF;KACA,cAAa;KACb,UAAA;IACD,CAAA;IACD,kBAAC,GAAD;KAAQ,MAAK;KAAS,WAAW;KAC9B,UAAA,EAAE,wCAAwC;IACrC,CAAA;GACJ;;CACG,CAAA,GAKb,kBAAC,GAAD;EACE,OAAO,EAAE,kCAAkC;EAC3C,UAAU,EAAE,qCAAqC;EAEhD,UAAA;CACS,CAAA;AAEhB"}
1
+ {"version":3,"file":"PasswordResetCompleteScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetCompleteScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormField } from '@plumile/ui/atomic/molecules/form_field/FormField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport * as styles from '../login/loginPage.css.js';\nimport { AuthPanel } from '../login/AuthPanel.js';\n\nconst MIN_PASSWORD_LENGTH = 8;\n\ntype Props = {\n onBackToLogin: () => void;\n onCompletePasswordReset: (input: {\n newPassword: string;\n token: string;\n }) => Promise<boolean>;\n token?: string;\n};\n\nexport const PasswordResetCompleteScreen = ({\n onBackToLogin,\n onCompletePasswordReset,\n token,\n}: Props): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const [password, setPassword] = useState('');\n const [passwordConfirm, setPasswordConfirm] = useState('');\n const [status, setStatus] = useState<'idle' | 'completed'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const resolvedToken = useMemo(() => {\n if (token != null) {\n return token;\n }\n if (typeof window === 'undefined') {\n return '';\n }\n const params = new URLSearchParams(window.location.search);\n return params.get('token') ?? '';\n }, [token]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (resolvedToken === '') {\n setError(t('auth.passwordResetComplete.errors.missingToken'));\n return;\n }\n\n if (password.length < MIN_PASSWORD_LENGTH) {\n setError(\n t('auth.passwordResetComplete.errors.minLength', {\n minLength: MIN_PASSWORD_LENGTH,\n }),\n );\n return;\n }\n\n if (password !== passwordConfirm) {\n setError(t('auth.passwordResetComplete.errors.mismatch'));\n return;\n }\n\n setIsSubmitting(true);\n\n const completePasswordReset = async (): Promise<void> => {\n try {\n const success = await onCompletePasswordReset({\n newPassword: password,\n token: resolvedToken,\n });\n if (success) {\n setStatus('completed');\n } else {\n setError(t('auth.passwordResetComplete.errors.invalid'));\n }\n } catch (mutationError) {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetComplete.errors.invalid'),\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n completePasswordReset().catch(() => {\n return undefined;\n });\n },\n [onCompletePasswordReset, password, passwordConfirm, resolvedToken, t],\n );\n\n let content: JSX.Element;\n if (status === 'completed') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.success.title')}\n description={t('auth.passwordResetComplete.success.description')}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n className={styles.brandGhostButton}\n onClick={onBackToLogin}\n >\n {t('auth.passwordResetComplete.success.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetComplete.success.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel\n title={t('auth.passwordResetComplete.form.title')}\n description={t('auth.passwordResetComplete.form.description')}\n >\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetComplete.form.passwordLabel')}\n name=\"new-password\"\n type=\"password\"\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.passwordPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <FormField\n label={t('auth.passwordResetComplete.form.confirmLabel')}\n name=\"confirm-password\"\n type=\"password\"\n value={passwordConfirm}\n onChange={(event) => {\n setPasswordConfirm(event.target.value);\n setError(null);\n }}\n placeholder={t(\n 'auth.passwordResetComplete.form.confirmPlaceholder',\n )}\n autoComplete=\"new-password\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetComplete.form.submit')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout\n title={t('auth.passwordResetComplete.title')}\n subtitle={t('auth.passwordResetComplete.subtitle')}\n >\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;AAmBA,IAAM,IAAsB,GAWf,KAA+B,EAC1C,kBACA,4BACA,eACwB;CACxB,IAAM,EAAE,SAAM,EAA8B,GACtC,CAAC,GAAU,KAAe,EAAS,EAAE,GACrC,CAAC,GAAiB,KAAsB,EAAS,EAAE,GACnD,CAAC,GAAQ,KAAa,EAA+B,MAAM,GAC3D,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAEhD,IAAgB,QAChB,MAGA,OAAO,SAAW,MACb,KAGF,IADY,gBAAgB,OAAO,SAAS,MAC5C,CAAA,CAAO,IAAI,OAAO,KAAK,KAC7B,CAAC,CAAK,CAAC,GAEJ,IAAe,GAClB,MAAsC;EAIrC,IAHA,EAAM,eAAe,GACrB,EAAS,IAAI,GAET,MAAkB,IAAI;GACxB,EAAS,EAAE,gDAAgD,CAAC;GAC5D;EACF;EAEA,IAAI,EAAS,SAAS,GAAqB;GACzC,EACE,EAAE,+CAA+C,EAC/C,WAAW,EACb,CAAC,CACH;GACA;EACF;EAEA,IAAI,MAAa,GAAiB;GAChC,EAAS,EAAE,4CAA4C,CAAC;GACxD;EACF;EA0BA,AAxBA,EAAgB,EAAI,IAwBpB,YAtByD;GACvD,IAAI;IAKF,AAAI,MAJkB,EAAwB;KAC5C,aAAa;KACb,OAAO;IACT,CAAC,IAEC,EAAU,WAAW,IAErB,EAAS,EAAE,2CAA2C,CAAC;GAE3D,SAAS,GAAe;IACtB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,2CAA2C,CACnD;GACF,UAAU;IACR,EAAgB,EAAK;GACvB;EACF,EAEA,CAAsB,CAAC,CAAC,YAAY,CAEpC,CAAC;CACH,GACA;EAAC;EAAyB;EAAU;EAAiB;EAAe;CAAC,CACvE,GAEI;CAyEJ,OAxEA,AAsBE,IAtBE,MAAW,cAEX,kBAAC,GAAD;EACE,OAAO,EAAE,0CAA0C;EACnD,aAAa,EAAE,gDAAgD;EAC/D,QACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,WAAW;GACX,SAAS;GAER,UAAA,EAAE,2CAA2C;EACxC,CAAA;EAGV,UAAA,kBAAC,KAAD;GAAG,WAAW;GACX,UAAA,EAAE,2CAA2C;EAC7C,CAAA;CACM,CAAA,IAIX,kBAAC,GAAD;EACE,OAAO,EAAE,uCAAuC;EAChD,aAAa,EAAE,6CAA6C;EAE5D,UAAA,kBAAC,GAAD;GACE,WAAW;GACX,UAAU;GACV,YAAA;GACA,cAAa;GAJf,UAAA;IAMG,KAAS,OAAwC,OAAjC,kBAAC,GAAD,EAAA,UAAY,EAAiB,CAAA;IAC9C,kBAAC,GAAD;KACE,OAAO,EAAE,+CAA+C;KACxD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAY,EAAM,OAAO,KAAK,GAC9B,EAAS,IAAI;KACf;KACA,aAAa,EACX,qDACF;KACA,cAAa;KACb,UAAA;IACD,CAAA;IACD,kBAAC,GAAD;KACE,OAAO,EAAE,8CAA8C;KACvD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAmB,EAAM,OAAO,KAAK,GACrC,EAAS,IAAI;KACf;KACA,aAAa,EACX,oDACF;KACA,cAAa;KACb,UAAA;IACD,CAAA;IACD,kBAAC,GAAD;KAAQ,MAAK;KAAS,WAAW;KAC9B,UAAA,EAAE,wCAAwC;IACrC,CAAA;GACJ;;CACG,CAAA,GAKb,kBAAC,GAAD;EACE,OAAO,EAAE,kCAAkC;EAC3C,UAAU,EAAE,qCAAqC;EAEhD,UAAA;CACS,CAAA;AAEhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"PasswordResetRequestScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetRequestScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormField } from '@plumile/ui/atomic/molecules/form_field/FormField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport * as styles from '../login/loginPage.css.js';\nimport AuthPanel from '../login/AuthPanel.js';\n\ntype Props = {\n onStartPasswordReset: (input: {\n email: string;\n locale?: string;\n }) => Promise<boolean>;\n};\n\nexport const PasswordResetRequestScreen = ({\n onStartPasswordReset,\n}: Props): JSX.Element => {\n const { i18n, t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [status, setStatus] = useState<'idle' | 'sent'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const locale = useMemo(() => {\n const language = i18n.language.trim();\n if (language !== '') {\n return language;\n }\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n return navigator.language;\n }, [i18n.language]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (email.trim() === '') {\n setError(t('auth.passwordResetRequest.errors.emailRequired'));\n return;\n }\n\n setIsSubmitting(true);\n onStartPasswordReset({\n email: email.trim(),\n locale,\n })\n .then((success) => {\n if (success) {\n setStatus('sent');\n } else {\n setError(t('auth.passwordResetRequest.errors.startFailed'));\n }\n })\n .catch((mutationError) => {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetRequest.errors.startFailed'),\n );\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [email, locale, onStartPasswordReset, t],\n );\n\n let content: JSX.Element;\n if (status === 'sent') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetRequest.sent.title')}\n description={t('auth.passwordResetRequest.sent.description', { email })}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n setStatus('idle');\n }}\n >\n {t('auth.passwordResetRequest.sent.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetRequest.sent.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.passwordResetRequest.form.description')}>\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetRequest.form.emailLabel')}\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.target.value);\n setError(null);\n }}\n placeholder={t('auth.passwordResetRequest.form.emailPlaceholder')}\n autoComplete=\"email\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetRequest.form.submit')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.passwordResetRequest.title')}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;AA0BA,IAAa,KAA8B,EACzC,8BACwB;CACxB,IAAM,EAAE,SAAM,SAAM,EAA8B,GAC5C,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAQ,KAAa,EAA0B,MAAM,GACtD,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAEhD,IAAS,QAAc;EAC3B,IAAM,IAAW,EAAK,SAAS,KAAK;EACpC,IAAI,MAAa,IACf,OAAO;EAEL,aAAO,YAAc,MAGzB,OAAO,UAAU;CACnB,GAAG,CAAC,EAAK,QAAQ,CAAC,GAEZ,IAAe,GAClB,MAAsC;EAIrC,IAHA,EAAM,eAAe,GACrB,EAAS,IAAI,GAET,EAAM,KAAK,MAAM,IAAI;GACvB,EAAS,EAAE,gDAAgD,CAAC;GAC5D;EACF;EAGA,AADA,EAAgB,EAAI,GACpB,EAAqB;GACnB,OAAO,EAAM,KAAK;GAClB;EACF,CAAC,CAAC,CACC,MAAM,MAAY;GACjB,AAAI,IACF,EAAU,MAAM,IAEhB,EAAS,EAAE,8CAA8C,CAAC;EAE9D,CAAC,CAAC,CACD,OAAO,MAAkB;GACxB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,8CAA8C,CACtD;EACF,CAAC,CAAC,CACD,cAAc;GACb,EAAgB,EAAK;EACvB,CAAC;CACL,GACA;EAAC;EAAO;EAAQ;EAAsB;CAAC,CACzC,GAEI;CAsDJ,OArDA,AAuBE,IAvBE,MAAW,SAEX,kBAAC,GAAD;EACE,OAAO,EAAE,sCAAsC;EAC/C,aAAa,EAAE,8CAA8C,EAAE,SAAM,CAAC;EACtE,QACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,eAAe;IACb,EAAU,MAAM;GAClB;GAEC,UAAA,EAAE,uCAAuC;EACpC,CAAA;EAGV,UAAA,kBAAC,KAAD;GAAG,WAAW;GACX,UAAA,EAAE,uCAAuC;EACzC,CAAA;CACM,CAAA,IAIX,kBAAC,GAAD;EAAW,aAAa,EAAE,4CAA4C;EACpE,UAAA,kBAAC,GAAD;GACE,WAAW;GACX,UAAU;GACV,YAAA;GACA,cAAa;GAJf,UAAA;IAMG,KAAS,OAAwC,OAAjC,kBAAC,GAAD,EAAA,UAAY,EAAiB,CAAA;IAC9C,kBAAC,GAAD;KACE,OAAO,EAAE,2CAA2C;KACpD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAS,EAAM,OAAO,KAAK,GAC3B,EAAS,IAAI;KACf;KACA,aAAa,EAAE,iDAAiD;KAChE,cAAa;KACb,UAAA;IACD,CAAA;IACD,kBAAC,GAAD;KAAQ,MAAK;KAAS,WAAW;KAC9B,UAAA,EAAE,uCAAuC;IACpC,CAAA;GACJ;;CACG,CAAA,GAKb,kBAAC,GAAD;EAAY,OAAO,EAAE,iCAAiC;EACnD,UAAA;CACS,CAAA;AAEhB"}
1
+ {"version":3,"file":"PasswordResetRequestScreen.js","names":[],"sources":["../../../../src/auth/pages/PasswordResetRequestScreen.tsx"],"sourcesContent":["/* eslint-disable no-ternary */\nimport {\n useCallback,\n useMemo,\n useState,\n type FormEvent,\n type JSX,\n} from 'react';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormField } from '@plumile/ui/atomic/molecules/form_field/FormField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { AuthLayout } from '@plumile/ui/atomic/templates/auth_layout/AuthLayout.js';\n\nimport * as styles from '../login/loginPage.css.js';\nimport { AuthPanel } from '../login/AuthPanel.js';\n\ntype Props = {\n onStartPasswordReset: (input: {\n email: string;\n locale?: string;\n }) => Promise<boolean>;\n};\n\nexport const PasswordResetRequestScreen = ({\n onStartPasswordReset,\n}: Props): JSX.Element => {\n const { i18n, t } = useBackofficeReactTranslation();\n const [email, setEmail] = useState('');\n const [status, setStatus] = useState<'idle' | 'sent'>('idle');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const locale = useMemo(() => {\n const language = i18n.language.trim();\n if (language !== '') {\n return language;\n }\n if (typeof navigator === 'undefined') {\n return undefined;\n }\n return navigator.language;\n }, [i18n.language]);\n\n const handleSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n setError(null);\n\n if (email.trim() === '') {\n setError(t('auth.passwordResetRequest.errors.emailRequired'));\n return;\n }\n\n setIsSubmitting(true);\n onStartPasswordReset({\n email: email.trim(),\n locale,\n })\n .then((success) => {\n if (success) {\n setStatus('sent');\n } else {\n setError(t('auth.passwordResetRequest.errors.startFailed'));\n }\n })\n .catch((mutationError) => {\n setError(\n mutationError instanceof Error\n ? mutationError.message\n : t('auth.passwordResetRequest.errors.startFailed'),\n );\n })\n .finally(() => {\n setIsSubmitting(false);\n });\n },\n [email, locale, onStartPasswordReset, t],\n );\n\n let content: JSX.Element;\n if (status === 'sent') {\n content = (\n <AuthPanel\n title={t('auth.passwordResetRequest.sent.title')}\n description={t('auth.passwordResetRequest.sent.description', { email })}\n footer={\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={() => {\n setStatus('idle');\n }}\n >\n {t('auth.passwordResetRequest.sent.action')}\n </Button>\n }\n >\n <p className={styles.helper}>\n {t('auth.passwordResetRequest.sent.helper')}\n </p>\n </AuthPanel>\n );\n } else {\n content = (\n <AuthPanel description={t('auth.passwordResetRequest.form.description')}>\n <Form\n className={styles.formSurface}\n onSubmit={handleSubmit}\n noValidate\n initialFocus=\"first-form-control\"\n >\n {error != null ? <FormError>{error}</FormError> : null}\n <FormField\n label={t('auth.passwordResetRequest.form.emailLabel')}\n name=\"email\"\n type=\"email\"\n value={email}\n onChange={(event) => {\n setEmail(event.target.value);\n setError(null);\n }}\n placeholder={t('auth.passwordResetRequest.form.emailPlaceholder')}\n autoComplete=\"email\"\n required\n />\n <Button type=\"submit\" isLoading={isSubmitting}>\n {t('auth.passwordResetRequest.form.submit')}\n </Button>\n </Form>\n </AuthPanel>\n );\n }\n\n return (\n <AuthLayout title={t('auth.passwordResetRequest.title')}>\n {content}\n </AuthLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;AA0BA,IAAa,KAA8B,EACzC,8BACwB;CACxB,IAAM,EAAE,SAAM,SAAM,EAA8B,GAC5C,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAQ,KAAa,EAA0B,MAAM,GACtD,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,CAAC,GAAc,KAAmB,EAAS,EAAK,GAEhD,IAAS,QAAc;EAC3B,IAAM,IAAW,EAAK,SAAS,KAAK;EACpC,IAAI,MAAa,IACf,OAAO;EAEL,aAAO,YAAc,MAGzB,OAAO,UAAU;CACnB,GAAG,CAAC,EAAK,QAAQ,CAAC,GAEZ,IAAe,GAClB,MAAsC;EAIrC,IAHA,EAAM,eAAe,GACrB,EAAS,IAAI,GAET,EAAM,KAAK,MAAM,IAAI;GACvB,EAAS,EAAE,gDAAgD,CAAC;GAC5D;EACF;EAGA,AADA,EAAgB,EAAI,GACpB,EAAqB;GACnB,OAAO,EAAM,KAAK;GAClB;EACF,CAAC,CAAC,CACC,MAAM,MAAY;GACjB,AAAI,IACF,EAAU,MAAM,IAEhB,EAAS,EAAE,8CAA8C,CAAC;EAE9D,CAAC,CAAC,CACD,OAAO,MAAkB;GACxB,EACE,aAAyB,QACrB,EAAc,UACd,EAAE,8CAA8C,CACtD;EACF,CAAC,CAAC,CACD,cAAc;GACb,EAAgB,EAAK;EACvB,CAAC;CACL,GACA;EAAC;EAAO;EAAQ;EAAsB;CAAC,CACzC,GAEI;CAsDJ,OArDA,AAuBE,IAvBE,MAAW,SAEX,kBAAC,GAAD;EACE,OAAO,EAAE,sCAAsC;EAC/C,aAAa,EAAE,8CAA8C,EAAE,SAAM,CAAC;EACtE,QACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,eAAe;IACb,EAAU,MAAM;GAClB;GAEC,UAAA,EAAE,uCAAuC;EACpC,CAAA;EAGV,UAAA,kBAAC,KAAD;GAAG,WAAW;GACX,UAAA,EAAE,uCAAuC;EACzC,CAAA;CACM,CAAA,IAIX,kBAAC,GAAD;EAAW,aAAa,EAAE,4CAA4C;EACpE,UAAA,kBAAC,GAAD;GACE,WAAW;GACX,UAAU;GACV,YAAA;GACA,cAAa;GAJf,UAAA;IAMG,KAAS,OAAwC,OAAjC,kBAAC,GAAD,EAAA,UAAY,EAAiB,CAAA;IAC9C,kBAAC,GAAD;KACE,OAAO,EAAE,2CAA2C;KACpD,MAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAU;MAEnB,AADA,EAAS,EAAM,OAAO,KAAK,GAC3B,EAAS,IAAI;KACf;KACA,aAAa,EAAE,iDAAiD;KAChE,cAAa;KACb,UAAA;IACD,CAAA;IACD,kBAAC,GAAD;KAAQ,MAAK;KAAS,WAAW;KAC9B,UAAA,EAAE,uCAAuC;IACpC,CAAA;GACJ;;CACG,CAAA,GAKb,kBAAC,GAAD;EAAY,OAAO,EAAE,iCAAiC;EACnD,UAAA;CACS,CAAA;AAEhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityActionFormDialog.js","names":[],"sources":["../../../../../src/components/backoffice/actions/BackofficeEntityActionFormDialog.tsx"],"sourcesContent":["import {\n type FormEvent,\n type JSX,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport {\n type MutationPayloadBase,\n resolveMutationOutcome,\n} from '../../../relay/mutationResult.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Input } from '@plumile/ui/atomic/atoms/input/Input.js';\nimport { Modal } from '@plumile/ui/atomic/atoms/modal/Modal.js';\nimport { Textarea } from '@plumile/ui/atomic/atoms/textarea/Textarea.js';\nimport { CheckboxField } from '@plumile/ui/atomic/molecules/checkbox_field/CheckboxField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormGrid } from '@plumile/ui/atomic/molecules/form_grid/FormGrid.js';\nimport { FormFieldLayout } from '@plumile/ui/atomic/molecules/form_field_layout/FormFieldLayout.js';\nimport { HighlightCode } from '@plumile/ui/atomic/molecules/highlight/HighlightCode.js';\nimport { useToast } from '@plumile/ui/atomic/molecules/toast/ToastProvider.js';\nimport { BackofficeFormSection } from '@plumile/ui/backoffice/molecules/backoffice_form_section/BackofficeFormSection.js';\nimport { SimpleSelect } from '@plumile/ui/components/select/SimpleSelect.js';\nimport type {\n BackofficeEntityActionFormFieldSpec,\n BackofficeEntityFormMutationActionSpec,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../../../provider/BackofficeConfigContext.js';\nimport { EntityIdFilterField } from '../filters/EntityIdFilterField.js';\nimport { EntityIdPickerDialog } from '../pickers/EntityIdPickerDialog.js';\nimport {\n resolveToastSpec,\n resolveToastViewActions,\n} from './toastViewAction.js';\n\nconst { commitMutation, useRelayEnvironment } = ReactRelay;\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport * as styles from './backofficeEntityActionFormDialog.css.js';\n\nexport type BackofficeEntityActionFormDialogProps<Node> = {\n isOpen: boolean;\n action: BackofficeEntityFormMutationActionSpec<Node, any, any, any>;\n node: Node;\n onClose: () => void;\n onSuccess?: () => void;\n};\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n};\n\nconst extractMutationPayload = (\n response: unknown,\n): MutationPayloadBase | null => {\n if (!isPlainObject(response)) {\n return null;\n }\n\n for (const value of Object.values(response)) {\n if (isPlainObject(value) && ('status' in value || 'result' in value)) {\n return value;\n }\n }\n\n return null;\n};\n\nconst buildDefaultValues = (\n fields: readonly BackofficeEntityActionFormFieldSpec[],\n): Record<string, unknown> => {\n const output: Record<string, unknown> = {};\n fields.forEach((field) => {\n if (field.kind === 'boolean') {\n output[field.id] = field.defaultValue ?? false;\n return;\n }\n if (field.kind === 'multiEnum') {\n output[field.id] = field.defaultValue ?? [];\n return;\n }\n if (field.defaultValue != null) {\n output[field.id] = field.defaultValue;\n return;\n }\n output[field.id] = '';\n });\n return output;\n};\n\nconst normalizeInitialValue = (\n field: BackofficeEntityActionFormFieldSpec,\n value: unknown,\n): unknown => {\n if (field.kind === 'number') {\n if (typeof value === 'number') {\n return String(value);\n }\n if (typeof value === 'string') {\n return value;\n }\n return '';\n }\n if (field.kind === 'multiEnum') {\n if (Array.isArray(value)) {\n return value.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n return [];\n }\n if (field.kind === 'boolean') {\n return value === true;\n }\n if (typeof value === 'string') {\n return value;\n }\n return value ?? '';\n};\n\nconst buildInitialValues = <Node,>(\n action: BackofficeEntityFormMutationActionSpec<Node, any, any, any>,\n node: Node,\n): Record<string, unknown> => {\n const defaults = buildDefaultValues(action.fields);\n if (action.getInitialValues == null) {\n return defaults;\n }\n const overrides: unknown = action.getInitialValues(node);\n if (!isPlainObject(overrides)) {\n return defaults;\n }\n const next: Record<string, unknown> = { ...defaults };\n action.fields.forEach((field) => {\n if (!(field.id in overrides)) {\n return;\n }\n next[field.id] = normalizeInitialValue(field, overrides[field.id]);\n });\n return next;\n};\n\nexport const BackofficeEntityActionFormDialog = <Node,>({\n isOpen,\n action,\n node,\n onClose,\n onSuccess,\n}: BackofficeEntityActionFormDialogProps<Node>): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const routing = useContext(RoutingContext);\n const environment = useRelayEnvironment();\n const toast = useToast();\n const formId = useId();\n\n const [values, setValues] = useState<Record<string, unknown>>({});\n const [formError, setFormError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [resultValue, setResultValue] = useState<string | null>(null);\n const [resultResponse, setResultResponse] = useState<unknown>(null);\n const [activeEntityPicker, setActiveEntityPicker] = useState<{\n fieldId: string;\n entity: string;\n label: string;\n } | null>(null);\n\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n setValues(buildInitialValues(action, node));\n setFormError(null);\n setFieldErrors({});\n setResultValue(null);\n setResultResponse(null);\n }, [action, isOpen, node]);\n\n const handleClose = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n onClose();\n }, [isSubmitting, onClose]);\n\n const setFieldValue = useCallback((fieldId: string, value: unknown) => {\n setValues((current) => {\n return { ...current, [fieldId]: value };\n });\n setFieldErrors((current) => {\n if (current[fieldId] == null) {\n return current;\n }\n const { [fieldId]: removedValue, ...next } = current;\n return next;\n });\n }, []);\n\n const title = resolveLabel(action.label, tApp);\n\n const resolveRequiredError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.required', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidNumberError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidNumber', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJson', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonObjectError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonObject', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonArrayError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonArray', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const buildPayload = useCallback(():\n | { values: Record<string, unknown> }\n | { error: string; fieldId?: string } => {\n const output: Record<string, unknown> = {};\n\n for (const field of action.fields) {\n const fieldLabel = resolveLabel(field.label, tApp);\n const rawValue = values[field.id];\n\n switch (field.kind) {\n case 'text': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'textarea': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'number': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n } else if (\n typeof rawValue === 'number' &&\n Number.isFinite(rawValue)\n ) {\n valueString = String(rawValue);\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n const parsed = Number(valueString);\n if (!Number.isFinite(parsed)) {\n return {\n error: resolveInvalidNumberError(fieldLabel),\n fieldId: field.id,\n };\n }\n output[field.id] = parsed;\n break;\n }\n case 'json': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(valueString);\n } catch {\n return {\n error: resolveInvalidJsonError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n const jsonType = field.jsonType ?? 'object';\n if (jsonType === 'object' && !isPlainObject(parsed)) {\n return {\n error: resolveInvalidJsonObjectError(fieldLabel),\n fieldId: field.id,\n };\n }\n if (jsonType === 'array' && !Array.isArray(parsed)) {\n return {\n error: resolveInvalidJsonArrayError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n output[field.id] = parsed;\n break;\n }\n case 'enum': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'boolean': {\n output[field.id] = rawValue === true;\n break;\n }\n case 'entityId': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'multiEnum': {\n let list: string[] = [];\n if (Array.isArray(rawValue)) {\n list = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n if (list.length === 0) {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = list;\n break;\n }\n default: {\n break;\n }\n }\n }\n\n return { values: output };\n }, [\n action.fields,\n resolveInvalidJsonArrayError,\n resolveInvalidJsonError,\n resolveInvalidJsonObjectError,\n resolveInvalidNumberError,\n resolveRequiredError,\n tApp,\n values,\n ]);\n\n const handleSubmit = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n\n setFormError(null);\n setFieldErrors({});\n\n const payload = buildPayload();\n if ('error' in payload) {\n setFormError(payload.error);\n if (payload.fieldId != null) {\n setFieldErrors({ [payload.fieldId]: payload.error });\n }\n return;\n }\n\n let variables: ReturnType<typeof action.getVariables>;\n try {\n variables = action.getVariables(node, payload.values);\n } catch {\n const message = t('actions.form.errors.invalidPayload');\n setFormError(message);\n return;\n }\n\n setIsSubmitting(true);\n commitMutation(environment, {\n mutation: action.mutation,\n variables,\n updater: (store) => {\n action.updater?.(store, node);\n },\n onCompleted: (response) => {\n setIsSubmitting(false);\n const mutationPayload = extractMutationPayload(response);\n if (mutationPayload != null) {\n let defaultErrorMessage = t('actions.form.errors.invalidPayload');\n if (action.toasts?.error?.message != null) {\n defaultErrorMessage = resolveLabel(\n action.toasts.error.message,\n tApp,\n );\n } else if (action.toasts?.error?.title != null) {\n defaultErrorMessage = resolveLabel(action.toasts.error.title, tApp);\n }\n\n const outcome = resolveMutationOutcome(mutationPayload, {\n defaultErrorMessage,\n mapReason: (reason) => {\n const mapped = action.mapErrorReason?.(reason, node);\n if (mapped == null) {\n return null;\n }\n if (typeof mapped === 'function') {\n return resolveLabel(mapped, tApp);\n }\n return String(mapped);\n },\n });\n if (!outcome.ok) {\n const error = new Error(outcome.message);\n setFormError(outcome.message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n return;\n }\n }\n\n action.onCompleted?.(response, node);\n\n let hasCustomResult = false;\n if (action.result?.render != null) {\n const renderedResult = action.result.render(response, node);\n if (renderedResult != null) {\n hasCustomResult = true;\n setResultResponse(response);\n }\n }\n if (action.toasts?.success != null) {\n const toastSpec = resolveToastSpec(action.toasts.success, tApp);\n const toastActions = resolveToastViewActions({\n toast: action.toasts.success,\n response,\n node,\n tApp,\n entities,\n defaultLabel: t('actions.view'),\n navigateTo: (to) => {\n routing?.history.push({ pathname: to });\n },\n });\n toast.push({\n kind: 'info',\n title: toastSpec.title,\n message: toastSpec.message,\n actions: toastActions,\n });\n }\n\n if (action.result != null) {\n const nextValue = action.result.getValue(response, node);\n if (typeof nextValue === 'string' && nextValue.trim() !== '') {\n setResultValue(nextValue);\n onSuccess?.();\n return;\n }\n }\n\n if (hasCustomResult) {\n onSuccess?.();\n return;\n }\n\n onSuccess?.();\n onClose();\n },\n onError: (error) => {\n setIsSubmitting(false);\n const message = t('actions.form.errors.submitFailed');\n setFormError(message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n },\n });\n }, [\n action,\n buildPayload,\n entities,\n environment,\n isSubmitting,\n node,\n onClose,\n onSuccess,\n routing?.history,\n t,\n tApp,\n toast,\n ]);\n\n const handleFormSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n handleSubmit();\n },\n [handleSubmit],\n );\n\n const resultLabel = useMemo(() => {\n if (action.result == null) {\n return null;\n }\n return resolveLabel(action.result.label, tApp);\n }, [action.result, tApp]);\n\n const resultRender = useMemo(() => {\n if (action.result?.render == null || resultResponse == null) {\n return null;\n }\n return action.result.render(resultResponse, node);\n }, [action.result, node, resultResponse]);\n\n const showResult =\n (resultValue != null && resultLabel != null) || resultRender != null;\n\n const submitLabel = resolveLabel(action.label, tApp);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n initialFocus=\"first-form-control\"\n footer={\n <div className={styles.actions}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n disabled={isSubmitting}\n onClick={handleClose}\n >\n {t('actions.form.cancel')}\n </Button>\n {!showResult && (\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"small\"\n disabled={isSubmitting}\n isLoading={isSubmitting}\n loadingLabel={t('actions.form.submitting')}\n onClick={handleSubmit}\n >\n {submitLabel}\n </Button>\n )}\n </div>\n }\n >\n <Form onSubmit={handleFormSubmit} className={styles.form}>\n <FormError message={formError} />\n <BackofficeFormSection>\n <FormGrid layout=\"vertical\">\n {action.fields.map((field) => {\n const fieldLabel = resolveLabel(field.label, tApp);\n let fieldDescription: string | null = null;\n if (field.description != null) {\n fieldDescription = resolveLabel(field.description, tApp);\n }\n const fieldInputId = `${formId}-${field.id}`;\n const fieldDescriptionId = `${fieldInputId}-description`;\n const fieldErrorId = `${fieldInputId}-error`;\n const fieldError = fieldErrors[field.id] ?? null;\n const isFieldInvalid = fieldError != null;\n let inputVariant: 'error' | undefined;\n let selectState: 'default' | 'error' = 'default';\n if (isFieldInvalid) {\n inputVariant = 'error';\n selectState = 'error';\n }\n let describedBy: string | undefined;\n if (fieldDescription != null && fieldError != null) {\n describedBy = `${fieldDescriptionId} ${fieldErrorId}`;\n } else if (fieldDescription != null) {\n describedBy = fieldDescriptionId;\n } else if (fieldError != null) {\n describedBy = fieldErrorId;\n }\n\n switch (field.kind) {\n case 'text': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Input\n id={fieldInputId}\n type=\"text\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'textarea': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={field.rows ?? 8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'number': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Input\n id={fieldInputId}\n type=\"number\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'json': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'enum': {\n const rawValue = values[field.id];\n let selected = '';\n if (typeof rawValue === 'string') {\n selected = rawValue;\n }\n const options = field.options.map((option) => {\n return {\n id: option.value,\n value: option.value,\n label: resolveLabel(option.label, tApp),\n };\n });\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelId={`${fieldInputId}-label`}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <SimpleSelect\n options={options}\n value={selected}\n placeholder={fieldLabel}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n ariaLabelledBy={`${fieldInputId}-label`}\n isDisabled={isSubmitting}\n state={selectState}\n onChange={(nextValue) => {\n setFieldValue(field.id, nextValue);\n }}\n />\n </FormFieldLayout>\n );\n }\n case 'boolean': {\n const checked = values[field.id] === true;\n return (\n <FormFieldLayout key={field.id}>\n <CheckboxField\n id={fieldInputId}\n label={fieldLabel}\n helperText={fieldDescription ?? undefined}\n error={fieldError ?? undefined}\n checked={checked}\n disabled={isSubmitting}\n onChange={(event) => {\n setFieldValue(field.id, event.target.checked);\n }}\n />\n </FormFieldLayout>\n );\n }\n case 'entityId': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <EntityIdFilterField\n id={fieldInputId}\n label={fieldLabel}\n value={value}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n disabled={isSubmitting}\n onPick={() => {\n setActiveEntityPicker({\n fieldId: field.id,\n entity: field.entity,\n label: fieldLabel,\n });\n }}\n onClear={() => {\n setFieldValue(field.id, '');\n }}\n />\n </FormFieldLayout>\n );\n }\n case 'multiEnum': {\n const rawValue = values[field.id];\n const fieldLegendId = `${fieldInputId}-legend`;\n let selected: string[] = [];\n if (Array.isArray(rawValue)) {\n selected = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string';\n });\n }\n return (\n <FormFieldLayout\n key={field.id}\n as=\"fieldset\"\n label={fieldLabel}\n labelId={fieldLegendId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <div\n className={styles.checkboxGroup}\n role=\"group\"\n aria-labelledby={fieldLegendId}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n >\n {field.options.map((option, index) => {\n const optionLabel = resolveLabel(\n option.label,\n tApp,\n );\n const isChecked = selected.includes(option.value);\n return (\n <CheckboxField\n key={`${option.value}-${index}`}\n id={`${fieldInputId}-${index}`}\n label={optionLabel}\n checked={isChecked}\n disabled={isSubmitting}\n onChange={(event) => {\n let nextList = selected;\n if (event.target.checked) {\n if (!selected.includes(option.value)) {\n nextList = [...selected, option.value];\n }\n } else {\n nextList = selected.filter((value) => {\n return value !== option.value;\n });\n }\n setFieldValue(field.id, nextList);\n }}\n />\n );\n })}\n </div>\n </FormFieldLayout>\n );\n }\n default: {\n return null;\n }\n }\n })}\n </FormGrid>\n </BackofficeFormSection>\n\n {showResult && (\n <div className={styles.resultSection}>\n {resultValue != null && resultLabel != null && (\n <HighlightCode\n badgeLabel={resultLabel}\n copyCode={resultValue}\n fallbackCodeText={resultValue}\n />\n )}\n {resultRender}\n </div>\n )}\n </Form>\n </Modal>\n <EntityIdPickerDialog\n isOpen={activeEntityPicker != null}\n entity={activeEntityPicker?.entity ?? ''}\n title={activeEntityPicker?.label ?? ''}\n onClose={() => {\n setActiveEntityPicker(null);\n }}\n onSelectId={(id) => {\n if (activeEntityPicker == null) {\n return;\n }\n setFieldValue(activeEntityPicker.fieldId, id);\n setActiveEntityPicker(null);\n }}\n />\n </>\n );\n};\n\nexport default BackofficeEntityActionFormDialog;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,IAAM,EAAE,gBAAA,IAAgB,4BAAwB,GAa1C,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGb,KAAiB,MACd,OAAO,KAAU,cAAY,KAAiB,CAAC,MAAM,QAAQ,CAAK,GAGrE,MACJ,MAC+B;CAC/B,IAAI,CAAC,EAAc,CAAQ,GACzB,OAAO;CAGT,KAAK,IAAM,KAAS,OAAO,OAAO,CAAQ,GACxC,IAAI,EAAc,CAAK,MAAM,YAAY,KAAS,YAAY,IAC5D,OAAO;CAIX,OAAO;AACT,GAEM,KACJ,MAC4B;CAC5B,IAAM,IAAkC,CAAC;CAgBzC,OAfA,EAAO,SAAS,MAAU;EACxB,IAAI,EAAM,SAAS,WAAW;GAC5B,EAAO,EAAM,MAAM,EAAM,gBAAgB;GACzC;EACF;EACA,IAAI,EAAM,SAAS,aAAa;GAC9B,EAAO,EAAM,MAAM,EAAM,gBAAgB,CAAC;GAC1C;EACF;EACA,IAAI,EAAM,gBAAgB,MAAM;GAC9B,EAAO,EAAM,MAAM,EAAM;GACzB;EACF;EACA,EAAO,EAAM,MAAM;CACrB,CAAC,GACM;AACT,GAEM,KACJ,GACA,MAEI,EAAM,SAAS,WACb,OAAO,KAAU,WACZ,OAAO,CAAK,IAEjB,OAAO,KAAU,WACZ,IAEF,KAEL,EAAM,SAAS,cACb,MAAM,QAAQ,CAAK,IACd,EAAM,QAAQ,MACZ,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,EACtD,IAEI,CAAC,IAEN,EAAM,SAAS,YACV,MAAU,KAEf,OAAO,KAAU,WACZ,IAEF,KAAS,IAGZ,MACJ,GACA,MAC4B;CAC5B,IAAM,IAAW,EAAmB,EAAO,MAAM;CACjD,IAAI,EAAO,oBAAoB,MAC7B,OAAO;CAET,IAAM,IAAqB,EAAO,iBAAiB,CAAI;CACvD,IAAI,CAAC,EAAc,CAAS,GAC1B,OAAO;CAET,IAAM,IAAgC,EAAE,GAAG,EAAS;CAOpD,OANA,EAAO,OAAO,SAAS,MAAU;EACzB,EAAM,MAAM,MAGlB,EAAK,EAAM,MAAM,EAAsB,GAAO,EAAU,EAAM,GAAG;CACnE,CAAC,GACM;AACT,GAEa,KAA2C,EACtD,WACA,WACA,SACA,YACA,mBACqE;CACrE,IAAM,EAAE,GAAG,MAAS,GAAe,GAC7B,EAAE,SAAM,EAA8B,GACtC,EAAE,gBAAa,EAAoB,GACnC,IAAU,EAAW,EAAc,GACnC,IAAc,GAAoB,GAClC,IAAQ,GAAS,GACjB,KAAS,GAAM,GAEf,CAAC,GAAQ,KAAa,EAAkC,CAAC,CAAC,GAC1D,CAAC,IAAW,KAAgB,EAAwB,IAAI,GACxD,CAAC,IAAa,KAAkB,EAAiC,CAAC,CAAC,GACnE,CAAC,GAAc,KAAmB,EAAS,EAAK,GAChD,CAAC,GAAa,KAAkB,EAAwB,IAAI,GAC5D,CAAC,GAAgB,KAAqB,EAAkB,IAAI,GAC5D,CAAC,GAAoB,KAAyB,EAI1C,IAAI;CAEd,QAAgB;EACT,MAGL,EAAU,GAAmB,GAAQ,CAAI,CAAC,GAC1C,EAAa,IAAI,GACjB,EAAe,CAAC,CAAC,GACjB,EAAe,IAAI,GACnB,EAAkB,IAAI;CACxB,GAAG;EAAC;EAAQ;EAAQ;CAAI,CAAC;CAEzB,IAAM,IAAc,QAAkB;EAChC,KAGJ,EAAQ;CACV,GAAG,CAAC,GAAc,CAAO,CAAC,GAEpB,IAAgB,GAAa,GAAiB,MAAmB;EAIrE,AAHA,GAAW,OACF;GAAE,GAAG;IAAU,IAAU;EAAM,EACvC,GACD,GAAgB,MAAY;GAC1B,IAAI,EAAQ,MAAY,MACtB,OAAO;GAET,IAAM,GAAG,IAAU,GAAc,GAAG,MAAS;GAC7C,OAAO;EACT,CAAC;CACH,GAAG,CAAC,CAAC,GAEC,KAAQ,EAAa,EAAO,OAAO,CAAI,GAEvC,IAAuB,GAC1B,MACQ,EAAE,gCAAgC,EACvC,OAAO,EACT,CAAC,GAEH,CAAC,CAAC,CACJ,GAEM,IAA4B,GAC/B,MACQ,EAAE,qCAAqC,EAC5C,OAAO,EACT,CAAC,GAEH,CAAC,CAAC,CACJ,GAEM,KAA0B,GAC7B,MACQ,EAAE,mCAAmC,EAC1C,OAAO,EACT,CAAC,GAEH,CAAC,CAAC,CACJ,GAEM,KAAgC,GACnC,MACQ,EAAE,yCAAyC,EAChD,OAAO,EACT,CAAC,GAEH,CAAC,CAAC,CACJ,GAEM,KAA+B,GAClC,MACQ,EAAE,wCAAwC,EAC/C,OAAO,EACT,CAAC,GAEH,CAAC,CAAC,CACJ,GAEM,KAAe,QAEsB;EACzC,IAAM,IAAkC,CAAC;EAEzC,KAAK,IAAM,KAAS,EAAO,QAAQ;GACjC,IAAM,IAAa,EAAa,EAAM,OAAO,CAAI,GAC3C,IAAW,EAAO,EAAM;GAE9B,QAAQ,EAAM,MAAd;IACE,KAAK,QAAQ;KACX,IAAI,IAAQ;KAIZ,IAHI,OAAO,KAAa,aACtB,IAAQ,EAAS,KAAK,IAEpB,MAAU,IAAI;MAChB,IAAI,EAAM,UACR,OAAO;OACL,OAAO,EAAqB,CAAU;OACtC,SAAS,EAAM;MACjB;MAEF;KACF;KACA,EAAO,EAAM,MAAM;KACnB;IACF;IACA,KAAK,YAAY;KACf,IAAI,IAAQ;KAIZ,IAHI,OAAO,KAAa,aACtB,IAAQ,EAAS,KAAK,IAEpB,MAAU,IAAI;MAChB,IAAI,EAAM,UACR,OAAO;OACL,OAAO,EAAqB,CAAU;OACtC,SAAS,EAAM;MACjB;MAEF;KACF;KACA,EAAO,EAAM,MAAM;KACnB;IACF;IACA,KAAK,UAAU;KACb,IAAI,IAAc;KASlB,IARI,OAAO,KAAa,WACtB,IAAc,EAAS,KAAK,IAE5B,OAAO,KAAa,YACpB,OAAO,SAAS,CAAQ,MAExB,IAAc,OAAO,CAAQ,IAE3B,MAAgB,IAAI;MACtB,IAAI,EAAM,UACR,OAAO;OACL,OAAO,EAAqB,CAAU;OACtC,SAAS,EAAM;MACjB;MAEF;KACF;KACA,IAAM,IAAS,OAAO,CAAW;KACjC,IAAI,CAAC,OAAO,SAAS,CAAM,GACzB,OAAO;MACL,OAAO,EAA0B,CAAU;MAC3C,SAAS,EAAM;KACjB;KAEF,EAAO,EAAM,MAAM;KACnB;IACF;IACA,KAAK,QAAQ;KACX,IAAI,IAAc;KAIlB,IAHI,OAAO,KAAa,aACtB,IAAc,EAAS,KAAK,IAE1B,MAAgB,IAAI;MACtB,IAAI,EAAM,UACR,OAAO;OACL,OAAO,EAAqB,CAAU;OACtC,SAAS,EAAM;MACjB;MAEF;KACF;KACA,IAAI;KACJ,IAAI;MACF,IAAS,KAAK,MAAM,CAAW;KACjC,QAAQ;MACN,OAAO;OACL,OAAO,GAAwB,CAAU;OACzC,SAAS,EAAM;MACjB;KACF;KAEA,IAAM,IAAW,EAAM,YAAY;KACnC,IAAI,MAAa,YAAY,CAAC,EAAc,CAAM,GAChD,OAAO;MACL,OAAO,GAA8B,CAAU;MAC/C,SAAS,EAAM;KACjB;KAEF,IAAI,MAAa,WAAW,CAAC,MAAM,QAAQ,CAAM,GAC/C,OAAO;MACL,OAAO,GAA6B,CAAU;MAC9C,SAAS,EAAM;KACjB;KAGF,EAAO,EAAM,MAAM;KACnB;IACF;IACA,KAAK,QAAQ;KACX,IAAI,IAAQ;KAIZ,IAHI,OAAO,KAAa,aACtB,IAAQ,EAAS,KAAK,IAEpB,MAAU,IAAI;MAChB,IAAI,EAAM,UACR,OAAO;OACL,OAAO,EAAqB,CAAU;OACtC,SAAS,EAAM;MACjB;MAEF;KACF;KACA,EAAO,EAAM,MAAM;KACnB;IACF;IACA,KAAK;KACH,EAAO,EAAM,MAAM,MAAa;KAChC;IAEF,KAAK,YAAY;KACf,IAAI,IAAQ;KAIZ,IAHI,OAAO,KAAa,aACtB,IAAQ,EAAS,KAAK,IAEpB,MAAU,IAAI;MAChB,IAAI,EAAM,UACR,OAAO;OACL,OAAO,EAAqB,CAAU;OACtC,SAAS,EAAM;MACjB;MAEF;KACF;KACA,EAAO,EAAM,MAAM;KACnB;IACF;IACA,KAAK,aAAa;KAChB,IAAI,IAAiB,CAAC;KAMtB,IALI,MAAM,QAAQ,CAAQ,MACxB,IAAO,EAAS,QAAQ,MACf,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,EACtD,IAEC,EAAK,WAAW,GAAG;MACrB,IAAI,EAAM,UACR,OAAO;OACL,OAAO,EAAqB,CAAU;OACtC,SAAS,EAAM;MACjB;MAEF;KACF;KACA,EAAO,EAAM,MAAM;KACnB;IACF;GAIF;EACF;EAEA,OAAO,EAAE,QAAQ,EAAO;CAC1B,GAAG;EACD,EAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,GAEK,IAAe,QAAkB;EACrC,IAAI,GACF;EAIF,AADA,EAAa,IAAI,GACjB,EAAe,CAAC,CAAC;EAEjB,IAAM,IAAU,GAAa;EAC7B,IAAI,WAAW,GAAS;GAEtB,AADA,EAAa,EAAQ,KAAK,GACtB,EAAQ,WAAW,QACrB,EAAe,GAAG,EAAQ,UAAU,EAAQ,MAAM,CAAC;GAErD;EACF;EAEA,IAAI;EACJ,IAAI;GACF,IAAY,EAAO,aAAa,GAAM,EAAQ,MAAM;EACtD,QAAQ;GACN,IAAM,IAAU,EAAE,oCAAoC;GACtD,EAAa,CAAO;GACpB;EACF;EAGA,AADA,EAAgB,EAAI,GACpB,GAAe,GAAa;GAC1B,UAAU,EAAO;GACjB;GACA,UAAU,MAAU;IAClB,EAAO,UAAU,GAAO,CAAI;GAC9B;GACA,cAAc,MAAa;IACzB,EAAgB,EAAK;IACrB,IAAM,IAAkB,GAAuB,CAAQ;IACvD,IAAI,KAAmB,MAAM;KAC3B,IAAI,IAAsB,EAAE,oCAAoC;KAChE,AAAI,EAAO,QAAQ,OAAO,WAAW,OAK1B,EAAO,QAAQ,OAAO,SAAS,SACxC,IAAsB,EAAa,EAAO,OAAO,MAAM,OAAO,CAAI,KALlE,IAAsB,EACpB,EAAO,OAAO,MAAM,SACpB,CACF;KAKF,IAAM,IAAU,EAAuB,GAAiB;MACtD;MACA,YAAY,MAAW;OACrB,IAAM,IAAS,EAAO,iBAAiB,GAAQ,CAAI;OAOnD,OANI,KAAU,OACL,OAEL,OAAO,KAAW,aACb,EAAa,GAAQ,CAAI,IAE3B,OAAO,CAAM;MACtB;KACF,CAAC;KACD,IAAI,CAAC,EAAQ,IAAI;MACf,IAAM,IAAY,MAAM,EAAQ,OAAO;MAGvC,IAFA,EAAa,EAAQ,OAAO,GAC5B,EAAO,UAAU,GAAO,CAAI,GACxB,EAAO,QAAQ,SAAS,MAAM;OAChC,IAAM,IAAa,EAAa,EAAO,OAAO,MAAM,OAAO,CAAI,GAC3D;OAIJ,AAHI,EAAO,OAAO,MAAM,WAAW,SACjC,IAAe,EAAa,EAAO,OAAO,MAAM,SAAS,CAAI,IAE/D,EAAM,MAAM,GAAY,CAAY;MACtC;MACA;KACF;IACF;IAEA,EAAO,cAAc,GAAU,CAAI;IAEnC,IAAI,IAAkB;IAQtB,IAPI,EAAO,QAAQ,UAAU,QACJ,EAAO,OAAO,OAAO,GAAU,CAClD,KAAkB,SACpB,IAAkB,IAClB,EAAkB,CAAQ,IAG1B,EAAO,QAAQ,WAAW,MAAM;KAClC,IAAM,IAAY,EAAiB,EAAO,OAAO,SAAS,CAAI,GACxD,IAAe,EAAwB;MAC3C,OAAO,EAAO,OAAO;MACrB;MACA;MACA;MACA;MACA,cAAc,EAAE,cAAc;MAC9B,aAAa,MAAO;OAClB,GAAS,QAAQ,KAAK,EAAE,UAAU,EAAG,CAAC;MACxC;KACF,CAAC;KACD,EAAM,KAAK;MACT,MAAM;MACN,OAAO,EAAU;MACjB,SAAS,EAAU;MACnB,SAAS;KACX,CAAC;IACH;IAEA,IAAI,EAAO,UAAU,MAAM;KACzB,IAAM,IAAY,EAAO,OAAO,SAAS,GAAU,CAAI;KACvD,IAAI,OAAO,KAAc,YAAY,EAAU,KAAK,MAAM,IAAI;MAE5D,AADA,EAAe,CAAS,GACxB,IAAY;MACZ;KACF;IACF;IAEA,IAAI,GAAiB;KACnB,IAAY;KACZ;IACF;IAGA,AADA,IAAY,GACZ,EAAQ;GACV;GACA,UAAU,MAAU;IAClB,EAAgB,EAAK;IACrB,IAAM,IAAU,EAAE,kCAAkC;IAGpD,IAFA,EAAa,CAAO,GACpB,EAAO,UAAU,GAAO,CAAI,GACxB,EAAO,QAAQ,SAAS,MAAM;KAChC,IAAM,IAAa,EAAa,EAAO,OAAO,MAAM,OAAO,CAAI,GAC3D;KAIJ,AAHI,EAAO,OAAO,MAAM,WAAW,SACjC,IAAe,EAAa,EAAO,OAAO,MAAM,SAAS,CAAI,IAE/D,EAAM,MAAM,GAAY,CAAY;IACtC;GACF;EACF,CAAC;CACH,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,GAAS;EACT;EACA;EACA;CACF,CAAC,GAEK,KAAmB,GACtB,MAAsC;EAErC,AADA,EAAM,eAAe,GACrB,EAAa;CACf,GACA,CAAC,CAAY,CACf,GAEM,IAAc,QACd,EAAO,UAAU,OACZ,OAEF,EAAa,EAAO,OAAO,OAAO,CAAI,GAC5C,CAAC,EAAO,QAAQ,CAAI,CAAC,GAElB,KAAe,QACf,EAAO,QAAQ,UAAU,QAAQ,KAAkB,OAC9C,OAEF,EAAO,OAAO,OAAO,GAAgB,CAAI,GAC/C;EAAC,EAAO;EAAQ;EAAM;CAAc,CAAC,GAElC,IACH,KAAe,QAAQ,KAAe,QAAS,MAAgB,MAE5D,KAAc,EAAa,EAAO,OAAO,CAAI;CAMnD,OAJK,IAKH,kBAAA,IAAA,EAAA,UAAA,CACE,kBAAC,IAAD;EACU;EACR,SAAS;EACF;EACP,cAAa;EACb,QACE,kBAAC,OAAD;GAAK,WAAW;GAAhB,UAAA,CACE,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,MAAK;IACL,UAAU;IACV,SAAS;IAER,UAAA,EAAE,qBAAqB;GAClB,CAAA,GACP,CAAC,KACA,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,MAAK;IACL,UAAU;IACV,WAAW;IACX,cAAc,EAAE,yBAAyB;IACzC,SAAS;IAER,UAAA;GACK,CAAA,CAEP;;EAGP,UAAA,kBAAC,IAAD;GAAM,UAAU;GAAkB,WAAW;GAA7C,UAAA;IACE,kBAAC,IAAD,EAAW,SAAS,GAAY,CAAA;IAChC,kBAAC,IAAD,EAAA,UACE,kBAAC,IAAD;KAAU,QAAO;KACd,UAAA,EAAO,OAAO,KAAK,MAAU;MAC5B,IAAM,IAAa,EAAa,EAAM,OAAO,CAAI,GAC7C,IAAkC;MACtC,AAAI,EAAM,eAAe,SACvB,IAAmB,EAAa,EAAM,aAAa,CAAI;MAEzD,IAAM,IAAe,GAAG,GAAO,GAAG,EAAM,MAClC,IAAqB,GAAG,EAAa,eACrC,IAAe,GAAG,EAAa,SAC/B,IAAa,GAAY,EAAM,OAAO,MACtC,IAAiB,KAAc,MACjC,GACA,IAAmC;MACvC,AAAI,MACF,IAAe,SACf,IAAc;MAEhB,IAAI;MASJ,QARI,KAAoB,QAAQ,KAAc,OAC5C,IAAc,GAAG,EAAmB,GAAG,MAC9B,KAAoB,OAEpB,KAAc,SACvB,IAAc,KAFd,IAAc,GAKR,EAAM,MAAd;OACE,KAAK,QAAQ;QACX,IAAM,IAAW,EAAO,EAAM,KAC1B,IAAQ;QACZ,AAAI,OAAO,KAAa,aACtB,IAAQ;QAEV,IAAI;QAIJ,OAHI,EAAM,eAAe,SACvB,IAAc,EAAa,EAAM,aAAa,CAAI,IAGlD,kBAAC,GAAD;SAEE,OAAO;SACP,UAAU;SACV,UAAU,EAAM;SAChB,aAAa;SACb,eAAe;SACf,OAAO;SACP,SAAS;SAET,UAAA,kBAAC,GAAD;UACE,IAAI;UACJ,MAAK;UACE;UACM;UACb,oBAAkB;UAClB,gBAAc;UACd,UAAU;UACV,SAAS;UACT,WAAW,MAAU;WACnB,EAAc,EAAM,IAAI,EAAM,OAAO,KAAK;UAC5C;UACA,WAAA;SACD,CAAA;QACc,GAvBV,EAAM,EAuBI;OAErB;OACA,KAAK,YAAY;QACf,IAAM,IAAW,EAAO,EAAM,KAC1B,IAAQ;QACZ,AAAI,OAAO,KAAa,aACtB,IAAQ;QAEV,IAAI;QAIJ,OAHI,EAAM,eAAe,SACvB,IAAc,EAAa,EAAM,aAAa,CAAI,IAGlD,kBAAC,GAAD;SAEE,OAAO;SACP,UAAU;SACV,UAAU,EAAM;SAChB,aAAa;SACb,eAAe;SACf,OAAO;SACP,SAAS;SAET,UAAA,kBAAC,GAAD;UACE,IAAI;UACG;UACM;UACb,MAAM,EAAM,QAAQ;UACpB,oBAAkB;UAClB,gBAAc;UACd,UAAU;UACV,SAAS;UACT,WAAW,MAAU;WACnB,EAAc,EAAM,IAAI,EAAM,OAAO,KAAK;UAC5C;UACA,WAAA;SACD,CAAA;QACc,GAvBV,EAAM,EAuBI;OAErB;OACA,KAAK,UAAU;QACb,IAAM,IAAW,EAAO,EAAM,KAC1B,IAAQ;QACZ,AAAI,OAAO,KAAa,aACtB,IAAQ;QAEV,IAAI;QAIJ,OAHI,EAAM,eAAe,SACvB,IAAc,EAAa,EAAM,aAAa,CAAI,IAGlD,kBAAC,GAAD;SAEE,OAAO;SACP,UAAU;SACV,UAAU,EAAM;SAChB,aAAa;SACb,eAAe;SACf,OAAO;SACP,SAAS;SAET,UAAA,kBAAC,GAAD;UACE,IAAI;UACJ,MAAK;UACE;UACM;UACb,oBAAkB;UAClB,gBAAc;UACd,UAAU;UACV,SAAS;UACT,WAAW,MAAU;WACnB,EAAc,EAAM,IAAI,EAAM,OAAO,KAAK;UAC5C;UACA,WAAA;SACD,CAAA;QACc,GAvBV,EAAM,EAuBI;OAErB;OACA,KAAK,QAAQ;QACX,IAAM,IAAW,EAAO,EAAM,KAC1B,IAAQ;QACZ,AAAI,OAAO,KAAa,aACtB,IAAQ;QAEV,IAAI;QAIJ,OAHI,EAAM,eAAe,SACvB,IAAc,EAAa,EAAM,aAAa,CAAI,IAGlD,kBAAC,GAAD;SAEE,OAAO;SACP,UAAU;SACV,UAAU,EAAM;SAChB,aAAa;SACb,eAAe;SACf,OAAO;SACP,SAAS;SAET,UAAA,kBAAC,GAAD;UACE,IAAI;UACG;UACM;UACb,MAAM;UACN,oBAAkB;UAClB,gBAAc;UACd,UAAU;UACV,SAAS;UACT,WAAW,MAAU;WACnB,EAAc,EAAM,IAAI,EAAM,OAAO,KAAK;UAC5C;UACA,WAAA;SACD,CAAA;QACc,GAvBV,EAAM,EAuBI;OAErB;OACA,KAAK,QAAQ;QACX,IAAM,IAAW,EAAO,EAAM,KAC1B,IAAW;QACf,AAAI,OAAO,KAAa,aACtB,IAAW;QAEb,IAAM,IAAU,EAAM,QAAQ,KAAK,OAC1B;SACL,IAAI,EAAO;SACX,OAAO,EAAO;SACd,OAAO,EAAa,EAAO,OAAO,CAAI;QACxC,EACD;QACD,OACE,kBAAC,GAAD;SAEE,OAAO;SACP,SAAS,GAAG,EAAa;SACzB,UAAU,EAAM;SAChB,aAAa;SACb,eAAe;SACf,OAAO;SACP,SAAS;SAET,UAAA,kBAAC,IAAD;UACW;UACT,OAAO;UACP,aAAa;UACb,iBAAiB;UACjB,aAAa;UACb,gBAAgB,GAAG,EAAa;UAChC,YAAY;UACZ,OAAO;UACP,WAAW,MAAc;WACvB,EAAc,EAAM,IAAI,CAAS;UACnC;SACD,CAAA;QACc,GAtBV,EAAM,EAsBI;OAErB;OACA,KAAK,WAAW;QACd,IAAM,IAAU,EAAO,EAAM,QAAQ;QACrC,OACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;SACE,IAAI;SACJ,OAAO;SACP,YAAY,KAAoB,KAAA;SAChC,OAAO,KAAc,KAAA;SACZ;SACT,UAAU;SACV,WAAW,MAAU;UACnB,EAAc,EAAM,IAAI,EAAM,OAAO,OAAO;SAC9C;QACD,CAAA,EACc,GAZK,EAAM,EAYX;OAErB;OACA,KAAK,YAAY;QACf,IAAM,IAAW,EAAO,EAAM,KAC1B,IAAQ;QAIZ,OAHI,OAAO,KAAa,aACtB,IAAQ,IAGR,kBAAC,GAAD;SAEE,OAAO;SACP,UAAU;SACV,UAAU,EAAM;SAChB,aAAa;SACb,eAAe;SACf,OAAO;SACP,SAAS;SAET,UAAA,kBAAC,GAAD;UACE,IAAI;UACJ,OAAO;UACA;UACP,iBAAiB;UACjB,aAAa;UACb,UAAU;UACV,cAAc;WACZ,EAAsB;YACpB,SAAS,EAAM;YACf,QAAQ,EAAM;YACd,OAAO;WACT,CAAC;UACH;UACA,eAAe;WACb,EAAc,EAAM,IAAI,EAAE;UAC5B;SACD,CAAA;QACc,GA3BV,EAAM,EA2BI;OAErB;OACA,KAAK,aAAa;QAChB,IAAM,IAAW,EAAO,EAAM,KACxB,IAAgB,GAAG,EAAa,UAClC,IAAqB,CAAC;QAM1B,OALI,MAAM,QAAQ,CAAQ,MACxB,IAAW,EAAS,QAAQ,MACnB,OAAO,KAAU,QACzB,IAGD,kBAAC,GAAD;SAEE,IAAG;SACH,OAAO;SACP,SAAS;SACT,UAAU,EAAM;SAChB,aAAa;SACb,eAAe;SACf,OAAO;SACP,SAAS;SAET,UAAA,kBAAC,OAAD;UACE,WAAW;UACX,MAAK;UACL,mBAAiB;UACjB,oBAAkB;UAClB,gBAAc;UAEb,UAAA,EAAM,QAAQ,KAAK,GAAQ,MAAU;WACpC,IAAM,IAAc,EAClB,EAAO,OACP,CACF,GACM,IAAY,EAAS,SAAS,EAAO,KAAK;WAChD,OACE,kBAAC,GAAD;YAEE,IAAI,GAAG,EAAa,GAAG;YACvB,OAAO;YACP,SAAS;YACT,UAAU;YACV,WAAW,MAAU;aACnB,IAAI,IAAW;aAUf,AATI,EAAM,OAAO,UACV,EAAS,SAAS,EAAO,KAAK,MACjC,IAAW,CAAC,GAAG,GAAU,EAAO,KAAK,KAGvC,IAAW,EAAS,QAAQ,MACnB,MAAU,EAAO,KACzB,GAEH,EAAc,EAAM,IAAI,CAAQ;YAClC;WACD,GAlBM,GAAG,EAAO,MAAM,GAAG,GAkBzB;UAEL,CAAC;SACE,CAAA;QACU,GA/CV,EAAM,EA+CI;OAErB;OACA,SACE,OAAO;MAEX;KACF,CAAC;IACO,CAAA,EACW,CAAA;IAEtB,KACC,kBAAC,OAAD;KAAK,WAAW;KAAhB,UAAA,CACG,KAAe,QAAQ,KAAe,QACrC,kBAAC,IAAD;MACE,YAAY;MACZ,UAAU;MACV,kBAAkB;KACnB,CAAA,GAEF,EACE;;GAEH;;CACD,CAAA,GACP,kBAAC,GAAD;EACE,QAAQ,KAAsB;EAC9B,QAAQ,GAAoB,UAAU;EACtC,OAAO,GAAoB,SAAS;EACpC,eAAe;GACb,EAAsB,IAAI;EAC5B;EACA,aAAa,MAAO;GACd,KAAsB,SAG1B,EAAc,EAAmB,SAAS,CAAE,GAC5C,EAAsB,IAAI;EAC5B;CACD,CAAA,CACD,EAAA,CAAA,IA9ZK;AAgaX"}
1
+ {"version":3,"file":"BackofficeEntityActionFormDialog.js","names":[],"sources":["../../../../../src/components/backoffice/actions/BackofficeEntityActionFormDialog.tsx"],"sourcesContent":["import {\n type FormEvent,\n type JSX,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport {\n type MutationPayloadBase,\n resolveMutationOutcome,\n} from '../../../relay/mutationResult.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Input } from '@plumile/ui/atomic/atoms/input/Input.js';\nimport { Modal } from '@plumile/ui/atomic/atoms/modal/Modal.js';\nimport { Textarea } from '@plumile/ui/atomic/atoms/textarea/Textarea.js';\nimport { CheckboxField } from '@plumile/ui/atomic/molecules/checkbox_field/CheckboxField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormGrid } from '@plumile/ui/atomic/molecules/form_grid/FormGrid.js';\nimport { FormFieldLayout } from '@plumile/ui/atomic/molecules/form_field_layout/FormFieldLayout.js';\nimport { HighlightCode } from '@plumile/ui/atomic/molecules/highlight/HighlightCode.js';\nimport { useToast } from '@plumile/ui/atomic/molecules/toast/ToastProvider.js';\nimport { BackofficeFormSection } from '@plumile/ui/backoffice/molecules/backoffice_form_section/BackofficeFormSection.js';\nimport { SimpleSelect } from '@plumile/ui/components/select/SimpleSelect.js';\nimport type {\n BackofficeEntityActionFormFieldSpec,\n BackofficeRuntimeEntityFormMutationActionSpec,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../../../provider/BackofficeConfigContext.js';\nimport { EntityIdFilterField } from '../filters/EntityIdFilterField.js';\nimport { EntityIdPickerDialog } from '../pickers/EntityIdPickerDialog.js';\nimport {\n resolveToastSpec,\n resolveToastViewActions,\n} from './toastViewAction.js';\n\nconst { commitMutation, useRelayEnvironment } = ReactRelay;\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport * as styles from './backofficeEntityActionFormDialog.css.js';\n\nexport type BackofficeEntityActionFormDialogProps<Node> = {\n isOpen: boolean;\n action: BackofficeRuntimeEntityFormMutationActionSpec<Node>;\n node: Node;\n onClose: () => void;\n onSuccess?: () => void;\n};\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n};\n\nconst extractMutationPayload = (\n response: unknown,\n): MutationPayloadBase | null => {\n if (!isPlainObject(response)) {\n return null;\n }\n\n for (const value of Object.values(response)) {\n if (isPlainObject(value) && ('status' in value || 'result' in value)) {\n return value;\n }\n }\n\n return null;\n};\n\nconst buildDefaultValues = (\n fields: readonly BackofficeEntityActionFormFieldSpec[],\n): Record<string, unknown> => {\n const output: Record<string, unknown> = {};\n fields.forEach((field) => {\n if (field.kind === 'boolean') {\n output[field.id] = field.defaultValue ?? false;\n return;\n }\n if (field.kind === 'multiEnum') {\n output[field.id] = field.defaultValue ?? [];\n return;\n }\n if (field.defaultValue != null) {\n output[field.id] = field.defaultValue;\n return;\n }\n output[field.id] = '';\n });\n return output;\n};\n\nconst normalizeInitialValue = (\n field: BackofficeEntityActionFormFieldSpec,\n value: unknown,\n): unknown => {\n if (field.kind === 'number') {\n if (typeof value === 'number') {\n return String(value);\n }\n if (typeof value === 'string') {\n return value;\n }\n return '';\n }\n if (field.kind === 'multiEnum') {\n if (Array.isArray(value)) {\n return value.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n return [];\n }\n if (field.kind === 'boolean') {\n return value === true;\n }\n if (typeof value === 'string') {\n return value;\n }\n return value ?? '';\n};\n\nconst buildInitialValues = <Node,>(\n action: BackofficeRuntimeEntityFormMutationActionSpec<Node>,\n node: Node,\n): Record<string, unknown> => {\n const defaults = buildDefaultValues(action.fields);\n if (action.getInitialValues == null) {\n return defaults;\n }\n const overrides: unknown = action.getInitialValues(node);\n if (!isPlainObject(overrides)) {\n return defaults;\n }\n const next: Record<string, unknown> = { ...defaults };\n action.fields.forEach((field) => {\n if (!(field.id in overrides)) {\n return;\n }\n next[field.id] = normalizeInitialValue(field, overrides[field.id]);\n });\n return next;\n};\n\nexport const BackofficeEntityActionFormDialog = <Node,>({\n isOpen,\n action,\n node,\n onClose,\n onSuccess,\n}: BackofficeEntityActionFormDialogProps<Node>): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const routing = useContext(RoutingContext);\n const environment = useRelayEnvironment();\n const toast = useToast();\n const formId = useId();\n\n const [values, setValues] = useState<Record<string, unknown>>({});\n const [formError, setFormError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [resultValue, setResultValue] = useState<string | null>(null);\n const [resultResponse, setResultResponse] = useState<unknown>(null);\n const [activeEntityPicker, setActiveEntityPicker] = useState<{\n fieldId: string;\n entity: string;\n label: string;\n } | null>(null);\n\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n setValues(buildInitialValues(action, node));\n setFormError(null);\n setFieldErrors({});\n setResultValue(null);\n setResultResponse(null);\n }, [action, isOpen, node]);\n\n const handleClose = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n onClose();\n }, [isSubmitting, onClose]);\n\n const setFieldValue = useCallback((fieldId: string, value: unknown) => {\n setValues((current) => {\n return { ...current, [fieldId]: value };\n });\n setFieldErrors((current) => {\n if (current[fieldId] == null) {\n return current;\n }\n const { [fieldId]: removedValue, ...next } = current;\n return next;\n });\n }, []);\n\n const title = resolveLabel(action.label, tApp);\n\n const resolveRequiredError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.required', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidNumberError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidNumber', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJson', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonObjectError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonObject', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonArrayError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonArray', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const buildPayload = useCallback(():\n | { values: Record<string, unknown> }\n | { error: string; fieldId?: string } => {\n const output: Record<string, unknown> = {};\n\n for (const field of action.fields) {\n const fieldLabel = resolveLabel(field.label, tApp);\n const rawValue = values[field.id];\n\n switch (field.kind) {\n case 'text': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'textarea': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'number': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n } else if (\n typeof rawValue === 'number' &&\n Number.isFinite(rawValue)\n ) {\n valueString = String(rawValue);\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n const parsed = Number(valueString);\n if (!Number.isFinite(parsed)) {\n return {\n error: resolveInvalidNumberError(fieldLabel),\n fieldId: field.id,\n };\n }\n output[field.id] = parsed;\n break;\n }\n case 'json': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(valueString);\n } catch {\n return {\n error: resolveInvalidJsonError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n const jsonType = field.jsonType ?? 'object';\n if (jsonType === 'object' && !isPlainObject(parsed)) {\n return {\n error: resolveInvalidJsonObjectError(fieldLabel),\n fieldId: field.id,\n };\n }\n if (jsonType === 'array' && !Array.isArray(parsed)) {\n return {\n error: resolveInvalidJsonArrayError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n output[field.id] = parsed;\n break;\n }\n case 'enum': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'boolean': {\n output[field.id] = rawValue === true;\n break;\n }\n case 'entityId': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'multiEnum': {\n let list: string[] = [];\n if (Array.isArray(rawValue)) {\n list = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n if (list.length === 0) {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = list;\n break;\n }\n default: {\n break;\n }\n }\n }\n\n return { values: output };\n }, [\n action.fields,\n resolveInvalidJsonArrayError,\n resolveInvalidJsonError,\n resolveInvalidJsonObjectError,\n resolveInvalidNumberError,\n resolveRequiredError,\n tApp,\n values,\n ]);\n\n const handleSubmit = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n\n setFormError(null);\n setFieldErrors({});\n\n const payload = buildPayload();\n if ('error' in payload) {\n setFormError(payload.error);\n if (payload.fieldId != null) {\n setFieldErrors({ [payload.fieldId]: payload.error });\n }\n return;\n }\n\n let variables: ReturnType<typeof action.getVariables>;\n try {\n variables = action.getVariables(node, payload.values);\n } catch {\n const message = t('actions.form.errors.invalidPayload');\n setFormError(message);\n return;\n }\n\n setIsSubmitting(true);\n commitMutation(environment, {\n mutation: action.mutation,\n variables,\n updater: (store) => {\n action.updater?.(store, node);\n },\n onCompleted: (response) => {\n setIsSubmitting(false);\n const mutationPayload = extractMutationPayload(response);\n if (mutationPayload != null) {\n let defaultErrorMessage = t('actions.form.errors.invalidPayload');\n if (action.toasts?.error?.message != null) {\n defaultErrorMessage = resolveLabel(\n action.toasts.error.message,\n tApp,\n );\n } else if (action.toasts?.error?.title != null) {\n defaultErrorMessage = resolveLabel(action.toasts.error.title, tApp);\n }\n\n const outcome = resolveMutationOutcome(mutationPayload, {\n defaultErrorMessage,\n mapReason: (reason) => {\n const mapped = action.mapErrorReason?.(reason, node);\n if (mapped == null) {\n return null;\n }\n if (typeof mapped === 'function') {\n return resolveLabel(mapped, tApp);\n }\n return String(mapped);\n },\n });\n if (!outcome.ok) {\n const error = new Error(outcome.message);\n setFormError(outcome.message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n return;\n }\n }\n\n action.onCompleted?.(response, node);\n\n let hasCustomResult = false;\n if (action.result?.render != null) {\n const renderedResult = action.result.render(response, node);\n if (renderedResult != null) {\n hasCustomResult = true;\n setResultResponse(response);\n }\n }\n if (action.toasts?.success != null) {\n const toastSpec = resolveToastSpec(action.toasts.success, tApp);\n const toastActions = resolveToastViewActions({\n toast: action.toasts.success,\n response,\n node,\n tApp,\n entities,\n defaultLabel: t('actions.view'),\n navigateTo: (to) => {\n routing?.history.push({ pathname: to });\n },\n });\n toast.push({\n kind: 'info',\n title: toastSpec.title,\n message: toastSpec.message,\n actions: toastActions,\n });\n }\n\n if (action.result != null) {\n const nextValue = action.result.getValue(response, node);\n if (typeof nextValue === 'string' && nextValue.trim() !== '') {\n setResultValue(nextValue);\n onSuccess?.();\n return;\n }\n }\n\n if (hasCustomResult) {\n onSuccess?.();\n return;\n }\n\n onSuccess?.();\n onClose();\n },\n onError: (error) => {\n setIsSubmitting(false);\n const message = t('actions.form.errors.submitFailed');\n setFormError(message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n },\n });\n }, [\n action,\n buildPayload,\n entities,\n environment,\n isSubmitting,\n node,\n onClose,\n onSuccess,\n routing?.history,\n t,\n tApp,\n toast,\n ]);\n\n const handleFormSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n handleSubmit();\n },\n [handleSubmit],\n );\n\n const resultLabel = useMemo(() => {\n if (action.result == null) {\n return null;\n }\n return resolveLabel(action.result.label, tApp);\n }, [action.result, tApp]);\n\n const resultRender = useMemo(() => {\n if (action.result?.render == null || resultResponse == null) {\n return null;\n }\n return action.result.render(resultResponse, node);\n }, [action.result, node, resultResponse]);\n\n const showResult =\n (resultValue != null && resultLabel != null) || resultRender != null;\n\n const submitLabel = resolveLabel(action.label, tApp);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n initialFocus=\"first-form-control\"\n footer={\n <div className={styles.actions}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n disabled={isSubmitting}\n onClick={handleClose}\n >\n {t('actions.form.cancel')}\n </Button>\n {!showResult && (\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"small\"\n disabled={isSubmitting}\n isLoading={isSubmitting}\n loadingLabel={t('actions.form.submitting')}\n onClick={handleSubmit}\n >\n {submitLabel}\n </Button>\n )}\n </div>\n }\n >\n <Form onSubmit={handleFormSubmit} className={styles.form}>\n <FormError message={formError} />\n <BackofficeFormSection>\n <FormGrid layout=\"vertical\">\n {action.fields.map((field) => {\n const fieldLabel = resolveLabel(field.label, tApp);\n let fieldDescription: string | null = null;\n if (field.description != null) {\n fieldDescription = resolveLabel(field.description, tApp);\n }\n const fieldInputId = `${formId}-${field.id}`;\n const fieldDescriptionId = `${fieldInputId}-description`;\n const fieldErrorId = `${fieldInputId}-error`;\n const fieldError = fieldErrors[field.id] ?? null;\n const isFieldInvalid = fieldError != null;\n let inputVariant: 'error' | undefined;\n let selectState: 'default' | 'error' = 'default';\n if (isFieldInvalid) {\n inputVariant = 'error';\n selectState = 'error';\n }\n let describedBy: string | undefined;\n if (fieldDescription != null && fieldError != null) {\n describedBy = `${fieldDescriptionId} ${fieldErrorId}`;\n } else if (fieldDescription != null) {\n describedBy = fieldDescriptionId;\n } else if (fieldError != null) {\n describedBy = fieldErrorId;\n }\n\n switch (field.kind) {\n case 'text': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Input\n id={fieldInputId}\n type=\"text\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'textarea': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={field.rows ?? 8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'number': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Input\n id={fieldInputId}\n type=\"number\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'json': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n </FormFieldLayout>\n );\n }\n case 'enum': {\n const rawValue = values[field.id];\n let selected = '';\n if (typeof rawValue === 'string') {\n selected = rawValue;\n }\n const options = field.options.map((option) => {\n return {\n id: option.value,\n value: option.value,\n label: resolveLabel(option.label, tApp),\n };\n });\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelId={`${fieldInputId}-label`}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <SimpleSelect\n options={options}\n value={selected}\n placeholder={fieldLabel}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n ariaLabelledBy={`${fieldInputId}-label`}\n isDisabled={isSubmitting}\n state={selectState}\n onChange={(nextValue) => {\n setFieldValue(field.id, nextValue);\n }}\n />\n </FormFieldLayout>\n );\n }\n case 'boolean': {\n const checked = values[field.id] === true;\n return (\n <FormFieldLayout key={field.id}>\n <CheckboxField\n id={fieldInputId}\n label={fieldLabel}\n helperText={fieldDescription ?? undefined}\n error={fieldError ?? undefined}\n checked={checked}\n disabled={isSubmitting}\n onChange={(event) => {\n setFieldValue(field.id, event.target.checked);\n }}\n />\n </FormFieldLayout>\n );\n }\n case 'entityId': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n return (\n <FormFieldLayout\n key={field.id}\n label={fieldLabel}\n labelFor={fieldInputId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <EntityIdFilterField\n id={fieldInputId}\n label={fieldLabel}\n value={value}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n disabled={isSubmitting}\n onPick={() => {\n setActiveEntityPicker({\n fieldId: field.id,\n entity: field.entity,\n label: fieldLabel,\n });\n }}\n onClear={() => {\n setFieldValue(field.id, '');\n }}\n />\n </FormFieldLayout>\n );\n }\n case 'multiEnum': {\n const rawValue = values[field.id];\n const fieldLegendId = `${fieldInputId}-legend`;\n let selected: string[] = [];\n if (Array.isArray(rawValue)) {\n selected = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string';\n });\n }\n return (\n <FormFieldLayout\n key={field.id}\n as=\"fieldset\"\n label={fieldLabel}\n labelId={fieldLegendId}\n required={field.required}\n description={fieldDescription}\n descriptionId={fieldDescriptionId}\n error={fieldError}\n errorId={fieldErrorId}\n >\n <div\n className={styles.checkboxGroup}\n role=\"group\"\n aria-labelledby={fieldLegendId}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n >\n {field.options.map((option, index) => {\n const optionLabel = resolveLabel(\n option.label,\n tApp,\n );\n const isChecked = selected.includes(option.value);\n return (\n <CheckboxField\n key={`${option.value}-${index}`}\n id={`${fieldInputId}-${index}`}\n label={optionLabel}\n checked={isChecked}\n disabled={isSubmitting}\n onChange={(event) => {\n let nextList = selected;\n if (event.target.checked) {\n if (!selected.includes(option.value)) {\n nextList = [...selected, option.value];\n }\n } else {\n nextList = selected.filter((value) => {\n return value !== option.value;\n });\n }\n setFieldValue(field.id, nextList);\n }}\n />\n );\n })}\n </div>\n </FormFieldLayout>\n );\n }\n default: {\n return null;\n }\n }\n })}\n </FormGrid>\n </BackofficeFormSection>\n\n {showResult && (\n <div className={styles.resultSection}>\n {resultValue != null && resultLabel != null && (\n <HighlightCode\n badgeLabel={resultLabel}\n copyCode={resultValue}\n fallbackCodeText={resultValue}\n />\n )}\n {resultRender}\n </div>\n )}\n </Form>\n </Modal>\n <EntityIdPickerDialog\n isOpen={activeEntityPicker != null}\n entity={activeEntityPicker?.entity ?? ''}\n title={activeEntityPicker?.label ?? ''}\n onClose={() => {\n setActiveEntityPicker(null);\n }}\n onSelectId={(id) => {\n if (activeEntityPicker == null) {\n return;\n }\n setFieldValue(activeEntityPicker.fieldId, id);\n setActiveEntityPicker(null);\n }}\n />\n </>\n );\n};\n\nexport default BackofficeEntityActionFormDialog;\n"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { useBackofficeReactTranslation as e } from "../../../i18n/useBackofficeReactTranslation.js";
2
- import { BackofficeStatusMetaBadge as t } from "./BackofficeStatusMetaBadge.js";
3
- import { identity as n, root as r, title as i, titleRow as a, top as o } from "./backofficeEntitySummaryHeader.css.js";
4
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
5
- import { Button as l } from "@plumile/ui/atomic/atoms/button/Button.js";
6
- import { Tag as u } from "@plumile/ui/backoffice/atoms/tag/Tag.js";
7
- import { CopyableText as d } from "@plumile/ui/backoffice/atoms/copyable_text/CopyableText.js";
2
+ import { identity as t, root as n, title as r, titleRow as i, top as a } from "./backofficeEntitySummaryHeader.css.js";
3
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
4
+ import { Button as c } from "@plumile/ui/atomic/atoms/button/Button.js";
5
+ import { Tag as l } from "@plumile/ui/backoffice/atoms/tag/Tag.js";
6
+ import { CopyableText as u } from "@plumile/ui/backoffice/atoms/copyable_text/CopyableText.js";
7
+ import { BackofficeStatusMetaBadge as d } from "@plumile/ui/backoffice/molecules/backoffice_status_meta_badge/BackofficeStatusMetaBadge.js";
8
8
  //#region src/components/backoffice/detail/BackofficeEntitySummaryHeader.tsx
9
- var f = (e) => e === "danger" ? "danger" : e === "neutral" ? "secondary" : "primary", p = (e) => /* @__PURE__ */ s(l, {
9
+ var f = (e) => e === "danger" ? "danger" : e === "neutral" ? "secondary" : "primary", p = (e) => /* @__PURE__ */ o(c, {
10
10
  type: "button",
11
11
  variant: f(e.tone),
12
12
  size: "small",
@@ -15,51 +15,51 @@ var f = (e) => e === "danger" ? "danger" : e === "neutral" ? "secondary" : "prim
15
15
  isLoading: e.loading,
16
16
  onClick: e.onPress,
17
17
  children: e.label
18
- }, e.id), m = ({ title: l, entityLabel: f, subtitle: m, status: h, meta: g, primaryActions: _, secondaryActions: v }) => {
18
+ }, e.id), m = ({ title: c, entityLabel: f, subtitle: m, status: h, meta: g, primaryActions: _, secondaryActions: v }) => {
19
19
  let { t: y } = e(), b = [..._ ?? [], ...v ?? []];
20
- return /* @__PURE__ */ c("header", {
21
- className: r,
22
- children: [/* @__PURE__ */ c("div", {
23
- className: o,
24
- children: [/* @__PURE__ */ c("div", {
25
- className: n,
26
- children: [/* @__PURE__ */ c("div", {
27
- className: a,
20
+ return /* @__PURE__ */ s("header", {
21
+ className: n,
22
+ children: [/* @__PURE__ */ s("div", {
23
+ className: a,
24
+ children: [/* @__PURE__ */ s("div", {
25
+ className: t,
26
+ children: [/* @__PURE__ */ s("div", {
27
+ className: i,
28
28
  children: [
29
- /* @__PURE__ */ s("h1", {
30
- className: i,
31
- children: l
29
+ /* @__PURE__ */ o("h1", {
30
+ className: r,
31
+ children: c
32
32
  }),
33
- /* @__PURE__ */ s(u, {
33
+ /* @__PURE__ */ o(l, {
34
34
  tone: "neutral",
35
35
  children: f
36
36
  }),
37
- h != null && /* @__PURE__ */ s(t, { status: h })
37
+ h != null && /* @__PURE__ */ o(d, { status: h })
38
38
  ]
39
- }), m != null && /* @__PURE__ */ s("div", {
39
+ }), m != null && /* @__PURE__ */ o("div", {
40
40
  className: "txvbqb9j txvbqb1bgt txvbqbws9",
41
41
  children: m
42
42
  })]
43
- }), b.length > 0 && /* @__PURE__ */ s("div", {
43
+ }), b.length > 0 && /* @__PURE__ */ o("div", {
44
44
  className: "txvbqbfpn txvbqbey txvbqblsh txvbqbhdl txvbqbh7g",
45
45
  children: b.map(p)
46
46
  })]
47
- }), g != null && g.length > 0 && /* @__PURE__ */ s("div", {
47
+ }), g != null && g.length > 0 && /* @__PURE__ */ o("div", {
48
48
  className: "txvbqbfq0 txvbqbhdy txvbqbjcq",
49
49
  children: g.map((e) => {
50
50
  let t = e.value;
51
- return e.copyValue != null && e.copyValue !== "" && (t = /* @__PURE__ */ s(d, {
51
+ return e.copyValue != null && e.copyValue !== "" && (t = /* @__PURE__ */ o(u, {
52
52
  value: e.copyValue,
53
53
  copyValue: e.copyValue,
54
54
  truncate: !1,
55
55
  copyLabel: y("common.actions.copy"),
56
56
  copiedLabel: y("common.actions.copied")
57
- })), /* @__PURE__ */ c("div", {
57
+ })), /* @__PURE__ */ s("div", {
58
58
  className: "txvbqbfpn txvbqbh4x txvbqbhd8 txvbqbv7x",
59
- children: [/* @__PURE__ */ s("span", {
59
+ children: [/* @__PURE__ */ o("span", {
60
60
  className: "txvbqb96 txvbqb6a txvbqbmw7 txvbqb1bgt",
61
61
  children: e.label
62
- }), /* @__PURE__ */ s("span", {
62
+ }), /* @__PURE__ */ o("span", {
63
63
  className: "txvbqb9j txvbqb1bgr txvbqbws9",
64
64
  children: t
65
65
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntitySummaryHeader.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeEntitySummaryHeader.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { CopyableText } from '@plumile/ui/backoffice/atoms/copyable_text/CopyableText.js';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport {\n BackofficeStatusMetaBadge,\n type BackofficeStatusMetaTone,\n} from './BackofficeStatusMetaBadge.js';\nimport * as styles from './backofficeEntitySummaryHeader.css.js';\n\nexport type BackofficeEntitySummaryHeaderTone = BackofficeStatusMetaTone;\n\nexport type BackofficeEntitySummaryHeaderMetaItem = {\n readonly id: string;\n readonly label: string;\n readonly value: ReactNode;\n readonly copyValue?: string;\n readonly tone?: BackofficeEntitySummaryHeaderTone;\n};\n\nexport type BackofficeEntitySummaryHeaderAction = {\n readonly id: string;\n readonly label: string;\n readonly icon?: ReactNode;\n readonly disabled?: boolean;\n readonly loading?: boolean;\n readonly tone?: 'neutral' | 'primary' | 'danger';\n readonly onPress: () => void;\n};\n\nexport type BackofficeEntitySummaryHeaderProps = {\n readonly title: ReactNode;\n readonly entityLabel: string;\n readonly subtitle?: ReactNode;\n readonly status?: {\n readonly label: string;\n readonly tone: BackofficeEntitySummaryHeaderTone;\n };\n readonly meta?: readonly BackofficeEntitySummaryHeaderMetaItem[];\n readonly primaryActions?: readonly BackofficeEntitySummaryHeaderAction[];\n readonly secondaryActions?: readonly BackofficeEntitySummaryHeaderAction[];\n};\n\nconst resolveActionVariant = (\n tone: BackofficeEntitySummaryHeaderAction['tone'],\n): 'primary' | 'secondary' | 'danger' => {\n if (tone === 'danger') {\n return 'danger';\n }\n if (tone === 'neutral') {\n return 'secondary';\n }\n return 'primary';\n};\n\nconst renderAction = (\n action: BackofficeEntitySummaryHeaderAction,\n): JSX.Element => {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={resolveActionVariant(action.tone)}\n size=\"small\"\n leftIcon={action.icon}\n disabled={action.disabled}\n isLoading={action.loading}\n onClick={action.onPress}\n >\n {action.label}\n </Button>\n );\n};\n\nexport const BackofficeEntitySummaryHeader = ({\n title,\n entityLabel,\n subtitle,\n status,\n meta,\n primaryActions,\n secondaryActions,\n}: BackofficeEntitySummaryHeaderProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const actions = [...(primaryActions ?? []), ...(secondaryActions ?? [])];\n\n return (\n <header className={styles.root}>\n <div className={styles.top}>\n <div className={styles.identity}>\n <div className={styles.titleRow}>\n <h1 className={styles.title}>{title}</h1>\n <Tag tone=\"neutral\">{entityLabel}</Tag>\n {status != null && <BackofficeStatusMetaBadge status={status} />}\n </div>\n {subtitle != null && (\n <div className={styles.subtitle}>{subtitle}</div>\n )}\n </div>\n {actions.length > 0 && (\n <div className={styles.actions}>{actions.map(renderAction)}</div>\n )}\n </div>\n {meta != null && meta.length > 0 && (\n <div className={styles.meta}>\n {meta.map((item) => {\n let valueNode = item.value;\n if (item.copyValue != null && item.copyValue !== '') {\n valueNode = (\n <CopyableText\n value={item.copyValue}\n copyValue={item.copyValue}\n truncate={false}\n copyLabel={t('common.actions.copy')}\n copiedLabel={t('common.actions.copied')}\n />\n );\n }\n\n return (\n <div key={item.id} className={styles.metaItem}>\n <span className={styles.metaLabel}>{item.label}</span>\n <span className={styles.metaValue}>{valueNode}</span>\n </div>\n );\n })}\n </div>\n )}\n </header>\n );\n};\n\nexport default BackofficeEntitySummaryHeader;\n"],"mappings":";;;;;;;;AA6CA,IAAM,KACJ,MAEI,MAAS,WACJ,WAEL,MAAS,YACJ,cAEF,WAGH,KACJ,MAGE,kBAAC,GAAD;CAEE,MAAK;CACL,SAAS,EAAqB,EAAO,IAAI;CACzC,MAAK;CACL,UAAU,EAAO;CACjB,UAAU,EAAO;CACjB,WAAW,EAAO;CAClB,SAAS,EAAO;CAEf,UAAA,EAAO;AACF,GAVD,EAAO,EAUN,GAIC,KAAiC,EAC5C,OAAA,GACA,gBACA,UAAA,GACA,WACA,MAAA,GACA,mBACA,0BACqD;CACrD,IAAM,EAAE,SAAM,EAA8B,GACtC,IAAU,CAAC,GAAI,KAAkB,CAAC,GAAI,GAAI,KAAoB,CAAC,CAAE;CAEvE,OACE,kBAAC,UAAD;EAAQ,WAAW;EAAnB,UAAA,CACE,kBAAC,OAAD;GAAK,WAAW;GAAhB,UAAA,CACE,kBAAC,OAAD;IAAK,WAAW;IAAhB,UAAA,CACE,kBAAC,OAAD;KAAK,WAAW;KAAhB,UAAA;MACE,kBAAC,MAAD;OAAI,WAAW;OAAe,UAAA;MAAU,CAAA;MACxC,kBAAC,GAAD;OAAK,MAAK;OAAW,UAAA;MAAiB,CAAA;MACrC,KAAU,QAAQ,kBAAC,GAAD,EAAmC,UAAS,CAAA;KAC5D;IACJ,CAAA,GAAA,KAAY,QACX,kBAAC,OAAD;KAAK,WAAW;KAAkB,UAAA;IAAc,CAAA,CAE/C;GACJ,CAAA,GAAA,EAAQ,SAAS,KAChB,kBAAC,OAAD;IAAK,WAAW;IAAiB,UAAA,EAAQ,IAAI,CAAY;GAAO,CAAA,CAE/D;EACJ,CAAA,GAAA,KAAQ,QAAQ,EAAK,SAAS,KAC7B,kBAAC,OAAD;GAAK,WAAW;GACb,UAAA,EAAK,KAAK,MAAS;IAClB,IAAI,IAAY,EAAK;IAarB,OAZI,EAAK,aAAa,QAAQ,EAAK,cAAc,OAC/C,IACE,kBAAC,GAAD;KACE,OAAO,EAAK;KACZ,WAAW,EAAK;KAChB,UAAU;KACV,WAAW,EAAE,qBAAqB;KAClC,aAAa,EAAE,uBAAuB;IACvC,CAAA,IAKH,kBAAC,OAAD;KAAmB,WAAW;KAA9B,UAAA,CACE,kBAAC,QAAD;MAAM,WAAW;MAAmB,UAAA,EAAK;KAAY,CAAA,GACrD,kBAAC,QAAD;MAAM,WAAW;MAAmB,UAAA;KAAgB,CAAA,CACjD;IAHK,GAAA,EAAK,EAGV;GAET,CAAC;EACE,CAAA,CAED;;AAEZ"}
1
+ {"version":3,"file":"BackofficeEntitySummaryHeader.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeEntitySummaryHeader.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { CopyableText } from '@plumile/ui/backoffice/atoms/copyable_text/CopyableText.js';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\nimport {\n BackofficeStatusMetaBadge,\n type BackofficeStatusMetaTone,\n} from '@plumile/ui/backoffice/molecules/backoffice_status_meta_badge/BackofficeStatusMetaBadge.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport * as styles from './backofficeEntitySummaryHeader.css.js';\n\nexport type BackofficeEntitySummaryHeaderTone = BackofficeStatusMetaTone;\n\nexport type BackofficeEntitySummaryHeaderMetaItem = {\n readonly id: string;\n readonly label: string;\n readonly value: ReactNode;\n readonly copyValue?: string;\n readonly tone?: BackofficeEntitySummaryHeaderTone;\n};\n\nexport type BackofficeEntitySummaryHeaderAction = {\n readonly id: string;\n readonly label: string;\n readonly icon?: ReactNode;\n readonly disabled?: boolean;\n readonly loading?: boolean;\n readonly tone?: 'neutral' | 'primary' | 'danger';\n readonly onPress: () => void;\n};\n\nexport type BackofficeEntitySummaryHeaderProps = {\n readonly title: ReactNode;\n readonly entityLabel: string;\n readonly subtitle?: ReactNode;\n readonly status?: {\n readonly label: string;\n readonly tone: BackofficeEntitySummaryHeaderTone;\n };\n readonly meta?: readonly BackofficeEntitySummaryHeaderMetaItem[];\n readonly primaryActions?: readonly BackofficeEntitySummaryHeaderAction[];\n readonly secondaryActions?: readonly BackofficeEntitySummaryHeaderAction[];\n};\n\nconst resolveActionVariant = (\n tone: BackofficeEntitySummaryHeaderAction['tone'],\n): 'primary' | 'secondary' | 'danger' => {\n if (tone === 'danger') {\n return 'danger';\n }\n if (tone === 'neutral') {\n return 'secondary';\n }\n return 'primary';\n};\n\nconst renderAction = (\n action: BackofficeEntitySummaryHeaderAction,\n): JSX.Element => {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={resolveActionVariant(action.tone)}\n size=\"small\"\n leftIcon={action.icon}\n disabled={action.disabled}\n isLoading={action.loading}\n onClick={action.onPress}\n >\n {action.label}\n </Button>\n );\n};\n\nexport const BackofficeEntitySummaryHeader = ({\n title,\n entityLabel,\n subtitle,\n status,\n meta,\n primaryActions,\n secondaryActions,\n}: BackofficeEntitySummaryHeaderProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const actions = [...(primaryActions ?? []), ...(secondaryActions ?? [])];\n\n return (\n <header className={styles.root}>\n <div className={styles.top}>\n <div className={styles.identity}>\n <div className={styles.titleRow}>\n <h1 className={styles.title}>{title}</h1>\n <Tag tone=\"neutral\">{entityLabel}</Tag>\n {status != null && <BackofficeStatusMetaBadge status={status} />}\n </div>\n {subtitle != null && (\n <div className={styles.subtitle}>{subtitle}</div>\n )}\n </div>\n {actions.length > 0 && (\n <div className={styles.actions}>{actions.map(renderAction)}</div>\n )}\n </div>\n {meta != null && meta.length > 0 && (\n <div className={styles.meta}>\n {meta.map((item) => {\n let valueNode = item.value;\n if (item.copyValue != null && item.copyValue !== '') {\n valueNode = (\n <CopyableText\n value={item.copyValue}\n copyValue={item.copyValue}\n truncate={false}\n copyLabel={t('common.actions.copy')}\n copiedLabel={t('common.actions.copied')}\n />\n );\n }\n\n return (\n <div key={item.id} className={styles.metaItem}>\n <span className={styles.metaLabel}>{item.label}</span>\n <span className={styles.metaValue}>{valueNode}</span>\n </div>\n );\n })}\n </div>\n )}\n </header>\n );\n};\n\nexport default BackofficeEntitySummaryHeader;\n"],"mappings":";;;;;;;;AA6CA,IAAM,KACJ,MAEI,MAAS,WACJ,WAEL,MAAS,YACJ,cAEF,WAGH,KACJ,MAGE,kBAAC,GAAD;CAEE,MAAK;CACL,SAAS,EAAqB,EAAO,IAAI;CACzC,MAAK;CACL,UAAU,EAAO;CACjB,UAAU,EAAO;CACjB,WAAW,EAAO;CAClB,SAAS,EAAO;CAEf,UAAA,EAAO;AACF,GAVD,EAAO,EAUN,GAIC,KAAiC,EAC5C,OAAA,GACA,gBACA,UAAA,GACA,WACA,MAAA,GACA,mBACA,0BACqD;CACrD,IAAM,EAAE,SAAM,EAA8B,GACtC,IAAU,CAAC,GAAI,KAAkB,CAAC,GAAI,GAAI,KAAoB,CAAC,CAAE;CAEvE,OACE,kBAAC,UAAD;EAAQ,WAAW;EAAnB,UAAA,CACE,kBAAC,OAAD;GAAK,WAAW;GAAhB,UAAA,CACE,kBAAC,OAAD;IAAK,WAAW;IAAhB,UAAA,CACE,kBAAC,OAAD;KAAK,WAAW;KAAhB,UAAA;MACE,kBAAC,MAAD;OAAI,WAAW;OAAe,UAAA;MAAU,CAAA;MACxC,kBAAC,GAAD;OAAK,MAAK;OAAW,UAAA;MAAiB,CAAA;MACrC,KAAU,QAAQ,kBAAC,GAAD,EAAmC,UAAS,CAAA;KAC5D;IACJ,CAAA,GAAA,KAAY,QACX,kBAAC,OAAD;KAAK,WAAW;KAAkB,UAAA;IAAc,CAAA,CAE/C;GACJ,CAAA,GAAA,EAAQ,SAAS,KAChB,kBAAC,OAAD;IAAK,WAAW;IAAiB,UAAA,EAAQ,IAAI,CAAY;GAAO,CAAA,CAE/D;EACJ,CAAA,GAAA,KAAQ,QAAQ,EAAK,SAAS,KAC7B,kBAAC,OAAD;GAAK,WAAW;GACb,UAAA,EAAK,KAAK,MAAS;IAClB,IAAI,IAAY,EAAK;IAarB,OAZI,EAAK,aAAa,QAAQ,EAAK,cAAc,OAC/C,IACE,kBAAC,GAAD;KACE,OAAO,EAAK;KACZ,WAAW,EAAK;KAChB,UAAU;KACV,WAAW,EAAE,qBAAqB;KAClC,aAAa,EAAE,uBAAuB;IACvC,CAAA,IAKH,kBAAC,OAAD;KAAmB,WAAW;KAA9B,UAAA,CACE,kBAAC,QAAD;MAAM,WAAW;MAAmB,UAAA,EAAK;KAAY,CAAA,GACrD,kBAAC,QAAD;MAAM,WAAW;MAAmB,UAAA;KAAgB,CAAA,CACjD;IAHK,GAAA,EAAK,EAGV;GAET,CAAC;EACE,CAAA,CAED;;AAEZ"}