diff --git a/typescript/frontend-marios2/src/content/dashboards/Information/InformationSodistoreHome.tsx b/typescript/frontend-marios2/src/content/dashboards/Information/InformationSodistoreHome.tsx index b7b8b6cfa..0b3308884 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Information/InformationSodistoreHome.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Information/InformationSodistoreHome.tsx @@ -53,6 +53,50 @@ function InformationSodistorehome(props: InformationSodistorehomeProps) { [] ); + // Parse inverter/datalogger serial numbers from various legacy formats: + // Slash-separated: "SN001/SN002" + // Labeled comma: "Inverter 1: SN001, Inverter 2: SN002" + // Labeled comma: "Datalogger 1: SN001, Datalogger 2: SN002" + // Plain string: "SN001" + const parseSerialNumbers = (value: string | undefined): string[] => { + if (!value || value.trim() === '') return []; + + // Check for labeled comma format: "Inverter 1: SN001, Inverter 2: SN002" + if (/(?:Inverter|Datalogger)\s*\d+\s*:/i.test(value)) { + const matches = value.match(/(?:Inverter|Datalogger)\s*\d+\s*:\s*([^,]+)/gi); + if (matches) { + return matches + .map((m) => m.replace(/^(?:Inverter|Datalogger)\s*\d+\s*:\s*/i, '').trim()) + .filter((s) => s !== ''); + } + } + + // Slash-separated format: "SN001/SN002" + if (value.includes('/')) { + return value.split('/').filter((s) => s.trim() !== ''); + } + + // Single value + return [value.trim()]; + }; + + const [inverterNumber, setInverterNumber] = useState(() => { + const parts = parseSerialNumbers(props.values.inverterSN); + return parts.length > 0 ? parts.length : 1; + }); + const [inverterSerialNumbers, setInverterSerialNumbers] = useState( + () => { + const parts = parseSerialNumbers(props.values.inverterSN); + return parts.length > 0 ? parts : ['']; + } + ); + const [dataloggerSerialNumbers, setDataloggerSerialNumbers] = useState( + () => { + const parts = parseSerialNumbers(props.values.dataloggerSN); + return parts.length > 0 ? parts : ['']; + } + ); + const DeviceTypes = [ { id: 3, name: 'Growatt' }, { id: 4, name: 'Sinexcel' } @@ -141,6 +185,59 @@ function InformationSodistorehome(props: InformationSodistorehomeProps) { } } }; + const handleInverterNumberChange = (e) => { + const inputValue = e.target.value; + // Allow empty while user is mid-edit + if (inputValue === '') { + setInverterNumber(''); + return; + } + if (/^\d+$/.test(inputValue)) { + const value = Math.max(1, parseInt(inputValue)); + setInverterNumber(value); + + const newInverterSNs = Array.from({ length: value }, (_, i) => + inverterSerialNumbers[i] || '' + ); + const newDataloggerSNs = Array.from({ length: value }, (_, i) => + dataloggerSerialNumbers[i] || '' + ); + setInverterSerialNumbers(newInverterSNs); + setDataloggerSerialNumbers(newDataloggerSNs); + setFormValues({ + ...formValues, + inverterSN: newInverterSNs.filter((s) => s !== '').join('/'), + dataloggerSN: newDataloggerSNs.filter((s) => s !== '').join('/') + }); + } + }; + + const handleInverterNumberBlur = () => { + if (inverterNumber === '' || inverterNumber < 1) { + setInverterNumber(1); + } + }; + + const handleInverterSerialNumberChange = (index: number, value: string) => { + const updated = [...inverterSerialNumbers]; + updated[index] = value; + setInverterSerialNumbers(updated); + setFormValues({ + ...formValues, + inverterSN: updated.filter((s) => s !== '').join('/') + }); + }; + + const handleDataloggerSerialNumberChange = (index: number, value: string) => { + const updated = [...dataloggerSerialNumbers]; + updated[index] = value; + setDataloggerSerialNumbers(updated); + setFormValues({ + ...formValues, + dataloggerSN: updated.filter((s) => s !== '').join('/') + }); + }; + const handleSubmit = () => { setLoading(true); setError(false); @@ -495,35 +592,54 @@ function InformationSodistorehome(props: InformationSodistorehomeProps) { } - name="inverterSN" - value={formValues.inverterSN} - onChange={handleChange} + name="inverterNumber" + type="text" + value={inverterNumber} + onChange={handleInverterNumberChange} + onBlur={handleInverterNumberBlur} variant="outlined" fullWidth inputProps={{ readOnly: !canEdit }} /> -
- 0 && + inverterSerialNumbers.map((sn, index) => ( +
+ + handleInverterSerialNumberChange(index, e.target.value) + } + variant="outlined" + fullWidth + inputProps={{ readOnly: !canEdit }} /> - } - name="dataloggerSN" - value={formValues.dataloggerSN} - onChange={handleChange} - variant="outlined" - fullWidth - inputProps={{ readOnly: !canEdit }} - /> -
+
+ ))} + + {typeof inverterNumber === 'number' && inverterNumber > 0 && + dataloggerSerialNumbers.map((sn, index) => ( +
+ + handleDataloggerSerialNumberChange(index, e.target.value) + } + variant="outlined" + fullWidth + inputProps={{ readOnly: !canEdit }} + /> +
+ ))}