@plumile/backoffice-react 0.1.187 → 0.1.189
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.
- package/lib/esm/auth/authRefreshNotice.css.js +1 -2
- package/lib/esm/auth/login/LoginFlow.js.map +1 -1
- package/lib/esm/auth/login/MethodChooser.js.map +1 -1
- package/lib/esm/auth/login/MfaChallengeForm.js.map +1 -1
- package/lib/esm/auth/login/PasskeyLoginForm.js.map +1 -1
- package/lib/esm/auth/login/loginPage.css.js +2 -1
- package/lib/esm/auth/login/synchronizeAuthStatusQuery.js.map +1 -1
- package/lib/esm/auth/pages/AcceptInvitationScreen.js.map +1 -1
- package/lib/esm/auth/pages/PasswordResetCompleteScreen.js.map +1 -1
- package/lib/esm/auth/pages/PasswordResetRequestScreen.js.map +1 -1
- package/lib/esm/auth/pages/VerifyEmailScreen.js.map +1 -1
- package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js +346 -403
- package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js.map +1 -1
- package/lib/esm/components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js.map +1 -1
- package/lib/esm/components/backoffice/actions/backofficeEntityActionFormDialog.css.js +1 -1
- package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js +1 -1
- package/lib/esm/components/backoffice/billing/BackofficeBillingUsageChart.js.map +1 -1
- package/lib/esm/components/backoffice/billing/backofficeBillingUsageChart.css.js +1 -1
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeEntitySummaryHeader.js +3 -3
- package/lib/esm/components/backoffice/detail/BackofficeLifecycleTimelineSection.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeTokenUsageBreakdown.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeUsageCostBreakdown.js +10 -10
- package/lib/esm/components/backoffice/detail/backofficeDetailErrorList.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +1 -2
- package/lib/esm/components/backoffice/detail/backofficeEntitySummaryHeader.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeRelationsSummaryGrid.css.js +1 -1
- package/lib/esm/components/backoffice/detail/backofficeUsageCostBreakdown.css.js +1 -1
- package/lib/esm/components/backoffice/detail/createBackofficeEntityLinkProps.js.map +1 -1
- package/lib/esm/components/backoffice/detail/detailPayloadUtils.js.map +1 -1
- package/lib/esm/components/backoffice/filters/backofficeFilterAction.css.js +1 -1
- package/lib/esm/components/backoffice/filters/deferredFilterSearchInput.css.js +1 -1
- package/lib/esm/components/backoffice/filters/entityIdFilterField.css.js +1 -1
- package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js +4 -4
- package/lib/esm/components/backoffice/hub/backofficeHubTemplate.css.js +1 -1
- package/lib/esm/components/backoffice/layout/backofficeSidebarActions.css.js +1 -1
- package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js +2 -2
- package/lib/esm/components/backoffice/layout/breadcrumb/assertValidBreadcrumb.js.map +1 -1
- package/lib/esm/components/backoffice/layout/breadcrumb/backofficeTopbarBreadcrumb.css.js +1 -1
- package/lib/esm/components/backoffice/layout/buildSidebarSections.js.map +1 -1
- package/lib/esm/components/backoffice/layout/mapViewerToSidebarProfileView.js.map +1 -1
- package/lib/esm/components/backoffice/layout/sidebarUtils.js.map +1 -1
- package/lib/esm/components/backoffice/links/BackofficeLinkContent.js +1 -1
- package/lib/esm/components/backoffice/links/backofficeLink.css.js +1 -1
- package/lib/esm/components/backoffice/links/resolveBackofficeLink.js.map +1 -1
- package/lib/esm/components/backoffice/links/resolveBackofficeTargetIcon.js.map +1 -1
- package/lib/esm/components/backoffice/list/RowFlagsCell.css.js +2 -1
- package/lib/esm/components/backoffice/list/RowFlagsCell.js.map +1 -1
- package/lib/esm/components/backoffice/pickers/EntityIdPickerDialog.js.map +1 -1
- package/lib/esm/components/backoffice/pickers/entityIdPickerDialog.css.js +1 -1
- package/lib/esm/components/backoffice/refs/BackofficeLazyEntityCount.js.map +1 -1
- package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js.map +1 -1
- package/lib/esm/components/backoffice/refs/backofficeEntityIdRef.css.js +1 -1
- package/lib/esm/components/backoffice/refs/backofficeRelatedCountLink.css.js +1 -1
- package/lib/esm/components/backoffice/routing/BackofficeContentBoundary.js.map +1 -1
- package/lib/esm/components/backoffice/routing/backofficeContentBoundary.css.js +1 -1
- package/lib/esm/components/backoffice/routing/backofficeContentError.css.js +1 -1
- package/lib/esm/components/backoffice/routing/backofficeContentFallback.css.js +1 -1
- package/lib/esm/components/backoffice/routing/backofficeRouteFallback.css.js +1 -1
- package/lib/esm/components/backoffice/routing/backofficeRoutePendingBar.css.js +1 -1
- package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +285 -269
- package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
- package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js +1 -1
- package/lib/esm/components/backoffice/shared/backofficeFilterableCell.css.js +4 -4
- package/lib/esm/components/backoffice/shared/backofficeInlineFilterRow.css.js +1 -1
- package/lib/esm/components/backoffice/technical/TechnicalIdentifierValue.js.map +1 -1
- package/lib/esm/components/backoffice/tools/BackofficeToolsDocPanel.js +1 -1
- package/lib/esm/components/backoffice/tools/BackofficeToolsJsonForm.js +4 -4
- package/lib/esm/components/backoffice/tools/backofficeToolsDocPanel.css.js +1 -1
- package/lib/esm/components/backoffice/tools/backofficeToolsForm.css.js +1 -1
- package/lib/esm/filters/filterHelpers.js +1 -1
- package/lib/esm/filters/filterHelpers.js.map +1 -1
- package/lib/esm/hooks/useAuth.js.map +1 -1
- package/lib/esm/hooks/useBackofficeAuth.js.map +1 -1
- package/lib/esm/hooks/useBackofficeInfiniteScrollSentinel.js.map +1 -1
- package/lib/esm/hooks/useBackofficeListUrlState.js.map +1 -1
- package/lib/esm/hooks/useBackofficeSessionAuth.js.map +1 -1
- package/lib/esm/hooks/useConditionalSubscription.js.map +1 -1
- package/lib/esm/hooks/useSidebarGroupCollapse.js.map +1 -1
- package/lib/esm/i18n/createI18nInstance.js.map +1 -1
- package/lib/esm/i18n/locales/en/backofficeReact.js +406 -405
- package/lib/esm/i18n/locales/fr/backofficeReact.js +408 -407
- package/lib/esm/i18n/mergeResourceLanguages.js.map +1 -1
- package/lib/esm/i18n/resources.js +1 -1
- package/lib/esm/i18n/resources.js.map +1 -1
- package/lib/esm/i18n/useBackofficeFormats.js.map +1 -1
- package/lib/esm/modules/base64.js.map +1 -1
- package/lib/esm/modules/formatFileSize.js.map +1 -1
- package/lib/esm/modules/uploads.js +17 -17
- package/lib/esm/modules/uploads.js.map +1 -1
- package/lib/esm/modules/webauthn.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/objectSpread2.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/toPrimitive.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/toPropertyKey.js.map +1 -1
- package/lib/esm/node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js.map +1 -1
- package/lib/esm/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js +1 -1
- package/lib/esm/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js.map +1 -1
- package/lib/esm/node_modules/fbjs/lib/areEqual.js.map +1 -1
- package/lib/esm/node_modules/relay-test-utils/lib/RelayMockPayloadGenerator.js.map +1 -1
- package/lib/esm/node_modules/relay-test-utils/lib/RelayModernMockEnvironment.js.map +1 -1
- package/lib/esm/node_modules/relay-test-utils/lib/RelayResolverTestUtils.js.map +1 -1
- package/lib/esm/pages/BackofficeDashboardPage.js.map +1 -1
- package/lib/esm/pages/BackofficeDashboardWidgetContent.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListPage.helpers.js +5 -5
- package/lib/esm/pages/BackofficeEntityListPage.helpers.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListPage.js.map +1 -1
- package/lib/esm/pages/BackofficeHubPage.js.map +1 -1
- package/lib/esm/pages/BackofficeLayoutPage.js.map +1 -1
- package/lib/esm/pages/BackofficeLoginPage.js.map +1 -1
- package/lib/esm/pages/BackofficePasswordResetRequestPage.js.map +1 -1
- package/lib/esm/pages/BackofficeVerifyEmailPage.js.map +1 -1
- package/lib/esm/pages/backofficeDashboardPage.css.js +1 -1
- package/lib/esm/pages/backofficeEntityDetailPage.css.js +1 -1
- package/lib/esm/pages/backofficeEntityListPage.css.js +1 -1
- package/lib/esm/pages/detail/BackofficeEntityDetailManifestFallback.js.map +1 -1
- package/lib/esm/pages/detail/pageResolution.js.map +1 -1
- package/lib/esm/provider/BackofficeProvider.js.map +1 -1
- package/lib/esm/provider/entityRegistry.js.map +1 -1
- package/lib/esm/provider/lazyValue.js.map +1 -1
- package/lib/esm/provider/useBackofficeEntityLoader.js.map +1 -1
- package/lib/esm/relay/connectionUtils.js.map +1 -1
- package/lib/esm/relay/envHelpers.js.map +1 -1
- package/lib/esm/router/createBackofficeRoutes.js.map +1 -1
- package/lib/esm/storybook/relay/RelayStory.css.js +1 -1
- package/lib/esm/storybook/relay/RelayStory.js.map +1 -1
- package/lib/esm/storybook/relay/mockResolvers.js.map +1 -1
- package/lib/esm/style.css +1 -1
- package/lib/types/components/backoffice/actions/BackofficeEntityActionFormDialog.d.ts.map +1 -1
- package/lib/types/components/backoffice/detail/BackofficeLifecycleTimelineSection.d.ts.map +1 -1
- package/lib/types/components/backoffice/pickers/EntityIdPickerDialog.d.ts.map +1 -1
- package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts.map +1 -1
- package/lib/types/components/backoffice/technical/TechnicalIdentifierValue.d.ts.map +1 -1
- package/lib/types/filters/filterHelpers.d.ts.map +1 -1
- package/lib/types/hooks/useAuth.d.ts.map +1 -1
- package/lib/types/modules/uploads.d.ts.map +1 -1
- package/lib/types/modules/webauthn.d.ts.map +1 -1
- package/lib/types/pages/BackofficePasswordResetRequestPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeVerifyEmailPage.d.ts.map +1 -1
- package/lib/types/pages/detail/pageResolution.d.ts.map +1 -1
- package/lib/types/provider/types.d.ts.map +1 -1
- package/package.json +16 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficePasswordResetRequestPage.js","names":[],"sources":["../../../src/pages/BackofficePasswordResetRequestPage.tsx"],"sourcesContent":["import { useCallback, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\n\nimport { PasswordResetRequestScreen } from '../auth/pages/PasswordResetRequestScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeAuthPasswordResetRequestConfig } from '../provider/useBackofficeLazyValue.js';\n\nconst { useMutation } = ReactRelay;\n\ntype StartPasswordResetErrorReason =\n
|
|
1
|
+
{"version":3,"file":"BackofficePasswordResetRequestPage.js","names":[],"sources":["../../../src/pages/BackofficePasswordResetRequestPage.tsx"],"sourcesContent":["import { useCallback, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\n\nimport { PasswordResetRequestScreen } from '../auth/pages/PasswordResetRequestScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeAuthPasswordResetRequestConfig } from '../provider/useBackofficeLazyValue.js';\n\nconst { useMutation } = ReactRelay;\n\ntype StartPasswordResetErrorReason =\n 'INVALID_EMAIL' | 'RATE_LIMITED' | 'INTERNAL_ERROR';\n\ntype StartPasswordResetMutationPayload =\n MutationPayloadBase<StartPasswordResetErrorReason> & {\n payload?: { success?: boolean | null } | null;\n };\n\nexport const BackofficePasswordResetRequestPage = (): JSX.Element => {\n const auth = useBackofficeAuthPasswordResetRequestConfig();\n const { t } = useBackofficeReactTranslation();\n type StartPasswordResetMutation = MutationParameters & {\n response: { startPasswordReset?: StartPasswordResetMutationPayload | null };\n variables: { input: { email: string; locale?: string } };\n };\n const [commitReset] = useMutation<StartPasswordResetMutation>(\n auth.startPasswordResetMutation,\n );\n\n const mapStartResetReason = useCallback(\n (reason: StartPasswordResetErrorReason): string | null => {\n switch (reason) {\n case 'INVALID_EMAIL':\n return t('auth.passwordResetRequest.errors.invalidEmail');\n case 'RATE_LIMITED':\n return t('auth.passwordResetRequest.errors.rateLimited');\n case 'INTERNAL_ERROR':\n return t('auth.passwordResetRequest.errors.startFailed');\n default:\n return null;\n }\n },\n [t],\n );\n\n const handleStartReset = useCallback(\n async (input: { email: string; locale?: string }): Promise<boolean> => {\n const defaultErrorMessage = t(\n 'auth.passwordResetRequest.errors.startFailed',\n );\n\n return new Promise((resolve, reject) => {\n commitReset({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.startPasswordReset ?? null,\n {\n defaultErrorMessage,\n mapReason: mapStartResetReason,\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.payload?.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: () => {\n reject(new Error(defaultErrorMessage));\n },\n });\n });\n },\n [commitReset, mapStartResetReason, t],\n );\n\n return <PasswordResetRequestScreen onStartPasswordReset={handleStartReset} />;\n};\n\nexport default BackofficePasswordResetRequestPage;\n"],"mappings":";;;;;;;;AAaA,IAAM,EAAE,mBAAgB,GAUX,UAAwD;CACnE,IAAM,IAAO,EAA4C,GACnD,EAAE,SAAM,EAA8B,GAKtC,CAAC,KAAe,EACpB,EAAK,0BACP,GAEM,IAAsB,GACzB,MAAyD;EACxD,QAAQ,GAAR;GACE,KAAK,iBACH,OAAO,EAAE,+CAA+C;GAC1D,KAAK,gBACH,OAAO,EAAE,8CAA8C;GACzD,KAAK,kBACH,OAAO,EAAE,8CAA8C;GACzD,SACE,OAAO;EACX;CACF,GACA,CAAC,CAAC,CACJ;CA6CA,OAAO,kBAAC,GAAD,EAA4B,sBA3CV,EACvB,OAAO,MAAgE;EACrE,IAAM,IAAsB,EAC1B,8CACF;EAEA,OAAO,IAAI,SAAS,GAAS,MAAW;GACtC,EAAY;IACV,WAAW,EACT,SACF;IACA,cAAc,MAAa;KACzB,IAAM,IAAU,EACd,EAAS,sBAAsB,MAC/B;MACE;MACA,WAAW;KACb,CACF;KACA,IAAI,CAAC,EAAQ,IAAI;MACf,EAAW,MAAM,EAAQ,OAAO,CAAC;MACjC;KACF;KAEA,IAAM,IAAgB,EACpB,EAAQ,QAAQ,SAAS,WAAW,MACpC,CACF;KACA,IAAI,CAAC,EAAc,IAAI;MACrB,EAAW,MAAM,EAAc,OAAO,CAAC;MACvC;KACF;KACA,EAAQ,EAAc,KAAK;IAC7B;IACA,eAAe;KACb,EAAW,MAAM,CAAmB,CAAC;IACvC;GACF,CAAC;EACH,CAAC;CACH,GACA;EAAC;EAAa;EAAqB;CAAC,CAGmB,EAAmB,CAAA;AAC9E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeVerifyEmailPage.js","names":[],"sources":["../../../src/pages/BackofficeVerifyEmailPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport { VerifyEmailScreen } from '../auth/pages/VerifyEmailScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthVerifyEmailConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype VerifyEmailErrorReason =\n
|
|
1
|
+
{"version":3,"file":"BackofficeVerifyEmailPage.js","names":[],"sources":["../../../src/pages/BackofficeVerifyEmailPage.tsx"],"sourcesContent":["import { useCallback, useContext, type JSX } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { MutationParameters } from 'relay-runtime';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport { VerifyEmailScreen } from '../auth/pages/VerifyEmailScreen.js';\nimport {\n type MutationPayloadBase,\n requireField,\n resolveMutationOutcome,\n} from '../relay/mutationResult.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../provider/BackofficeConfigContext.js';\nimport { useBackofficeAuthVerifyEmailConfig } from '../provider/useBackofficeLazyValue.js';\nimport { getBackofficeLoginPath } from '../router/backofficeAuthPaths.js';\n\nconst { useMutation } = ReactRelay;\n\ntype VerifyEmailErrorReason =\n 'INVALID_TOKEN' | 'TOKEN_EXPIRED' | 'ALREADY_VERIFIED' | 'INTERNAL_ERROR';\n\ntype VerifyEmailMutationPayload =\n MutationPayloadBase<VerifyEmailErrorReason> & {\n success?: boolean | null;\n };\n\nexport const BackofficeVerifyEmailPage = (): JSX.Element => {\n const routerContext = useContext(RoutingContext);\n const { basePath } = useBackofficeConfig();\n const auth = useBackofficeAuthVerifyEmailConfig();\n const { t } = useBackofficeReactTranslation();\n type VerifyEmailMutation = MutationParameters & {\n response: { verifyEmail?: VerifyEmailMutationPayload | null };\n variables: { input: { token: string } };\n };\n const [commitVerify] = useMutation<VerifyEmailMutation>(\n auth.verifyEmailMutation,\n );\n\n const handleBackToLogin = useCallback(() => {\n routerContext?.history.push({ pathname: getBackofficeLoginPath(basePath) });\n }, [basePath, routerContext?.history]);\n\n const handleVerifyEmail = useCallback(\n async (input: { token: string }): Promise<boolean> => {\n const invalidMessage = t('auth.verifyEmail.errors.invalid');\n const defaultErrorMessage = invalidMessage;\n\n return new Promise((resolve, reject) => {\n commitVerify({\n variables: {\n input,\n },\n onCompleted: (response) => {\n const outcome = resolveMutationOutcome(\n response.verifyEmail ?? null,\n {\n defaultErrorMessage,\n mapReason: (reason) => {\n switch (reason) {\n case 'INVALID_TOKEN':\n return invalidMessage;\n case 'TOKEN_EXPIRED':\n return t('auth.verifyEmail.errors.expired');\n case 'ALREADY_VERIFIED':\n return t('auth.verifyEmail.errors.alreadyVerified');\n case 'INTERNAL_ERROR':\n return invalidMessage;\n default:\n return null;\n }\n },\n },\n );\n if (!outcome.ok) {\n reject(new Error(outcome.message));\n return;\n }\n\n const successResult = requireField(\n outcome.payload.success ?? null,\n defaultErrorMessage,\n );\n if (!successResult.ok) {\n reject(new Error(successResult.message));\n return;\n }\n resolve(successResult.value);\n },\n onError: () => {\n reject(new Error(defaultErrorMessage));\n },\n });\n });\n },\n [commitVerify, t],\n );\n\n return (\n <VerifyEmailScreen\n onBackToLogin={handleBackToLogin}\n onVerifyEmail={handleVerifyEmail}\n />\n );\n};\n\nexport default BackofficeVerifyEmailPage;\n"],"mappings":";;;;;;;;;;;AAgBA,IAAM,EAAE,mBAAgB,GAUX,UAA+C;CAC1D,IAAM,IAAgB,EAAW,CAAc,GACzC,EAAE,gBAAa,EAAoB,GACnC,IAAO,EAAmC,GAC1C,EAAE,SAAM,EAA8B,GAKtC,CAAC,KAAgB,EACrB,EAAK,mBACP;CA6DA,OACE,kBAAC,GAAD;EACE,eA7DsB,QAAkB;GAC1C,GAAe,QAAQ,KAAK,EAAE,UAAU,EAAuB,CAAQ,EAAE,CAAC;EAC5E,GAAG,CAAC,GAAU,GAAe,OAAO,CA2DjB;EACf,eA1DsB,EACxB,OAAO,MAA+C;GACpD,IAAM,IAAiB,EAAE,iCAAiC,GACpD,IAAsB;GAE5B,OAAO,IAAI,SAAS,GAAS,MAAW;IACtC,EAAa;KACX,WAAW,EACT,SACF;KACA,cAAc,MAAa;MACzB,IAAM,IAAU,EACd,EAAS,eAAe,MACxB;OACE;OACA,YAAY,MAAW;QACrB,QAAQ,GAAR;SACE,KAAK,iBACH,OAAO;SACT,KAAK,iBACH,OAAO,EAAE,iCAAiC;SAC5C,KAAK,oBACH,OAAO,EAAE,yCAAyC;SACpD,KAAK,kBACH,OAAO;SACT,SACE,OAAO;QACX;OACF;MACF,CACF;MACA,IAAI,CAAC,EAAQ,IAAI;OACf,EAAW,MAAM,EAAQ,OAAO,CAAC;OACjC;MACF;MAEA,IAAM,IAAgB,EACpB,EAAQ,QAAQ,WAAW,MAC3B,CACF;MACA,IAAI,CAAC,EAAc,IAAI;OACrB,EAAW,MAAM,EAAc,OAAO,CAAC;OACvC;MACF;MACA,EAAQ,EAAc,KAAK;KAC7B;KACA,eAAe;MACb,EAAW,MAAM,CAAmB,CAAC;KACvC;IACF,CAAC;GACH,CAAC;EACH,GACA,CAAC,GAAc,CAAC,CAMC;CAChB,CAAA;AAEL"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* empty css */
|
|
2
2
|
//#region src/pages/backofficeDashboardPage.css.ts
|
|
3
|
-
var e = "txvbqbfpn txvbqbh4x txvbqbhdl", t = "txvbqbfpn txvbqbey txvbqbhdl
|
|
3
|
+
var e = "txvbqbfpn txvbqbh4x txvbqbhdl", t = "txvbqbfpn txvbqbey txvbqbhdl txvbqb1bgv txvbqb9j", n = "txvbqbbc txvbqbhbs txvbqbmzg";
|
|
4
4
|
//#endregion
|
|
5
5
|
export { t as loadingBody, e as tileBody, n as tileCount };
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* empty css */
|
|
2
2
|
//#region src/pages/backofficeEntityDetailPage.css.ts
|
|
3
|
-
var e = "txvbqbfpn txvbqbey txvbqblsh txvbqbhdl txvbqbh7g txvbqbv7x", t = "txvbqbfpn txvbqbey txvbqblsh txvbqbhdl txvbqbh7g", n = "txvbqbfpn txvbqbey
|
|
3
|
+
var e = "txvbqbfpn txvbqbey txvbqblsh txvbqbhdl txvbqbh7g txvbqbv7x", t = "txvbqbfpn txvbqbey txvbqblsh txvbqbhdl txvbqbh7g", n = "txvbqbfpn txvbqbey txvbqb10n4 txvbqbb49 txvbqbbkc txvbqb2sj txvbqb7tt", r = "txvbqbfpn txvbqbh4x txvbqbhdy", i = "txvbqbfpn txvbqbey txvbqbhdl txvbqbh7g", a = "txvbqbfpn txvbqbh4x txvbqbhdl", o = "txvbqbfqq txvbqbey txvbqbls4 txvbqb19fz txvbqbjl1 txvbqb1bgv";
|
|
4
4
|
//#endregion
|
|
5
5
|
export { t as headerActionGroup, e as headerActions, r as headerBlock, i as headerMeta, a as headerMetaList, n as headerRelationGroup, o as relationCountLoading };
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* empty css */
|
|
2
2
|
//#region src/pages/backofficeEntityListPage.css.ts
|
|
3
|
-
var e = "txvbqbfpn txvbqbey txvbqbhdl txvbqbh7g", t = "txvbqblsh", n = "c0tad0 txvbqbfqq txvbqbey txvbqbls4
|
|
3
|
+
var e = "txvbqbfpn txvbqbey txvbqbhdl txvbqbh7g", t = "txvbqblsh", n = "c0tad0 txvbqbfqq txvbqbey txvbqbls4 txvbqb19hf txvbqbjmh txvbqbvat txvbqbub2 txvbqb2tz txvbqb1b5h txvbqb1bgt txvbqb3f txvbqb7h txvbqb76 txvbqb7t txvbqb1ctz txvbqb1emf qbwcue0 txvbqb1fgi txvbqb1gaq";
|
|
4
4
|
//#endregion
|
|
5
5
|
export { n as actionTrigger, t as actionsColumnCell, e as headerActions };
|
|
6
6
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeEntityDetailManifestFallback.js","names":[],"sources":["../../../../src/pages/detail/BackofficeEntityDetailManifestFallback.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport useLocation from '@plumile/router/routing/useLocation.js';\n\nimport type {\n BackofficeDetailPageManifestItem,\n BackofficeEntityManifestItem,\n} from '@plumile/backoffice-core/types.js';\nimport { Tabs } from '@plumile/ui/atomic/molecules/tabs/Tabs.js';\nimport { BackofficePageHeader } from '@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\n\nimport { BackofficeRightPageLayout } from '../../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport type { BackofficeTopbarBreadcrumbItem } from '../../components/backoffice/layout/breadcrumb/types.js';\nimport { BackofficeStaticRouteFallback } from '../../components/backoffice/routing/BackofficeRouteFallback.js';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nexport type BackofficeEntityDetailManifestFallbackProps = {\n entityManifest: BackofficeEntityManifestItem;\n id: string;\n pageId?: string | null;\n pagePath?: string | null;\n};\n\nconst normalizePath = (value: string): string => {\n return value.trim().replace(/^\\/+|\\/+$/g, '');\n};\n\nconst resolveManifestPage = (\n entityManifest: BackofficeEntityManifestItem,\n id: string,\n pageId: string | null | undefined,\n pagePath: string | null | undefined,\n currentPathname: string,\n): BackofficeDetailPageManifestItem | null => {\n const pages = entityManifest.detailPages ?? [];\n if (pages.length === 0) {\n return null;\n }\n\n const normalizedPagePath = normalizePath(pagePath ?? '');\n if (normalizedPagePath !== '') {\n const byPath = pages.find((page) => {\n return normalizePath(page.pathSegment) === normalizedPagePath;\n });\n if (byPath != null) {\n return byPath;\n }\n }\n\n const normalizedCurrentPathname = normalizePath(currentPathname);\n if (normalizedCurrentPathname !== '') {\n const byCurrentPathname = pages.find((page) => {\n return (\n normalizePath(entityManifest.routes.detailPage(id, page.id)) ===\n normalizedCurrentPathname\n );\n });\n if (byCurrentPathname != null) {\n return byCurrentPathname;\n }\n }\n\n if (pageId != null) {\n const byId = pages.find((page) => {\n return page.id === pageId;\n });\n if (byId != null) {\n return byId;\n }\n }\n\n const defaultPage = pages.find((page) => {\n return page.id === entityManifest.defaultDetailPageId;\n });\n return defaultPage ?? pages[0] ?? null;\n};\n\nexport const BackofficeEntityDetailManifestFallback = ({\n entityManifest,\n id,\n pageId,\n pagePath,\n}: BackofficeEntityDetailManifestFallbackProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { pathname } = useLocation();\n const listLabel = entityManifest.label(tApp);\n const detailLabel =\n entityManifest.detailLabel?.(tApp) ?? t('detail.loadingTitle');\n const activePage = resolveManifestPage(\n entityManifest,\n id,\n pageId,\n pagePath,\n pathname,\n );\n const breadcrumb: BackofficeTopbarBreadcrumbItem[] = [\n {\n kind: 'link',\n target: {\n kind: 'entity-list',\n entityId: entityManifest.id,\n },\n label: listLabel,\n },\n ];\n\n if (activePage == null) {\n breadcrumb.push({\n kind: 'current',\n target: {\n kind: 'entity-detail',\n entityId: entityManifest.id,\n id,\n },\n label: detailLabel,\n });\n } else {\n breadcrumb.push(\n {\n kind: 'link',\n target: {\n kind: 'entity-detail',\n entityId: entityManifest.id,\n id,\n },\n label: detailLabel,\n },\n {\n kind: 'current',\n target: {\n kind: 'entity-detail-page',\n entityId: entityManifest.id,\n id,\n pageId: activePage.id,\n },\n label: activePage.label(tApp),\n },\n );\n }\n\n const pages = entityManifest.detailPages ?? [];\n let tabsNode: JSX.Element | null = null;\n if (pages.length > 1 && activePage != null) {\n tabsNode = (\n <Tabs\n items={pages.map((page) => {\n return {\n id: page.id,\n label: page.label(tApp),\n preloadOnHover: 'code-and-data',\n to: entityManifest.routes.detailPage(id, page.id),\n };\n })}\n activeId={activePage.id}\n variant=\"underline\"\n />\n );\n }\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n headerNode={<BackofficePageHeader title={detailLabel} />}\n tabsNode={tabsNode}\n headerDensity=\"compact\"\n >\n <BackofficeStaticRouteFallback label={t('common.loading')} />\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;AAwBA,IAAM,KAAiB,MACd,EAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"BackofficeEntityDetailManifestFallback.js","names":[],"sources":["../../../../src/pages/detail/BackofficeEntityDetailManifestFallback.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport useLocation from '@plumile/router/routing/useLocation.js';\n\nimport type {\n BackofficeDetailPageManifestItem,\n BackofficeEntityManifestItem,\n} from '@plumile/backoffice-core/types.js';\nimport { Tabs } from '@plumile/ui/atomic/molecules/tabs/Tabs.js';\nimport { BackofficePageHeader } from '@plumile/ui/backoffice/molecules/backoffice_page_header/BackofficePageHeader.js';\nimport { DetailPageTemplate } from '@plumile/ui/backoffice/templates/detail_page_template/DetailPageTemplate.js';\n\nimport { BackofficeRightPageLayout } from '../../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport type { BackofficeTopbarBreadcrumbItem } from '../../components/backoffice/layout/breadcrumb/types.js';\nimport { BackofficeStaticRouteFallback } from '../../components/backoffice/routing/BackofficeRouteFallback.js';\nimport { useBackofficeReactTranslation } from '../../i18n/useBackofficeReactTranslation.js';\n\nexport type BackofficeEntityDetailManifestFallbackProps = {\n entityManifest: BackofficeEntityManifestItem;\n id: string;\n pageId?: string | null;\n pagePath?: string | null;\n};\n\nconst normalizePath = (value: string): string => {\n return value.trim().replace(/^\\/+|\\/+$/g, '');\n};\n\nconst resolveManifestPage = (\n entityManifest: BackofficeEntityManifestItem,\n id: string,\n pageId: string | null | undefined,\n pagePath: string | null | undefined,\n currentPathname: string,\n): BackofficeDetailPageManifestItem | null => {\n const pages = entityManifest.detailPages ?? [];\n if (pages.length === 0) {\n return null;\n }\n\n const normalizedPagePath = normalizePath(pagePath ?? '');\n if (normalizedPagePath !== '') {\n const byPath = pages.find((page) => {\n return normalizePath(page.pathSegment) === normalizedPagePath;\n });\n if (byPath != null) {\n return byPath;\n }\n }\n\n const normalizedCurrentPathname = normalizePath(currentPathname);\n if (normalizedCurrentPathname !== '') {\n const byCurrentPathname = pages.find((page) => {\n return (\n normalizePath(entityManifest.routes.detailPage(id, page.id)) ===\n normalizedCurrentPathname\n );\n });\n if (byCurrentPathname != null) {\n return byCurrentPathname;\n }\n }\n\n if (pageId != null) {\n const byId = pages.find((page) => {\n return page.id === pageId;\n });\n if (byId != null) {\n return byId;\n }\n }\n\n const defaultPage = pages.find((page) => {\n return page.id === entityManifest.defaultDetailPageId;\n });\n return defaultPage ?? pages[0] ?? null;\n};\n\nexport const BackofficeEntityDetailManifestFallback = ({\n entityManifest,\n id,\n pageId,\n pagePath,\n}: BackofficeEntityDetailManifestFallbackProps): JSX.Element => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { pathname } = useLocation();\n const listLabel = entityManifest.label(tApp);\n const detailLabel =\n entityManifest.detailLabel?.(tApp) ?? t('detail.loadingTitle');\n const activePage = resolveManifestPage(\n entityManifest,\n id,\n pageId,\n pagePath,\n pathname,\n );\n const breadcrumb: BackofficeTopbarBreadcrumbItem[] = [\n {\n kind: 'link',\n target: {\n kind: 'entity-list',\n entityId: entityManifest.id,\n },\n label: listLabel,\n },\n ];\n\n if (activePage == null) {\n breadcrumb.push({\n kind: 'current',\n target: {\n kind: 'entity-detail',\n entityId: entityManifest.id,\n id,\n },\n label: detailLabel,\n });\n } else {\n breadcrumb.push(\n {\n kind: 'link',\n target: {\n kind: 'entity-detail',\n entityId: entityManifest.id,\n id,\n },\n label: detailLabel,\n },\n {\n kind: 'current',\n target: {\n kind: 'entity-detail-page',\n entityId: entityManifest.id,\n id,\n pageId: activePage.id,\n },\n label: activePage.label(tApp),\n },\n );\n }\n\n const pages = entityManifest.detailPages ?? [];\n let tabsNode: JSX.Element | null = null;\n if (pages.length > 1 && activePage != null) {\n tabsNode = (\n <Tabs\n items={pages.map((page) => {\n return {\n id: page.id,\n label: page.label(tApp),\n preloadOnHover: 'code-and-data',\n to: entityManifest.routes.detailPage(id, page.id),\n };\n })}\n activeId={activePage.id}\n variant=\"underline\"\n />\n );\n }\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <DetailPageTemplate\n headerNode={<BackofficePageHeader title={detailLabel} />}\n tabsNode={tabsNode}\n headerDensity=\"compact\"\n >\n <BackofficeStaticRouteFallback label={t('common.loading')} />\n </DetailPageTemplate>\n </BackofficeRightPageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;AAwBA,IAAM,KAAiB,MACd,EAAM,KAAK,CAAC,CAAC,QAAQ,cAAc,EAAE,GAGxC,KACJ,GACA,GACA,GACA,GACA,MAC4C;CAC5C,IAAM,IAAQ,EAAe,eAAe,CAAC;CAC7C,IAAI,EAAM,WAAW,GACnB,OAAO;CAGT,IAAM,IAAqB,EAAc,KAAY,EAAE;CACvD,IAAI,MAAuB,IAAI;EAC7B,IAAM,IAAS,EAAM,MAAM,MAClB,EAAc,EAAK,WAAW,MAAM,CAC5C;EACD,IAAI,KAAU,MACZ,OAAO;CAEX;CAEA,IAAM,IAA4B,EAAc,CAAe;CAC/D,IAAI,MAA8B,IAAI;EACpC,IAAM,IAAoB,EAAM,MAAM,MAElC,EAAc,EAAe,OAAO,WAAW,GAAI,EAAK,EAAE,CAAC,MAC3D,CAEH;EACD,IAAI,KAAqB,MACvB,OAAO;CAEX;CAEA,IAAI,KAAU,MAAM;EAClB,IAAM,IAAO,EAAM,MAAM,MAChB,EAAK,OAAO,CACpB;EACD,IAAI,KAAQ,MACV,OAAO;CAEX;CAKA,OAHoB,EAAM,MAAM,MACvB,EAAK,OAAO,EAAe,mBAE7B,KAAe,EAAM,MAAM;AACpC,GAEa,KAA0C,EACrD,mBACA,OACA,WACA,kBAC8D;CAC9D,IAAM,EAAE,GAAG,MAAS,EAAe,GAC7B,EAAE,SAAM,EAA8B,GACtC,EAAE,gBAAa,EAAY,GAC3B,IAAY,EAAe,MAAM,CAAI,GACrC,IACJ,EAAe,cAAc,CAAI,KAAK,EAAE,qBAAqB,GACzD,IAAa,EACjB,GACA,GACA,GACA,GACA,CACF,GACM,IAA+C,CACnD;EACE,MAAM;EACN,QAAQ;GACN,MAAM;GACN,UAAU,EAAe;EAC3B;EACA,OAAO;CACT,CACF;CAEA,AAAI,KAAc,OAChB,EAAW,KAAK;EACd,MAAM;EACN,QAAQ;GACN,MAAM;GACN,UAAU,EAAe;GACzB;EACF;EACA,OAAO;CACT,CAAC,IAED,EAAW,KACT;EACE,MAAM;EACN,QAAQ;GACN,MAAM;GACN,UAAU,EAAe;GACzB;EACF;EACA,OAAO;CACT,GACA;EACE,MAAM;EACN,QAAQ;GACN,MAAM;GACN,UAAU,EAAe;GACzB;GACA,QAAQ,EAAW;EACrB;EACA,OAAO,EAAW,MAAM,CAAI;CAC9B,CACF;CAGF,IAAM,IAAQ,EAAe,eAAe,CAAC,GACzC,IAA+B;CAkBnC,OAjBI,EAAM,SAAS,KAAK,KAAc,SACpC,IACE,kBAAC,GAAD;EACE,OAAO,EAAM,KAAK,OACT;GACL,IAAI,EAAK;GACT,OAAO,EAAK,MAAM,CAAI;GACtB,gBAAgB;GAChB,IAAI,EAAe,OAAO,WAAW,GAAI,EAAK,EAAE;EAClD,EACD;EACD,UAAU,EAAW;EACrB,SAAQ;CACT,CAAA,IAKH,kBAAC,GAAD;EAAuC;YACrC,kBAAC,GAAD;GACE,YAAY,kBAAC,GAAD,EAAsB,OAAO,EAAc,CAAA;GAC7C;GACV,eAAc;aAEd,kBAAC,GAAD,EAA+B,OAAO,EAAE,gBAAgB,EAAI,CAAA;EAC1C,CAAA;CACK,CAAA;AAE/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageResolution.js","names":[],"sources":["../../../../src/pages/detail/pageResolution.ts"],"sourcesContent":["type DetailPageBase<ShellView> = {\n id: string;\n path: string;\n isVisible?: (layout: ShellView) => boolean;\n};\n\ntype PageResolutionInput<\n ShellView,\n MainPage extends DetailPageBase<ShellView>,\n SubPage extends DetailPageBase<ShellView> = MainPage,\n> = {\n mainPage: MainPage;\n subPages?: readonly SubPage[];\n activePagePath?: string;\n node: ShellView;\n};\n\nexport type ResolvedDetailPages<Page> = {\n pages: readonly Page[];\n activePage: Page | null;\n hasVisiblePages: boolean;\n hasMultiplePages: boolean;\n};\n\nconst normalizePath = (value: string): string => {\n return value.trim().replace(/^\\/+|\\/+$/g, '');\n};\n\nexport const resolveVisibleDetailPages = <\n ShellView,\n MainPage extends DetailPageBase<ShellView>,\n SubPage extends DetailPageBase<ShellView> = MainPage,\n>(\n input: PageResolutionInput<ShellView, MainPage, SubPage>,\n): ResolvedDetailPages<MainPage | SubPage> => {\n const allPages = [input.mainPage, ...(input.subPages ?? [])] as readonly (\n
|
|
1
|
+
{"version":3,"file":"pageResolution.js","names":[],"sources":["../../../../src/pages/detail/pageResolution.ts"],"sourcesContent":["type DetailPageBase<ShellView> = {\n id: string;\n path: string;\n isVisible?: (layout: ShellView) => boolean;\n};\n\ntype PageResolutionInput<\n ShellView,\n MainPage extends DetailPageBase<ShellView>,\n SubPage extends DetailPageBase<ShellView> = MainPage,\n> = {\n mainPage: MainPage;\n subPages?: readonly SubPage[];\n activePagePath?: string;\n node: ShellView;\n};\n\nexport type ResolvedDetailPages<Page> = {\n pages: readonly Page[];\n activePage: Page | null;\n hasVisiblePages: boolean;\n hasMultiplePages: boolean;\n};\n\nconst normalizePath = (value: string): string => {\n return value.trim().replace(/^\\/+|\\/+$/g, '');\n};\n\nexport const resolveVisibleDetailPages = <\n ShellView,\n MainPage extends DetailPageBase<ShellView>,\n SubPage extends DetailPageBase<ShellView> = MainPage,\n>(\n input: PageResolutionInput<ShellView, MainPage, SubPage>,\n): ResolvedDetailPages<MainPage | SubPage> => {\n const allPages = [input.mainPage, ...(input.subPages ?? [])] as readonly (\n MainPage | SubPage\n )[];\n const visiblePages = allPages.filter((page) => {\n if (page.isVisible == null) {\n return true;\n }\n return page.isVisible(input.node);\n });\n\n if (visiblePages.length === 0) {\n return {\n pages: [],\n activePage: null,\n hasVisiblePages: false,\n hasMultiplePages: false,\n };\n }\n\n const activePath = normalizePath(input.activePagePath ?? '');\n let activeByPath: MainPage | SubPage | null = null;\n if (activePath !== '') {\n activeByPath =\n visiblePages.find((page) => {\n return normalizePath(page.path) === activePath;\n }) ?? null;\n }\n\n const defaultPage =\n visiblePages.find((page) => {\n return page.id === input.mainPage.id;\n }) ?? visiblePages[0];\n if (defaultPage == null) {\n return {\n pages: [],\n activePage: null,\n hasVisiblePages: false,\n hasMultiplePages: false,\n };\n }\n\n const activePage = activeByPath ?? defaultPage;\n\n return {\n pages: visiblePages,\n activePage,\n hasVisiblePages: true,\n hasMultiplePages: visiblePages.length > 1,\n };\n};\n"],"mappings":";AAwBA,IAAM,KAAiB,MACd,EAAM,KAAK,CAAC,CAAC,QAAQ,cAAc,EAAE,GAGjC,KAKX,MAC4C;CAI5C,IAAM,IAAe,CAHH,EAAM,UAAU,GAAI,EAAM,YAAY,CAAC,CAGpC,CAAA,CAAS,QAAQ,MAChC,EAAK,aAAa,OACb,KAEF,EAAK,UAAU,EAAM,IAAI,CACjC;CAED,IAAI,EAAa,WAAW,GAC1B,OAAO;EACL,OAAO,CAAC;EACR,YAAY;EACZ,iBAAiB;EACjB,kBAAkB;CACpB;CAGF,IAAM,IAAa,EAAc,EAAM,kBAAkB,EAAE,GACvD,IAA0C;CAC9C,AAAI,MAAe,OACjB,IACE,EAAa,MAAM,MACV,EAAc,EAAK,IAAI,MAAM,CACrC,KAAK;CAGV,IAAM,IACJ,EAAa,MAAM,MACV,EAAK,OAAO,EAAM,SAAS,EACnC,KAAK,EAAa;CAYrB,OAXI,KAAe,OACV;EACL,OAAO,CAAC;EACR,YAAY;EACZ,iBAAiB;EACjB,kBAAkB;CACpB,IAKK;EACL,OAAO;EACP,YAJiB,KAAgB;EAKjC,iBAAiB;EACjB,kBAAkB,EAAa,SAAS;CAC1C;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeProvider.js","names":[],"sources":["../../../src/provider/BackofficeProvider.tsx"],"sourcesContent":["import {\n StrictMode,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ContextType,\n type JSX,\n} from 'react';\nimport { createInstance } from 'i18next';\nimport { I18nextProvider } from 'react-i18next';\nimport createRouter from '@plumile/router/routing/createRouter.js';\nimport RouterRenderer from '@plumile/router/routing/RouterRenderer.js';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\nimport { BackofficeThemeProvider } from '@plumile/ui/admin/theme/BackofficeThemeProvider.js';\nimport { RoutePendingBar } from '@plumile/ui/components/routing/RoutePendingBar.js';\n\nimport { type BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\nimport {\n RelayProvider,\n configureRelayEnvironment,\n useRelayOperationActivity,\n} from '@plumile/relay';\n\nimport { createI18nInstance } from '../i18n/createI18nInstance.js';\nimport { withBackofficeReactI18nResources } from '../i18n/resources.js';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { BackofficeConfigProvider } from './BackofficeConfigContext.js';\nimport {\n createBackofficeRoutes,\n type BackofficeRouterContext,\n} from '../router/createBackofficeRoutes.js';\nimport type { BackofficeProviderProps } from './types.js';\nimport { validateBackofficeDashboardRegistrations } from './dashboardRegistrations.js';\nimport {\n BackofficeRouteFallback,\n BackofficeStaticRouteFallback,\n} from '../components/backoffice/routing/BackofficeRouteFallback.js';\nimport { createBackofficeEntityRegistry } from './entityRegistry.js';\n\nconst normalizeAbsolutePath = (value: string): string => {\n if (value.trim() === '' || value === '/') {\n return '/';\n }\n if (!value.startsWith('/')) {\n return `/${value}`;\n }\n if (value.endsWith('/')) {\n return value.slice(0, -1);\n }\n return value;\n};\n\nconst prefixRoutePath = (basePath: string, value: string): string => {\n const normalizedPath = normalizeAbsolutePath(value);\n const normalizedBasePath = normalizeAbsolutePath(basePath);\n if (normalizedBasePath === '/') {\n return normalizedPath;\n }\n if (\n normalizedPath === normalizedBasePath ||\n normalizedPath.startsWith(`${normalizedBasePath}/`)\n ) {\n return normalizedPath;\n }\n if (normalizedPath === '/') {\n return normalizedBasePath;\n }\n return `${normalizedBasePath}${normalizedPath}`;\n};\n\nconst resolveEntityManifest = (\n manifest: BackofficeEntityManifestMap,\n basePath: string,\n): BackofficeEntityManifestMap => {\n return Object.fromEntries(\n Object.entries(manifest).map(([entityId, item]) => {\n return [\n entityId,\n {\n ...item,\n routes: {\n list: prefixRoutePath(basePath, item.routes.list),\n detail: (id: string) => {\n return prefixRoutePath(basePath, item.routes.detail(id));\n },\n detailPage: (id: string, pageId: string) => {\n return prefixRoutePath(\n basePath,\n item.routes.detailPage(id, pageId),\n );\n },\n },\n } satisfies BackofficeEntityManifestMap[string],\n ] as const;\n }),\n );\n};\n\ntype RouterShellProps = {\n routes: ReturnType<typeof createBackofficeRoutes>;\n instrumentations?: BackofficeProviderProps['instrumentations'];\n};\n\ntype BackofficeRouterInstance = {\n context: NonNullable<ContextType<typeof RoutingContext>>;\n cleanup: () => void;\n};\n\nconst useBackofficeRouterInstance = ({\n routes,\n context,\n instrumentations,\n}: {\n routes: ReturnType<typeof createBackofficeRoutes>;\n context: BackofficeRouterContext;\n instrumentations?: BackofficeProviderProps['instrumentations'];\n}): BackofficeRouterInstance | null => {\n const [router, setRouter] = useState<BackofficeRouterInstance | null>(null);\n const routerRef = useRef<BackofficeRouterInstance | null>(null);\n\n useEffect(() => {\n const nextRouter = createRouter(routes, {\n context,\n instrumentations,\n });\n routerRef.current = nextRouter;\n setRouter(nextRouter);\n\n return () => {\n if (routerRef.current === nextRouter) {\n routerRef.current = null;\n }\n nextRouter.cleanup();\n };\n }, [context, instrumentations, routes]);\n\n return router;\n};\n\nconst RouterShell = ({\n routes,\n instrumentations,\n}: RouterShellProps): JSX.Element => {\n const relayEnvironment = useRelayEnvironment();\n const relayOperationActivity = useRelayOperationActivity();\n\n const routerContext = useMemo(() => {\n return { relayEnvironment };\n }, [relayEnvironment]);\n\n const router = useBackofficeRouterInstance({\n routes,\n context: routerContext,\n instrumentations,\n });\n\n if (router == null) {\n return <BackofficeRouteFallback />;\n }\n\n return (\n <RoutingContext.Provider value={router.context}>\n <RouterRenderer\n enableTransition\n externalPending={relayOperationActivity.pendingCount > 0}\n fallback={<BackofficeRouteFallback />}\n pending={<RoutePendingBar />}\n />\n </RoutingContext.Provider>\n );\n};\n\nexport const BackofficeProvider = (\n props: BackofficeProviderProps,\n): JSX.Element => {\n const basePath = normalizeAbsolutePath(props.basePath ?? '/');\n\n const entityManifest = useMemo(() => {\n return resolveEntityManifest(props.entityManifest, basePath);\n }, [basePath, props.entityManifest]);\n const entityRegistry = useMemo(() => {\n return createBackofficeEntityRegistry(entityManifest, { basePath });\n }, [basePath, entityManifest]);\n\n const graphQLConfig = props.graphql;\n const dashboards = useMemo(() => {\n return validateBackofficeDashboardRegistrations(props.dashboards);\n }, [props.dashboards]);\n\n useEffect(() => {\n const httpUrl = graphQLConfig.httpUrl ?? graphQLConfig.endpoint;\n const wsUrl = graphQLConfig.wsUrl ?? graphQLConfig.wsEndpoint;\n configureRelayEnvironment({\n httpUrl,\n wsUrl,\n getDataId: graphQLConfig.getDataId,\n logEvents: graphQLConfig.logEvents,\n getAuthHeaders: graphQLConfig.getAuthHeaders,\n });\n }, [\n graphQLConfig.endpoint,\n graphQLConfig.getAuthHeaders,\n graphQLConfig.getDataId,\n graphQLConfig.httpUrl,\n graphQLConfig.logEvents,\n graphQLConfig.wsEndpoint,\n graphQLConfig.wsUrl,\n ]);\n\n const mergedResources = useMemo(() => {\n return withBackofficeReactI18nResources(props.i18n?.resources ?? {});\n }, [props.i18n?.resources]);\n\n const i18nInstance = useMemo(() => {\n return props.i18n?.instance ?? createInstance();\n }, [props.i18n?.instance]);\n const [isI18nReady, setIsI18nReady] = useState(i18nInstance.isInitialized);\n\n useEffect(() => {\n let isCurrent = true;\n const markI18nReady = (): void => {\n if (isCurrent) {\n setIsI18nReady(true);\n }\n };\n\n i18nInstance.on('initialized', markI18nReady);\n if (i18nInstance.isInitialized) {\n markI18nReady();\n return () => {\n isCurrent = false;\n i18nInstance.off('initialized', markI18nReady);\n };\n }\n\n const readyCheck = globalThis.setTimeout(() => {\n if (i18nInstance.isInitialized) {\n markI18nReady();\n }\n }, 0);\n\n const initOptions = props.i18n?.initOptions ?? {};\n const defaultNs = initOptions.defaultNS ?? 'translations';\n const ns = initOptions.ns ?? ['backofficeReact', 'translations', 'ui'];\n createI18nInstance({\n resources: mergedResources,\n lng: props.i18n?.lng,\n fallbackLng: props.i18n?.fallbackLng,\n initOptions: {\n ...initOptions,\n defaultNS: defaultNs,\n ns,\n react: {\n useSuspense: false,\n ...initOptions.react,\n },\n },\n instance: i18nInstance,\n useLanguageDetector: props.i18n?.useLanguageDetector,\n detection: props.i18n?.detection,\n })\n .then(markI18nReady)\n .catch((error: unknown) => {\n markI18nReady();\n // eslint-disable-next-line no-console\n console.error(error);\n });\n\n return () => {\n isCurrent = false;\n globalThis.clearTimeout(readyCheck);\n i18nInstance.off('initialized', markI18nReady);\n };\n }, [\n i18nInstance,\n mergedResources,\n props.i18n?.initOptions,\n props.i18n?.detection,\n props.i18n?.fallbackLng,\n props.i18n?.lng,\n props.i18n?.useLanguageDetector,\n ]);\n\n const configValue = useMemo(() => {\n return {\n basePath,\n entities: entityManifest,\n entityManifest,\n entityRegistry,\n filterColumnAliases: props.filterColumnAliases,\n sidebar: props.sidebar,\n dashboard: props.dashboard,\n dashboards,\n auth: props.auth,\n graphql: props.graphql,\n };\n }, [\n basePath,\n props.auth,\n props.dashboard,\n dashboards,\n entityManifest,\n entityRegistry,\n props.filterColumnAliases,\n props.graphql,\n props.sidebar,\n ]);\n\n const routes = useMemo(() => {\n return createBackofficeRoutes({\n basePath,\n entityManifest,\n entityRegistry,\n sidebar: props.sidebar,\n auth: props.auth,\n dashboard: props.dashboard,\n dashboards,\n toolsOperationPage: props.toolsOperationPage,\n });\n }, [\n basePath,\n entityManifest,\n entityRegistry,\n props.auth,\n props.dashboard,\n dashboards,\n props.toolsOperationPage,\n props.sidebar,\n ]);\n\n let contentNode = <BackofficeStaticRouteFallback label=\"Loading...\" />;\n if (isI18nReady) {\n contentNode = (\n <BackofficeThemeProvider>\n <RelayProvider>\n <BackofficeConfigProvider value={configValue}>\n {props.overlay}\n <RouterShell\n routes={routes}\n instrumentations={props.instrumentations}\n />\n </BackofficeConfigProvider>\n </RelayProvider>\n </BackofficeThemeProvider>\n );\n }\n\n return (\n <StrictMode>\n <I18nextProvider i18n={i18nInstance}>{contentNode}</I18nextProvider>\n </StrictMode>\n );\n};\n\nexport default BackofficeProvider;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BackofficeProvider.js","names":[],"sources":["../../../src/provider/BackofficeProvider.tsx"],"sourcesContent":["import {\n StrictMode,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ContextType,\n type JSX,\n} from 'react';\nimport { createInstance } from 'i18next';\nimport { I18nextProvider } from 'react-i18next';\nimport createRouter from '@plumile/router/routing/createRouter.js';\nimport RouterRenderer from '@plumile/router/routing/RouterRenderer.js';\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\nimport { BackofficeThemeProvider } from '@plumile/ui/admin/theme/BackofficeThemeProvider.js';\nimport { RoutePendingBar } from '@plumile/ui/components/routing/RoutePendingBar.js';\n\nimport { type BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\nimport {\n RelayProvider,\n configureRelayEnvironment,\n useRelayOperationActivity,\n} from '@plumile/relay';\n\nimport { createI18nInstance } from '../i18n/createI18nInstance.js';\nimport { withBackofficeReactI18nResources } from '../i18n/resources.js';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { BackofficeConfigProvider } from './BackofficeConfigContext.js';\nimport {\n createBackofficeRoutes,\n type BackofficeRouterContext,\n} from '../router/createBackofficeRoutes.js';\nimport type { BackofficeProviderProps } from './types.js';\nimport { validateBackofficeDashboardRegistrations } from './dashboardRegistrations.js';\nimport {\n BackofficeRouteFallback,\n BackofficeStaticRouteFallback,\n} from '../components/backoffice/routing/BackofficeRouteFallback.js';\nimport { createBackofficeEntityRegistry } from './entityRegistry.js';\n\nconst normalizeAbsolutePath = (value: string): string => {\n if (value.trim() === '' || value === '/') {\n return '/';\n }\n if (!value.startsWith('/')) {\n return `/${value}`;\n }\n if (value.endsWith('/')) {\n return value.slice(0, -1);\n }\n return value;\n};\n\nconst prefixRoutePath = (basePath: string, value: string): string => {\n const normalizedPath = normalizeAbsolutePath(value);\n const normalizedBasePath = normalizeAbsolutePath(basePath);\n if (normalizedBasePath === '/') {\n return normalizedPath;\n }\n if (\n normalizedPath === normalizedBasePath ||\n normalizedPath.startsWith(`${normalizedBasePath}/`)\n ) {\n return normalizedPath;\n }\n if (normalizedPath === '/') {\n return normalizedBasePath;\n }\n return `${normalizedBasePath}${normalizedPath}`;\n};\n\nconst resolveEntityManifest = (\n manifest: BackofficeEntityManifestMap,\n basePath: string,\n): BackofficeEntityManifestMap => {\n return Object.fromEntries(\n Object.entries(manifest).map(([entityId, item]) => {\n return [\n entityId,\n {\n ...item,\n routes: {\n list: prefixRoutePath(basePath, item.routes.list),\n detail: (id: string) => {\n return prefixRoutePath(basePath, item.routes.detail(id));\n },\n detailPage: (id: string, pageId: string) => {\n return prefixRoutePath(\n basePath,\n item.routes.detailPage(id, pageId),\n );\n },\n },\n } satisfies BackofficeEntityManifestMap[string],\n ] as const;\n }),\n );\n};\n\ntype RouterShellProps = {\n routes: ReturnType<typeof createBackofficeRoutes>;\n instrumentations?: BackofficeProviderProps['instrumentations'];\n};\n\ntype BackofficeRouterInstance = {\n context: NonNullable<ContextType<typeof RoutingContext>>;\n cleanup: () => void;\n};\n\nconst useBackofficeRouterInstance = ({\n routes,\n context,\n instrumentations,\n}: {\n routes: ReturnType<typeof createBackofficeRoutes>;\n context: BackofficeRouterContext;\n instrumentations?: BackofficeProviderProps['instrumentations'];\n}): BackofficeRouterInstance | null => {\n const [router, setRouter] = useState<BackofficeRouterInstance | null>(null);\n const routerRef = useRef<BackofficeRouterInstance | null>(null);\n\n useEffect(() => {\n const nextRouter = createRouter(routes, {\n context,\n instrumentations,\n });\n routerRef.current = nextRouter;\n setRouter(nextRouter);\n\n return () => {\n if (routerRef.current === nextRouter) {\n routerRef.current = null;\n }\n nextRouter.cleanup();\n };\n }, [context, instrumentations, routes]);\n\n return router;\n};\n\nconst RouterShell = ({\n routes,\n instrumentations,\n}: RouterShellProps): JSX.Element => {\n const relayEnvironment = useRelayEnvironment();\n const relayOperationActivity = useRelayOperationActivity();\n\n const routerContext = useMemo(() => {\n return { relayEnvironment };\n }, [relayEnvironment]);\n\n const router = useBackofficeRouterInstance({\n routes,\n context: routerContext,\n instrumentations,\n });\n\n if (router == null) {\n return <BackofficeRouteFallback />;\n }\n\n return (\n <RoutingContext.Provider value={router.context}>\n <RouterRenderer\n enableTransition\n externalPending={relayOperationActivity.pendingCount > 0}\n fallback={<BackofficeRouteFallback />}\n pending={<RoutePendingBar />}\n />\n </RoutingContext.Provider>\n );\n};\n\nexport const BackofficeProvider = (\n props: BackofficeProviderProps,\n): JSX.Element => {\n const basePath = normalizeAbsolutePath(props.basePath ?? '/');\n\n const entityManifest = useMemo(() => {\n return resolveEntityManifest(props.entityManifest, basePath);\n }, [basePath, props.entityManifest]);\n const entityRegistry = useMemo(() => {\n return createBackofficeEntityRegistry(entityManifest, { basePath });\n }, [basePath, entityManifest]);\n\n const graphQLConfig = props.graphql;\n const dashboards = useMemo(() => {\n return validateBackofficeDashboardRegistrations(props.dashboards);\n }, [props.dashboards]);\n\n useEffect(() => {\n const httpUrl = graphQLConfig.httpUrl ?? graphQLConfig.endpoint;\n const wsUrl = graphQLConfig.wsUrl ?? graphQLConfig.wsEndpoint;\n configureRelayEnvironment({\n httpUrl,\n wsUrl,\n getDataId: graphQLConfig.getDataId,\n logEvents: graphQLConfig.logEvents,\n getAuthHeaders: graphQLConfig.getAuthHeaders,\n });\n }, [\n graphQLConfig.endpoint,\n graphQLConfig.getAuthHeaders,\n graphQLConfig.getDataId,\n graphQLConfig.httpUrl,\n graphQLConfig.logEvents,\n graphQLConfig.wsEndpoint,\n graphQLConfig.wsUrl,\n ]);\n\n const mergedResources = useMemo(() => {\n return withBackofficeReactI18nResources(props.i18n?.resources ?? {});\n }, [props.i18n?.resources]);\n\n const i18nInstance = useMemo(() => {\n return props.i18n?.instance ?? createInstance();\n }, [props.i18n?.instance]);\n const [isI18nReady, setIsI18nReady] = useState(i18nInstance.isInitialized);\n\n useEffect(() => {\n let isCurrent = true;\n const markI18nReady = (): void => {\n if (isCurrent) {\n setIsI18nReady(true);\n }\n };\n\n i18nInstance.on('initialized', markI18nReady);\n if (i18nInstance.isInitialized) {\n markI18nReady();\n return () => {\n isCurrent = false;\n i18nInstance.off('initialized', markI18nReady);\n };\n }\n\n const readyCheck = globalThis.setTimeout(() => {\n if (i18nInstance.isInitialized) {\n markI18nReady();\n }\n }, 0);\n\n const initOptions = props.i18n?.initOptions ?? {};\n const defaultNs = initOptions.defaultNS ?? 'translations';\n const ns = initOptions.ns ?? ['backofficeReact', 'translations', 'ui'];\n createI18nInstance({\n resources: mergedResources,\n lng: props.i18n?.lng,\n fallbackLng: props.i18n?.fallbackLng,\n initOptions: {\n ...initOptions,\n defaultNS: defaultNs,\n ns,\n react: {\n useSuspense: false,\n ...initOptions.react,\n },\n },\n instance: i18nInstance,\n useLanguageDetector: props.i18n?.useLanguageDetector,\n detection: props.i18n?.detection,\n })\n .then(markI18nReady)\n .catch((error: unknown) => {\n markI18nReady();\n // eslint-disable-next-line no-console\n console.error(error);\n });\n\n return () => {\n isCurrent = false;\n globalThis.clearTimeout(readyCheck);\n i18nInstance.off('initialized', markI18nReady);\n };\n }, [\n i18nInstance,\n mergedResources,\n props.i18n?.initOptions,\n props.i18n?.detection,\n props.i18n?.fallbackLng,\n props.i18n?.lng,\n props.i18n?.useLanguageDetector,\n ]);\n\n const configValue = useMemo(() => {\n return {\n basePath,\n entities: entityManifest,\n entityManifest,\n entityRegistry,\n filterColumnAliases: props.filterColumnAliases,\n sidebar: props.sidebar,\n dashboard: props.dashboard,\n dashboards,\n auth: props.auth,\n graphql: props.graphql,\n };\n }, [\n basePath,\n props.auth,\n props.dashboard,\n dashboards,\n entityManifest,\n entityRegistry,\n props.filterColumnAliases,\n props.graphql,\n props.sidebar,\n ]);\n\n const routes = useMemo(() => {\n return createBackofficeRoutes({\n basePath,\n entityManifest,\n entityRegistry,\n sidebar: props.sidebar,\n auth: props.auth,\n dashboard: props.dashboard,\n dashboards,\n toolsOperationPage: props.toolsOperationPage,\n });\n }, [\n basePath,\n entityManifest,\n entityRegistry,\n props.auth,\n props.dashboard,\n dashboards,\n props.toolsOperationPage,\n props.sidebar,\n ]);\n\n let contentNode = <BackofficeStaticRouteFallback label=\"Loading...\" />;\n if (isI18nReady) {\n contentNode = (\n <BackofficeThemeProvider>\n <RelayProvider>\n <BackofficeConfigProvider value={configValue}>\n {props.overlay}\n <RouterShell\n routes={routes}\n instrumentations={props.instrumentations}\n />\n </BackofficeConfigProvider>\n </RelayProvider>\n </BackofficeThemeProvider>\n );\n }\n\n return (\n <StrictMode>\n <I18nextProvider i18n={i18nInstance}>{contentNode}</I18nextProvider>\n </StrictMode>\n );\n};\n\nexport default BackofficeProvider;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entityRegistry.js","names":[],"sources":["../../../src/provider/entityRegistry.ts"],"sourcesContent":["import {\n resolveBackofficeLoadedFacetModule,\n type ResolveBackofficeEntityOptions,\n} from '@plumile/backoffice-core/resolve.js';\nimport type {\n BackofficeEntityFacetModuleCacheEntry,\n BackofficeEntityLoadMode,\n BackofficeEntityManifestMap,\n BackofficeResolvedEntityFacetModule,\n BackofficeListDetailFacetLoaderMap,\n BackofficeToolFacetLoaderMap,\n BackofficeResolvedDetailLayoutFacetModule,\n BackofficeResolvedDetailPageFacetModule,\n BackofficeResolvedListFacetModule,\n BackofficeResolvedPickerFacetModule,\n BackofficeResolvedToolFacetModule,\n} from '@plumile/backoffice-core/types.js';\n\nexport type BackofficeEntityRegistry = {\n getManifest: (entityId: string) => BackofficeEntityManifestMap[string] | null;\n getLoadedListEntity: (\n entityId: string,\n ) => BackofficeResolvedListFacetModule | null;\n getLoadedPickerEntity: (\n entityId: string,\n ) => BackofficeResolvedPickerFacetModule | null;\n getLoadedDetailLayoutEntity: (\n entityId: string,\n ) => BackofficeResolvedDetailLayoutFacetModule | null;\n getLoadedDetailPageEntity: (\n entityId: string,\n pageId: string,\n ) => BackofficeResolvedDetailPageFacetModule | null;\n getLoadedToolEntity: (\n entityId: string,\n ) => BackofficeResolvedToolFacetModule | null;\n loadListEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedListFacetModule>;\n loadPickerEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedPickerFacetModule>;\n loadDetailLayoutEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedDetailLayoutFacetModule>;\n loadDetailPageEntity: (\n entityId: string,\n pageId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedDetailPageFacetModule>;\n loadToolEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedToolFacetModule>;\n};\n\nconst DEFAULT_LOAD_MODE: BackofficeEntityLoadMode = 'cache-first';\nconst DETAIL_PAGE_FACET_KIND = 'detail-page';\nconst DETAIL_LAYOUT_FACET_KIND = 'detail-layout';\nconst LIST_FACET_KIND = 'list';\nconst PICKER_FACET_KIND = 'picker';\nconst TOOL_FACET_KIND = 'tool';\n\nconst hasListFacets = (\n manifestItem: BackofficeEntityManifestMap[string],\n): manifestItem is BackofficeEntityManifestMap[string] & {\n facets: BackofficeListDetailFacetLoaderMap;\n} => {\n return manifestItem.kind === 'list-detail';\n};\n\nconst hasToolFacet = (\n manifestItem: BackofficeEntityManifestMap[string],\n): manifestItem is BackofficeEntityManifestMap[string] & {\n facets: BackofficeToolFacetLoaderMap;\n} => {\n return manifestItem.kind === 'tool';\n};\n\nconst buildFacetCacheKey = (\n entityId: string,\n kind: 'list' | 'picker' | 'detail-layout' | 'detail-page' | 'tool',\n pageId?: string,\n): string => {\n if (kind === DETAIL_PAGE_FACET_KIND) {\n return `${entityId}:${kind}:${pageId ?? ''}`;\n }\n return `${entityId}:${kind}`;\n};\n\nconst toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n};\n\nconst getLoadedModule = <TModule>(\n entry: BackofficeEntityFacetModuleCacheEntry | undefined,\n): TModule | null => {\n if (entry?.status !== 'loaded' || entry.module == null) {\n return null;\n }\n return entry.module as TModule;\n};\n\nconst resolveManifest = (\n manifest: BackofficeEntityManifestMap,\n entityId: string,\n): BackofficeEntityManifestMap[string] => {\n const manifestItem = manifest[entityId];\n if (manifestItem == null) {\n throw new Error(`Unknown backoffice entity: ${entityId}`);\n }\n return manifestItem;\n};\n\nexport const createBackofficeEntityRegistry = (\n manifest: BackofficeEntityManifestMap,\n options: ResolveBackofficeEntityOptions,\n): BackofficeEntityRegistry => {\n const cache = new Map<string, BackofficeEntityFacetModuleCacheEntry>();\n\n const getManifest: BackofficeEntityRegistry['getManifest'] = (entityId) => {\n return manifest[entityId] ?? null;\n };\n\n const loadFacet = async <TModule>(\n cacheKey: string,\n loadOptions: { mode?: BackofficeEntityLoadMode } | undefined,\n loader: () => Promise<TModule>,\n ): Promise<TModule> => {\n const resolvedMode = loadOptions?.mode ?? DEFAULT_LOAD_MODE;\n\n if (resolvedMode === 'cache-first') {\n const loadedModule = getLoadedModule<TModule>(cache.get(cacheKey));\n if (loadedModule != null) {\n return loadedModule;\n }\n\n const existing = cache.get(cacheKey);\n if (existing?.status === 'loading' && existing.promise != null) {\n return existing.promise as Promise<TModule>;\n }\n }\n\n const promise = loader()\n .then((module) => {\n cache.set(cacheKey, {\n status: 'loaded',\n module: module as unknown as BackofficeResolvedEntityFacetModule,\n });\n return module;\n })\n .catch((error: unknown) => {\n const resolvedError = toError(error);\n cache.set(cacheKey, {\n status: 'error',\n error: resolvedError,\n });\n throw resolvedError;\n });\n\n cache.set(cacheKey, {\n status: 'loading',\n promise: promise as Promise<BackofficeResolvedEntityFacetModule>,\n });\n\n return promise;\n };\n\n const getLoadedListEntity: BackofficeEntityRegistry['getLoadedListEntity'] = (\n entityId,\n ) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, LIST_FACET_KIND)),\n );\n };\n\n const getLoadedPickerEntity: BackofficeEntityRegistry['getLoadedPickerEntity'] =\n (entityId) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, PICKER_FACET_KIND)),\n );\n };\n\n const getLoadedDetailLayoutEntity: BackofficeEntityRegistry['getLoadedDetailLayoutEntity'] =\n (entityId) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, DETAIL_LAYOUT_FACET_KIND)),\n );\n };\n\n const getLoadedDetailPageEntity: BackofficeEntityRegistry['getLoadedDetailPageEntity'] =\n (entityId, pageId) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, DETAIL_PAGE_FACET_KIND, pageId)),\n );\n };\n\n const getLoadedToolEntity: BackofficeEntityRegistry['getLoadedToolEntity'] = (\n entityId,\n ) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, TOOL_FACET_KIND)),\n );\n };\n\n const loadListEntity: BackofficeEntityRegistry['loadListEntity'] = async (\n entityId,\n loadOptions,\n ) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a list facet.`,\n );\n }\n const facetLoader = manifestItem.facets.list;\n if (facetLoader == null) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a list facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, LIST_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await facetLoader();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== LIST_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a list facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadPickerEntity: BackofficeEntityRegistry['loadPickerEntity'] = async (\n entityId,\n loadOptions,\n ) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a picker facet.`,\n );\n }\n const facetLoader = manifestItem.facets.picker;\n if (facetLoader == null) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a picker facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, PICKER_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await facetLoader();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== PICKER_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a picker facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadDetailLayoutEntity: BackofficeEntityRegistry['loadDetailLayoutEntity'] =\n async (entityId, loadOptions) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a detail-layout facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, DETAIL_LAYOUT_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await manifestItem.facets.detailLayout();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== DETAIL_LAYOUT_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a detail-layout facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadDetailPageEntity: BackofficeEntityRegistry['loadDetailPageEntity'] =\n async (entityId, pageId, loadOptions) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a detail-page facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, DETAIL_PAGE_FACET_KIND, pageId),\n loadOptions,\n async () => {\n const loaded = await manifestItem.facets.detailPage(pageId);\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== DETAIL_PAGE_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a detail-page facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadToolEntity: BackofficeEntityRegistry['loadToolEntity'] = async (\n entityId,\n loadOptions,\n ) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasToolFacet(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a tool facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, TOOL_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await manifestItem.facets.tool();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== TOOL_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a tool facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n return {\n getManifest,\n getLoadedListEntity,\n getLoadedPickerEntity,\n getLoadedDetailLayoutEntity,\n getLoadedDetailPageEntity,\n getLoadedToolEntity,\n loadListEntity,\n loadPickerEntity,\n loadDetailLayoutEntity,\n loadDetailPageEntity,\n loadToolEntity,\n };\n};\n\nexport const __test = {\n buildFacetCacheKey,\n resolveManifest,\n toError,\n};\n\nexport default createBackofficeEntityRegistry;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"entityRegistry.js","names":[],"sources":["../../../src/provider/entityRegistry.ts"],"sourcesContent":["import {\n resolveBackofficeLoadedFacetModule,\n type ResolveBackofficeEntityOptions,\n} from '@plumile/backoffice-core/resolve.js';\nimport type {\n BackofficeEntityFacetModuleCacheEntry,\n BackofficeEntityLoadMode,\n BackofficeEntityManifestMap,\n BackofficeResolvedEntityFacetModule,\n BackofficeListDetailFacetLoaderMap,\n BackofficeToolFacetLoaderMap,\n BackofficeResolvedDetailLayoutFacetModule,\n BackofficeResolvedDetailPageFacetModule,\n BackofficeResolvedListFacetModule,\n BackofficeResolvedPickerFacetModule,\n BackofficeResolvedToolFacetModule,\n} from '@plumile/backoffice-core/types.js';\n\nexport type BackofficeEntityRegistry = {\n getManifest: (entityId: string) => BackofficeEntityManifestMap[string] | null;\n getLoadedListEntity: (\n entityId: string,\n ) => BackofficeResolvedListFacetModule | null;\n getLoadedPickerEntity: (\n entityId: string,\n ) => BackofficeResolvedPickerFacetModule | null;\n getLoadedDetailLayoutEntity: (\n entityId: string,\n ) => BackofficeResolvedDetailLayoutFacetModule | null;\n getLoadedDetailPageEntity: (\n entityId: string,\n pageId: string,\n ) => BackofficeResolvedDetailPageFacetModule | null;\n getLoadedToolEntity: (\n entityId: string,\n ) => BackofficeResolvedToolFacetModule | null;\n loadListEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedListFacetModule>;\n loadPickerEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedPickerFacetModule>;\n loadDetailLayoutEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedDetailLayoutFacetModule>;\n loadDetailPageEntity: (\n entityId: string,\n pageId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedDetailPageFacetModule>;\n loadToolEntity: (\n entityId: string,\n options?: { mode?: BackofficeEntityLoadMode },\n ) => Promise<BackofficeResolvedToolFacetModule>;\n};\n\nconst DEFAULT_LOAD_MODE: BackofficeEntityLoadMode = 'cache-first';\nconst DETAIL_PAGE_FACET_KIND = 'detail-page';\nconst DETAIL_LAYOUT_FACET_KIND = 'detail-layout';\nconst LIST_FACET_KIND = 'list';\nconst PICKER_FACET_KIND = 'picker';\nconst TOOL_FACET_KIND = 'tool';\n\nconst hasListFacets = (\n manifestItem: BackofficeEntityManifestMap[string],\n): manifestItem is BackofficeEntityManifestMap[string] & {\n facets: BackofficeListDetailFacetLoaderMap;\n} => {\n return manifestItem.kind === 'list-detail';\n};\n\nconst hasToolFacet = (\n manifestItem: BackofficeEntityManifestMap[string],\n): manifestItem is BackofficeEntityManifestMap[string] & {\n facets: BackofficeToolFacetLoaderMap;\n} => {\n return manifestItem.kind === 'tool';\n};\n\nconst buildFacetCacheKey = (\n entityId: string,\n kind: 'list' | 'picker' | 'detail-layout' | 'detail-page' | 'tool',\n pageId?: string,\n): string => {\n if (kind === DETAIL_PAGE_FACET_KIND) {\n return `${entityId}:${kind}:${pageId ?? ''}`;\n }\n return `${entityId}:${kind}`;\n};\n\nconst toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n};\n\nconst getLoadedModule = <TModule>(\n entry: BackofficeEntityFacetModuleCacheEntry | undefined,\n): TModule | null => {\n if (entry?.status !== 'loaded' || entry.module == null) {\n return null;\n }\n return entry.module as TModule;\n};\n\nconst resolveManifest = (\n manifest: BackofficeEntityManifestMap,\n entityId: string,\n): BackofficeEntityManifestMap[string] => {\n const manifestItem = manifest[entityId];\n if (manifestItem == null) {\n throw new Error(`Unknown backoffice entity: ${entityId}`);\n }\n return manifestItem;\n};\n\nexport const createBackofficeEntityRegistry = (\n manifest: BackofficeEntityManifestMap,\n options: ResolveBackofficeEntityOptions,\n): BackofficeEntityRegistry => {\n const cache = new Map<string, BackofficeEntityFacetModuleCacheEntry>();\n\n const getManifest: BackofficeEntityRegistry['getManifest'] = (entityId) => {\n return manifest[entityId] ?? null;\n };\n\n const loadFacet = async <TModule>(\n cacheKey: string,\n loadOptions: { mode?: BackofficeEntityLoadMode } | undefined,\n loader: () => Promise<TModule>,\n ): Promise<TModule> => {\n const resolvedMode = loadOptions?.mode ?? DEFAULT_LOAD_MODE;\n\n if (resolvedMode === 'cache-first') {\n const loadedModule = getLoadedModule<TModule>(cache.get(cacheKey));\n if (loadedModule != null) {\n return loadedModule;\n }\n\n const existing = cache.get(cacheKey);\n if (existing?.status === 'loading' && existing.promise != null) {\n return existing.promise as Promise<TModule>;\n }\n }\n\n const promise = loader()\n .then((module) => {\n cache.set(cacheKey, {\n status: 'loaded',\n module: module as unknown as BackofficeResolvedEntityFacetModule,\n });\n return module;\n })\n .catch((error: unknown) => {\n const resolvedError = toError(error);\n cache.set(cacheKey, {\n status: 'error',\n error: resolvedError,\n });\n throw resolvedError;\n });\n\n cache.set(cacheKey, {\n status: 'loading',\n promise: promise as Promise<BackofficeResolvedEntityFacetModule>,\n });\n\n return promise;\n };\n\n const getLoadedListEntity: BackofficeEntityRegistry['getLoadedListEntity'] = (\n entityId,\n ) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, LIST_FACET_KIND)),\n );\n };\n\n const getLoadedPickerEntity: BackofficeEntityRegistry['getLoadedPickerEntity'] =\n (entityId) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, PICKER_FACET_KIND)),\n );\n };\n\n const getLoadedDetailLayoutEntity: BackofficeEntityRegistry['getLoadedDetailLayoutEntity'] =\n (entityId) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, DETAIL_LAYOUT_FACET_KIND)),\n );\n };\n\n const getLoadedDetailPageEntity: BackofficeEntityRegistry['getLoadedDetailPageEntity'] =\n (entityId, pageId) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, DETAIL_PAGE_FACET_KIND, pageId)),\n );\n };\n\n const getLoadedToolEntity: BackofficeEntityRegistry['getLoadedToolEntity'] = (\n entityId,\n ) => {\n return getLoadedModule(\n cache.get(buildFacetCacheKey(entityId, TOOL_FACET_KIND)),\n );\n };\n\n const loadListEntity: BackofficeEntityRegistry['loadListEntity'] = async (\n entityId,\n loadOptions,\n ) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a list facet.`,\n );\n }\n const facetLoader = manifestItem.facets.list;\n if (facetLoader == null) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a list facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, LIST_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await facetLoader();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== LIST_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a list facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadPickerEntity: BackofficeEntityRegistry['loadPickerEntity'] = async (\n entityId,\n loadOptions,\n ) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a picker facet.`,\n );\n }\n const facetLoader = manifestItem.facets.picker;\n if (facetLoader == null) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a picker facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, PICKER_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await facetLoader();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== PICKER_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a picker facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadDetailLayoutEntity: BackofficeEntityRegistry['loadDetailLayoutEntity'] =\n async (entityId, loadOptions) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a detail-layout facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, DETAIL_LAYOUT_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await manifestItem.facets.detailLayout();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== DETAIL_LAYOUT_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a detail-layout facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadDetailPageEntity: BackofficeEntityRegistry['loadDetailPageEntity'] =\n async (entityId, pageId, loadOptions) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasListFacets(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a detail-page facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, DETAIL_PAGE_FACET_KIND, pageId),\n loadOptions,\n async () => {\n const loaded = await manifestItem.facets.detailPage(pageId);\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== DETAIL_PAGE_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a detail-page facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n const loadToolEntity: BackofficeEntityRegistry['loadToolEntity'] = async (\n entityId,\n loadOptions,\n ) => {\n const manifestItem = resolveManifest(manifest, entityId);\n if (!hasToolFacet(manifestItem)) {\n throw new Error(\n `Backoffice entity ${entityId} does not expose a tool facet.`,\n );\n }\n return loadFacet(\n buildFacetCacheKey(entityId, TOOL_FACET_KIND),\n loadOptions,\n async () => {\n const loaded = await manifestItem.facets.tool();\n const resolved = resolveBackofficeLoadedFacetModule(\n manifestItem,\n loaded,\n options,\n );\n if (resolved.kind !== TOOL_FACET_KIND) {\n throw new Error(\n `Backoffice entity ${entityId} did not resolve to a tool facet.`,\n );\n }\n return resolved;\n },\n );\n };\n\n return {\n getManifest,\n getLoadedListEntity,\n getLoadedPickerEntity,\n getLoadedDetailLayoutEntity,\n getLoadedDetailPageEntity,\n getLoadedToolEntity,\n loadListEntity,\n loadPickerEntity,\n loadDetailLayoutEntity,\n loadDetailPageEntity,\n loadToolEntity,\n };\n};\n\nexport const __test = {\n buildFacetCacheKey,\n resolveManifest,\n toError,\n};\n\nexport default createBackofficeEntityRegistry;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazyValue.js","names":[],"sources":["../../../src/provider/lazyValue.ts"],"sourcesContent":["export type BackofficeLazyValue<TValue> = {\n get: () => TValue | null;\n load: () => Promise<TValue>;\n};\n\nexport const createBackofficeLazyValue = <TValue>(\n loader: () => Promise<TValue>,\n): BackofficeLazyValue<TValue> => {\n let loadedValue: TValue | null = null;\n let inFlightPromise: Promise<TValue> | null = null;\n\n return {\n get: () => {\n return loadedValue;\n },\n load: async () => {\n if (loadedValue != null) {\n return loadedValue;\n }\n if (inFlightPromise != null) {\n return inFlightPromise;\n }\n\n inFlightPromise = loader()\n .then((value) => {\n loadedValue = value;\n return value;\n })\n .finally(() => {\n inFlightPromise = null;\n });\n\n return inFlightPromise;\n },\n };\n};\n\nexport default createBackofficeLazyValue;\n"],"mappings":";AAKA,IAAa,KACX,MACgC;CAChC,IAAI,IAA6B,MAC7B,IAA0C;CAE9C,OAAO;EACL,WACS;EAET,MAAM,YACA,MAGA,AAIJ,MAAkB,EAAO,
|
|
1
|
+
{"version":3,"file":"lazyValue.js","names":[],"sources":["../../../src/provider/lazyValue.ts"],"sourcesContent":["export type BackofficeLazyValue<TValue> = {\n get: () => TValue | null;\n load: () => Promise<TValue>;\n};\n\nexport const createBackofficeLazyValue = <TValue>(\n loader: () => Promise<TValue>,\n): BackofficeLazyValue<TValue> => {\n let loadedValue: TValue | null = null;\n let inFlightPromise: Promise<TValue> | null = null;\n\n return {\n get: () => {\n return loadedValue;\n },\n load: async () => {\n if (loadedValue != null) {\n return loadedValue;\n }\n if (inFlightPromise != null) {\n return inFlightPromise;\n }\n\n inFlightPromise = loader()\n .then((value) => {\n loadedValue = value;\n return value;\n })\n .finally(() => {\n inFlightPromise = null;\n });\n\n return inFlightPromise;\n },\n };\n};\n\nexport default createBackofficeLazyValue;\n"],"mappings":";AAKA,IAAa,KACX,MACgC;CAChC,IAAI,IAA6B,MAC7B,IAA0C;CAE9C,OAAO;EACL,WACS;EAET,MAAM,YACA,MAGA,AAIJ,MAAkB,EAAO,CAAC,CACvB,MAAM,OACL,IAAc,GACP,EACR,CAAC,CACD,cAAc;GACb,IAAkB;EACpB,CAAC,GAVM;CAcb;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBackofficeEntityLoader.js","names":[],"sources":["../../../src/provider/useBackofficeEntityLoader.ts"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\n\nimport type {\n BackofficeResolvedListFacetModule,\n BackofficeResolvedPickerFacetModule,\n BackofficeResolvedToolFacetModule,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeConfig } from './BackofficeConfigContext.js';\n\ntype LoadState<TModule> =\n | {\n status: 'loading';\n module: null;\n error: null;\n }\n | {\n status: 'loaded';\n module: TModule;\n error: null;\n }\n | {\n status: 'error';\n module: null;\n error: Error;\n };\n\ntype MultiLoadState<TModule> =\n | {\n status: 'loading';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'loaded';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'error';\n modules: Record<string, TModule>;\n error: Error;\n };\n\nconst toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n};\n\nconst buildSortedEntityIds = (\n entityIds: readonly string[],\n): readonly string[] => {\n return [...new Set(entityIds)].sort();\n};\n\nconst createMultiLoadState = <TModule>(\n status: 'loading' | 'loaded',\n modules: Record<string, TModule>,\n): MultiLoadState<TModule> => {\n return {\n status,\n modules,\n error: null,\n };\n};\n\nconst areErrorsEqual = (left: Error | null, right: Error | null): boolean => {\n if (left === right) {\n return true;\n }\n if (left == null || right == null) {\n return false;\n }\n return left.name === right.name && left.message === right.message;\n};\n\nconst areModuleMapsEqual = <TModule>(\n left: Record<string, TModule>,\n right: Record<string, TModule>,\n): boolean => {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n\n if (leftKeys.length !== rightKeys.length) {\n return false;\n }\n\n for (const key of leftKeys) {\n if (!(key in right) || left[key] !== right[key]) {\n return false;\n }\n }\n\n return true;\n};\n\nconst areLoadStatesEqual = <TModule>(\n left: LoadState<TModule>,\n right: LoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (left.module !== right.module) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst areMultiLoadStatesEqual = <TModule>(\n left: MultiLoadState<TModule>,\n right: MultiLoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (!areModuleMapsEqual(left.modules, right.modules)) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst selectLoadState = <TModule>(\n currentState: LoadState<TModule>,\n nextState: LoadState<TModule>,\n): LoadState<TModule> => {\n if (areLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst selectMultiLoadState = <TModule>(\n currentState: MultiLoadState<TModule>,\n nextState: MultiLoadState<TModule>,\n): MultiLoadState<TModule> => {\n if (areMultiLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst useFacetLoader = <TModule>(\n entityId: string,\n getLoaded: (entityId: string) => TModule | null,\n load: (entityId: string) => Promise<TModule>,\n enabled = true,\n): LoadState<TModule> => {\n const initialModule = getLoaded(entityId);\n const [state, setState] = useState<LoadState<TModule>>(() => {\n if (initialModule != null) {\n return {\n status: 'loaded',\n module: initialModule,\n error: null,\n };\n }\n return {\n status: 'loading',\n module: null,\n error: null,\n };\n });\n\n useEffect(() => {\n if (!enabled) {\n const loadedModule = getLoaded(entityId);\n setState((currentState) => {\n let nextState: LoadState<TModule>;\n\n if (loadedModule != null) {\n nextState = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n } else {\n nextState = {\n status: 'loading',\n module: null,\n error: null,\n };\n }\n\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n const loadedModule = getLoaded(entityId);\n if (loadedModule != null) {\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loading',\n module: null,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n\n load(entityId)\n .then((module) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'error',\n module: null,\n error: nextError,\n };\n return selectLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [enabled, entityId, getLoaded, load]);\n\n return state;\n};\n\nexport const useBackofficeListEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedListEntity,\n entityRegistry.loadListEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficePickerEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedPickerFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedPickerEntity,\n entityRegistry.loadPickerEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeToolEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedToolFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedToolEntity,\n entityRegistry.loadToolEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeListEntitiesLoader = (\n entityIds: readonly string[],\n): MultiLoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n const normalizedEntityIds = useMemo(() => {\n return buildSortedEntityIds(entityIds);\n }, [entityIds]);\n const entityIdsKey = normalizedEntityIds.join('|');\n const [state, setState] = useState<\n MultiLoadState<BackofficeResolvedListFacetModule>\n >(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n return createMultiLoadState('loaded', modules);\n }\n return createMultiLoadState('loading', modules);\n });\n\n useEffect(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n const nextState = createMultiLoadState('loaded', modules);\n setState((currentState) => {\n return selectMultiLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loading',\n modules,\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n\n Promise.all(\n normalizedEntityIds.map(async (entityId) => {\n const module = await entityRegistry.loadListEntity(entityId);\n return [entityId, module] as const;\n }),\n )\n .then((entries) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loaded',\n modules: Object.fromEntries(entries),\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'error',\n modules,\n error: nextError,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [entityIdsKey, entityRegistry, normalizedEntityIds]);\n\n return state;\n};\n\nexport const __test = {\n areErrorsEqual,\n buildSortedEntityIds,\n toError,\n};\n"],"mappings":";;;AA4CA,IAAM,KAAW,MACX,aAAiB,QACZ,IAEE,MAAM,OAAO,CAAK,CAAC,GAG1B,KACJ,MAEO,CAAC,GAAG,IAAI,IAAI,CAAS,CAAC,EAAE,KAAK,GAGhC,KACJ,GACA,OAEO;CACL;CACA;CACA,OAAO;AACT,IAGI,KAAkB,GAAoB,MACtC,MAAS,IACJ,KAEL,KAAQ,QAAQ,KAAS,OACpB,KAEF,EAAK,SAAS,EAAM,QAAQ,EAAK,YAAY,EAAM,SAGtD,KACJ,GACA,MACY;CACZ,IAAM,IAAW,OAAO,KAAK,CAAI,GAC3B,IAAY,OAAO,KAAK,CAAK;CAEnC,IAAI,EAAS,WAAW,EAAU,QAChC,OAAO;CAGT,KAAK,IAAM,KAAO,GAChB,IAAI,EAAE,KAAO,MAAU,EAAK,OAAS,EAAM,IACzC,OAAO;CAIX,OAAO;AACT,GAEM,KACJ,GACA,MAEI,EAAK,WAAW,EAAM,UAItB,EAAK,WAAW,EAAM,SACjB,KAGF,EAAe,EAAK,OAAO,EAAM,KAAK,GAGzC,KACJ,GACA,MAEI,EAAK,WAAW,EAAM,UAItB,CAAC,EAAmB,EAAK,SAAS,EAAM,OAAO,IAC1C,KAGF,EAAe,EAAK,OAAO,EAAM,KAAK,GAGzC,KACJ,GACA,MAEI,EAAmB,GAAc,CAAS,IACrC,IAEF,GAGH,KACJ,GACA,MAEI,EAAwB,GAAc,CAAS,IAC1C,IAEF,GAGH,KACJ,GACA,GACA,GACA,IAAU,OACa;CACvB,IAAM,IAAgB,EAAU,CAAQ,GAClC,CAAC,GAAO,KAAY,QACpB,KAAiB,OAOd;EACL,QAAQ;EACR,QAAQ;EACR,OAAO;CACT,IAVS;EACL,QAAQ;EACR,QAAQ;EACR,OAAO;CACT,CAOH;CAoFD,OAlFA,QAAgB;EACd,IAAI,CAAC,GAAS;GACZ,IAAM,IAAe,EAAU,CAAQ;GACvC,GAAU,MAAiB;IACzB,IAAI;IAgBJ,OAdA,AACE,IADE,KAAgB,OAON;KACV,QAAQ;KACR,QAAQ;KACR,OAAO;IACT,IAVY;KACV,QAAQ;KACR,QAAQ;KACR,OAAO;IACT,GASK,EAAgB,GAAc,CAAS;GAChD,CAAC;GACD;EACF;EAEA,IAAM,IAAe,EAAU,CAAQ;EACvC,IAAI,KAAgB,MAAM;GACxB,GAAU,MAMD,EAAgB,GAAc;IAJnC,QAAQ;IACR,QAAQ;IACR,OAAO;GAE4B,CAAS,CAC/C;GACD;EACF;EAEA,IAAI,IAAY;EAuChB,OAtCA,GAAU,MAMD,EAAgB,GAAc;GAJnC,QAAQ;GACR,QAAQ;GACR,OAAO;EAE4B,CAAS,CAC/C,GAED,EAAK,CAAQ,EACV,MAAM,MAAW;GACZ,KAGJ,GAAU,MAMD,EAAgB,GAAc;IAJnC,QAAQ;IACR;IACA,OAAO;GAE4B,CAAS,CAC/C;EACH,CAAC,EACA,OAAO,MAAmB;GACzB,IAAI,GACF;GAEF,IAAM,IAAY,EAAQ,CAAK;GAC/B,GAAU,MAMD,EAAgB,GAAc;IAJnC,QAAQ;IACR,QAAQ;IACR,OAAO;GAE4B,CAAS,CAC/C;EACH,CAAC,SAEU;GACX,IAAY;EACd;CACF,GAAG;EAAC;EAAS;EAAU;EAAW;CAAI,CAAC,GAEhC;AACT,GAEa,KACX,GACA,MACiD;CACjD,IAAM,EAAE,sBAAmB,EAAoB;CAC/C,OAAO,EACL,GACA,EAAe,qBACf,EAAe,gBACf,GAAS,OACX;AACF,GAEa,KACX,GACA,MACmD;CACnD,IAAM,EAAE,sBAAmB,EAAoB;CAC/C,OAAO,EACL,GACA,EAAe,uBACf,EAAe,kBACf,GAAS,OACX;AACF,GAEa,KACX,GACA,MACiD;CACjD,IAAM,EAAE,sBAAmB,EAAoB;CAC/C,OAAO,EACL,GACA,EAAe,qBACf,EAAe,gBACf,GAAS,OACX;AACF,GAEa,KACX,MACsD;CACtD,IAAM,EAAE,sBAAmB,EAAoB,GACzC,IAAsB,QACnB,EAAqB,CAAS,GACpC,CAAC,CAAS,CAAC,GACR,IAAe,EAAoB,KAAK,GAAG,GAC3C,CAAC,GAAO,KAAY,QAElB;EACN,IAAM,IAA6D,CAAC,GAChE,IAAa;EAEjB,KAAK,IAAM,KAAY,GAAqB;GAC1C,IAAM,IAAS,EAAe,oBAAoB,CAAQ;GAC1D,AAAI,KAAU,OACZ,IAAa,KAEb,EAAQ,KAAY;EAExB;EAKA,OAFS,EADL,IAC0B,WAEF,WAFY,CAAO;CAGjD,CAAC;CAwED,OAtEA,QAAgB;EACd,IAAM,IAA6D,CAAC,GAChE,IAAa;EAEjB,KAAK,IAAM,KAAY,GAAqB;GAC1C,IAAM,IAAS,EAAe,oBAAoB,CAAQ;GAC1D,AAAI,KAAU,OACZ,IAAa,KAEb,EAAQ,KAAY;EAExB;EAEA,IAAI,GAAY;GACd,IAAM,IAAY,EAAqB,UAAU,CAAO;GACxD,GAAU,MACD,EAAqB,GAAc,CAAS,CACpD;GACD;EACF;EAEA,IAAI,IAAY;EA4ChB,OA3CA,GAAU,MAMD,EAAqB,GAAc;GAJxC,QAAQ;GACR;GACA,OAAO;EAEiC,CAAS,CACpD,GAED,QAAQ,IACN,EAAoB,IAAI,OAAO,MAEtB,CAAC,GAAU,MADG,EAAe,eAAe,CAAQ,CACnC,CACzB,CACH,EACG,MAAM,MAAY;GACb,KAGJ,GAAU,MAMD,EAAqB,GAAc;IAJxC,QAAQ;IACR,SAAS,OAAO,YAAY,CAAO;IACnC,OAAO;GAEiC,CAAS,CACpD;EACH,CAAC,EACA,OAAO,MAAmB;GACzB,IAAI,GACF;GAEF,IAAM,IAAY,EAAQ,CAAK;GAC/B,GAAU,MAMD,EAAqB,GAAc;IAJxC,QAAQ;IACR;IACA,OAAO;GAEiC,CAAS,CACpD;EACH,CAAC,SAEU;GACX,IAAY;EACd;CACF,GAAG;EAAC;EAAc;EAAgB;CAAmB,CAAC,GAE/C;AACT,GAEa,IAAS;CACpB;CACA;CACA;AACF"}
|
|
1
|
+
{"version":3,"file":"useBackofficeEntityLoader.js","names":[],"sources":["../../../src/provider/useBackofficeEntityLoader.ts"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\n\nimport type {\n BackofficeResolvedListFacetModule,\n BackofficeResolvedPickerFacetModule,\n BackofficeResolvedToolFacetModule,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeConfig } from './BackofficeConfigContext.js';\n\ntype LoadState<TModule> =\n | {\n status: 'loading';\n module: null;\n error: null;\n }\n | {\n status: 'loaded';\n module: TModule;\n error: null;\n }\n | {\n status: 'error';\n module: null;\n error: Error;\n };\n\ntype MultiLoadState<TModule> =\n | {\n status: 'loading';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'loaded';\n modules: Record<string, TModule>;\n error: null;\n }\n | {\n status: 'error';\n modules: Record<string, TModule>;\n error: Error;\n };\n\nconst toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n};\n\nconst buildSortedEntityIds = (\n entityIds: readonly string[],\n): readonly string[] => {\n return [...new Set(entityIds)].sort();\n};\n\nconst createMultiLoadState = <TModule>(\n status: 'loading' | 'loaded',\n modules: Record<string, TModule>,\n): MultiLoadState<TModule> => {\n return {\n status,\n modules,\n error: null,\n };\n};\n\nconst areErrorsEqual = (left: Error | null, right: Error | null): boolean => {\n if (left === right) {\n return true;\n }\n if (left == null || right == null) {\n return false;\n }\n return left.name === right.name && left.message === right.message;\n};\n\nconst areModuleMapsEqual = <TModule>(\n left: Record<string, TModule>,\n right: Record<string, TModule>,\n): boolean => {\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n\n if (leftKeys.length !== rightKeys.length) {\n return false;\n }\n\n for (const key of leftKeys) {\n if (!(key in right) || left[key] !== right[key]) {\n return false;\n }\n }\n\n return true;\n};\n\nconst areLoadStatesEqual = <TModule>(\n left: LoadState<TModule>,\n right: LoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (left.module !== right.module) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst areMultiLoadStatesEqual = <TModule>(\n left: MultiLoadState<TModule>,\n right: MultiLoadState<TModule>,\n): boolean => {\n if (left.status !== right.status) {\n return false;\n }\n\n if (!areModuleMapsEqual(left.modules, right.modules)) {\n return false;\n }\n\n return areErrorsEqual(left.error, right.error);\n};\n\nconst selectLoadState = <TModule>(\n currentState: LoadState<TModule>,\n nextState: LoadState<TModule>,\n): LoadState<TModule> => {\n if (areLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst selectMultiLoadState = <TModule>(\n currentState: MultiLoadState<TModule>,\n nextState: MultiLoadState<TModule>,\n): MultiLoadState<TModule> => {\n if (areMultiLoadStatesEqual(currentState, nextState)) {\n return currentState;\n }\n return nextState;\n};\n\nconst useFacetLoader = <TModule>(\n entityId: string,\n getLoaded: (entityId: string) => TModule | null,\n load: (entityId: string) => Promise<TModule>,\n enabled = true,\n): LoadState<TModule> => {\n const initialModule = getLoaded(entityId);\n const [state, setState] = useState<LoadState<TModule>>(() => {\n if (initialModule != null) {\n return {\n status: 'loaded',\n module: initialModule,\n error: null,\n };\n }\n return {\n status: 'loading',\n module: null,\n error: null,\n };\n });\n\n useEffect(() => {\n if (!enabled) {\n const loadedModule = getLoaded(entityId);\n setState((currentState) => {\n let nextState: LoadState<TModule>;\n\n if (loadedModule != null) {\n nextState = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n } else {\n nextState = {\n status: 'loading',\n module: null,\n error: null,\n };\n }\n\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n const loadedModule = getLoaded(entityId);\n if (loadedModule != null) {\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module: loadedModule,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loading',\n module: null,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n\n load(entityId)\n .then((module) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'loaded',\n module,\n error: null,\n };\n return selectLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: LoadState<TModule> = {\n status: 'error',\n module: null,\n error: nextError,\n };\n return selectLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [enabled, entityId, getLoaded, load]);\n\n return state;\n};\n\nexport const useBackofficeListEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedListEntity,\n entityRegistry.loadListEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficePickerEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedPickerFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedPickerEntity,\n entityRegistry.loadPickerEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeToolEntityLoader = (\n entityId: string,\n options?: { enabled?: boolean },\n): LoadState<BackofficeResolvedToolFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n return useFacetLoader(\n entityId,\n entityRegistry.getLoadedToolEntity,\n entityRegistry.loadToolEntity,\n options?.enabled,\n );\n};\n\nexport const useBackofficeListEntitiesLoader = (\n entityIds: readonly string[],\n): MultiLoadState<BackofficeResolvedListFacetModule> => {\n const { entityRegistry } = useBackofficeConfig();\n const normalizedEntityIds = useMemo(() => {\n return buildSortedEntityIds(entityIds);\n }, [entityIds]);\n const entityIdsKey = normalizedEntityIds.join('|');\n const [state, setState] = useState<\n MultiLoadState<BackofficeResolvedListFacetModule>\n >(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n return createMultiLoadState('loaded', modules);\n }\n return createMultiLoadState('loading', modules);\n });\n\n useEffect(() => {\n const modules: Record<string, BackofficeResolvedListFacetModule> = {};\n let isComplete = true;\n\n for (const entityId of normalizedEntityIds) {\n const module = entityRegistry.getLoadedListEntity(entityId);\n if (module == null) {\n isComplete = false;\n } else {\n modules[entityId] = module;\n }\n }\n\n if (isComplete) {\n const nextState = createMultiLoadState('loaded', modules);\n setState((currentState) => {\n return selectMultiLoadState(currentState, nextState);\n });\n return undefined;\n }\n\n let cancelled = false;\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loading',\n modules,\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n\n Promise.all(\n normalizedEntityIds.map(async (entityId) => {\n const module = await entityRegistry.loadListEntity(entityId);\n return [entityId, module] as const;\n }),\n )\n .then((entries) => {\n if (cancelled) {\n return;\n }\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'loaded',\n modules: Object.fromEntries(entries),\n error: null,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n })\n .catch((error: unknown) => {\n if (cancelled) {\n return;\n }\n const nextError = toError(error);\n setState((currentState) => {\n const nextState: MultiLoadState<BackofficeResolvedListFacetModule> = {\n status: 'error',\n modules,\n error: nextError,\n };\n return selectMultiLoadState(currentState, nextState);\n });\n });\n\n return () => {\n cancelled = true;\n };\n }, [entityIdsKey, entityRegistry, normalizedEntityIds]);\n\n return state;\n};\n\nexport const __test = {\n areErrorsEqual,\n buildSortedEntityIds,\n toError,\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectionUtils.js","names":[],"sources":["../../../src/relay/connectionUtils.ts"],"sourcesContent":["import RelayRuntime, {\n type RecordProxy,\n type RecordSourceSelectorProxy,\n} from 'relay-runtime';\n\nconst { ConnectionHandler } = RelayRuntime;\n\nexport type AppendNodeToConnectionsOptions = {\n store: RecordSourceSelectorProxy;\n parentId: string;\n connectionKeys: readonly string[];\n node: RecordProxy;\n edgeTypeName: string;\n};\n\n/** Appends a node to existing Relay connections on the parent record. */\nexport function appendNodeToConnections(\n options: AppendNodeToConnectionsOptions,\n): void {\n const { store, parentId, connectionKeys, node, edgeTypeName } = options;\n const parentRecord = store.get(parentId);\n if (parentRecord == null) {\n return;\n }\n\n const nodeId = node.getDataID();\n const uniqueKeys = Array.from(new Set(connectionKeys)).filter((key) => {\n return key.trim() !== '';\n });\n\n for (const connectionKey of uniqueKeys) {\n const connection = ConnectionHandler.getConnection(\n parentRecord,\n connectionKey,\n );\n if (connection != null) {\n const edges = connection.getLinkedRecords('edges');\n const alreadyPresent = edges.some((edge) => {\n const edgeNode = edge.getLinkedRecord('node');\n return edgeNode.getDataID() === nodeId;\n });\n\n if (!alreadyPresent) {\n const newEdge = ConnectionHandler.createEdge(\n store,\n connection,\n node,\n edgeTypeName,\n );\n ConnectionHandler.insertEdgeAfter(connection, newEdge);\n }\n }\n }\n}\n"],"mappings":";;AAKA,IAAM,EAAE,yBAAsB;AAW9B,SAAgB,EACd,GACM;CACN,IAAM,EAAE,UAAO,aAAU,mBAAgB,SAAM,oBAAiB,GAC1D,IAAe,EAAM,IAAI,CAAQ;CACvC,IAAI,KAAgB,MAClB;CAGF,IAAM,IAAS,EAAK,UAAU,GACxB,IAAa,MAAM,KAAK,IAAI,IAAI,CAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"connectionUtils.js","names":[],"sources":["../../../src/relay/connectionUtils.ts"],"sourcesContent":["import RelayRuntime, {\n type RecordProxy,\n type RecordSourceSelectorProxy,\n} from 'relay-runtime';\n\nconst { ConnectionHandler } = RelayRuntime;\n\nexport type AppendNodeToConnectionsOptions = {\n store: RecordSourceSelectorProxy;\n parentId: string;\n connectionKeys: readonly string[];\n node: RecordProxy;\n edgeTypeName: string;\n};\n\n/** Appends a node to existing Relay connections on the parent record. */\nexport function appendNodeToConnections(\n options: AppendNodeToConnectionsOptions,\n): void {\n const { store, parentId, connectionKeys, node, edgeTypeName } = options;\n const parentRecord = store.get(parentId);\n if (parentRecord == null) {\n return;\n }\n\n const nodeId = node.getDataID();\n const uniqueKeys = Array.from(new Set(connectionKeys)).filter((key) => {\n return key.trim() !== '';\n });\n\n for (const connectionKey of uniqueKeys) {\n const connection = ConnectionHandler.getConnection(\n parentRecord,\n connectionKey,\n );\n if (connection != null) {\n const edges = connection.getLinkedRecords('edges');\n const alreadyPresent = edges.some((edge) => {\n const edgeNode = edge.getLinkedRecord('node');\n return edgeNode.getDataID() === nodeId;\n });\n\n if (!alreadyPresent) {\n const newEdge = ConnectionHandler.createEdge(\n store,\n connection,\n node,\n edgeTypeName,\n );\n ConnectionHandler.insertEdgeAfter(connection, newEdge);\n }\n }\n }\n}\n"],"mappings":";;AAKA,IAAM,EAAE,yBAAsB;AAW9B,SAAgB,EACd,GACM;CACN,IAAM,EAAE,UAAO,aAAU,mBAAgB,SAAM,oBAAiB,GAC1D,IAAe,EAAM,IAAI,CAAQ;CACvC,IAAI,KAAgB,MAClB;CAGF,IAAM,IAAS,EAAK,UAAU,GACxB,IAAa,MAAM,KAAK,IAAI,IAAI,CAAc,CAAC,CAAC,CAAC,QAAQ,MACtD,EAAI,KAAK,MAAM,EACvB;CAED,KAAK,IAAM,KAAiB,GAAY;EACtC,IAAM,IAAa,EAAkB,cACnC,GACA,CACF;EACA,IAAI,KAAc,QAOZ,CANU,EAAW,iBAAiB,OACnB,CAAA,CAAM,MAAM,MAChB,EAAK,gBAAgB,MAC/B,CAAA,CAAS,UAAU,MAAM,CAG7B,GAAgB;GACnB,IAAM,IAAU,EAAkB,WAChC,GACA,GACA,GACA,CACF;GACA,EAAkB,gBAAgB,GAAY,CAAO;EACvD;CAEJ;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envHelpers.js","names":[],"sources":["../../../src/relay/envHelpers.ts"],"sourcesContent":["type EnvRecord = Record<string, string | boolean | undefined>;\n\nconst viteEnv: EnvRecord = (() => {\n try {\n const meta = import.meta as unknown as { env?: EnvRecord };\n if (meta.env != null) {\n return meta.env;\n }\n return {};\n } catch {\n // `import.meta` is not defined outside of ESM environments; fall back to an empty record.\n return {};\n }\n})();\n\nexport type ReadEnvFn = (key: string) => string | undefined;\n\nconst readEnvFromRecord = (env: EnvRecord, key: string): string | undefined => {\n const value = env[key];\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (trimmed === '') {\n return undefined;\n }\n\n return trimmed;\n};\n\nconst readBooleanEnvFromRecord = (\n env: EnvRecord,\n key: string,\n): boolean | undefined => {\n const value = env[key];\n if (value === true || value === false) {\n return value;\n }\n if (typeof value === 'string') {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n }\n return undefined;\n};\n\nconst isDevEnvFromRecord = (env: EnvRecord): boolean => {\n return Boolean(readBooleanEnvFromRecord(env, 'DEV'));\n};\n\n/**\n * Read a string environment variable from Vite's `import.meta.env` (if available).\n * Returns `undefined` when the value is missing or empty.\n */\nexport function readEnv(key: string): string | undefined {\n return readEnvFromRecord(viteEnv, key);\n}\n\n/**\n * Reads an environment variable and coerces common string values to booleans.\n */\nexport function readBooleanEnv(key: string): boolean | undefined {\n return readBooleanEnvFromRecord(viteEnv, key);\n}\n\n/**\n * Indicates whether the current build is running in development mode.\n */\nexport function isDevEnv(): boolean {\n return isDevEnvFromRecord(viteEnv);\n}\n\ninterface ResolveEndpointOptions {\n envKeys: readonly string[];\n fallback: string;\n read?: ReadEnvFn;\n}\n\n/**\n * Resolve HTTP endpoint from environment variables.\n */\nexport function resolveHttpEndpoint(options: ResolveEndpointOptions): string {\n const { envKeys, fallback, read = readEnv } = options;\n for (const key of envKeys) {\n const value = read(key);\n if (value != null) {\n return value;\n }\n }\n return fallback;\n}\n\ninterface ResolveWebsocketEndpointOptions extends ResolveEndpointOptions {\n httpEndpoint: string;\n}\n\n/**\n * Resolve websocket endpoint from environment variables or derive it from the HTTP endpoint.\n */\nexport function resolveWebsocketEndpoint(\n options: ResolveWebsocketEndpointOptions,\n): string {\n const { envKeys, fallback, httpEndpoint, read = readEnv } = options;\n\n for (const key of envKeys) {\n const value = read(key);\n if (value != null) {\n return value;\n }\n }\n\n if (httpEndpoint.startsWith('http')) {\n return httpEndpoint.replace(/^http/, 'ws');\n }\n\n if (httpEndpoint.startsWith('/')) {\n return httpEndpoint.replace(/\\/graphql$/, '/ws');\n }\n\n return fallback;\n}\n\nexport const __test = {\n isDevEnvFromRecord,\n readBooleanEnvFromRecord,\n readEnvFromRecord,\n};\n"],"mappings":";AAEA,IAAM,WAA4B;CAChC,IAAI;EACF,IAAM,IAAO,OAAO;EAIpB,OAHI,EAAK,OAAO,OAGT,CAAC,IAFC,EAAK;CAGhB,QAAQ;EAEN,OAAO,CAAC;CACV;AACF,
|
|
1
|
+
{"version":3,"file":"envHelpers.js","names":[],"sources":["../../../src/relay/envHelpers.ts"],"sourcesContent":["type EnvRecord = Record<string, string | boolean | undefined>;\n\nconst viteEnv: EnvRecord = (() => {\n try {\n const meta = import.meta as unknown as { env?: EnvRecord };\n if (meta.env != null) {\n return meta.env;\n }\n return {};\n } catch {\n // `import.meta` is not defined outside of ESM environments; fall back to an empty record.\n return {};\n }\n})();\n\nexport type ReadEnvFn = (key: string) => string | undefined;\n\nconst readEnvFromRecord = (env: EnvRecord, key: string): string | undefined => {\n const value = env[key];\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (trimmed === '') {\n return undefined;\n }\n\n return trimmed;\n};\n\nconst readBooleanEnvFromRecord = (\n env: EnvRecord,\n key: string,\n): boolean | undefined => {\n const value = env[key];\n if (value === true || value === false) {\n return value;\n }\n if (typeof value === 'string') {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n }\n return undefined;\n};\n\nconst isDevEnvFromRecord = (env: EnvRecord): boolean => {\n return Boolean(readBooleanEnvFromRecord(env, 'DEV'));\n};\n\n/**\n * Read a string environment variable from Vite's `import.meta.env` (if available).\n * Returns `undefined` when the value is missing or empty.\n */\nexport function readEnv(key: string): string | undefined {\n return readEnvFromRecord(viteEnv, key);\n}\n\n/**\n * Reads an environment variable and coerces common string values to booleans.\n */\nexport function readBooleanEnv(key: string): boolean | undefined {\n return readBooleanEnvFromRecord(viteEnv, key);\n}\n\n/**\n * Indicates whether the current build is running in development mode.\n */\nexport function isDevEnv(): boolean {\n return isDevEnvFromRecord(viteEnv);\n}\n\ninterface ResolveEndpointOptions {\n envKeys: readonly string[];\n fallback: string;\n read?: ReadEnvFn;\n}\n\n/**\n * Resolve HTTP endpoint from environment variables.\n */\nexport function resolveHttpEndpoint(options: ResolveEndpointOptions): string {\n const { envKeys, fallback, read = readEnv } = options;\n for (const key of envKeys) {\n const value = read(key);\n if (value != null) {\n return value;\n }\n }\n return fallback;\n}\n\ninterface ResolveWebsocketEndpointOptions extends ResolveEndpointOptions {\n httpEndpoint: string;\n}\n\n/**\n * Resolve websocket endpoint from environment variables or derive it from the HTTP endpoint.\n */\nexport function resolveWebsocketEndpoint(\n options: ResolveWebsocketEndpointOptions,\n): string {\n const { envKeys, fallback, httpEndpoint, read = readEnv } = options;\n\n for (const key of envKeys) {\n const value = read(key);\n if (value != null) {\n return value;\n }\n }\n\n if (httpEndpoint.startsWith('http')) {\n return httpEndpoint.replace(/^http/, 'ws');\n }\n\n if (httpEndpoint.startsWith('/')) {\n return httpEndpoint.replace(/\\/graphql$/, '/ws');\n }\n\n return fallback;\n}\n\nexport const __test = {\n isDevEnvFromRecord,\n readBooleanEnvFromRecord,\n readEnvFromRecord,\n};\n"],"mappings":";AAEA,IAAM,WAA4B;CAChC,IAAI;EACF,IAAM,IAAO,OAAO;EAIpB,OAHI,EAAK,OAAO,OAGT,CAAC,IAFC,EAAK;CAGhB,QAAQ;EAEN,OAAO,CAAC;CACV;AACF,EAAA,CAAG,GAIG,KAAqB,GAAgB,MAAoC;CAC7E,IAAM,IAAQ,EAAI;CAClB,IAAI,OAAO,KAAU,UACnB;CAGF,IAAM,IAAU,EAAM,KAAK;CACvB,UAAY,IAIhB,OAAO;AACT,GAEM,KACJ,GACA,MACwB;CACxB,IAAM,IAAQ,EAAI;CAClB,IAAI,MAAU,MAAQ,MAAU,IAC9B,OAAO;CAET,IAAI,OAAO,KAAU,UAAU;EAC7B,IAAI,MAAU,QACZ,OAAO;EAET,IAAI,MAAU,SACZ,OAAO;CAEX;AAEF,GAEM,KAAsB,MACnB,EAAQ,EAAyB,GAAK,KAAK;AAOpD,SAAgB,EAAQ,GAAiC;CACvD,OAAO,EAAkB,GAAS,CAAG;AACvC;AAKA,SAAgB,EAAe,GAAkC;CAC/D,OAAO,EAAyB,GAAS,CAAG;AAC9C;AAKA,SAAgB,IAAoB;CAClC,OAAO,EAAmB,CAAO;AACnC;AAWA,SAAgB,EAAoB,GAAyC;CAC3E,IAAM,EAAE,YAAS,aAAU,UAAO,MAAY;CAC9C,KAAK,IAAM,KAAO,GAAS;EACzB,IAAM,IAAQ,EAAK,CAAG;EACtB,IAAI,KAAS,MACX,OAAO;CAEX;CACA,OAAO;AACT;AASA,SAAgB,EACd,GACQ;CACR,IAAM,EAAE,YAAS,aAAU,iBAAc,UAAO,MAAY;CAE5D,KAAK,IAAM,KAAO,GAAS;EACzB,IAAM,IAAQ,EAAK,CAAG;EACtB,IAAI,KAAS,MACX,OAAO;CAEX;CAUA,OARI,EAAa,WAAW,MAAM,IACzB,EAAa,QAAQ,SAAS,IAAI,IAGvC,EAAa,WAAW,GAAG,IACtB,EAAa,QAAQ,cAAc,KAAK,IAG1C;AACT;AAEA,IAAa,IAAS;CACpB;CACA;CACA;AACF"}
|