mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-09-02 10:23:43 +00:00
feat: add inspection, issuance, and renewal toggles to certificate requirement settings
This commit is contained in:
@@ -33,6 +33,9 @@ interface Draft {
|
|||||||
completionEffect: CompletionEffect | null;
|
completionEffect: CompletionEffect | null;
|
||||||
certificateCategory: CertificateCategory | null;
|
certificateCategory: CertificateCategory | null;
|
||||||
requiresExamination: boolean;
|
requiresExamination: boolean;
|
||||||
|
inspectionRequired: boolean;
|
||||||
|
issuesCertificate: boolean;
|
||||||
|
renewalEnabled: boolean;
|
||||||
requiresSeafarerRegistration: boolean;
|
requiresSeafarerRegistration: boolean;
|
||||||
requiresValidMedical: boolean;
|
requiresValidMedical: boolean;
|
||||||
minSeaTimeDays: number | null;
|
minSeaTimeDays: number | null;
|
||||||
@@ -58,6 +61,9 @@ function toDraft(licenseType: LicenseType): Draft {
|
|||||||
completionEffect: licenseType.completionEffect ?? null,
|
completionEffect: licenseType.completionEffect ?? null,
|
||||||
certificateCategory: licenseType.certificateCategory ?? null,
|
certificateCategory: licenseType.certificateCategory ?? null,
|
||||||
requiresExamination: licenseType.requiresExamination ?? false,
|
requiresExamination: licenseType.requiresExamination ?? false,
|
||||||
|
inspectionRequired: licenseType.inspectionRequired ?? true,
|
||||||
|
issuesCertificate: licenseType.issuesCertificate ?? true,
|
||||||
|
renewalEnabled: licenseType.renewalEnabled ?? true,
|
||||||
requiresSeafarerRegistration:
|
requiresSeafarerRegistration:
|
||||||
licenseType.requiresSeafarerRegistration ?? false,
|
licenseType.requiresSeafarerRegistration ?? false,
|
||||||
requiresValidMedical: licenseType.requiresValidMedical ?? false,
|
requiresValidMedical: licenseType.requiresValidMedical ?? false,
|
||||||
@@ -182,6 +188,17 @@ export function BehaviorTab({ licenseType }: { licenseType: LicenseType }) {
|
|||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
checked={draft.issuesCertificate}
|
||||||
|
onChange={(e) => set('issuesCertificate', e.currentTarget.checked)}
|
||||||
|
label={t('certReq.behavior.issuesCertificate', 'Issues a certificate')}
|
||||||
|
description={t(
|
||||||
|
'certReq.behavior.issuesCertificateHint',
|
||||||
|
'Turn off for a type that ends with an EMA decision and never reaches a payment stage. Turning it back on requires a new-application fee to be set, or approved applicants would be asked for a fee that does not exist.',
|
||||||
|
)}
|
||||||
|
disabled={!canEdit}
|
||||||
|
/>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
label={t('certReq.behavior.serviceKind', 'Service kind')}
|
label={t('certReq.behavior.serviceKind', 'Service kind')}
|
||||||
description={t(
|
description={t(
|
||||||
@@ -315,33 +332,53 @@ export function BehaviorTab({ licenseType }: { licenseType: LicenseType }) {
|
|||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<NumberInput
|
<Switch
|
||||||
label={t('certReq.behavior.renewalWindow', 'Renewal opens (days before expiry)')}
|
checked={draft.renewalEnabled}
|
||||||
value={draft.renewalWindowDays}
|
onChange={(e) => set('renewalEnabled', e.currentTarget.checked)}
|
||||||
onChange={(v) => set('renewalWindowDays', typeof v === 'number' ? v : draft.renewalWindowDays)}
|
label={t('certReq.behavior.renewalEnabled', 'Holders may renew this licence')}
|
||||||
min={1}
|
description={t(
|
||||||
max={365}
|
'certReq.behavior.renewalEnabledHint',
|
||||||
allowNegative={false}
|
'Off for one-off issues — a registration that does not lapse, or a waiver written for a single shipment.',
|
||||||
|
)}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MultiSelect
|
{/* The window and the reminders are both measured against an expiry a
|
||||||
label={t('certReq.behavior.reminders', 'Expiry reminders (days before)')}
|
non-renewing licence never reaches, so they are hidden rather than
|
||||||
description={t(
|
shown as settings that quietly do nothing. */}
|
||||||
'certReq.behavior.remindersHint',
|
{draft.renewalEnabled && (
|
||||||
'The holder is reminded at each of these offsets.',
|
<>
|
||||||
)}
|
<NumberInput
|
||||||
data={REMINDER_OFFSETS}
|
label={t('certReq.behavior.renewalWindow', 'Renewal opens (days before expiry)')}
|
||||||
value={draft.expiryReminderDays.map(String)}
|
value={draft.renewalWindowDays}
|
||||||
onChange={(values) =>
|
onChange={(v) =>
|
||||||
set(
|
set('renewalWindowDays', typeof v === 'number' ? v : draft.renewalWindowDays)
|
||||||
'expiryReminderDays',
|
}
|
||||||
values.map(Number).sort((a, b) => b - a),
|
min={1}
|
||||||
)
|
max={365}
|
||||||
}
|
allowNegative={false}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
clearable
|
/>
|
||||||
/>
|
|
||||||
|
<MultiSelect
|
||||||
|
label={t('certReq.behavior.reminders', 'Expiry reminders (days before)')}
|
||||||
|
description={t(
|
||||||
|
'certReq.behavior.remindersHint',
|
||||||
|
'The holder is reminded at each of these offsets.',
|
||||||
|
)}
|
||||||
|
data={REMINDER_OFFSETS}
|
||||||
|
value={draft.expiryReminderDays.map(String)}
|
||||||
|
onChange={(values) =>
|
||||||
|
set(
|
||||||
|
'expiryReminderDays',
|
||||||
|
values.map(Number).sort((a, b) => b - a),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
disabled={!canEdit}
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
<Section title={t('certReq.behavior.applicantRules', 'Applicant rules')}>
|
<Section title={t('certReq.behavior.applicantRules', 'Applicant rules')}>
|
||||||
@@ -367,6 +404,17 @@ export function BehaviorTab({ licenseType }: { licenseType: LicenseType }) {
|
|||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Switch
|
||||||
|
checked={draft.inspectionRequired}
|
||||||
|
onChange={(e) => set('inspectionRequired', e.currentTarget.checked)}
|
||||||
|
label={t('certReq.behavior.inspectionRequired', 'Requires a physical inspection')}
|
||||||
|
description={t(
|
||||||
|
'certReq.behavior.inspectionRequiredHint',
|
||||||
|
'An officer cannot approve until an inspection has been recorded and passed. Safe to change with applications in progress — an officer can still assign an inspector to a file already under evaluation.',
|
||||||
|
)}
|
||||||
|
disabled={!canEdit}
|
||||||
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
checked={draft.requiresIssuanceScheduling}
|
checked={draft.requiresIssuanceScheduling}
|
||||||
onChange={(e) => set('requiresIssuanceScheduling', e.currentTarget.checked)}
|
onChange={(e) => set('requiresIssuanceScheduling', e.currentTarget.checked)}
|
||||||
|
|||||||
@@ -1292,6 +1292,15 @@ export const am: Translations = {
|
|||||||
requiresExamination: "ፈተና ያስፈልገዋል",
|
requiresExamination: "ፈተና ያስፈልገዋል",
|
||||||
requiresExaminationHint:
|
requiresExaminationHint:
|
||||||
"ማመልከቻውን በብቁነት፣ ከዚያ በፈተና፣ ከዚያ በምስክር ወረቀት ሂደት ያሳልፋል። ሦስቱን የደረጃ ክፍያዎች በክፍያ ቅንብር ገጽ ላይ ያስቀምጡ።",
|
"ማመልከቻውን በብቁነት፣ ከዚያ በፈተና፣ ከዚያ በምስክር ወረቀት ሂደት ያሳልፋል። ሦስቱን የደረጃ ክፍያዎች በክፍያ ቅንብር ገጽ ላይ ያስቀምጡ።",
|
||||||
|
issuesCertificate: "የምስክር ወረቀት ይሰጣል",
|
||||||
|
issuesCertificateHint:
|
||||||
|
"በኢማ ውሳኔ ተጠናቆ ወደ ክፍያ ደረጃ ለማይደርስ ዓይነት ያጥፉ። እንደገና ማብራት የአዲስ ማመልከቻ ክፍያ እንዲዘጋጅ ይጠይቃል፤ አለበለዚያ የጸደቁ አመልካቾች የሌለ ክፍያ እንዲከፍሉ ይጠየቃሉ።",
|
||||||
|
inspectionRequired: "አካላዊ ምርመራ ያስፈልገዋል",
|
||||||
|
inspectionRequiredHint:
|
||||||
|
"ምርመራ ተመዝግቦ እስኪያልፍ ድረስ ኃላፊው ማጽደቅ አይችልም። ማመልከቻዎች በሂደት ላይ እያሉ መቀየር አስተማማኝ ነው — ኃላፊው በግምገማ ላይ ላለ ማመልከቻ አሁንም መርማሪ መመደብ ይችላል።",
|
||||||
|
renewalEnabled: "ባለቤቶች ይህንን ፈቃድ ማደስ ይችላሉ",
|
||||||
|
renewalEnabledHint:
|
||||||
|
"አንድ ጊዜ ብቻ ለሚሰጡ ያጥፉ — ጊዜው ለማያልፍ ምዝገባ፣ ወይም ለአንድ ጭነት ለተጻፈ ነፃ ፈቃድ።",
|
||||||
serviceKind: "የአገልግሎት ዓይነት",
|
serviceKind: "የአገልግሎት ዓይነት",
|
||||||
serviceKindHint: "ለዝርዝር ምድብ ብቻ — ምንም የሥራ ሂደት በእሱ ላይ አይመሠረትም።",
|
serviceKindHint: "ለዝርዝር ምድብ ብቻ — ምንም የሥራ ሂደት በእሱ ላይ አይመሠረትም።",
|
||||||
license: "ፈቃድ",
|
license: "ፈቃድ",
|
||||||
|
|||||||
@@ -1297,6 +1297,15 @@ export const en = {
|
|||||||
requiresExamination: 'Requires an examination',
|
requiresExamination: 'Requires an examination',
|
||||||
requiresExaminationHint:
|
requiresExaminationHint:
|
||||||
'Routes the application through eligibility, then exam, then certificate. Set the three stage fees on the payment configuration screen.',
|
'Routes the application through eligibility, then exam, then certificate. Set the three stage fees on the payment configuration screen.',
|
||||||
|
issuesCertificate: 'Issues a certificate',
|
||||||
|
issuesCertificateHint:
|
||||||
|
'Turn off for a type that ends with an EMA decision and never reaches a payment stage. Turning it back on requires a new-application fee to be set, or approved applicants would be asked for a fee that does not exist.',
|
||||||
|
inspectionRequired: 'Requires a physical inspection',
|
||||||
|
inspectionRequiredHint:
|
||||||
|
'An officer cannot approve until an inspection has been recorded and passed. Safe to change with applications in progress — an officer can still assign an inspector to a file already under evaluation.',
|
||||||
|
renewalEnabled: 'Holders may renew this licence',
|
||||||
|
renewalEnabledHint:
|
||||||
|
'Off for one-off issues — a registration that does not lapse, or a waiver written for a single shipment.',
|
||||||
serviceKind: 'Service kind',
|
serviceKind: 'Service kind',
|
||||||
serviceKindHint: 'Catalogue classification only — no workflow depends on it.',
|
serviceKindHint: 'Catalogue classification only — no workflow depends on it.',
|
||||||
license: 'Licence',
|
license: 'Licence',
|
||||||
|
|||||||
@@ -223,6 +223,9 @@ export const licensingApi = baseApi
|
|||||||
completionEffect?: CompletionEffect | null;
|
completionEffect?: CompletionEffect | null;
|
||||||
certificateCategory?: CertificateCategory | null;
|
certificateCategory?: CertificateCategory | null;
|
||||||
requiresExamination?: boolean;
|
requiresExamination?: boolean;
|
||||||
|
inspectionRequired?: boolean;
|
||||||
|
issuesCertificate?: boolean;
|
||||||
|
renewalEnabled?: boolean;
|
||||||
requiresSeafarerRegistration?: boolean;
|
requiresSeafarerRegistration?: boolean;
|
||||||
requiresValidMedical?: boolean;
|
requiresValidMedical?: boolean;
|
||||||
minSeaTimeDays?: number | null;
|
minSeaTimeDays?: number | null;
|
||||||
|
|||||||
Reference in New Issue
Block a user