From e1150cab63d8056b6f07d165956d9a9486c6861f Mon Sep 17 00:00:00 2001 From: estifanos Date: Tue, 8 Sep 2026 06:45:34 +0000 Subject: [PATCH] feat: add NATIONALITY and NATION field types with dedicated country-picker logic and storage conversion --- .../components/FieldEditorDrawer.tsx | 33 ++++++++++- apps/backoffice/src/app/i18n/locales/am.ts | 2 + apps/backoffice/src/app/i18n/locales/en.ts | 2 + .../components/ConfigDrivenSection.tsx | 58 +++++++++++++++++-- .../pages/LicenseApplicationPage.tsx | 28 ++++++--- .../lib/features/licensing/licensing.types.ts | 6 +- libs/ui/src/lib/input/CountrySelect.tsx | 12 ++++ 7 files changed, 126 insertions(+), 15 deletions(-) diff --git a/apps/backoffice/src/app/features/certificate-requirements/components/FieldEditorDrawer.tsx b/apps/backoffice/src/app/features/certificate-requirements/components/FieldEditorDrawer.tsx index 370ba0572..bab67f514 100644 --- a/apps/backoffice/src/app/features/certificate-requirements/components/FieldEditorDrawer.tsx +++ b/apps/backoffice/src/app/features/certificate-requirements/components/FieldEditorDrawer.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { Button, Checkbox, @@ -20,6 +20,18 @@ import type { ConditionTarget } from '../config/schema-paths'; const KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_]*$/; +/** + * Field types the builder offers on top of whatever the server palette lists. + * Both render the shared country picker in the portal — the full nationality + * list ("Ethiopian") and the full country list ("Ethiopia") — so neither takes + * options, a range or a max length. Merged in rather than assumed present so a + * palette that predates them still offers them. + */ +const EXTRA_FIELD_TYPES: FormSchemaPalette['fieldTypes'] = [ + { type: 'NATIONALITY', supportsOptions: false, supportsRange: false, supportsMaxLength: false }, + { type: 'NATION', supportsOptions: false, supportsRange: false, supportsMaxLength: false }, +]; + function emptyField(): FormFieldConfig { return { key: '', label: { en: '', am: '' }, type: 'TEXT' }; } @@ -52,7 +64,15 @@ export function FieldEditorDrawer({ } }, [opened, field]); - const typeInfo = palette?.fieldTypes.find((f) => f.type === draft.type); + const fieldTypes = useMemo(() => { + const fromPalette = palette?.fieldTypes ?? []; + return [ + ...fromPalette, + ...EXTRA_FIELD_TYPES.filter((extra) => !fromPalette.some((f) => f.type === extra.type)), + ]; + }, [palette]); + + const typeInfo = fieldTypes.find((f) => f.type === draft.type); const isNew = !field; function save() { @@ -128,7 +148,14 @@ export function FieldEditorDrawer({