@plumile/backoffice-react 0.1.154 → 0.1.157
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/login/synchronizeAuthStatusQuery.js.map +1 -1
- package/lib/esm/components/backoffice/actions/BackofficeEntityActionFormDialog.js.map +1 -1
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js +1 -0
- package/lib/esm/components/backoffice/columns/buildDataTableColumns.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeDetailRelationListBlock.js +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeDetailRelationListBlock.js.map +1 -1
- package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js +1 -0
- package/lib/esm/components/backoffice/detail/BackofficeRelationsSummaryGrid.js.map +1 -1
- package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +0 -1
- package/lib/esm/components/backoffice/filters/BackofficeFilterAction.js +1 -0
- package/lib/esm/components/backoffice/filters/BackofficeFilterAction.js.map +1 -1
- package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js +1 -0
- package/lib/esm/components/backoffice/hub/BackofficeHubTemplate.js.map +1 -1
- package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js +1 -0
- package/lib/esm/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.js.map +1 -1
- package/lib/esm/components/backoffice/links/BackofficeInlineLink.js +15 -14
- package/lib/esm/components/backoffice/links/BackofficeInlineLink.js.map +1 -1
- package/lib/esm/components/backoffice/links/BackofficeLink.js +9 -8
- package/lib/esm/components/backoffice/links/BackofficeLink.js.map +1 -1
- package/lib/esm/components/backoffice/list/RowFlagsCell.css.js +1 -0
- package/lib/esm/components/backoffice/refs/BackofficeLazyEntityCount.js +31 -0
- package/lib/esm/components/backoffice/refs/BackofficeLazyEntityCount.js.map +1 -0
- package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js +36 -32
- package/lib/esm/components/backoffice/refs/BackofficeRelatedCountLink.js.map +1 -1
- package/lib/esm/i18n/locales/en/backofficeReact.js +0 -1
- package/lib/esm/i18n/locales/en/backofficeReact.js.map +1 -1
- package/lib/esm/i18n/locales/fr/backofficeReact.js +0 -1
- package/lib/esm/i18n/locales/fr/backofficeReact.js.map +1 -1
- package/lib/esm/index.js +33 -32
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js +110 -10
- package/lib/esm/pages/BackofficeEntityDetailLayoutPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.js +220 -283
- package/lib/esm/pages/BackofficeEntityDetailPage.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js +0 -1
- package/lib/esm/pages/BackofficeEntityDetailPage.view-helpers.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListPage.helpers.js +2 -2
- package/lib/esm/pages/BackofficeEntityListPage.helpers.js.map +1 -1
- package/lib/esm/pages/BackofficeEntityListPage.js +78 -267
- package/lib/esm/pages/BackofficeEntityListPage.js.map +1 -1
- package/lib/esm/pages/detail/BackofficeEntityDetailLayoutContext.js.map +1 -1
- package/lib/esm/pages/detail/buildTabsItems.js +1 -0
- package/lib/esm/pages/detail/buildTabsItems.js.map +1 -1
- package/lib/types/components/backoffice/columns/buildDataTableColumns.d.ts.map +1 -1
- package/lib/types/components/backoffice/detail/BackofficeDetailRelationListBlock.d.ts.map +1 -1
- package/lib/types/components/backoffice/detail/BackofficeRelationsSummaryGrid.d.ts +1 -1
- package/lib/types/components/backoffice/detail/BackofficeRelationsSummaryGrid.d.ts.map +1 -1
- package/lib/types/components/backoffice/filters/BackofficeFilterAction.d.ts.map +1 -1
- package/lib/types/components/backoffice/hub/BackofficeHubTemplate.d.ts.map +1 -1
- package/lib/types/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.d.ts.map +1 -1
- package/lib/types/components/backoffice/links/BackofficeInlineLink.d.ts +2 -1
- package/lib/types/components/backoffice/links/BackofficeInlineLink.d.ts.map +1 -1
- package/lib/types/components/backoffice/links/BackofficeLink.d.ts +2 -1
- package/lib/types/components/backoffice/links/BackofficeLink.d.ts.map +1 -1
- package/lib/types/components/backoffice/refs/BackofficeLazyEntityCount.d.ts +8 -0
- package/lib/types/components/backoffice/refs/BackofficeLazyEntityCount.d.ts.map +1 -0
- package/lib/types/components/backoffice/refs/BackofficeRelatedCountLink.d.ts +1 -1
- package/lib/types/components/backoffice/refs/BackofficeRelatedCountLink.d.ts.map +1 -1
- package/lib/types/i18n/resources.d.ts +0 -2
- package/lib/types/i18n/resources.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailLayoutPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts +2 -3
- package/lib/types/pages/BackofficeEntityDetailPage.view-helpers.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityListPage.d.ts.map +1 -1
- package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts +1 -6
- package/lib/types/pages/BackofficeEntityListPage.helpers.d.ts.map +1 -1
- package/lib/types/pages/detail/BackofficeEntityDetailLayoutContext.d.ts +7 -0
- package/lib/types/pages/detail/BackofficeEntityDetailLayoutContext.d.ts.map +1 -1
- package/lib/types/pages/detail/buildTabsItems.d.ts.map +1 -1
- package/package.json +11 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synchronizeAuthStatusQuery.js","names":[],"sources":["../../../../src/auth/login/synchronizeAuthStatusQuery.ts"],"sourcesContent":["import RelayRuntime, {\n type GraphQLTaggedNode,\n type IEnvironment,\n type OperationType,\n} from 'relay-runtime';\n\nconst { fetchQuery } = RelayRuntime;\n\ntype AuthStatusQueryResponse = {\n readonly isLoggedIn?: boolean | null;\n};\n\n/**\n * Forces a fresh auth-status read from network to avoid stale cache guards\n * right after login mutations complete.\n */\nexport async function synchronizeAuthStatusQuery<TQuery extends OperationType>(\n environment: IEnvironment,\n query: GraphQLTaggedNode,\n): Promise<boolean> {\n const response = await fetchQuery<TQuery>(\n environment,\n query,\n {},\n { fetchPolicy: 'network-only' },\n ).toPromise();\n\n const isLoggedIn = (response as AuthStatusQueryResponse | null | undefined)\n ?.isLoggedIn;\n return isLoggedIn === true;\n}\n"],"mappings":";;AAMA,IAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"synchronizeAuthStatusQuery.js","names":[],"sources":["../../../../src/auth/login/synchronizeAuthStatusQuery.ts"],"sourcesContent":["import RelayRuntime, {\n type GraphQLTaggedNode,\n type IEnvironment,\n type OperationType,\n} from 'relay-runtime';\n\nconst { fetchQuery } = RelayRuntime;\n\ntype AuthStatusQueryResponse = {\n readonly isLoggedIn?: boolean | null;\n};\n\n/**\n * Forces a fresh auth-status read from network to avoid stale cache guards\n * right after login mutations complete.\n */\nexport async function synchronizeAuthStatusQuery<TQuery extends OperationType>(\n environment: IEnvironment,\n query: GraphQLTaggedNode,\n): Promise<boolean> {\n const response = await fetchQuery<TQuery>(\n environment,\n query,\n {},\n { fetchPolicy: 'network-only' },\n ).toPromise();\n\n const isLoggedIn = (response as AuthStatusQueryResponse | null | undefined)\n ?.isLoggedIn;\n return isLoggedIn === true;\n}\n"],"mappings":";;AAMA,IAAM,EAAE,kBAAe;AAUvB,eAAsB,EACpB,GACA,GACkB;CAUlB,QAFoB,MAPG,EACrB,GACA,GACA,CAAC,GACD,EAAE,aAAa,eAAe,CAChC,EAAE,UAAU,IAGR,eACkB;AACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeEntityActionFormDialog.js","names":[],"sources":["../../../../../src/components/backoffice/actions/BackofficeEntityActionFormDialog.tsx"],"sourcesContent":["import {\n type FormEvent,\n type JSX,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport {\n type MutationPayloadBase,\n resolveMutationOutcome,\n} from '../../../relay/mutationResult.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Input } from '@plumile/ui/atomic/atoms/input/Input.js';\nimport { Label } from '@plumile/ui/atomic/atoms/label/Label.js';\nimport { Modal } from '@plumile/ui/atomic/atoms/modal/Modal.js';\nimport { Textarea } from '@plumile/ui/atomic/atoms/textarea/Textarea.js';\nimport { CheckboxField } from '@plumile/ui/atomic/molecules/checkbox_field/CheckboxField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormGroup } from '@plumile/ui/atomic/molecules/form/FormGroup.js';\nimport { HighlightCode } from '@plumile/ui/atomic/molecules/highlight/HighlightCode.js';\nimport { useToast } from '@plumile/ui/atomic/molecules/toast/ToastProvider.js';\nimport { BackofficeFormSection } from '@plumile/ui/backoffice/molecules/backoffice_form_section/BackofficeFormSection.js';\nimport { SimpleSelect } from '@plumile/ui/components/select/SimpleSelect.js';\nimport type {\n BackofficeEntityActionFormFieldSpec,\n BackofficeEntityFormMutationActionSpec,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../../../provider/BackofficeConfigContext.js';\nimport { EntityIdFilterField } from '../filters/EntityIdFilterField.js';\nimport { EntityIdPickerDialog } from '../pickers/EntityIdPickerDialog.js';\nimport {\n resolveToastSpec,\n resolveToastViewActions,\n} from './toastViewAction.js';\n\nconst { commitMutation, useRelayEnvironment } = ReactRelay;\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport * as styles from './backofficeEntityActionFormDialog.css.js';\n\nexport type BackofficeEntityActionFormDialogProps<Node> = {\n isOpen: boolean;\n action: BackofficeEntityFormMutationActionSpec<Node>;\n node: Node;\n onClose: () => void;\n onSuccess?: () => void;\n};\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n};\n\nconst extractMutationPayload = (\n response: unknown,\n): MutationPayloadBase | null => {\n if (!isPlainObject(response)) {\n return null;\n }\n\n for (const value of Object.values(response)) {\n if (isPlainObject(value) && ('status' in value || 'result' in value)) {\n return value;\n }\n }\n\n return null;\n};\n\nconst buildDefaultValues = (\n fields: readonly BackofficeEntityActionFormFieldSpec[],\n): Record<string, unknown> => {\n const output: Record<string, unknown> = {};\n fields.forEach((field) => {\n if (field.kind === 'boolean') {\n output[field.id] = field.defaultValue ?? false;\n return;\n }\n if (field.kind === 'multiEnum') {\n output[field.id] = field.defaultValue ?? [];\n return;\n }\n if (field.defaultValue != null) {\n output[field.id] = field.defaultValue;\n return;\n }\n output[field.id] = '';\n });\n return output;\n};\n\nconst normalizeInitialValue = (\n field: BackofficeEntityActionFormFieldSpec,\n value: unknown,\n): unknown => {\n if (field.kind === 'number') {\n if (typeof value === 'number') {\n return String(value);\n }\n if (typeof value === 'string') {\n return value;\n }\n return '';\n }\n if (field.kind === 'multiEnum') {\n if (Array.isArray(value)) {\n return value.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n return [];\n }\n if (field.kind === 'boolean') {\n return value === true;\n }\n if (typeof value === 'string') {\n return value;\n }\n return value ?? '';\n};\n\nconst buildInitialValues = <Node,>(\n action: BackofficeEntityFormMutationActionSpec<Node>,\n node: Node,\n): Record<string, unknown> => {\n const defaults = buildDefaultValues(action.fields);\n if (action.getInitialValues == null) {\n return defaults;\n }\n const overrides = action.getInitialValues(node);\n const next: Record<string, unknown> = { ...defaults };\n action.fields.forEach((field) => {\n if (!(field.id in overrides)) {\n return;\n }\n next[field.id] = normalizeInitialValue(field, overrides[field.id]);\n });\n return next;\n};\n\nexport const BackofficeEntityActionFormDialog = <Node,>({\n isOpen,\n action,\n node,\n onClose,\n onSuccess,\n}: BackofficeEntityActionFormDialogProps<Node>): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const routing = useContext(RoutingContext);\n const environment = useRelayEnvironment();\n const toast = useToast();\n const formId = useId();\n\n const [values, setValues] = useState<Record<string, unknown>>({});\n const [formError, setFormError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [resultValue, setResultValue] = useState<string | null>(null);\n const [resultResponse, setResultResponse] = useState<unknown>(null);\n const [activeEntityPicker, setActiveEntityPicker] = useState<{\n fieldId: string;\n entity: string;\n label: string;\n } | null>(null);\n\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n setValues(buildInitialValues(action, node));\n setFormError(null);\n setFieldErrors({});\n setResultValue(null);\n setResultResponse(null);\n }, [action, isOpen, node]);\n\n const handleClose = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n onClose();\n }, [isSubmitting, onClose]);\n\n const setFieldValue = useCallback((fieldId: string, value: unknown) => {\n setValues((current) => {\n return { ...current, [fieldId]: value };\n });\n setFieldErrors((current) => {\n if (current[fieldId] == null) {\n return current;\n }\n const { [fieldId]: removedValue, ...next } = current;\n return next;\n });\n }, []);\n\n const title = resolveLabel(action.label, tApp);\n\n const resolveRequiredError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.required', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidNumberError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidNumber', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJson', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonObjectError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonObject', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonArrayError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonArray', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const buildPayload = useCallback(():\n | { values: Record<string, unknown> }\n | { error: string; fieldId?: string } => {\n const output: Record<string, unknown> = {};\n\n for (const field of action.fields) {\n const fieldLabel = resolveLabel(field.label, tApp);\n const rawValue = values[field.id];\n\n switch (field.kind) {\n case 'text': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'textarea': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'number': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n } else if (\n typeof rawValue === 'number' &&\n Number.isFinite(rawValue)\n ) {\n valueString = String(rawValue);\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n const parsed = Number(valueString);\n if (!Number.isFinite(parsed)) {\n return {\n error: resolveInvalidNumberError(fieldLabel),\n fieldId: field.id,\n };\n }\n output[field.id] = parsed;\n break;\n }\n case 'json': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(valueString);\n } catch {\n return {\n error: resolveInvalidJsonError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n const jsonType = field.jsonType ?? 'object';\n if (jsonType === 'object' && !isPlainObject(parsed)) {\n return {\n error: resolveInvalidJsonObjectError(fieldLabel),\n fieldId: field.id,\n };\n }\n if (jsonType === 'array' && !Array.isArray(parsed)) {\n return {\n error: resolveInvalidJsonArrayError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n output[field.id] = parsed;\n break;\n }\n case 'enum': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'boolean': {\n output[field.id] = rawValue === true;\n break;\n }\n case 'entityId': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'multiEnum': {\n let list: string[] = [];\n if (Array.isArray(rawValue)) {\n list = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n if (list.length === 0) {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = list;\n break;\n }\n default: {\n break;\n }\n }\n }\n\n return { values: output };\n }, [\n action.fields,\n resolveInvalidJsonArrayError,\n resolveInvalidJsonError,\n resolveInvalidJsonObjectError,\n resolveInvalidNumberError,\n resolveRequiredError,\n tApp,\n values,\n ]);\n\n const handleSubmit = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n\n setFormError(null);\n setFieldErrors({});\n\n const payload = buildPayload();\n if ('error' in payload) {\n setFormError(payload.error);\n if (payload.fieldId != null) {\n setFieldErrors({ [payload.fieldId]: payload.error });\n }\n return;\n }\n\n let variables: ReturnType<typeof action.getVariables>;\n try {\n variables = action.getVariables(node, payload.values);\n } catch {\n const message = t('actions.form.errors.invalidPayload');\n setFormError(message);\n return;\n }\n\n setIsSubmitting(true);\n commitMutation(environment, {\n mutation: action.mutation,\n variables,\n updater: (store) => {\n action.updater?.(store, node);\n },\n onCompleted: (response) => {\n setIsSubmitting(false);\n const mutationPayload = extractMutationPayload(response);\n if (mutationPayload != null) {\n let defaultErrorMessage = t('actions.form.errors.invalidPayload');\n if (action.toasts?.error?.message != null) {\n defaultErrorMessage = resolveLabel(\n action.toasts.error.message,\n tApp,\n );\n } else if (action.toasts?.error?.title != null) {\n defaultErrorMessage = resolveLabel(action.toasts.error.title, tApp);\n }\n\n const outcome = resolveMutationOutcome(mutationPayload, {\n defaultErrorMessage,\n mapReason: (reason) => {\n const mapped = action.mapErrorReason?.(reason, node);\n if (mapped == null) {\n return null;\n }\n if (typeof mapped === 'function') {\n return resolveLabel(mapped, tApp);\n }\n return String(mapped);\n },\n });\n if (!outcome.ok) {\n const error = new Error(outcome.message);\n setFormError(outcome.message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n return;\n }\n }\n\n action.onCompleted?.(response, node);\n\n let hasCustomResult = false;\n if (action.result?.render != null) {\n const renderedResult = action.result.render(response, node);\n if (renderedResult != null) {\n hasCustomResult = true;\n setResultResponse(response);\n }\n }\n if (action.toasts?.success != null) {\n const toastSpec = resolveToastSpec(action.toasts.success, tApp);\n const toastActions = resolveToastViewActions({\n toast: action.toasts.success,\n response,\n node,\n tApp,\n entities,\n defaultLabel: t('actions.view'),\n navigateTo: (to) => {\n routing?.history.push({ pathname: to });\n },\n });\n toast.push({\n kind: 'info',\n title: toastSpec.title,\n message: toastSpec.message,\n actions: toastActions,\n });\n }\n\n if (action.result != null) {\n const nextValue = action.result.getValue(response, node);\n if (typeof nextValue === 'string' && nextValue.trim() !== '') {\n setResultValue(nextValue);\n onSuccess?.();\n return;\n }\n }\n\n if (hasCustomResult) {\n onSuccess?.();\n return;\n }\n\n onSuccess?.();\n onClose();\n },\n onError: (error) => {\n setIsSubmitting(false);\n const message = t('actions.form.errors.submitFailed');\n setFormError(message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n },\n });\n }, [\n action,\n buildPayload,\n entities,\n environment,\n isSubmitting,\n node,\n onClose,\n onSuccess,\n routing?.history,\n t,\n tApp,\n toast,\n ]);\n\n const handleFormSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n handleSubmit();\n },\n [handleSubmit],\n );\n\n const resultLabel = useMemo(() => {\n if (action.result == null) {\n return null;\n }\n return resolveLabel(action.result.label, tApp);\n }, [action.result, tApp]);\n\n const resultRender = useMemo(() => {\n if (action.result?.render == null || resultResponse == null) {\n return null;\n }\n return action.result.render(resultResponse, node);\n }, [action.result, node, resultResponse]);\n\n const showResult =\n (resultValue != null && resultLabel != null) || resultRender != null;\n\n const submitLabel = resolveLabel(action.label, tApp);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n initialFocus=\"first-form-control\"\n footer={\n <div className={styles.actions}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n disabled={isSubmitting}\n onClick={handleClose}\n >\n {t('actions.form.cancel')}\n </Button>\n {!showResult && (\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"small\"\n disabled={isSubmitting}\n isLoading={isSubmitting}\n loadingLabel={t('actions.form.submitting')}\n onClick={handleSubmit}\n >\n {submitLabel}\n </Button>\n )}\n </div>\n }\n >\n <Form onSubmit={handleFormSubmit} className={styles.form}>\n <FormError message={formError} />\n <BackofficeFormSection>\n {action.fields.map((field) => {\n const fieldLabel = resolveLabel(field.label, tApp);\n let fieldDescription: string | null = null;\n if (field.description != null) {\n fieldDescription = resolveLabel(field.description, tApp);\n }\n const fieldInputId = `${formId}-${field.id}`;\n const fieldDescriptionId = `${fieldInputId}-description`;\n const fieldErrorId = `${fieldInputId}-error`;\n const fieldError = fieldErrors[field.id] ?? null;\n const isFieldInvalid = fieldError != null;\n let inputVariant: 'error' | undefined;\n let selectState: 'default' | 'error' = 'default';\n if (isFieldInvalid) {\n inputVariant = 'error';\n selectState = 'error';\n }\n let describedBy: string | undefined;\n if (fieldDescription != null && fieldError != null) {\n describedBy = `${fieldDescriptionId} ${fieldErrorId}`;\n } else if (fieldDescription != null) {\n describedBy = fieldDescriptionId;\n } else if (fieldError != null) {\n describedBy = fieldErrorId;\n }\n\n switch (field.kind) {\n case 'text': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Input\n id={fieldInputId}\n type=\"text\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'textarea': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={field.rows ?? 8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'number': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Input\n id={fieldInputId}\n type=\"number\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'json': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'enum': {\n const rawValue = values[field.id];\n let selected = '';\n if (typeof rawValue === 'string') {\n selected = rawValue;\n }\n const options = field.options.map((option) => {\n return {\n id: option.value,\n value: option.value,\n label: resolveLabel(option.label, tApp),\n };\n });\n return (\n <FormGroup key={field.id}>\n <Label\n id={`${fieldInputId}-label`}\n required={field.required}\n >\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <SimpleSelect\n options={options}\n value={selected}\n placeholder={fieldLabel}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n ariaLabelledBy={`${fieldInputId}-label`}\n isDisabled={isSubmitting}\n state={selectState}\n onChange={(nextValue) => {\n setFieldValue(field.id, nextValue);\n }}\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'boolean': {\n const checked = values[field.id] === true;\n return (\n <FormGroup key={field.id}>\n <CheckboxField\n id={fieldInputId}\n label={fieldLabel}\n helperText={fieldDescription ?? undefined}\n error={fieldError ?? undefined}\n checked={checked}\n disabled={isSubmitting}\n onChange={(event) => {\n setFieldValue(field.id, event.target.checked);\n }}\n />\n </FormGroup>\n );\n }\n case 'entityId': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <EntityIdFilterField\n id={fieldInputId}\n label={fieldLabel}\n value={value}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n disabled={isSubmitting}\n onPick={() => {\n setActiveEntityPicker({\n fieldId: field.id,\n entity: field.entity,\n label: fieldLabel,\n });\n }}\n onClear={() => {\n setFieldValue(field.id, '');\n }}\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'multiEnum': {\n const rawValue = values[field.id];\n const fieldLegendId = `${fieldInputId}-legend`;\n let selected: string[] = [];\n if (Array.isArray(rawValue)) {\n selected = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string';\n });\n }\n return (\n <FormGroup key={field.id}>\n <fieldset className={styles.fieldset}>\n <legend id={fieldLegendId} className={styles.legend}>\n {fieldLabel}\n {field.required && (\n <span className={styles.requiredMark}>*</span>\n )}\n </legend>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <div\n className={styles.checkboxGroup}\n role=\"group\"\n aria-labelledby={fieldLegendId}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n >\n {field.options.map((option, index) => {\n const optionLabel = resolveLabel(\n option.label,\n tApp,\n );\n const isChecked = selected.includes(option.value);\n return (\n <CheckboxField\n key={`${option.value}-${index}`}\n id={`${fieldInputId}-${index}`}\n label={optionLabel}\n checked={isChecked}\n disabled={isSubmitting}\n onChange={(event) => {\n let nextList = selected;\n if (event.target.checked) {\n if (!selected.includes(option.value)) {\n nextList = [...selected, option.value];\n }\n } else {\n nextList = selected.filter((value) => {\n return value !== option.value;\n });\n }\n setFieldValue(field.id, nextList);\n }}\n />\n );\n })}\n </div>\n </fieldset>\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n default: {\n return null;\n }\n }\n })}\n </BackofficeFormSection>\n\n {showResult && (\n <div className={styles.resultSection}>\n {resultValue != null && resultLabel != null && (\n <HighlightCode\n badgeLabel={resultLabel}\n copyCode={resultValue}\n fallbackCodeText={resultValue}\n />\n )}\n {resultRender}\n </div>\n )}\n </Form>\n </Modal>\n <EntityIdPickerDialog\n isOpen={activeEntityPicker != null}\n entity={activeEntityPicker?.entity ?? ''}\n title={activeEntityPicker?.label ?? ''}\n onClose={() => {\n setActiveEntityPicker(null);\n }}\n onSelectId={(id) => {\n if (activeEntityPicker == null) {\n return;\n }\n setFieldValue(activeEntityPicker.fieldId, id);\n setActiveEntityPicker(null);\n }}\n />\n </>\n );\n};\n\nexport default BackofficeEntityActionFormDialog;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BackofficeEntityActionFormDialog.js","names":[],"sources":["../../../../../src/components/backoffice/actions/BackofficeEntityActionFormDialog.tsx"],"sourcesContent":["import {\n type FormEvent,\n type JSX,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport {\n type MutationPayloadBase,\n resolveMutationOutcome,\n} from '../../../relay/mutationResult.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { Input } from '@plumile/ui/atomic/atoms/input/Input.js';\nimport { Label } from '@plumile/ui/atomic/atoms/label/Label.js';\nimport { Modal } from '@plumile/ui/atomic/atoms/modal/Modal.js';\nimport { Textarea } from '@plumile/ui/atomic/atoms/textarea/Textarea.js';\nimport { CheckboxField } from '@plumile/ui/atomic/molecules/checkbox_field/CheckboxField.js';\nimport { Form } from '@plumile/ui/atomic/molecules/form/Form.js';\nimport { FormError } from '@plumile/ui/atomic/molecules/form_error/FormError.js';\nimport { FormGroup } from '@plumile/ui/atomic/molecules/form/FormGroup.js';\nimport { HighlightCode } from '@plumile/ui/atomic/molecules/highlight/HighlightCode.js';\nimport { useToast } from '@plumile/ui/atomic/molecules/toast/ToastProvider.js';\nimport { BackofficeFormSection } from '@plumile/ui/backoffice/molecules/backoffice_form_section/BackofficeFormSection.js';\nimport { SimpleSelect } from '@plumile/ui/components/select/SimpleSelect.js';\nimport type {\n BackofficeEntityActionFormFieldSpec,\n BackofficeEntityFormMutationActionSpec,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeConfig } from '../../../provider/BackofficeConfigContext.js';\nimport { EntityIdFilterField } from '../filters/EntityIdFilterField.js';\nimport { EntityIdPickerDialog } from '../pickers/EntityIdPickerDialog.js';\nimport {\n resolveToastSpec,\n resolveToastViewActions,\n} from './toastViewAction.js';\n\nconst { commitMutation, useRelayEnvironment } = ReactRelay;\nimport RoutingContext from '@plumile/router/routing/RoutingContext.js';\n\nimport * as styles from './backofficeEntityActionFormDialog.css.js';\n\nexport type BackofficeEntityActionFormDialogProps<Node> = {\n isOpen: boolean;\n action: BackofficeEntityFormMutationActionSpec<Node>;\n node: Node;\n onClose: () => void;\n onSuccess?: () => void;\n};\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n};\n\nconst extractMutationPayload = (\n response: unknown,\n): MutationPayloadBase | null => {\n if (!isPlainObject(response)) {\n return null;\n }\n\n for (const value of Object.values(response)) {\n if (isPlainObject(value) && ('status' in value || 'result' in value)) {\n return value;\n }\n }\n\n return null;\n};\n\nconst buildDefaultValues = (\n fields: readonly BackofficeEntityActionFormFieldSpec[],\n): Record<string, unknown> => {\n const output: Record<string, unknown> = {};\n fields.forEach((field) => {\n if (field.kind === 'boolean') {\n output[field.id] = field.defaultValue ?? false;\n return;\n }\n if (field.kind === 'multiEnum') {\n output[field.id] = field.defaultValue ?? [];\n return;\n }\n if (field.defaultValue != null) {\n output[field.id] = field.defaultValue;\n return;\n }\n output[field.id] = '';\n });\n return output;\n};\n\nconst normalizeInitialValue = (\n field: BackofficeEntityActionFormFieldSpec,\n value: unknown,\n): unknown => {\n if (field.kind === 'number') {\n if (typeof value === 'number') {\n return String(value);\n }\n if (typeof value === 'string') {\n return value;\n }\n return '';\n }\n if (field.kind === 'multiEnum') {\n if (Array.isArray(value)) {\n return value.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n return [];\n }\n if (field.kind === 'boolean') {\n return value === true;\n }\n if (typeof value === 'string') {\n return value;\n }\n return value ?? '';\n};\n\nconst buildInitialValues = <Node,>(\n action: BackofficeEntityFormMutationActionSpec<Node>,\n node: Node,\n): Record<string, unknown> => {\n const defaults = buildDefaultValues(action.fields);\n if (action.getInitialValues == null) {\n return defaults;\n }\n const overrides = action.getInitialValues(node);\n const next: Record<string, unknown> = { ...defaults };\n action.fields.forEach((field) => {\n if (!(field.id in overrides)) {\n return;\n }\n next[field.id] = normalizeInitialValue(field, overrides[field.id]);\n });\n return next;\n};\n\nexport const BackofficeEntityActionFormDialog = <Node,>({\n isOpen,\n action,\n node,\n onClose,\n onSuccess,\n}: BackofficeEntityActionFormDialogProps<Node>): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { entities } = useBackofficeConfig();\n const routing = useContext(RoutingContext);\n const environment = useRelayEnvironment();\n const toast = useToast();\n const formId = useId();\n\n const [values, setValues] = useState<Record<string, unknown>>({});\n const [formError, setFormError] = useState<string | null>(null);\n const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [resultValue, setResultValue] = useState<string | null>(null);\n const [resultResponse, setResultResponse] = useState<unknown>(null);\n const [activeEntityPicker, setActiveEntityPicker] = useState<{\n fieldId: string;\n entity: string;\n label: string;\n } | null>(null);\n\n useEffect(() => {\n if (!isOpen) {\n return;\n }\n setValues(buildInitialValues(action, node));\n setFormError(null);\n setFieldErrors({});\n setResultValue(null);\n setResultResponse(null);\n }, [action, isOpen, node]);\n\n const handleClose = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n onClose();\n }, [isSubmitting, onClose]);\n\n const setFieldValue = useCallback((fieldId: string, value: unknown) => {\n setValues((current) => {\n return { ...current, [fieldId]: value };\n });\n setFieldErrors((current) => {\n if (current[fieldId] == null) {\n return current;\n }\n const { [fieldId]: removedValue, ...next } = current;\n return next;\n });\n }, []);\n\n const title = resolveLabel(action.label, tApp);\n\n const resolveRequiredError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.required', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidNumberError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidNumber', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJson', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonObjectError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonObject', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const resolveInvalidJsonArrayError = useCallback(\n (fieldLabel: string): string => {\n return t('actions.form.errors.invalidJsonArray', {\n label: fieldLabel,\n });\n },\n [t],\n );\n\n const buildPayload = useCallback(():\n | { values: Record<string, unknown> }\n | { error: string; fieldId?: string } => {\n const output: Record<string, unknown> = {};\n\n for (const field of action.fields) {\n const fieldLabel = resolveLabel(field.label, tApp);\n const rawValue = values[field.id];\n\n switch (field.kind) {\n case 'text': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'textarea': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'number': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n } else if (\n typeof rawValue === 'number' &&\n Number.isFinite(rawValue)\n ) {\n valueString = String(rawValue);\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n const parsed = Number(valueString);\n if (!Number.isFinite(parsed)) {\n return {\n error: resolveInvalidNumberError(fieldLabel),\n fieldId: field.id,\n };\n }\n output[field.id] = parsed;\n break;\n }\n case 'json': {\n let valueString = '';\n if (typeof rawValue === 'string') {\n valueString = rawValue.trim();\n }\n if (valueString === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(valueString);\n } catch {\n return {\n error: resolveInvalidJsonError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n const jsonType = field.jsonType ?? 'object';\n if (jsonType === 'object' && !isPlainObject(parsed)) {\n return {\n error: resolveInvalidJsonObjectError(fieldLabel),\n fieldId: field.id,\n };\n }\n if (jsonType === 'array' && !Array.isArray(parsed)) {\n return {\n error: resolveInvalidJsonArrayError(fieldLabel),\n fieldId: field.id,\n };\n }\n\n output[field.id] = parsed;\n break;\n }\n case 'enum': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'boolean': {\n output[field.id] = rawValue === true;\n break;\n }\n case 'entityId': {\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue.trim();\n }\n if (value === '') {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = value;\n break;\n }\n case 'multiEnum': {\n let list: string[] = [];\n if (Array.isArray(rawValue)) {\n list = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string' && entry.trim() !== '';\n });\n }\n if (list.length === 0) {\n if (field.required) {\n return {\n error: resolveRequiredError(fieldLabel),\n fieldId: field.id,\n };\n }\n break;\n }\n output[field.id] = list;\n break;\n }\n default: {\n break;\n }\n }\n }\n\n return { values: output };\n }, [\n action.fields,\n resolveInvalidJsonArrayError,\n resolveInvalidJsonError,\n resolveInvalidJsonObjectError,\n resolveInvalidNumberError,\n resolveRequiredError,\n tApp,\n values,\n ]);\n\n const handleSubmit = useCallback(() => {\n if (isSubmitting) {\n return;\n }\n\n setFormError(null);\n setFieldErrors({});\n\n const payload = buildPayload();\n if ('error' in payload) {\n setFormError(payload.error);\n if (payload.fieldId != null) {\n setFieldErrors({ [payload.fieldId]: payload.error });\n }\n return;\n }\n\n let variables: ReturnType<typeof action.getVariables>;\n try {\n variables = action.getVariables(node, payload.values);\n } catch {\n const message = t('actions.form.errors.invalidPayload');\n setFormError(message);\n return;\n }\n\n setIsSubmitting(true);\n commitMutation(environment, {\n mutation: action.mutation,\n variables,\n updater: (store) => {\n action.updater?.(store, node);\n },\n onCompleted: (response) => {\n setIsSubmitting(false);\n const mutationPayload = extractMutationPayload(response);\n if (mutationPayload != null) {\n let defaultErrorMessage = t('actions.form.errors.invalidPayload');\n if (action.toasts?.error?.message != null) {\n defaultErrorMessage = resolveLabel(\n action.toasts.error.message,\n tApp,\n );\n } else if (action.toasts?.error?.title != null) {\n defaultErrorMessage = resolveLabel(action.toasts.error.title, tApp);\n }\n\n const outcome = resolveMutationOutcome(mutationPayload, {\n defaultErrorMessage,\n mapReason: (reason) => {\n const mapped = action.mapErrorReason?.(reason, node);\n if (mapped == null) {\n return null;\n }\n if (typeof mapped === 'function') {\n return resolveLabel(mapped, tApp);\n }\n return String(mapped);\n },\n });\n if (!outcome.ok) {\n const error = new Error(outcome.message);\n setFormError(outcome.message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n return;\n }\n }\n\n action.onCompleted?.(response, node);\n\n let hasCustomResult = false;\n if (action.result?.render != null) {\n const renderedResult = action.result.render(response, node);\n if (renderedResult != null) {\n hasCustomResult = true;\n setResultResponse(response);\n }\n }\n if (action.toasts?.success != null) {\n const toastSpec = resolveToastSpec(action.toasts.success, tApp);\n const toastActions = resolveToastViewActions({\n toast: action.toasts.success,\n response,\n node,\n tApp,\n entities,\n defaultLabel: t('actions.view'),\n navigateTo: (to) => {\n routing?.history.push({ pathname: to });\n },\n });\n toast.push({\n kind: 'info',\n title: toastSpec.title,\n message: toastSpec.message,\n actions: toastActions,\n });\n }\n\n if (action.result != null) {\n const nextValue = action.result.getValue(response, node);\n if (typeof nextValue === 'string' && nextValue.trim() !== '') {\n setResultValue(nextValue);\n onSuccess?.();\n return;\n }\n }\n\n if (hasCustomResult) {\n onSuccess?.();\n return;\n }\n\n onSuccess?.();\n onClose();\n },\n onError: (error) => {\n setIsSubmitting(false);\n const message = t('actions.form.errors.submitFailed');\n setFormError(message);\n action.onError?.(error, node);\n if (action.toasts?.error != null) {\n const toastTitle = resolveLabel(action.toasts.error.title, tApp);\n let toastMessage: string | undefined;\n if (action.toasts.error.message != null) {\n toastMessage = resolveLabel(action.toasts.error.message, tApp);\n }\n toast.error(toastTitle, toastMessage);\n }\n },\n });\n }, [\n action,\n buildPayload,\n entities,\n environment,\n isSubmitting,\n node,\n onClose,\n onSuccess,\n routing?.history,\n t,\n tApp,\n toast,\n ]);\n\n const handleFormSubmit = useCallback(\n (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n handleSubmit();\n },\n [handleSubmit],\n );\n\n const resultLabel = useMemo(() => {\n if (action.result == null) {\n return null;\n }\n return resolveLabel(action.result.label, tApp);\n }, [action.result, tApp]);\n\n const resultRender = useMemo(() => {\n if (action.result?.render == null || resultResponse == null) {\n return null;\n }\n return action.result.render(resultResponse, node);\n }, [action.result, node, resultResponse]);\n\n const showResult =\n (resultValue != null && resultLabel != null) || resultRender != null;\n\n const submitLabel = resolveLabel(action.label, tApp);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n initialFocus=\"first-form-control\"\n footer={\n <div className={styles.actions}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n disabled={isSubmitting}\n onClick={handleClose}\n >\n {t('actions.form.cancel')}\n </Button>\n {!showResult && (\n <Button\n type=\"submit\"\n variant=\"primary\"\n size=\"small\"\n disabled={isSubmitting}\n isLoading={isSubmitting}\n loadingLabel={t('actions.form.submitting')}\n onClick={handleSubmit}\n >\n {submitLabel}\n </Button>\n )}\n </div>\n }\n >\n <Form onSubmit={handleFormSubmit} className={styles.form}>\n <FormError message={formError} />\n <BackofficeFormSection>\n {action.fields.map((field) => {\n const fieldLabel = resolveLabel(field.label, tApp);\n let fieldDescription: string | null = null;\n if (field.description != null) {\n fieldDescription = resolveLabel(field.description, tApp);\n }\n const fieldInputId = `${formId}-${field.id}`;\n const fieldDescriptionId = `${fieldInputId}-description`;\n const fieldErrorId = `${fieldInputId}-error`;\n const fieldError = fieldErrors[field.id] ?? null;\n const isFieldInvalid = fieldError != null;\n let inputVariant: 'error' | undefined;\n let selectState: 'default' | 'error' = 'default';\n if (isFieldInvalid) {\n inputVariant = 'error';\n selectState = 'error';\n }\n let describedBy: string | undefined;\n if (fieldDescription != null && fieldError != null) {\n describedBy = `${fieldDescriptionId} ${fieldErrorId}`;\n } else if (fieldDescription != null) {\n describedBy = fieldDescriptionId;\n } else if (fieldError != null) {\n describedBy = fieldErrorId;\n }\n\n switch (field.kind) {\n case 'text': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Input\n id={fieldInputId}\n type=\"text\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'textarea': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={field.rows ?? 8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'number': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Input\n id={fieldInputId}\n type=\"number\"\n value={value}\n placeholder={placeholder}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'json': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n let placeholder: string | undefined;\n if (field.placeholder != null) {\n placeholder = resolveLabel(field.placeholder, tApp);\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <Textarea\n id={fieldInputId}\n value={value}\n placeholder={placeholder}\n rows={8}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n disabled={isSubmitting}\n variant={inputVariant}\n onChange={(event) => {\n setFieldValue(field.id, event.target.value);\n }}\n fullWidth\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'enum': {\n const rawValue = values[field.id];\n let selected = '';\n if (typeof rawValue === 'string') {\n selected = rawValue;\n }\n const options = field.options.map((option) => {\n return {\n id: option.value,\n value: option.value,\n label: resolveLabel(option.label, tApp),\n };\n });\n return (\n <FormGroup key={field.id}>\n <Label\n id={`${fieldInputId}-label`}\n required={field.required}\n >\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <SimpleSelect\n options={options}\n value={selected}\n placeholder={fieldLabel}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n ariaLabelledBy={`${fieldInputId}-label`}\n isDisabled={isSubmitting}\n state={selectState}\n onChange={(nextValue) => {\n setFieldValue(field.id, nextValue);\n }}\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'boolean': {\n const checked = values[field.id] === true;\n return (\n <FormGroup key={field.id}>\n <CheckboxField\n id={fieldInputId}\n label={fieldLabel}\n helperText={fieldDescription ?? undefined}\n error={fieldError ?? undefined}\n checked={checked}\n disabled={isSubmitting}\n onChange={(event) => {\n setFieldValue(field.id, event.target.checked);\n }}\n />\n </FormGroup>\n );\n }\n case 'entityId': {\n const rawValue = values[field.id];\n let value = '';\n if (typeof rawValue === 'string') {\n value = rawValue;\n }\n return (\n <FormGroup key={field.id}>\n <Label htmlFor={fieldInputId} required={field.required}>\n {fieldLabel}\n </Label>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <EntityIdFilterField\n id={fieldInputId}\n label={fieldLabel}\n value={value}\n ariaDescribedBy={describedBy}\n ariaInvalid={isFieldInvalid}\n disabled={isSubmitting}\n onPick={() => {\n setActiveEntityPicker({\n fieldId: field.id,\n entity: field.entity,\n label: fieldLabel,\n });\n }}\n onClear={() => {\n setFieldValue(field.id, '');\n }}\n />\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n case 'multiEnum': {\n const rawValue = values[field.id];\n const fieldLegendId = `${fieldInputId}-legend`;\n let selected: string[] = [];\n if (Array.isArray(rawValue)) {\n selected = rawValue.filter((entry): entry is string => {\n return typeof entry === 'string';\n });\n }\n return (\n <FormGroup key={field.id}>\n <fieldset className={styles.fieldset}>\n <legend id={fieldLegendId} className={styles.legend}>\n {fieldLabel}\n {field.required && (\n <span className={styles.requiredMark}>*</span>\n )}\n </legend>\n {fieldDescription != null && (\n <span\n id={fieldDescriptionId}\n className={styles.fieldDescription}\n >\n {fieldDescription}\n </span>\n )}\n <div\n className={styles.checkboxGroup}\n role=\"group\"\n aria-labelledby={fieldLegendId}\n aria-describedby={describedBy}\n aria-invalid={isFieldInvalid}\n >\n {field.options.map((option, index) => {\n const optionLabel = resolveLabel(\n option.label,\n tApp,\n );\n const isChecked = selected.includes(option.value);\n return (\n <CheckboxField\n key={`${option.value}-${index}`}\n id={`${fieldInputId}-${index}`}\n label={optionLabel}\n checked={isChecked}\n disabled={isSubmitting}\n onChange={(event) => {\n let nextList = selected;\n if (event.target.checked) {\n if (!selected.includes(option.value)) {\n nextList = [...selected, option.value];\n }\n } else {\n nextList = selected.filter((value) => {\n return value !== option.value;\n });\n }\n setFieldValue(field.id, nextList);\n }}\n />\n );\n })}\n </div>\n </fieldset>\n {fieldError != null && (\n <span id={fieldErrorId} className={styles.fieldError}>\n {fieldError}\n </span>\n )}\n </FormGroup>\n );\n }\n default: {\n return null;\n }\n }\n })}\n </BackofficeFormSection>\n\n {showResult && (\n <div className={styles.resultSection}>\n {resultValue != null && resultLabel != null && (\n <HighlightCode\n badgeLabel={resultLabel}\n copyCode={resultValue}\n fallbackCodeText={resultValue}\n />\n )}\n {resultRender}\n </div>\n )}\n </Form>\n </Modal>\n <EntityIdPickerDialog\n isOpen={activeEntityPicker != null}\n entity={activeEntityPicker?.entity ?? ''}\n title={activeEntityPicker?.label ?? ''}\n onClose={() => {\n setActiveEntityPicker(null);\n }}\n onSelectId={(id) => {\n if (activeEntityPicker == null) {\n return;\n }\n setFieldValue(activeEntityPicker.fieldId, id);\n setActiveEntityPicker(null);\n }}\n />\n </>\n );\n};\n\nexport default BackofficeEntityActionFormDialog;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildDataTableColumns.js","names":[],"sources":["../../../../../src/components/backoffice/columns/buildDataTableColumns.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n BackofficeListColumnVisibility,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport { FormattedDate } from '@plumile/ui/atomic/atoms/formatted-date/FormattedDate.js';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\nimport { type DataTableColumn } from '@plumile/ui/components/data-table/DataTable.js';\nimport { type DataTableBreakpoint } from '@plumile/ui/components/data-table/tableBreakpoints.js';\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst resolveTextValue = (\n value: string | number | null,\n fallback: string,\n): string => {\n if (value == null) {\n return fallback;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return fallback;\n }\n return String(value);\n};\n\nexport type BuildDataTableColumnsOptions = {\n tApp: TFunction;\n t: TFunction;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> = DataTableColumn<Row> & {\n size: BackofficeFieldSize;\n};\n\nconst resolveBreakpoint = (\n value: BackofficeListColumnVisibility['minVisibleAt'] | undefined,\n): DataTableBreakpoint | undefined => {\n if (value === 'sm' || value === 'md' || value === 'lg' || value === 'xl') {\n return value;\n }\n return undefined;\n};\n\n/**\n *\n */\nexport function buildDataTableColumns<Row>(\n columns: readonly BackofficeColumnSpec<Row>[],\n options: BuildDataTableColumnsOptions,\n): readonly BackofficeSizedDataTableColumn<Row>[] {\n const { tApp, t } = options;\n const fallback = t('common.notAvailable');\n const filteredColumns = columns.filter((column) => {\n return column.key !== 'id';\n });\n\n return filteredColumns.map((column) => {\n return {\n id: column.key,\n header: resolveLabel(column.header, tApp),\n size: column.size,\n isPrimary: column.visibility?.priority === 'primary',\n priority: column.visibility?.priority,\n align: column.visibility?.align,\n mobileRole: column.visibility?.mobile,\n minVisibleAt: resolveBreakpoint(column.visibility?.minVisibleAt),\n cell: (row) => {\n const { cell } = column;\n switch (cell.type) {\n case 'text': {\n return resolveTextValue(cell.value(row), fallback);\n }\n case 'link': {\n const value = cell.value(row);\n if (\n value == null ||\n (typeof value === 'string' && value.trim() === '')\n ) {\n return fallback;\n }\n return <Link to={cell.to(row)}
|
|
1
|
+
{"version":3,"file":"buildDataTableColumns.js","names":[],"sources":["../../../../../src/components/backoffice/columns/buildDataTableColumns.tsx"],"sourcesContent":["import { BACKOFFICE_DATE_TIME_OPTIONS } from '@plumile/backoffice-core/constants.js';\nimport type {\n BackofficeColumnSpec,\n BackofficeFieldSize,\n BackofficeListColumnVisibility,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport { FormattedDate } from '@plumile/ui/atomic/atoms/formatted-date/FormattedDate.js';\nimport { Tag } from '@plumile/ui/backoffice/atoms/tag/Tag.js';\nimport { type DataTableColumn } from '@plumile/ui/components/data-table/DataTable.js';\nimport { type DataTableBreakpoint } from '@plumile/ui/components/data-table/tableBreakpoints.js';\nimport { BackofficeInlineLink } from '../links/BackofficeInlineLink.js';\nimport type { BackofficeLinkTarget } from '../links/types.js';\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nconst resolveTextValue = (\n value: string | number | null,\n fallback: string,\n): string => {\n if (value == null) {\n return fallback;\n }\n if (typeof value === 'string' && value.trim() === '') {\n return fallback;\n }\n return String(value);\n};\n\nexport type BuildDataTableColumnsOptions = {\n tApp: TFunction;\n t: TFunction;\n};\n\nexport type BackofficeSizedDataTableColumn<Row> = DataTableColumn<Row> & {\n size: BackofficeFieldSize;\n};\n\nconst resolveBreakpoint = (\n value: BackofficeListColumnVisibility['minVisibleAt'] | undefined,\n): DataTableBreakpoint | undefined => {\n if (value === 'sm' || value === 'md' || value === 'lg' || value === 'xl') {\n return value;\n }\n return undefined;\n};\n\n/**\n *\n */\nexport function buildDataTableColumns<Row>(\n columns: readonly BackofficeColumnSpec<Row>[],\n options: BuildDataTableColumnsOptions,\n): readonly BackofficeSizedDataTableColumn<Row>[] {\n const { tApp, t } = options;\n const fallback = t('common.notAvailable');\n const filteredColumns = columns.filter((column) => {\n return column.key !== 'id';\n });\n\n return filteredColumns.map((column) => {\n return {\n id: column.key,\n header: resolveLabel(column.header, tApp),\n size: column.size,\n isPrimary: column.visibility?.priority === 'primary',\n priority: column.visibility?.priority,\n align: column.visibility?.align,\n mobileRole: column.visibility?.mobile,\n minVisibleAt: resolveBreakpoint(column.visibility?.minVisibleAt),\n cell: (row) => {\n const { cell } = column;\n switch (cell.type) {\n case 'text': {\n return resolveTextValue(cell.value(row), fallback);\n }\n case 'link': {\n const value = cell.value(row);\n if (\n value == null ||\n (typeof value === 'string' && value.trim() === '')\n ) {\n return fallback;\n }\n return (\n <Link to={cell.to(row)} preloadOnMouseEnter>\n {value}\n </Link>\n );\n }\n case 'badge': {\n const value = cell.value(row);\n if (value == null || value.trim() === '') {\n return fallback;\n }\n let { tone } = cell;\n if (typeof tone === 'function') {\n tone = tone(row);\n }\n return <Tag tone={tone}>{value}</Tag>;\n }\n case 'dateTime': {\n const value = cell.value(row);\n return (\n <FormattedDate\n value={value}\n fallback={fallback}\n options={BACKOFFICE_DATE_TIME_OPTIONS}\n />\n );\n }\n case 'entityRef': {\n const id = cell.value(row);\n if (id.trim() === '') {\n return fallback;\n }\n const label = cell.label?.(row) ?? t('actions.view');\n const target = {\n kind: 'entity-detail',\n entityId: cell.entity,\n id,\n } as BackofficeLinkTarget;\n return (\n <BackofficeInlineLink target={target}>\n {label}\n </BackofficeInlineLink>\n );\n }\n case 'custom': {\n const rendered = cell.render(row);\n if (rendered == null || rendered === '') {\n return fallback;\n }\n return <>{rendered}</>;\n }\n default: {\n return fallback;\n }\n }\n },\n };\n });\n}\n"],"mappings":";;;;;;;AAgBA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGb,KACJ,GACA,MAEI,KAAS,QAGT,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KACzC,IAEF,OAAO,CAAK,GAYf,KACJ,MACoC;CACpC,IAAI,MAAU,QAAQ,MAAU,QAAQ,MAAU,QAAQ,MAAU,MAClE,OAAO;AAGX;AAKA,SAAgB,EACd,GACA,GACgD;CAChD,IAAM,EAAE,SAAM,SAAM,GACd,IAAW,EAAE,qBAAqB;CAKxC,OAJwB,EAAQ,QAAQ,MAC/B,EAAO,QAAQ,IAGjB,EAAgB,KAAK,OACnB;EACL,IAAI,EAAO;EACX,QAAQ,EAAa,EAAO,QAAQ,CAAI;EACxC,MAAM,EAAO;EACb,WAAW,EAAO,YAAY,aAAa;EAC3C,UAAU,EAAO,YAAY;EAC7B,OAAO,EAAO,YAAY;EAC1B,YAAY,EAAO,YAAY;EAC/B,cAAc,EAAkB,EAAO,YAAY,YAAY;EAC/D,OAAO,MAAQ;GACb,IAAM,EAAE,YAAS;GACjB,QAAQ,EAAK,MAAb;IACE,KAAK,QACH,OAAO,EAAiB,EAAK,MAAM,CAAG,GAAG,CAAQ;IAEnD,KAAK,QAAQ;KACX,IAAM,IAAQ,EAAK,MAAM,CAAG;KAO5B,OALE,KAAS,QACR,OAAO,KAAU,YAAY,EAAM,KAAK,MAAM,KAExC,IAGP,kBAAC,GAAD;MAAM,IAAI,EAAK,GAAG,CAAG;MAAG,qBAAA;gBACrB;KACG,CAAA;IAEV;IACA,KAAK,SAAS;KACZ,IAAM,IAAQ,EAAK,MAAM,CAAG;KAC5B,IAAI,KAAS,QAAQ,EAAM,KAAK,MAAM,IACpC,OAAO;KAET,IAAI,EAAE,YAAS;KAIf,OAHI,OAAO,KAAS,eAClB,IAAO,EAAK,CAAG,IAEV,kBAAC,GAAD;MAAW;gBAAO;KAAW,CAAA;IACtC;IACA,KAAK,YAEH,OACE,kBAAC,GAAD;KACS,OAHG,EAAK,MAAM,CAGd;KACG;KACV,SAAS;IACV,CAAA;IAGL,KAAK,aAAa;KAChB,IAAM,IAAK,EAAK,MAAM,CAAG;KACzB,IAAI,EAAG,KAAK,MAAM,IAChB,OAAO;KAET,IAAM,IAAQ,EAAK,QAAQ,CAAG,KAAK,EAAE,cAAc;KAMnD,OACE,kBAAC,GAAD;MAA8B,QAAA;OAL9B,MAAM;OACN,UAAU,EAAK;OACf;MAG8B;gBAC3B;KACmB,CAAA;IAE1B;IACA,KAAK,UAAU;KACb,IAAM,IAAW,EAAK,OAAO,CAAG;KAIhC,OAHI,KAAY,QAAQ,MAAa,KAC5B,IAEF,kBAAA,GAAA,EAAA,UAAG,EAAW,CAAA;IACvB;IACA,SACE,OAAO;GAEX;EACF;CACF,EACD;AACH"}
|
|
@@ -94,7 +94,7 @@ var { useLazyLoadQuery: y, usePaginationFragment: b } = m, x = () => {
|
|
|
94
94
|
children: a("relations.unavailable.description")
|
|
95
95
|
});
|
|
96
96
|
let s = o.modules[r.target]?.config;
|
|
97
|
-
return s == null
|
|
97
|
+
return s == null ? null : /* @__PURE__ */ f(S, {
|
|
98
98
|
title: t,
|
|
99
99
|
config: s,
|
|
100
100
|
relation: r,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeDetailRelationListBlock.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeDetailRelationListBlock.tsx"],"sourcesContent":["import { Suspense, useCallback, useMemo, useState, type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\n\nimport {\n BACKOFFICE_LIST_REFETCH_POLICY,\n BACKOFFICE_RELATED_TAB_PAGE_SIZE,\n} from '@plumile/backoffice-core/constants.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\nimport type {\n BackofficeListState,\n BackofficeRuntimeRelationFilterSpec,\n BackofficeRuntimeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { BackofficeTableSkeleton } from '@plumile/ui/backoffice/molecules/backoffice_table_skeleton/BackofficeTableSkeleton.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\n\nimport { buildDataTableColumns } from '../columns/buildDataTableColumns.js';\nimport { useBackofficeLoadMore } from '../../../hooks/useBackofficeLoadMore.js';\nimport { useBackofficeListRefetch } from '../../../hooks/useBackofficeListRefetch.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeListEntitiesLoader } from '../../../provider/useBackofficeEntityLoader.js';\nimport { BackofficeEntityListScaffold } from '../scaffolds/BackofficeEntityListScaffold.js';\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\n\nconst { useLazyLoadQuery, usePaginationFragment } = ReactRelay;\n\nexport type BackofficeDetailRelationListBlockProps = {\n title: string;\n relation: BackofficeRuntimeRelationFilterSpec;\n value: string | null;\n};\n\ntype RelationListContentProps = {\n title: string;\n config: BackofficeRuntimeResolvedListFacetConfig
|
|
1
|
+
{"version":3,"file":"BackofficeDetailRelationListBlock.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeDetailRelationListBlock.tsx"],"sourcesContent":["import { Suspense, useCallback, useMemo, useState, type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport * as ReactRelay from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\n\nimport {\n BACKOFFICE_LIST_REFETCH_POLICY,\n BACKOFFICE_RELATED_TAB_PAGE_SIZE,\n} from '@plumile/backoffice-core/constants.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\nimport type {\n BackofficeListState,\n BackofficeRuntimeRelationFilterSpec,\n BackofficeRuntimeResolvedListFacetConfig,\n} from '@plumile/backoffice-core/types.js';\nimport { BackofficeTableSkeleton } from '@plumile/ui/backoffice/molecules/backoffice_table_skeleton/BackofficeTableSkeleton.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\n\nimport { buildDataTableColumns } from '../columns/buildDataTableColumns.js';\nimport { useBackofficeLoadMore } from '../../../hooks/useBackofficeLoadMore.js';\nimport { useBackofficeListRefetch } from '../../../hooks/useBackofficeListRefetch.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficeListEntitiesLoader } from '../../../provider/useBackofficeEntityLoader.js';\nimport { BackofficeEntityListScaffold } from '../scaffolds/BackofficeEntityListScaffold.js';\nimport { BackofficeErrorBoundary } from '../errors/BackofficeErrorBoundary.js';\n\nconst { useLazyLoadQuery, usePaginationFragment } = ReactRelay;\n\nexport type BackofficeDetailRelationListBlockProps = {\n title: string;\n relation: BackofficeRuntimeRelationFilterSpec;\n value: string | null;\n};\n\ntype RelationListContentProps = {\n title: string;\n config: BackofficeRuntimeResolvedListFacetConfig;\n relation: BackofficeRuntimeRelationFilterSpec;\n value: string | null;\n};\n\ntype RelationListBlockBodyProps = {\n title: string;\n relation: BackofficeRuntimeRelationFilterSpec;\n value: string | null;\n};\n\nconst RelationListSkeleton = (): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n\n return <BackofficeTableSkeleton rows={6} ariaLabel={t('common.loading')} />;\n};\n\nconst RelationListContent = ({\n title,\n config,\n relation,\n value,\n}: RelationListContentProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const listConfig = config.list;\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n\n const [state, setState] = useState<BackofficeListState<unknown, string>>({\n where: listDefaults.where as never,\n sort: listDefaults.sort ?? null,\n });\n\n const relationWhere = useMemo(() => {\n if (value == null || value.trim() === '') {\n return null;\n }\n return setWhereValue(\n state.where as Record<string, unknown> | null,\n relation.whereKey as never,\n value,\n relation.path,\n );\n }, [relation.path, relation.whereKey, state.where, value]);\n\n const effectiveWhere = relationWhere ?? (state.where as never);\n const resolvedSort = state.sort ?? listDefaults.sort;\n const variablesBase = useMemo(() => {\n return {\n where: effectiveWhere as never,\n sort: resolvedSort as never,\n count: BACKOFFICE_RELATED_TAB_PAGE_SIZE,\n cursor: null,\n };\n }, [effectiveWhere, resolvedSort]);\n\n const variables = useMemo(() => {\n return listConfig.buildQueryVariables(variablesBase);\n }, [listConfig, variablesBase]);\n\n const queryData = useLazyLoadQuery<OperationType>(\n listConfig.query,\n variables,\n { fetchPolicy: 'store-or-network' },\n );\n\n const {\n data: fragmentData,\n loadNext,\n hasNext,\n isLoadingNext,\n refetch,\n } = usePaginationFragment(listConfig.fragment, queryData as never);\n\n const connection = listConfig.getConnection(fragmentData);\n const rows = useMemo(() => {\n return connection.edges.map((edge) => {\n return listConfig.toRow(edge.node);\n });\n }, [connection.edges, listConfig]);\n\n const columns = useMemo(() => {\n return buildDataTableColumns(listConfig.columns, {\n tApp,\n t,\n });\n }, [listConfig.columns, t, tApp]);\n\n const getRowId = useCallback(\n (row: unknown) => {\n return listConfig.getRowId(row);\n },\n [listConfig],\n );\n\n const defaults = useMemo(() => {\n const baseWhere = relationWhere ?? listDefaults.where;\n return {\n where: baseWhere,\n sort: listDefaults.sort,\n count: BACKOFFICE_RELATED_TAB_PAGE_SIZE,\n cursor: null,\n };\n }, [listDefaults.sort, listDefaults.where, relationWhere]);\n\n const { onRefresh } = useBackofficeListRefetch({\n refetch,\n variables: variablesBase,\n defaults,\n fetchPolicy: BACKOFFICE_LIST_REFETCH_POLICY,\n buildQueryVariables: listConfig.buildQueryVariables,\n });\n\n const handleLoadMore = useBackofficeLoadMore({\n hasNext,\n isLoadingNext,\n loadNext,\n count: BACKOFFICE_RELATED_TAB_PAGE_SIZE,\n });\n\n return (\n <BackofficeEntityListScaffold\n config={config as never}\n state={state as never}\n pushState={(next) => {\n setState(next);\n }}\n header={{ title }}\n rows={rows}\n columns={columns as never}\n getRowId={getRowId}\n hasNextPage={hasNext}\n isLoadingMore={isLoadingNext}\n onLoadMore={handleLoadMore}\n onRefresh={onRefresh}\n totalCount={connection.totalCount ?? null}\n variant=\"embedded\"\n />\n );\n};\n\nconst RelationListBlockBody = ({\n title,\n relation,\n value,\n}: RelationListBlockBodyProps): JSX.Element | null => {\n const { t } = useBackofficeReactTranslation();\n const relatedEntityIds = useMemo(() => {\n return [relation.target];\n }, [relation.target]);\n const relatedEntitiesState =\n useBackofficeListEntitiesLoader(relatedEntityIds);\n\n if (relatedEntitiesState.status === 'loading') {\n return <BackofficeTableSkeleton rows={6} ariaLabel={t('common.loading')} />;\n }\n\n if (relatedEntitiesState.status === 'error') {\n return (\n <InlineBanner tone=\"warning\" title={t('relations.unavailable.title')}>\n {t('relations.unavailable.description')}\n </InlineBanner>\n );\n }\n\n const config = relatedEntitiesState.modules[relation.target]?.config;\n if (config == null) {\n return null;\n }\n\n return (\n <RelationListContent\n title={title}\n config={config}\n relation={relation}\n value={value}\n />\n );\n};\n\nexport const BackofficeDetailRelationListBlock = ({\n title,\n relation,\n value,\n}: BackofficeDetailRelationListBlockProps): JSX.Element => {\n return (\n <BackofficeErrorBoundary\n fallback={() => {\n return <RelationListSkeleton />;\n }}\n >\n <Suspense fallback={<RelationListSkeleton />}>\n <RelationListBlockBody\n title={title}\n relation={relation}\n value={value}\n />\n </Suspense>\n </BackofficeErrorBoundary>\n );\n};\n\nexport default BackofficeDetailRelationListBlock;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeRelationsSummaryGrid.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeRelationsSummaryGrid.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\nimport type { MetricTone } from '@plumile/ui/components/dashboard/metric_card/MetricCard.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport * as styles from './backofficeRelationsSummaryGrid.css.js';\n\nexport type BackofficeRelationSummaryItem = {\n readonly id: string;\n readonly label: string;\n readonly count?:
|
|
1
|
+
{"version":3,"file":"BackofficeRelationsSummaryGrid.js","names":[],"sources":["../../../../../src/components/backoffice/detail/BackofficeRelationsSummaryGrid.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\nimport { BackofficeDetailSection } from '@plumile/ui/backoffice/molecules/backoffice_detail_section/BackofficeDetailSection.js';\nimport type { MetricTone } from '@plumile/ui/components/dashboard/metric_card/MetricCard.js';\n\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\nimport * as styles from './backofficeRelationsSummaryGrid.css.js';\n\nexport type BackofficeRelationSummaryItem = {\n readonly id: string;\n readonly label: string;\n readonly count?: ReactNode;\n readonly href?: string;\n readonly description?: ReactNode;\n readonly tone?: MetricTone;\n};\n\nexport type BackofficeRelationsSummaryGridProps = {\n readonly title: string;\n readonly items: readonly BackofficeRelationSummaryItem[];\n};\n\nexport const BackofficeRelationsSummaryGrid = ({\n title,\n items,\n}: BackofficeRelationsSummaryGridProps): JSX.Element | null => {\n const { t } = useBackofficeReactTranslation();\n\n if (items.length === 0) {\n return null;\n }\n\n return (\n <BackofficeDetailSection title={title}>\n <div className={styles.grid}>\n {items.map((item) => {\n const countNode = item.count ?? t('common.notAvailable');\n const content = (\n <>\n <span className={styles.label}>{item.label}</span>\n <span className={styles.count}>{countNode}</span>\n {item.description != null && (\n <span className={styles.description}>{item.description}</span>\n )}\n </>\n );\n\n if (item.href == null) {\n return (\n <div className={styles.item} key={item.id}>\n {content}\n </div>\n );\n }\n\n return (\n <Link\n className={styles.item}\n key={item.id}\n to={item.href}\n preloadOnMouseEnter\n >\n {content}\n </Link>\n );\n })}\n </div>\n </BackofficeDetailSection>\n );\n};\n\nexport default BackofficeRelationsSummaryGrid;\n"],"mappings":";;;;;;AAsBA,IAAa,KAAkC,EAC7C,UACA,eAC6D;CAC7D,IAAM,EAAE,SAAM,EAA8B;CAM5C,OAJI,EAAM,WAAW,IACZ,OAIP,kBAAC,GAAD;EAAgC;YAC9B,kBAAC,OAAD;GAAK,WAAW;aACb,EAAM,KAAK,MAAS;IACnB,IAAM,IAAY,EAAK,SAAS,EAAE,qBAAqB,GACjD,IACJ,kBAAA,GAAA,EAAA,UAAA;KACE,kBAAC,QAAD;MAAM,WAAW;gBAAe,EAAK;KAAY,CAAA;KACjD,kBAAC,QAAD;MAAM,WAAW;gBAAe;KAAgB,CAAA;KAC/C,EAAK,eAAe,QACnB,kBAAC,QAAD;MAAM,WAAW;gBAAqB,EAAK;KAAkB,CAAA;IAE/D,EAAA,CAAA;IAWJ,OARI,EAAK,QAAQ,OAEb,kBAAC,OAAD;KAAK,WAAW;eACb;IACE,GAF6B,EAAK,EAElC,IAKP,kBAAC,GAAD;KACE,WAAW;KAEX,IAAI,EAAK;KACT,qBAAA;eAEC;IACG,GALC,EAAK,EAKN;GAEV,CAAC;EACE,CAAA;CACkB,CAAA;AAE7B"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* empty css */
|
|
2
1
|
/* empty css */
|
|
3
2
|
//#region src/components/backoffice/detail/backofficeDetailRelationLink.css.ts
|
|
4
3
|
var e = "_93gupm0 qbwcueg qbwcuee txvbqb2tz txvbqb1bg1 txvbqb3f txvbqb7g txvbqb76 txvbqb7t qbwcuef txvbqb1ct1 txvbqb1dsd qbwcue0 txvbqb1ffs txvbqb1ga0 txvbqb10mx txvbqb11ki txvbqb12hq txvbqbxtt txvbqb7h txvbqb75 txvbqbfpn txvbqblt7 txvbqbhdy txvbqb28o txvbqb2sj txvbqbik txvbqb1b4r txvbqbey txvbqbem txvbqbh4k txvbqbh4y txvbqb1ct4 txvbqb1dsg", t = "txvbqb9j txvbqbhb2 txvbqbv7x txvbqbws9", n = "txvbqbfqq txvbqbey txvbqbhd8 txvbqbh6d txvbqbv7x", r = "txvbqb96 txvbqb1bg3 txvbqbws9 txvbqb18e2", i = "txvbqbfqq txvbqbey txvbqbls4 txvbqb1bg5 txvbqb9j txvbqbmzg";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeFilterAction.js","names":[],"sources":["../../../../../src/components/backoffice/filters/BackofficeFilterAction.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport { SidebarSearchSvg } from '@plumile/ui/icons/SidebarSearchSvg.js';\n\nimport type {\n BackofficeRuntimeResolvedListFacetConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport { buildBackofficeListLink } from '@plumile/backoffice-core/state/buildListHref.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\n\nimport {\n canFilterValue,\n resolveFilterForColumn,\n resolveFilterForWhereKey,\n} from '../../../filters/filterHelpers.js';\nimport { useBackofficeConfig } from '../../../provider/BackofficeConfigContext.js';\nimport { useBackofficeListFilterContext } from '../scaffolds/BackofficeListFilterContext.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './backofficeFilterAction.css.js';\n\nexport type BackofficeFilterActionProps = {\n whereKey: string;\n value: unknown;\n path?: readonly string[];\n label?: string;\n listConfig?: BackofficeRuntimeResolvedListFacetConfig;\n};\n\ntype ListFilterContext = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n applyFilter: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => void;\n};\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nexport const BackofficeFilterAction = (\n props: BackofficeFilterActionProps,\n): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { filterColumnAliases } = useBackofficeConfig();\n const { whereKey, value, path, label, listConfig } = props;\n\n const getContext =\n useBackofficeListFilterContext as () => ListFilterContext | null;\n const context = getContext();\n let config: BackofficeRuntimeResolvedListFacetConfig | null = null;\n\n if (listConfig != null) {\n config = listConfig;\n } else if (context != null) {\n config = context.config;\n }\n\n if (config == null) {\n return null;\n }\n\n let filter = resolveFilterForWhereKey(config, whereKey, path);\n if (filter == null && path == null) {\n filter = resolveFilterForColumn(config, whereKey, filterColumnAliases);\n }\n if (filter == null || !canFilterValue(filter, value)) {\n return null;\n }\n\n const filterLabel = resolveLabel(filter.label, tApp);\n const actionLabel =\n label ??\n t('filters.actions.filterBy', {\n label: filterLabel,\n });\n const icon = (\n <SidebarSearchSvg\n width={14}\n height={14}\n className={styles.icon}\n aria-hidden=\"true\"\n />\n );\n\n if (context != null) {\n return (\n <button\n type=\"button\"\n className={styles.action}\n title={actionLabel}\n aria-label={actionLabel}\n onClick={() => {\n context.applyFilter(whereKey, value, path);\n }}\n >\n {icon}\n </button>\n );\n }\n\n const baseWhere =\n config.listDefaults?.where ?? config.list.defaultState?.where ?? null;\n const nextWhere = setWhereValue(baseWhere, whereKey, value, path);\n const to = buildBackofficeListLink(config, { where: nextWhere });\n\n return (\n <Link\n to={to}\n className={styles.action}\n title={actionLabel}\n aria-label={actionLabel}\n >\n {icon}\n </Link>\n );\n};\n\nexport default BackofficeFilterAction;\n"],"mappings":";;;;;;;;;;;;AAyCA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGN,KACX,MACuB;CACvB,IAAM,EAAE,GAAG,MAAS,EAAe,GAC7B,EAAE,SAAM,EAA8B,GACtC,EAAE,2BAAwB,EAAoB,GAC9C,EAAE,aAAU,UAAO,SAAM,UAAO,kBAAe,GAI/C,IAAU,EAAW,GACvB,IAA0D;CAQ9D,IANI,KAAc,OAEP,KAAW,SACpB,IAAS,EAAQ,UAFjB,IAAS,GAKP,KAAU,MACZ,OAAO;CAGT,IAAI,IAAS,EAAyB,GAAQ,GAAU,CAAI;CAI5D,IAHI,KAAU,QAAQ,KAAQ,SAC5B,IAAS,EAAuB,GAAQ,GAAU,CAAmB,IAEnE,KAAU,QAAQ,CAAC,EAAe,GAAQ,CAAK,GACjD,OAAO;CAGT,IAAM,IAAc,EAAa,EAAO,OAAO,CAAI,GAC7C,IACJ,KACA,EAAE,4BAA4B,EAC5B,OAAO,EACT,CAAC,GACG,IACJ,kBAAC,GAAD;EACE,OAAO;EACP,QAAQ;EACR,WAAW;EACX,eAAY;CACb,CAAA;CAGH,IAAI,KAAW,MACb,OACE,kBAAC,UAAD;EACE,MAAK;EACL,WAAW;EACX,OAAO;EACP,cAAY;EACZ,eAAe;GACb,EAAQ,YAAY,GAAU,GAAO,CAAI;EAC3C;YAEC;CACK,CAAA;CAMZ,IAAM,IAAY,EADhB,EAAO,cAAc,SAAS,EAAO,KAAK,cAAc,SAAS,MACxB,GAAU,GAAO,CAAI;CAGhE,OACE,kBAAC,GAAD;EACM,IAJG,EAAwB,GAAQ,EAAE,OAAO,EAAU,CAItD;EACJ,WAAW;EACX,OAAO;EACP,cAAY;
|
|
1
|
+
{"version":3,"file":"BackofficeFilterAction.js","names":[],"sources":["../../../../../src/components/backoffice/filters/BackofficeFilterAction.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport { SidebarSearchSvg } from '@plumile/ui/icons/SidebarSearchSvg.js';\n\nimport type {\n BackofficeRuntimeResolvedListFacetConfig,\n I18nLabel,\n} from '@plumile/backoffice-core/types.js';\nimport type { TFunction } from 'i18next';\nimport { buildBackofficeListLink } from '@plumile/backoffice-core/state/buildListHref.js';\nimport { setWhereValue } from '@plumile/backoffice-core/filters/where.js';\n\nimport {\n canFilterValue,\n resolveFilterForColumn,\n resolveFilterForWhereKey,\n} from '../../../filters/filterHelpers.js';\nimport { useBackofficeConfig } from '../../../provider/BackofficeConfigContext.js';\nimport { useBackofficeListFilterContext } from '../scaffolds/BackofficeListFilterContext.js';\nimport { useBackofficeReactTranslation } from '../../../i18n/useBackofficeReactTranslation.js';\n\nimport * as styles from './backofficeFilterAction.css.js';\n\nexport type BackofficeFilterActionProps = {\n whereKey: string;\n value: unknown;\n path?: readonly string[];\n label?: string;\n listConfig?: BackofficeRuntimeResolvedListFacetConfig;\n};\n\ntype ListFilterContext = {\n config: BackofficeRuntimeResolvedListFacetConfig;\n applyFilter: (\n whereKey: string,\n value: unknown,\n path?: readonly string[],\n ) => void;\n};\n\nconst resolveLabel = (label: I18nLabel, tApp: TFunction): string => {\n return label(tApp);\n};\n\nexport const BackofficeFilterAction = (\n props: BackofficeFilterActionProps,\n): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const { filterColumnAliases } = useBackofficeConfig();\n const { whereKey, value, path, label, listConfig } = props;\n\n const getContext =\n useBackofficeListFilterContext as () => ListFilterContext | null;\n const context = getContext();\n let config: BackofficeRuntimeResolvedListFacetConfig | null = null;\n\n if (listConfig != null) {\n config = listConfig;\n } else if (context != null) {\n config = context.config;\n }\n\n if (config == null) {\n return null;\n }\n\n let filter = resolveFilterForWhereKey(config, whereKey, path);\n if (filter == null && path == null) {\n filter = resolveFilterForColumn(config, whereKey, filterColumnAliases);\n }\n if (filter == null || !canFilterValue(filter, value)) {\n return null;\n }\n\n const filterLabel = resolveLabel(filter.label, tApp);\n const actionLabel =\n label ??\n t('filters.actions.filterBy', {\n label: filterLabel,\n });\n const icon = (\n <SidebarSearchSvg\n width={14}\n height={14}\n className={styles.icon}\n aria-hidden=\"true\"\n />\n );\n\n if (context != null) {\n return (\n <button\n type=\"button\"\n className={styles.action}\n title={actionLabel}\n aria-label={actionLabel}\n onClick={() => {\n context.applyFilter(whereKey, value, path);\n }}\n >\n {icon}\n </button>\n );\n }\n\n const baseWhere =\n config.listDefaults?.where ?? config.list.defaultState?.where ?? null;\n const nextWhere = setWhereValue(baseWhere, whereKey, value, path);\n const to = buildBackofficeListLink(config, { where: nextWhere });\n\n return (\n <Link\n to={to}\n className={styles.action}\n title={actionLabel}\n aria-label={actionLabel}\n preloadOnMouseEnter\n >\n {icon}\n </Link>\n );\n};\n\nexport default BackofficeFilterAction;\n"],"mappings":";;;;;;;;;;;;AAyCA,IAAM,KAAgB,GAAkB,MAC/B,EAAM,CAAI,GAGN,KACX,MACuB;CACvB,IAAM,EAAE,GAAG,MAAS,EAAe,GAC7B,EAAE,SAAM,EAA8B,GACtC,EAAE,2BAAwB,EAAoB,GAC9C,EAAE,aAAU,UAAO,SAAM,UAAO,kBAAe,GAI/C,IAAU,EAAW,GACvB,IAA0D;CAQ9D,IANI,KAAc,OAEP,KAAW,SACpB,IAAS,EAAQ,UAFjB,IAAS,GAKP,KAAU,MACZ,OAAO;CAGT,IAAI,IAAS,EAAyB,GAAQ,GAAU,CAAI;CAI5D,IAHI,KAAU,QAAQ,KAAQ,SAC5B,IAAS,EAAuB,GAAQ,GAAU,CAAmB,IAEnE,KAAU,QAAQ,CAAC,EAAe,GAAQ,CAAK,GACjD,OAAO;CAGT,IAAM,IAAc,EAAa,EAAO,OAAO,CAAI,GAC7C,IACJ,KACA,EAAE,4BAA4B,EAC5B,OAAO,EACT,CAAC,GACG,IACJ,kBAAC,GAAD;EACE,OAAO;EACP,QAAQ;EACR,WAAW;EACX,eAAY;CACb,CAAA;CAGH,IAAI,KAAW,MACb,OACE,kBAAC,UAAD;EACE,MAAK;EACL,WAAW;EACX,OAAO;EACP,cAAY;EACZ,eAAe;GACb,EAAQ,YAAY,GAAU,GAAO,CAAI;EAC3C;YAEC;CACK,CAAA;CAMZ,IAAM,IAAY,EADhB,EAAO,cAAc,SAAS,EAAO,KAAK,cAAc,SAAS,MACxB,GAAU,GAAO,CAAI;CAGhE,OACE,kBAAC,GAAD;EACM,IAJG,EAAwB,GAAQ,EAAE,OAAO,EAAU,CAItD;EACJ,WAAW;EACX,OAAO;EACP,cAAY;EACZ,qBAAA;YAEC;CACG,CAAA;AAEV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeHubTemplate.js","names":[],"sources":["../../../../../src/components/backoffice/hub/BackofficeHubTemplate.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { GlobalSearchInput } from '@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js';\nimport { SidebarTasksSvg } from '@plumile/ui/icons/SidebarTasksSvg.js';\n\nimport * as styles from './backofficeHubTemplate.css.js';\n\nexport type BackofficeHubTemplateItemKind = 'entity' | 'tool';\n\nexport type BackofficeHubTemplateItem = {\n id: string;\n kind: BackofficeHubTemplateItemKind;\n label: string;\n href: string;\n icon?: ReactNode;\n description?: string | null;\n metaLabel?: string | null;\n};\n\nexport type BackofficeHubTemplateGroup = {\n id: string;\n title: string;\n description?: string | null;\n icon?: ReactNode;\n items: readonly BackofficeHubTemplateItem[];\n};\n\nexport type BackofficeHubTemplateEmptyState = {\n title: string;\n description: string;\n icon?: ReactNode;\n};\n\nexport type BackofficeHubTemplateSearch = {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n};\n\nexport type BackofficeHubTemplateProps = {\n groups: readonly BackofficeHubTemplateGroup[];\n search?: BackofficeHubTemplateSearch;\n emptyState: BackofficeHubTemplateEmptyState;\n};\n\nconst fallbackIcon = (\n <SidebarTasksSvg width={20} height={20} aria-hidden=\"true\" />\n);\n\nexport const BackofficeHubTemplate = ({\n groups,\n search,\n emptyState,\n}: BackofficeHubTemplateProps): JSX.Element => {\n let body: JSX.Element;\n\n if (groups.length === 0) {\n body = (\n <BackofficeEmptyState\n title={emptyState.title}\n description={emptyState.description}\n icon={emptyState.icon ?? fallbackIcon}\n />\n );\n } else {\n body = (\n <div className={styles.groups}>\n {groups.map((group) => {\n return (\n <section key={group.id} className={styles.group}>\n <div className={styles.groupHeader}>\n {group.icon != null && (\n <span className={styles.groupIcon} aria-hidden=\"true\">\n {group.icon}\n </span>\n )}\n <span className={styles.groupHeading}>\n <h2 className={styles.groupTitle}>{group.title}</h2>\n {group.description != null && (\n <span className={styles.groupDescription}>\n {group.description}\n </span>\n )}\n </span>\n </div>\n <div className={styles.grid}>\n {group.items.map((item) => {\n const icon = item.icon ?? fallbackIcon;\n const hasDescription =\n item.description != null && item.description !== '';\n const hasMetaLabel =\n item.metaLabel != null && item.metaLabel !== '';\n\n return (\n <Link\n key={`${item.kind}-${item.id}`}\n to={item.href}\n className={styles.item}\n >\n <span className={styles.itemIcon} aria-hidden=\"true\">\n {icon}\n </span>\n <span className={styles.itemContent}>\n <span className={styles.itemTitle}>{item.label}</span>\n {hasDescription && (\n <span className={styles.itemDescription}>\n {item.description}\n </span>\n )}\n {hasMetaLabel && (\n <span className={styles.itemMeta}>\n {item.metaLabel}\n </span>\n )}\n </span>\n </Link>\n );\n })}\n </div>\n </section>\n );\n })}\n </div>\n );\n }\n\n return (\n <div className={styles.content}>\n {search != null && (\n <div className={styles.search}>\n <GlobalSearchInput\n value={search.value}\n onChange={search.onChange}\n placeholder={search.placeholder}\n />\n </div>\n )}\n {body}\n </div>\n );\n};\n\nexport default BackofficeHubTemplate;\n"],"mappings":";;;;;;;AA8CA,IAAM,IACJ,kBAAC,GAAD;CAAiB,OAAO;CAAI,QAAQ;CAAI,eAAY;AAAQ,CAAA,GAGjD,KAAyB,EACpC,QAAA,GACA,QAAA,GACA,oBAC6C;CAC7C,IAAI;
|
|
1
|
+
{"version":3,"file":"BackofficeHubTemplate.js","names":[],"sources":["../../../../../src/components/backoffice/hub/BackofficeHubTemplate.tsx"],"sourcesContent":["import { type JSX, type ReactNode } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\nimport { BackofficeEmptyState } from '@plumile/ui/backoffice/molecules/backoffice_empty_state/BackofficeEmptyState.js';\nimport { GlobalSearchInput } from '@plumile/ui/backoffice/molecules/global_search_input/GlobalSearchInput.js';\nimport { SidebarTasksSvg } from '@plumile/ui/icons/SidebarTasksSvg.js';\n\nimport * as styles from './backofficeHubTemplate.css.js';\n\nexport type BackofficeHubTemplateItemKind = 'entity' | 'tool';\n\nexport type BackofficeHubTemplateItem = {\n id: string;\n kind: BackofficeHubTemplateItemKind;\n label: string;\n href: string;\n icon?: ReactNode;\n description?: string | null;\n metaLabel?: string | null;\n};\n\nexport type BackofficeHubTemplateGroup = {\n id: string;\n title: string;\n description?: string | null;\n icon?: ReactNode;\n items: readonly BackofficeHubTemplateItem[];\n};\n\nexport type BackofficeHubTemplateEmptyState = {\n title: string;\n description: string;\n icon?: ReactNode;\n};\n\nexport type BackofficeHubTemplateSearch = {\n value: string;\n onChange: (value: string) => void;\n placeholder: string;\n};\n\nexport type BackofficeHubTemplateProps = {\n groups: readonly BackofficeHubTemplateGroup[];\n search?: BackofficeHubTemplateSearch;\n emptyState: BackofficeHubTemplateEmptyState;\n};\n\nconst fallbackIcon = (\n <SidebarTasksSvg width={20} height={20} aria-hidden=\"true\" />\n);\n\nexport const BackofficeHubTemplate = ({\n groups,\n search,\n emptyState,\n}: BackofficeHubTemplateProps): JSX.Element => {\n let body: JSX.Element;\n\n if (groups.length === 0) {\n body = (\n <BackofficeEmptyState\n title={emptyState.title}\n description={emptyState.description}\n icon={emptyState.icon ?? fallbackIcon}\n />\n );\n } else {\n body = (\n <div className={styles.groups}>\n {groups.map((group) => {\n return (\n <section key={group.id} className={styles.group}>\n <div className={styles.groupHeader}>\n {group.icon != null && (\n <span className={styles.groupIcon} aria-hidden=\"true\">\n {group.icon}\n </span>\n )}\n <span className={styles.groupHeading}>\n <h2 className={styles.groupTitle}>{group.title}</h2>\n {group.description != null && (\n <span className={styles.groupDescription}>\n {group.description}\n </span>\n )}\n </span>\n </div>\n <div className={styles.grid}>\n {group.items.map((item) => {\n const icon = item.icon ?? fallbackIcon;\n const hasDescription =\n item.description != null && item.description !== '';\n const hasMetaLabel =\n item.metaLabel != null && item.metaLabel !== '';\n\n return (\n <Link\n key={`${item.kind}-${item.id}`}\n to={item.href}\n className={styles.item}\n preloadOnMouseEnter\n >\n <span className={styles.itemIcon} aria-hidden=\"true\">\n {icon}\n </span>\n <span className={styles.itemContent}>\n <span className={styles.itemTitle}>{item.label}</span>\n {hasDescription && (\n <span className={styles.itemDescription}>\n {item.description}\n </span>\n )}\n {hasMetaLabel && (\n <span className={styles.itemMeta}>\n {item.metaLabel}\n </span>\n )}\n </span>\n </Link>\n );\n })}\n </div>\n </section>\n );\n })}\n </div>\n );\n }\n\n return (\n <div className={styles.content}>\n {search != null && (\n <div className={styles.search}>\n <GlobalSearchInput\n value={search.value}\n onChange={search.onChange}\n placeholder={search.placeholder}\n />\n </div>\n )}\n {body}\n </div>\n );\n};\n\nexport default BackofficeHubTemplate;\n"],"mappings":";;;;;;;AA8CA,IAAM,IACJ,kBAAC,GAAD;CAAiB,OAAO;CAAI,QAAQ;CAAI,eAAY;AAAQ,CAAA,GAGjD,KAAyB,EACpC,QAAA,GACA,QAAA,GACA,oBAC6C;CAC7C,IAAI;CAyEJ,OAvEA,AASE,IATE,EAAO,WAAW,IAElB,kBAAC,GAAD;EACE,OAAO,EAAW;EAClB,aAAa,EAAW;EACxB,MAAM,EAAW,QAAQ;CAC1B,CAAA,IAID,kBAAC,OAAD;EAAK,WAAW;YACb,EAAO,KAAK,MAET,kBAAC,WAAD;GAAwB,WAAW;aAAnC,CACE,kBAAC,OAAD;IAAK,WAAW;cAAhB,CACG,EAAM,QAAQ,QACb,kBAAC,QAAD;KAAM,WAAW;KAAkB,eAAY;eAC5C,EAAM;IACH,CAAA,GAER,kBAAC,QAAD;KAAM,WAAW;eAAjB,CACE,kBAAC,MAAD;MAAI,WAAW;gBAAoB,EAAM;KAAU,CAAA,GAClD,EAAM,eAAe,QACpB,kBAAC,QAAD;MAAM,WAAW;gBACd,EAAM;KACH,CAAA,CAEJ;MACH;OACL,kBAAC,OAAD;IAAK,WAAW;cACb,EAAM,MAAM,KAAK,MAAS;KACzB,IAAM,IAAO,EAAK,QAAQ,GACpB,IACJ,EAAK,eAAe,QAAQ,EAAK,gBAAgB,IAC7C,IACJ,EAAK,aAAa,QAAQ,EAAK,cAAc;KAE/C,OACE,kBAAC,GAAD;MAEE,IAAI,EAAK;MACT,WAAW;MACX,qBAAA;gBAJF,CAME,kBAAC,QAAD;OAAM,WAAW;OAAiB,eAAY;iBAC3C;MACG,CAAA,GACN,kBAAC,QAAD;OAAM,WAAW;iBAAjB;QACE,kBAAC,QAAD;SAAM,WAAW;mBAAmB,EAAK;QAAY,CAAA;QACpD,KACC,kBAAC,QAAD;SAAM,WAAW;mBACd,EAAK;QACF,CAAA;QAEP,KACC,kBAAC,QAAD;SAAM,WAAW;mBACd,EAAK;QACF,CAAA;OAEJ;QACF;QArBC,GAAG,EAAK,KAAK,GAAG,EAAK,IAqBtB;IAEV,CAAC;GACE,CAAA,CACE;KAnDK,EAAM,EAmDX,CAEZ;CACE,CAAA,GAKP,kBAAC,OAAD;EAAK,WAAW;YAAhB,CACG,KAAU,QACT,kBAAC,OAAD;GAAK,WAAW;aACd,kBAAC,GAAD;IACE,OAAO,EAAO;IACd,UAAU,EAAO;IACjB,aAAa,EAAO;GACrB,CAAA;EACE,CAAA,GAEN,CACE;;AAET"}
|
|
@@ -40,6 +40,7 @@ var g = (e) => {
|
|
|
40
40
|
className: "_80s44h0 qbwcuej qbwcueh txvbqbfqq txvbqbey txvbqbls4 txvbqb1tv txvbqb2rt txvbqb2tz txvbqb1b4r txvbqb1bg3 txvbqbv txvbqbwvi txvbqb7h txvbqb76 txvbqb7t qbwcuei txvbqb1cta txvbqb1eom qbwcue4 txvbqb1f7o txvbqb1fe4 qbwcue0 txvbqb1ffs txvbqb1ga0 qbwcuex qbwcuer txvbqbh6d txvbqbo4m qbwcue11 qbwcuev txvbqb19h2 txvbqbjmh txvbqbvat txvbqbub2 txvbqb3f",
|
|
41
41
|
"aria-label": b,
|
|
42
42
|
title: b,
|
|
43
|
+
preloadOnMouseEnter: !0,
|
|
43
44
|
children: w
|
|
44
45
|
})]
|
|
45
46
|
}), C.map((e, t) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeTopbarBreadcrumb.js","names":[],"sources":["../../../../../../src/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\nimport { SidebarHomeSvg } from '@plumile/ui/icons/SidebarHomeSvg.js';\n\nimport { BackofficeLink } from '../../links/BackofficeLink.js';\nimport { BackofficeLinkLabel } from '../../links/BackofficeLinkLabel.js';\nimport { useBackofficeReactTranslation } from '../../../../i18n/useBackofficeReactTranslation.js';\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\nimport { useBackofficeTopbarPortalContext } from './BackofficeTopbarPortalContext.js';\nimport * as styles from './backofficeTopbarBreadcrumb.css.js';\n\nexport type BackofficeTopbarBreadcrumbProps = {\n items: readonly BackofficeTopbarBreadcrumbItem[];\n};\n\nconst getBreadcrumbItemKey = (item: BackofficeTopbarBreadcrumbItem): string => {\n const { target } = item;\n if (target.kind === 'dashboard') {\n return `${item.kind}-dashboard`;\n }\n if (target.kind === 'entity-list') {\n return `${item.kind}-entity-list-${target.entityId}`;\n }\n if (target.kind === 'entity-detail') {\n return `${item.kind}-entity-detail-${target.entityId}-${target.id}`;\n }\n if (target.kind === 'entity-detail-page') {\n return `${item.kind}-entity-detail-page-${target.entityId}-${target.id}-${target.pageId}`;\n }\n if (target.kind === 'tool') {\n return `${item.kind}-tool-${target.toolId}`;\n }\n if (target.kind === 'hub') {\n return `${item.kind}-hub-${target.hubId}`;\n }\n return `${item.kind}-href-${target.href}`;\n};\n\nexport const BackofficeTopbarBreadcrumb = ({\n items,\n}: BackofficeTopbarBreadcrumbProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const { dashboardHref, dashboardLabel } = useBackofficeTopbarPortalContext();\n let isDashboardCurrent = false;\n const [firstItem] = items;\n if (items.length === 1 && firstItem != null) {\n isDashboardCurrent =\n firstItem.target.kind === 'dashboard' && firstItem.kind === 'current';\n }\n let visibleItems: readonly BackofficeTopbarBreadcrumbItem[] = items;\n if (isDashboardCurrent) {\n visibleItems = [];\n }\n\n const homeContent = (\n <>\n <SidebarHomeSvg width={16} height={16} aria-hidden=\"true\" />\n <span className={styles.homeLabel}>{dashboardLabel}</span>\n </>\n );\n\n return (\n <nav className={styles.nav} aria-label={t('common.breadcrumb')}>\n <ol className={styles.list}>\n <li className={styles.item}>\n {isDashboardCurrent && (\n <span\n className={styles.homeCurrent}\n aria-current=\"page\"\n title={dashboardLabel}\n >\n {homeContent}\n </span>\n )}\n {!isDashboardCurrent && (\n <Link\n to={dashboardHref}\n className={styles.homeLink}\n aria-label={dashboardLabel}\n title={dashboardLabel}\n >\n {homeContent}\n </Link>\n )}\n </li>\n {visibleItems.map((item, index) => {\n const isCurrent = item.kind === 'current';\n const key = getBreadcrumbItemKey(item);\n let icon: 'auto' | 'none' = 'none';\n if (index === 0) {\n icon = 'auto';\n }\n let content: JSX.Element;\n\n if (!isCurrent) {\n content = (\n <BackofficeLink\n target={item.target}\n label={item.label}\n className={styles.link}\n icon={icon}\n />\n );\n } else {\n content = (\n <BackofficeLinkLabel\n target={item.target}\n label={item.label}\n className={styles.current}\n icon={icon}\n />\n );\n }\n\n return (\n <li key={key} className={styles.item}>\n <span className={styles.separator} aria-hidden=\"true\">\n /\n </span>\n {content}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n};\n\nexport default BackofficeTopbarBreadcrumb;\n"],"mappings":";;;;;;;;;AAeA,IAAM,KAAwB,MAAiD;CAC7E,IAAM,EAAE,cAAW;CAmBnB,OAlBI,EAAO,SAAS,cACX,GAAG,EAAK,KAAK,cAElB,EAAO,SAAS,gBACX,GAAG,EAAK,KAAK,eAAe,EAAO,aAExC,EAAO,SAAS,kBACX,GAAG,EAAK,KAAK,iBAAiB,EAAO,SAAS,GAAG,EAAO,OAE7D,EAAO,SAAS,uBACX,GAAG,EAAK,KAAK,sBAAsB,EAAO,SAAS,GAAG,EAAO,GAAG,GAAG,EAAO,WAE/E,EAAO,SAAS,SACX,GAAG,EAAK,KAAK,QAAQ,EAAO,WAEjC,EAAO,SAAS,QACX,GAAG,EAAK,KAAK,OAAO,EAAO,UAE7B,GAAG,EAAK,KAAK,QAAQ,EAAO;AACrC,GAEa,KAA8B,EACzC,eACkD;CAClD,IAAM,EAAE,SAAM,EAA8B,GACtC,EAAE,kBAAe,sBAAmB,EAAiC,GACvE,IAAqB,IACnB,CAAC,KAAa;CACpB,AAAI,EAAM,WAAW,KAAK,KAAa,SACrC,IACE,EAAU,OAAO,SAAS,eAAe,EAAU,SAAS;CAEhE,IAAI,IAA0D;CAC9D,AAAI,MACF,IAAe,CAAC;CAGlB,IAAM,IACJ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EAAgB,OAAO;EAAI,QAAQ;EAAI,eAAY;CAAQ,CAAA,GAC3D,kBAAC,QAAD;EAAM,WAAW;YAAmB;CAAqB,CAAA,CACzD,EAAA,CAAA;CAGJ,OACE,kBAAC,OAAD;EAAK,WAAW;EAAY,cAAY,EAAE,mBAAmB;YAC3D,kBAAC,MAAD;GAAI,WAAW;aAAf,CACE,kBAAC,MAAD;IAAI,WAAW;cAAf,CACG,KACC,kBAAC,QAAD;KACE,WAAW;KACX,gBAAa;KACb,OAAO;eAEN;IACG,CAAA,GAEP,CAAC,KACA,kBAAC,GAAD;KACE,IAAI;KACJ,WAAW;KACX,cAAY;KACZ,OAAO;
|
|
1
|
+
{"version":3,"file":"BackofficeTopbarBreadcrumb.js","names":[],"sources":["../../../../../../src/components/backoffice/layout/breadcrumb/BackofficeTopbarBreadcrumb.tsx"],"sourcesContent":["import { type JSX } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\nimport { SidebarHomeSvg } from '@plumile/ui/icons/SidebarHomeSvg.js';\n\nimport { BackofficeLink } from '../../links/BackofficeLink.js';\nimport { BackofficeLinkLabel } from '../../links/BackofficeLinkLabel.js';\nimport { useBackofficeReactTranslation } from '../../../../i18n/useBackofficeReactTranslation.js';\nimport type { BackofficeTopbarBreadcrumbItem } from './types.js';\nimport { useBackofficeTopbarPortalContext } from './BackofficeTopbarPortalContext.js';\nimport * as styles from './backofficeTopbarBreadcrumb.css.js';\n\nexport type BackofficeTopbarBreadcrumbProps = {\n items: readonly BackofficeTopbarBreadcrumbItem[];\n};\n\nconst getBreadcrumbItemKey = (item: BackofficeTopbarBreadcrumbItem): string => {\n const { target } = item;\n if (target.kind === 'dashboard') {\n return `${item.kind}-dashboard`;\n }\n if (target.kind === 'entity-list') {\n return `${item.kind}-entity-list-${target.entityId}`;\n }\n if (target.kind === 'entity-detail') {\n return `${item.kind}-entity-detail-${target.entityId}-${target.id}`;\n }\n if (target.kind === 'entity-detail-page') {\n return `${item.kind}-entity-detail-page-${target.entityId}-${target.id}-${target.pageId}`;\n }\n if (target.kind === 'tool') {\n return `${item.kind}-tool-${target.toolId}`;\n }\n if (target.kind === 'hub') {\n return `${item.kind}-hub-${target.hubId}`;\n }\n return `${item.kind}-href-${target.href}`;\n};\n\nexport const BackofficeTopbarBreadcrumb = ({\n items,\n}: BackofficeTopbarBreadcrumbProps): JSX.Element => {\n const { t } = useBackofficeReactTranslation();\n const { dashboardHref, dashboardLabel } = useBackofficeTopbarPortalContext();\n let isDashboardCurrent = false;\n const [firstItem] = items;\n if (items.length === 1 && firstItem != null) {\n isDashboardCurrent =\n firstItem.target.kind === 'dashboard' && firstItem.kind === 'current';\n }\n let visibleItems: readonly BackofficeTopbarBreadcrumbItem[] = items;\n if (isDashboardCurrent) {\n visibleItems = [];\n }\n\n const homeContent = (\n <>\n <SidebarHomeSvg width={16} height={16} aria-hidden=\"true\" />\n <span className={styles.homeLabel}>{dashboardLabel}</span>\n </>\n );\n\n return (\n <nav className={styles.nav} aria-label={t('common.breadcrumb')}>\n <ol className={styles.list}>\n <li className={styles.item}>\n {isDashboardCurrent && (\n <span\n className={styles.homeCurrent}\n aria-current=\"page\"\n title={dashboardLabel}\n >\n {homeContent}\n </span>\n )}\n {!isDashboardCurrent && (\n <Link\n to={dashboardHref}\n className={styles.homeLink}\n aria-label={dashboardLabel}\n title={dashboardLabel}\n preloadOnMouseEnter\n >\n {homeContent}\n </Link>\n )}\n </li>\n {visibleItems.map((item, index) => {\n const isCurrent = item.kind === 'current';\n const key = getBreadcrumbItemKey(item);\n let icon: 'auto' | 'none' = 'none';\n if (index === 0) {\n icon = 'auto';\n }\n let content: JSX.Element;\n\n if (!isCurrent) {\n content = (\n <BackofficeLink\n target={item.target}\n label={item.label}\n className={styles.link}\n icon={icon}\n />\n );\n } else {\n content = (\n <BackofficeLinkLabel\n target={item.target}\n label={item.label}\n className={styles.current}\n icon={icon}\n />\n );\n }\n\n return (\n <li key={key} className={styles.item}>\n <span className={styles.separator} aria-hidden=\"true\">\n /\n </span>\n {content}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n};\n\nexport default BackofficeTopbarBreadcrumb;\n"],"mappings":";;;;;;;;;AAeA,IAAM,KAAwB,MAAiD;CAC7E,IAAM,EAAE,cAAW;CAmBnB,OAlBI,EAAO,SAAS,cACX,GAAG,EAAK,KAAK,cAElB,EAAO,SAAS,gBACX,GAAG,EAAK,KAAK,eAAe,EAAO,aAExC,EAAO,SAAS,kBACX,GAAG,EAAK,KAAK,iBAAiB,EAAO,SAAS,GAAG,EAAO,OAE7D,EAAO,SAAS,uBACX,GAAG,EAAK,KAAK,sBAAsB,EAAO,SAAS,GAAG,EAAO,GAAG,GAAG,EAAO,WAE/E,EAAO,SAAS,SACX,GAAG,EAAK,KAAK,QAAQ,EAAO,WAEjC,EAAO,SAAS,QACX,GAAG,EAAK,KAAK,OAAO,EAAO,UAE7B,GAAG,EAAK,KAAK,QAAQ,EAAO;AACrC,GAEa,KAA8B,EACzC,eACkD;CAClD,IAAM,EAAE,SAAM,EAA8B,GACtC,EAAE,kBAAe,sBAAmB,EAAiC,GACvE,IAAqB,IACnB,CAAC,KAAa;CACpB,AAAI,EAAM,WAAW,KAAK,KAAa,SACrC,IACE,EAAU,OAAO,SAAS,eAAe,EAAU,SAAS;CAEhE,IAAI,IAA0D;CAC9D,AAAI,MACF,IAAe,CAAC;CAGlB,IAAM,IACJ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EAAgB,OAAO;EAAI,QAAQ;EAAI,eAAY;CAAQ,CAAA,GAC3D,kBAAC,QAAD;EAAM,WAAW;YAAmB;CAAqB,CAAA,CACzD,EAAA,CAAA;CAGJ,OACE,kBAAC,OAAD;EAAK,WAAW;EAAY,cAAY,EAAE,mBAAmB;YAC3D,kBAAC,MAAD;GAAI,WAAW;aAAf,CACE,kBAAC,MAAD;IAAI,WAAW;cAAf,CACG,KACC,kBAAC,QAAD;KACE,WAAW;KACX,gBAAa;KACb,OAAO;eAEN;IACG,CAAA,GAEP,CAAC,KACA,kBAAC,GAAD;KACE,IAAI;KACJ,WAAW;KACX,cAAY;KACZ,OAAO;KACP,qBAAA;eAEC;IACG,CAAA,CAEN;OACH,EAAa,KAAK,GAAM,MAAU;IACjC,IAAM,IAAY,EAAK,SAAS,WAC1B,IAAM,EAAqB,CAAI,GACjC,IAAwB;IAC5B,AAAI,MAAU,MACZ,IAAO;IAET,IAAI;IAsBJ,OApBA,AACE,IADG,IAWD,kBAAC,GAAD;KACE,QAAQ,EAAK;KACb,OAAO,EAAK;KACZ,WAAW;KACL;IACP,CAAA,IAdD,kBAAC,GAAD;KACE,QAAQ,EAAK;KACb,OAAO,EAAK;KACZ,WAAW;KACL;IACP,CAAA,GAcH,kBAAC,MAAD;KAAc,WAAW;eAAzB,CACE,kBAAC,QAAD;MAAM,WAAW;MAAkB,eAAY;gBAAO;KAEhD,CAAA,GACL,CACC;OALK,CAKL;GAER,CAAC,CACC;;CACD,CAAA;AAET"}
|
|
@@ -3,27 +3,28 @@ import { useBackofficeLink as t } from "./useBackofficeLink.js";
|
|
|
3
3
|
import { jsx as n } from "react/jsx-runtime";
|
|
4
4
|
import r from "@plumile/router/routing/Link.js";
|
|
5
5
|
//#region src/components/backoffice/links/BackofficeInlineLink.tsx
|
|
6
|
-
var i = ({ target:
|
|
7
|
-
let
|
|
8
|
-
return
|
|
6
|
+
var i = (e, t, n) => t ?? (n ? !1 : e.kind !== "href"), a = ({ target: a, label: o, className: s, title: c, ariaLabel: l, icon: u = "auto", openInNewTab: d = !1, preloadOnMouseEnter: f, endAdornment: p, onClick: m, children: h }) => {
|
|
7
|
+
let g = t(a, { label: h ?? o }), _ = {};
|
|
8
|
+
return d && (_ = {
|
|
9
9
|
target: "_blank",
|
|
10
10
|
rel: "noreferrer"
|
|
11
11
|
}), /* @__PURE__ */ n(r, {
|
|
12
|
-
to:
|
|
13
|
-
className:
|
|
14
|
-
title:
|
|
15
|
-
"aria-label":
|
|
16
|
-
onClick:
|
|
17
|
-
|
|
12
|
+
to: g.href,
|
|
13
|
+
className: s,
|
|
14
|
+
title: c,
|
|
15
|
+
"aria-label": l,
|
|
16
|
+
onClick: m,
|
|
17
|
+
preloadOnMouseEnter: i(a, f, d),
|
|
18
|
+
..._,
|
|
18
19
|
children: /* @__PURE__ */ n(e, {
|
|
19
|
-
icon:
|
|
20
|
-
label:
|
|
21
|
-
showIcon:
|
|
22
|
-
endAdornment:
|
|
20
|
+
icon: g.icon,
|
|
21
|
+
label: g.label,
|
|
22
|
+
showIcon: u === "auto",
|
|
23
|
+
endAdornment: p
|
|
23
24
|
})
|
|
24
25
|
});
|
|
25
26
|
};
|
|
26
27
|
//#endregion
|
|
27
|
-
export {
|
|
28
|
+
export { a as BackofficeInlineLink, a as default };
|
|
28
29
|
|
|
29
30
|
//# sourceMappingURL=BackofficeInlineLink.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackofficeInlineLink.js","names":[],"sources":["../../../../../src/components/backoffice/links/BackofficeInlineLink.tsx"],"sourcesContent":["import { type JSX, type MouseEventHandler, type ReactNode } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\n\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeLinkContent } from './BackofficeLinkContent.js';\nimport type { BackofficeLinkTarget } from './types.js';\nimport { useBackofficeLink } from './useBackofficeLink.js';\n\nexport type BackofficeInlineLinkProps<\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n> = {\n target: BackofficeLinkTarget<TManifest>;\n label?: ReactNode;\n className?: string;\n title?: string;\n ariaLabel?: string;\n icon?: 'auto' | 'none';\n openInNewTab?: boolean;\n endAdornment?: ReactNode;\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children?: ReactNode;\n};\n\nexport const BackofficeInlineLink = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>({\n target,\n label,\n className,\n title,\n ariaLabel,\n icon = 'auto',\n openInNewTab = false,\n endAdornment,\n onClick,\n children,\n}: BackofficeInlineLinkProps<TManifest>): JSX.Element => {\n const link = useBackofficeLink(target, {\n label: children ?? label,\n });\n\n let linkProps: { target?: '_blank'; rel?: 'noreferrer' } = {};\n if (openInNewTab) {\n linkProps = { target: '_blank', rel: 'noreferrer' };\n }\n\n return (\n <Link\n to={link.href}\n className={className}\n title={title}\n aria-label={ariaLabel}\n onClick={onClick}\n {...linkProps}\n >\n <BackofficeLinkContent\n icon={link.icon}\n label={link.label}\n showIcon={icon === 'auto'}\n endAdornment={endAdornment}\n />\n </Link>\n );\n};\n\nexport default BackofficeInlineLink;\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"BackofficeInlineLink.js","names":[],"sources":["../../../../../src/components/backoffice/links/BackofficeInlineLink.tsx"],"sourcesContent":["import { type JSX, type MouseEventHandler, type ReactNode } from 'react';\nimport Link from '@plumile/router/routing/Link.js';\n\nimport type { BackofficeEntityManifestMap } from '@plumile/backoffice-core/types.js';\n\nimport { BackofficeLinkContent } from './BackofficeLinkContent.js';\nimport type { BackofficeLinkTarget } from './types.js';\nimport { useBackofficeLink } from './useBackofficeLink.js';\n\nexport type BackofficeInlineLinkProps<\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n> = {\n target: BackofficeLinkTarget<TManifest>;\n label?: ReactNode;\n className?: string;\n title?: string;\n ariaLabel?: string;\n icon?: 'auto' | 'none';\n openInNewTab?: boolean;\n preloadOnMouseEnter?: boolean;\n endAdornment?: ReactNode;\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n children?: ReactNode;\n};\n\nconst shouldPreloadBackofficeTarget = (\n target: BackofficeLinkTarget,\n preloadOnMouseEnter: boolean | undefined,\n openInNewTab: boolean,\n): boolean => {\n if (preloadOnMouseEnter != null) {\n return preloadOnMouseEnter;\n }\n if (openInNewTab) {\n return false;\n }\n return target.kind !== 'href';\n};\n\nexport const BackofficeInlineLink = <\n TManifest extends BackofficeEntityManifestMap = BackofficeEntityManifestMap,\n>({\n target,\n label,\n className,\n title,\n ariaLabel,\n icon = 'auto',\n openInNewTab = false,\n preloadOnMouseEnter,\n endAdornment,\n onClick,\n children,\n}: BackofficeInlineLinkProps<TManifest>): JSX.Element => {\n const link = useBackofficeLink(target, {\n label: children ?? label,\n });\n\n let linkProps: { target?: '_blank'; rel?: 'noreferrer' } = {};\n if (openInNewTab) {\n linkProps = { target: '_blank', rel: 'noreferrer' };\n }\n\n return (\n <Link\n to={link.href}\n className={className}\n title={title}\n aria-label={ariaLabel}\n onClick={onClick}\n preloadOnMouseEnter={shouldPreloadBackofficeTarget(\n target,\n preloadOnMouseEnter,\n openInNewTab,\n )}\n {...linkProps}\n >\n <BackofficeLinkContent\n icon={link.icon}\n label={link.label}\n showIcon={icon === 'auto'}\n endAdornment={endAdornment}\n />\n </Link>\n );\n};\n\nexport default BackofficeInlineLink;\n"],"mappings":";;;;;AAyBA,IAAM,KACJ,GACA,GACA,MAEI,MAGA,IACK,KAEF,EAAO,SAAS,SAGZ,KAEX,EACA,WACA,UACA,cACA,UACA,cACA,UAAO,QACP,kBAAe,IACf,wBACA,iBACA,YACA,kBACuD;CACvD,IAAM,IAAO,EAAkB,GAAQ,EACrC,OAAO,KAAY,EACrB,CAAC,GAEG,IAAuD,CAAC;CAK5D,OAJI,MACF,IAAY;EAAE,QAAQ;EAAU,KAAK;CAAa,IAIlD,kBAAC,GAAD;EACE,IAAI,EAAK;EACE;EACJ;EACP,cAAY;EACH;EACT,qBAAqB,EACnB,GACA,GACA,CACF;EACA,GAAI;YAEJ,kBAAC,GAAD;GACE,MAAM,EAAK;GACX,OAAO,EAAK;GACZ,UAAU,MAAS;GACL;EACf,CAAA;CACG,CAAA;AAEV"}
|