added vehicles and vehicles extra, dynamic tables for entities, dynamic dropdowns with overlay for selecting and manage data
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import { useState, useMemo } from 'react';
|
||||
import { useNomenclatureData } from '../../contexts/NomenclatureDataContext';
|
||||
import NomenclatureManagementOverlay from './NomenclatureManagementOverlay';
|
||||
import './NomenclatureDropdown.css';
|
||||
|
||||
export default function NomenclatureDropdown({
|
||||
nomenclatureCode,
|
||||
value,
|
||||
onChange,
|
||||
label,
|
||||
disabled = false,
|
||||
}) {
|
||||
const { definitions, getActiveEntries, isLoading } = useNomenclatureData();
|
||||
const [showOverlay, setShowOverlay] = useState(false);
|
||||
|
||||
const nomenclature = definitions[nomenclatureCode];
|
||||
const activeEntries = useMemo(
|
||||
() => getActiveEntries(nomenclatureCode),
|
||||
[getActiveEntries, nomenclatureCode]
|
||||
);
|
||||
|
||||
if (!nomenclature) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="nui-dropdown">
|
||||
{label && <label className="nui-dropdown-label">{label}</label>}
|
||||
<select disabled className="nui-dropdown-select">
|
||||
<option>Loading...</option>
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const displayLabel = label || nomenclature.name;
|
||||
|
||||
// LOOKUP type: select dropdown + manage button
|
||||
if (nomenclature.kind === 'lookup') {
|
||||
const handleSelectChange = (e) => {
|
||||
const val = e.target.value;
|
||||
onChange(val ? parseInt(val, 10) : undefined);
|
||||
};
|
||||
|
||||
const handleOverlaySelect = (entryId) => {
|
||||
onChange(entryId);
|
||||
setShowOverlay(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="nui-dropdown">
|
||||
<label className="nui-dropdown-label">{displayLabel}</label>
|
||||
<div className="nui-dropdown-row">
|
||||
<select
|
||||
className="nui-dropdown-select"
|
||||
value={value || ''}
|
||||
onChange={handleSelectChange}
|
||||
disabled={disabled}
|
||||
>
|
||||
<option value="">-- Select --</option>
|
||||
{activeEntries.map(entry => (
|
||||
<option key={entry.id} value={entry.id}>
|
||||
{entry.display_value}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<button
|
||||
className="nui-dropdown-manage-btn"
|
||||
onClick={() => setShowOverlay(true)}
|
||||
disabled={disabled}
|
||||
type="button"
|
||||
title={`Manage ${displayLabel}`}
|
||||
>
|
||||
…
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<NomenclatureManagementOverlay
|
||||
nomenclatureCode={nomenclatureCode}
|
||||
isOpen={showOverlay}
|
||||
onClose={() => setShowOverlay(false)}
|
||||
mode="select"
|
||||
initialSelection={value || null}
|
||||
onSelect={handleOverlaySelect}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// FIELD type: render appropriate input
|
||||
const fieldDef = nomenclature.fields?.[0];
|
||||
if (!fieldDef) return null;
|
||||
|
||||
if (fieldDef.field_type === 'bool') {
|
||||
return (
|
||||
<div className="nui-dropdown">
|
||||
<label className="nui-dropdown-label nui-dropdown-label--checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={value || false}
|
||||
onChange={(e) => onChange(e.target.checked)}
|
||||
disabled={disabled}
|
||||
className="nui-dropdown-checkbox"
|
||||
/>
|
||||
{displayLabel}
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (fieldDef.field_type === 'number') {
|
||||
return (
|
||||
<div className="nui-dropdown">
|
||||
<label className="nui-dropdown-label">{displayLabel}</label>
|
||||
<input
|
||||
type="number"
|
||||
className="nui-dropdown-input"
|
||||
value={value ?? ''}
|
||||
onChange={(e) => onChange(e.target.value === '' ? undefined : Number(e.target.value))}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (fieldDef.field_type === 'choice' && fieldDef.choices) {
|
||||
return (
|
||||
<div className="nui-dropdown">
|
||||
<label className="nui-dropdown-label">{displayLabel}</label>
|
||||
<select
|
||||
className="nui-dropdown-select"
|
||||
value={value || ''}
|
||||
onChange={(e) => onChange(e.target.value || undefined)}
|
||||
disabled={disabled}
|
||||
>
|
||||
<option value="">-- Select --</option>
|
||||
{fieldDef.choices.map(c => (
|
||||
<option key={c} value={c}>{c}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Default: text input
|
||||
return (
|
||||
<div className="nui-dropdown">
|
||||
<label className="nui-dropdown-label">{displayLabel}</label>
|
||||
<input
|
||||
type="text"
|
||||
className="nui-dropdown-input"
|
||||
value={value || ''}
|
||||
onChange={(e) => onChange(e.target.value || undefined)}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user