mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-26 19:12:50 +00:00
feat: add onVesselSelected callback to ConfigDrivenSection for handling vessel selection
This commit is contained in:
@@ -25,15 +25,23 @@ interface Props {
|
|||||||
errors?: Record<string, string>;
|
errors?: Record<string, string>;
|
||||||
/** The applicant's registered vessels, for the vessel-picker field. */
|
/** The applicant's registered vessels, for the vessel-picker field. */
|
||||||
vessels?: Vessel[];
|
vessels?: Vessel[];
|
||||||
|
/**
|
||||||
|
* Fired when the vessel picker's value resolves to a known vessel. Vessel
|
||||||
|
* Information and Current Ownership are separate form sections, so this
|
||||||
|
* component (one instance per section) can only fill its own fields —
|
||||||
|
* the parent uses this to fill the rest via the same `VESSEL_FIELD_FILLERS`.
|
||||||
|
*/
|
||||||
|
onVesselSelected?: (vessel: Vessel) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a Vessel's own fields onto whichever sibling fields the backend put
|
* Maps a Vessel's own fields onto whichever fields the backend put in the
|
||||||
* in the same section — same dual key/label matching the nationality prefill
|
* license form — same dual key/label matching the nationality prefill in
|
||||||
* in LicenseApplicationPage uses, so this doesn't depend on exact field-key
|
* LicenseApplicationPage uses, so this doesn't depend on exact field-key
|
||||||
* naming in the seeded formSchema.
|
* naming in the seeded formSchema. Exported so the parent page can apply it
|
||||||
|
* across every section, not just the one the vessel picker lives in.
|
||||||
*/
|
*/
|
||||||
const VESSEL_FIELD_FILLERS: {
|
export const VESSEL_FIELD_FILLERS: {
|
||||||
matches: (label: string, key: string) => boolean;
|
matches: (label: string, key: string) => boolean;
|
||||||
value: (vessel: Vessel) => unknown;
|
value: (vessel: Vessel) => unknown;
|
||||||
}[] = [
|
}[] = [
|
||||||
@@ -53,9 +61,12 @@ const VESSEL_FIELD_FILLERS: {
|
|||||||
{ matches: (l, k) => k === 'enginePowerKw' || l.includes('engine power'), value: (v) => v.enginePowerKw },
|
{ matches: (l, k) => k === 'enginePowerKw' || l.includes('engine power'), value: (v) => v.enginePowerKw },
|
||||||
{ matches: (l, k) => k === 'numberOfEngines' || l.includes('number of engines'), value: (v) => v.numberOfEngines },
|
{ matches: (l, k) => k === 'numberOfEngines' || l.includes('number of engines'), value: (v) => v.numberOfEngines },
|
||||||
{ matches: (l, k) => k === 'hullMaterial' || l.includes('hull material'), value: (v) => v.hullMaterial },
|
{ matches: (l, k) => k === 'hullMaterial' || l.includes('hull material'), value: (v) => v.hullMaterial },
|
||||||
|
// Current Ownership: only the "current" owner, never "new owner" —
|
||||||
|
// that's who the vessel is being transferred to, not on file anywhere.
|
||||||
|
{ matches: (l, k) => k === 'currentOwnerName' || k === 'currentOwner' || l.includes('current owner'), value: (v) => v.ownerName },
|
||||||
];
|
];
|
||||||
|
|
||||||
function fillFromVessel(
|
export function fillFromVessel(
|
||||||
vessel: Vessel,
|
vessel: Vessel,
|
||||||
fields: FormFieldConfig[],
|
fields: FormFieldConfig[],
|
||||||
onChange: (key: string, value: unknown) => void,
|
onChange: (key: string, value: unknown) => void,
|
||||||
@@ -82,6 +93,7 @@ export function ConfigDrivenSection({
|
|||||||
disabled,
|
disabled,
|
||||||
errors = {},
|
errors = {},
|
||||||
vessels = [],
|
vessels = [],
|
||||||
|
onVesselSelected,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const fields = [...(section.fields ?? [])].sort(
|
const fields = [...(section.fields ?? [])].sort(
|
||||||
(a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0),
|
(a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0),
|
||||||
@@ -134,7 +146,7 @@ export function ConfigDrivenSection({
|
|||||||
// onChange={(v) => {
|
// onChange={(v) => {
|
||||||
// onChange(field.key, v);
|
// onChange(field.key, v);
|
||||||
// const vessel = vessels.find((x) => x.id === v);
|
// const vessel = vessels.find((x) => x.id === v);
|
||||||
// if (vessel) fillFromVessel(vessel, fields, onChange);
|
// if (vessel) { fillFromVessel(vessel, fields, onChange); onVesselSelected?.(vessel); }
|
||||||
// }}
|
// }}
|
||||||
// searchable
|
// searchable
|
||||||
// clearable={!field.required}
|
// clearable={!field.required}
|
||||||
@@ -147,7 +159,10 @@ export function ConfigDrivenSection({
|
|||||||
const v = e.currentTarget.value;
|
const v = e.currentTarget.value;
|
||||||
onChange(field.key, v);
|
onChange(field.key, v);
|
||||||
const vessel = vessels.find((x) => x.id === v);
|
const vessel = vessels.find((x) => x.id === v);
|
||||||
if (vessel) fillFromVessel(vessel, fields, onChange);
|
if (vessel) {
|
||||||
|
fillFromVessel(vessel, fields, onChange);
|
||||||
|
onVesselSelected?.(vessel);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : field.type === 'SELECT' ? (
|
) : field.type === 'SELECT' ? (
|
||||||
|
|||||||
@@ -50,10 +50,11 @@ import {
|
|||||||
type FieldErrors,
|
type FieldErrors,
|
||||||
type FormFieldConfig,
|
type FormFieldConfig,
|
||||||
type ValidationIssue,
|
type ValidationIssue,
|
||||||
|
type Vessel,
|
||||||
} from '@ema-platform/api';
|
} from '@ema-platform/api';
|
||||||
import { getCountryCode, getCountryName, ModalFooter } from '@ema-platform/ui';
|
import { getCountryCode, getCountryName, ModalFooter } from '@ema-platform/ui';
|
||||||
import { useCurrentProfile } from '@ema-platform/auth';
|
import { useCurrentProfile } from '@ema-platform/auth';
|
||||||
import { ConfigDrivenSection } from '../components/ConfigDrivenSection';
|
import { ConfigDrivenSection, fillFromVessel } from '../components/ConfigDrivenSection';
|
||||||
import { DocumentSlots } from '../components/DocumentSlots';
|
import { DocumentSlots } from '../components/DocumentSlots';
|
||||||
import { StaffEvidence } from '../components/StaffEvidence';
|
import { StaffEvidence } from '../components/StaffEvidence';
|
||||||
|
|
||||||
@@ -210,6 +211,20 @@ export function LicenseApplicationPage() {
|
|||||||
|
|
||||||
const readOnly = !['DRAFT', 'RESUBMIT_REQUIRED'].includes(application.status);
|
const readOnly = !['DRAFT', 'RESUBMIT_REQUIRED'].includes(application.status);
|
||||||
|
|
||||||
|
// Vessel Information and Current Ownership are separate form sections, so
|
||||||
|
// ConfigDrivenSection (one instance per section) can't fill both itself —
|
||||||
|
// it reports the pick up here and this fans it out across every section.
|
||||||
|
function handleVesselSelected(vessel: Vessel) {
|
||||||
|
for (const section of config?.licenseType.formSchema.sections ?? []) {
|
||||||
|
fillFromVessel(vessel, section.fields, (key, value) => {
|
||||||
|
setDraft((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[section.key]: { ...(prev[section.key] ?? {}), [key]: value },
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function saveSection(sectionKey: string) {
|
async function saveSection(sectionKey: string) {
|
||||||
// During an adjustment round only flagged sections are editable, so don't
|
// During an adjustment round only flagged sections are editable, so don't
|
||||||
// even attempt a write the server would reject.
|
// even attempt a write the server would reject.
|
||||||
@@ -459,6 +474,7 @@ export function LicenseApplicationPage() {
|
|||||||
section={section}
|
section={section}
|
||||||
values={draft[section.key] ?? {}}
|
values={draft[section.key] ?? {}}
|
||||||
formData={draft}
|
formData={draft}
|
||||||
|
onVesselSelected={handleVesselSelected}
|
||||||
errors={fieldErrors}
|
errors={fieldErrors}
|
||||||
vessels={vessels}
|
vessels={vessels}
|
||||||
disabled={readOnly || locked}
|
disabled={readOnly || locked}
|
||||||
@@ -589,6 +605,7 @@ export function LicenseApplicationPage() {
|
|||||||
</Text>
|
</Text>
|
||||||
<ConfigDrivenSection
|
<ConfigDrivenSection
|
||||||
section={section}
|
section={section}
|
||||||
|
onVesselSelected={handleVesselSelected}
|
||||||
values={draft[section.key] ?? {}}
|
values={draft[section.key] ?? {}}
|
||||||
formData={draft}
|
formData={draft}
|
||||||
errors={fieldErrors}
|
errors={fieldErrors}
|
||||||
|
|||||||
Reference in New Issue
Block a user