feat: add document requirements and form schema management for license types

- Implement DocumentRequirementsTab for managing document upload requirements.
- Create FieldEditorDrawer and SectionEditorDrawer for editing fields and sections in the form schema.
- Develop FormSchemaTab to handle sections and fields for a license type's form schema.
- Introduce CertificateRequirementsPage to serve as the main interface for configuring license type requirements.
- Add hooks for requirement actions to streamline mutation handling and notifications.
- Implement condition handling for fields and sections to manage visibility based on user input.
- Create schema-paths configuration to facilitate condition target collection.
This commit is contained in:
Nati
2026-08-20 13:37:26 +00:00
parent 2ec857f0f0
commit 357dc3e4d5
15 changed files with 1845 additions and 0 deletions

View File

@@ -33,6 +33,7 @@ export const am: Translations = {
allApplications: "ሁሉም ማመልከቻዎች",
licenceRegister: "የፈቃድ መዝገብ",
certificateDesigner: "የምስክር ወረቀት ንድፍ",
certificateRequirements: "የምስክር ወረቀት መስፈርቶች",
byType: "በዓይነት",
typeFreightForwarder: "የጭነት አስተላላፊ",
typeShippingAgent: "የመርከብ ወኪል",
@@ -1171,6 +1172,124 @@ export const am: Translations = {
noPublishPermission: "ንድፎችን ማተም አይችሉም",
},
certReq: {
title: "የምስክር ወረቀት መስፈርቶች",
subtitle:
"ለፈቃድ ዓይነት አመልካቾች መሙላት ያለባቸውን የቅጽ መስኮች እና የሰነድ ሰቀላዎች ያዋቅሩ፣ መስፈርቱ መቼ ተግባራዊ እንደሚሆንም ጨምሮ።",
licenseType: "የፈቃድ ዓይነት",
selectLicenseType: "የፈቃድ ዓይነት ይምረጡ",
loading: "የፈቃድ ዓይነቶችን በመጫን ላይ…",
loadFailed: "የፈቃድ ዓይነቶችን መጫን አልተቻለም",
tabSchema: "የቅጽ ቅንብር",
tabDocuments: "የሰነድ መስፈርቶች",
cancel: "ይቅር",
delete: "ሰርዝ",
saveChanges: "ለውጦችን አስቀምጥ",
actionFailed: "ተግባሩ አልተሳካም",
condition: {
title: "የሚታይበት ሁኔታ",
badge: "ሁኔታዊ",
enable: "ሁኔታ ሲሟላ ብቻ ተግባራዊ ይሁን",
field: "የመስክ መንገድ",
fieldHelp: "ወደ ቅጹ የነጥብ መንገድ፣ ለምሳሌ sectionKey.fieldKey",
operator: "አመልካች",
value: "ዋጋ",
values: "ከእነዚህ አንዱ",
removeValue: "ለማስወገድ ይጫኑ",
isSet: "ተሞልቷል",
isNotSet: "አልተሞላም",
unknownField: "ይህ መንገድ በአሁኑ ቅንብር ውስጥ ያለ መስክ አይደለም — ቢሆንም እንደተጻፈው ይቀመጣል።",
},
schema: {
subtitle:
"አመልካቹ ለዚህ የፈቃድ ዓይነት የሚያየው ክፍሎች እና መስኮች። አንድ ቡድን የሚጋሩ ክፍሎች በአንድ የዊዛርድ ደረጃ ላይ አብረው ይታያሉ።",
checkErrors: "ስህተቶችን ፈትሽ",
noIssues: "ምንም ችግር አልተገኘም",
issuesFound: "ችግሮች ተገኝተዋል",
save: "ቅንብር አስቀምጥ",
saved: "የቅጽ ቅንብር ተቀምጧል",
empty: "እስካሁን ክፍል የለም",
emptyBody: "ለዚህ የፈቃድ ዓይነት ቅጽ ለመገንባት ክፍል ይጨምሩ።",
},
section: {
add: "ክፍል ጨምር",
edit: "ክፍል አርትዕ",
delete: "ክፍል ሰርዝ",
deleteConfirm: '"{{name}}"ን እና ሁሉንም መስኮቹን ከዚህ ቅንብር ማስወገድ ይፈልጋሉ?',
key: "የክፍል ቁልፍ",
keyHelp: "ፊደላት፣ ቁጥሮች እና underscore ብቻ",
keyLocked: "ከተፈጠረ በኋላ ቁልፍ መቀየር አይቻልም",
keyInvalid: "ቁልፍ በፊደል መጀመር እና ፊደላት፣ ቁጥሮች፣ underscore ብቻ መያዝ አለበት",
title: "ርዕስ",
description: "መግለጫ",
group: "የዊዛርድ ደረጃ ቡድን",
groupHelp: "አንድ ቡድን የሚጋሩ ክፍሎች በአንድ ደረጃ ላይ አብረው ይታያሉ",
groupBadge: "ቡድን",
groupOrder: "የቡድን ቅደም ተከተል",
sortOrder: "የቅደም ተከተል ቁጥር",
},
field: {
add: "መስክ ጨምር",
edit: "መስክ አርትዕ",
delete: "መስክ ሰርዝ",
deleteConfirm: '"{{name}}"ን ከዚህ ክፍል ማስወገድ ይፈልጋሉ?',
key: "የመስክ ቁልፍ",
keyHelp: "ፊደላት፣ ቁጥሮች እና underscore ብቻ — የቅጽ መረጃ ቁልፍ ይሆናል",
keyLocked: "ከተፈጠረ በኋላ ቁልፍ መቀየር አይቻልም",
keyInvalid: "ቁልፍ በፊደል መጀመር እና ፊደላት፣ ቁጥሮች፣ underscore ብቻ መያዝ አለበት",
label: "መለያ",
type: "የመስክ ዓይነት",
required: "የግድ ያስፈልጋል",
placeholder: "ምሳሌ ጽሑፍ",
helpText: "የእገዛ ጽሑፍ",
min: "ዝቅተኛ",
max: "ከፍተኛ",
maxLength: "ከፍተኛ ርዝመት",
options: "አማራጮች",
addOption: "አማራጭ ጨምር",
optionValue: "ዋጋ",
optionLabel: "መለያ",
},
doc: {
subtitle: "አመልካቹ ለዚህ የፈቃድ ዓይነት መስቀል ያለበት፣ በአዲስ ማመልከቻ እና በዕድሳት የተከፈለ።",
add: "የሰነድ መስፈርት ጨምር",
edit: "የሰነድ መስፈርት አርትዕ",
delete: "የሰነድ መስፈርት ሰርዝ",
deleteWarning: "በዚህ ቦታ ላይ የሚተማመኑ አመልካቾች ከዚህ በኋላ አያዩትም። ይህ መመለስ አይቻልም።",
deleteConfirm: '"{{name}}"ን ማስወገድ ይፈልጋሉ?',
created: "የሰነድ መስፈርት ተጨምሯል",
updated: "የሰነድ መስፈርት ተዘምኗል",
deleted: "የሰነድ መስፈርት ተወግዷል",
loading: "የሰነድ መስፈርቶችን በመጫን ላይ…",
loadFailed: "የሰነድ መስፈርቶችን መጫን አልተቻለም",
empty: "ምንም የሰነድ መስፈርት አልተዋቀረም",
emptyBody: "አመልካቹ ለዚህ የፈቃድ ዓይነት መስቀል ያለባቸውን ሰነዶች ይጨምሩ።",
emptyKind: "ለዚህ የማመልከቻ ዓይነት እስካሁን የሰነድ መስፈርት የለም።",
key: "ቁልፍ",
keyHelp: "ይህን የሰነድ ቦታ የሚለይ ቋሚ መጠሪያ",
keyLocked: "ከተፈጠረ በኋላ ቁልፍ መቀየር አይቻልም",
keyRequired: "ቁልፍ ያስፈልጋል",
name: "ስም",
description: "መግለጫ",
applicationKind: "የማመልከቻ ዓይነት",
kindNew: "አዲስ ማመልከቻ",
kindRenewal: "ዕድሳት",
kindLocked: "ከተፈጠረ በኋላ የማመልከቻ ዓይነት መቀየር አይቻልም",
mode: "ዘዴ",
modeAlways: "ሁልጊዜ ያስፈልጋል",
modeConditional: "ሁኔታ ሲሟላ ያስፈልጋል",
modeOptional: "አማራጭ ስቀላ",
conditionRequired: "ሁኔታዊ መስፈርት ሁኔታ ያስፈልገዋል",
allowedTypes: "የተፈቀዱ የፋይል ዓይነቶች",
maxSize: "ከፍተኛ የፋይል መጠን (MB)",
requiresValidity: "የቀን ገደብ ያስፈልጋል",
allowMultiple: "ብዙ ስቀላዎችን ፍቀድ",
multiple: "ብዙ",
sortOrder: "የቅደም ተከተል ቁጥር",
when: "መቼ",
},
},
seafarerRegistry: {
title: "የመርከበኞች መዝገብ",
profileCount_one: "{{count}} መገለጫ",

View File

@@ -32,6 +32,7 @@ export const en = {
allApplications: 'All Applications',
licenceRegister: 'Licence Register',
certificateDesigner: 'Certificate Designer',
certificateRequirements: 'Certificate Requirements',
byType: 'By Type',
typeFreightForwarder: 'Freight Forwarder',
typeShippingAgent: 'Shipping Agent',
@@ -1173,6 +1174,124 @@ export const en = {
noPublishPermission: 'You cannot publish designs',
},
certReq: {
title: 'Certificate requirements',
subtitle:
'Configure the form fields and document uploads applicants must complete for a licence type, including conditions on when a requirement applies.',
licenseType: 'Licence type',
selectLicenseType: 'Select a licence type',
loading: 'Loading licence types…',
loadFailed: 'Could not load licence types',
tabSchema: 'Form schema',
tabDocuments: 'Document requirements',
cancel: 'Cancel',
delete: 'Delete',
saveChanges: 'Save changes',
actionFailed: 'Action failed',
condition: {
title: 'Visibility condition',
badge: 'conditional',
enable: 'Only apply when a condition holds',
field: 'Field path',
fieldHelp: 'Dot path into the form, e.g. sectionKey.fieldKey',
operator: 'Operator',
value: 'Value',
values: 'Any of',
removeValue: 'Click to remove',
isSet: 'is set',
isNotSet: 'is not set',
unknownField: 'This path is not a field in the current schema yet — it will still be saved as typed.',
},
schema: {
subtitle:
'Sections and fields the applicant sees for this licence type. Sections sharing a group render together on one wizard step.',
checkErrors: 'Check for errors',
noIssues: 'No issues found',
issuesFound: 'Issues found',
save: 'Save schema',
saved: 'Form schema saved',
empty: 'No sections yet',
emptyBody: "Add a section to start building this licence type's form.",
},
section: {
add: 'Add section',
edit: 'Edit section',
delete: 'Delete section',
deleteConfirm: 'Remove "{{name}}" and all of its fields from this schema?',
key: 'Section key',
keyHelp: 'Letters, numbers and underscores only',
keyLocked: 'Key cannot change once created',
keyInvalid: 'Key must start with a letter and contain only letters, numbers, underscores',
title: 'Title',
description: 'Description',
group: 'Wizard step group',
groupHelp: 'Sections sharing the same group render together on one step',
groupBadge: 'group',
groupOrder: 'Group order',
sortOrder: 'Sort order',
},
field: {
add: 'Add field',
edit: 'Edit field',
delete: 'Delete field',
deleteConfirm: 'Remove "{{name}}" from this section?',
key: 'Field key',
keyHelp: 'Letters, numbers and underscores only — becomes the form data key',
keyLocked: 'Key cannot change once created',
keyInvalid: 'Key must start with a letter and contain only letters, numbers, underscores',
label: 'Label',
type: 'Field type',
required: 'Required',
placeholder: 'Placeholder',
helpText: 'Help text',
min: 'Minimum',
max: 'Maximum',
maxLength: 'Max length',
options: 'Options',
addOption: 'Add option',
optionValue: 'Value',
optionLabel: 'Label',
},
doc: {
subtitle: 'What an applicant must upload for this licence type, split by new application and renewal.',
add: 'Add document requirement',
edit: 'Edit document requirement',
delete: 'Delete document requirement',
deleteWarning: 'Applicants already relying on this slot will no longer see it. This cannot be undone.',
deleteConfirm: 'Remove "{{name}}"?',
created: 'Document requirement added',
updated: 'Document requirement updated',
deleted: 'Document requirement removed',
loading: 'Loading document requirements…',
loadFailed: 'Could not load document requirements',
empty: 'No document requirements configured',
emptyBody: 'Add the documents an applicant must upload for this licence type.',
emptyKind: 'No document requirements for this application kind yet.',
key: 'Key',
keyHelp: 'Stable slug identifying this document slot',
keyLocked: 'Key cannot change once created',
keyRequired: 'Key is required',
name: 'Name',
description: 'Description',
applicationKind: 'Application kind',
kindNew: 'New application',
kindRenewal: 'Renewal',
kindLocked: 'Application kind cannot change once created',
mode: 'Mode',
modeAlways: 'Always required',
modeConditional: 'Required when condition holds',
modeOptional: 'Optional upload',
conditionRequired: 'A conditional requirement needs a condition',
allowedTypes: 'Allowed file types',
maxSize: 'Max file size (MB)',
requiresValidity: 'Requires validity dates',
allowMultiple: 'Allow multiple uploads',
multiple: 'multiple',
sortOrder: 'Sort order',
when: 'when',
},
},
seafarerRegistry: {
title: 'Seafarer registry',
profileCount_one: '{{count}} profile',