allow multiple inverter SN regiter

This commit is contained in:
Yinyin Liu 2026-03-19 13:34:37 +01:00
parent 758ad30890
commit 897f3137f5
1 changed files with 136 additions and 20 deletions

View File

@ -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<number | ''>(() => {
const parts = parseSerialNumbers(props.values.inverterSN);
return parts.length > 0 ? parts.length : 1;
});
const [inverterSerialNumbers, setInverterSerialNumbers] = useState<string[]>(
() => {
const parts = parseSerialNumbers(props.values.inverterSN);
return parts.length > 0 ? parts : [''];
}
);
const [dataloggerSerialNumbers, setDataloggerSerialNumbers] = useState<string[]>(
() => {
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) {
<TextField
label={
<FormattedMessage
id="inverterSN"
defaultMessage="Inverter Serial Number"
id="inverterNumber"
defaultMessage="Inverter Number"
/>
}
name="inverterSN"
value={formValues.inverterSN}
onChange={handleChange}
name="inverterNumber"
type="text"
value={inverterNumber}
onChange={handleInverterNumberChange}
onBlur={handleInverterNumberBlur}
variant="outlined"
fullWidth
inputProps={{ readOnly: !canEdit }}
/>
</div>
<div>
<TextField
label={
<FormattedMessage
id="dataloggerSN"
defaultMessage="Datalogger Serial Number"
{typeof inverterNumber === 'number' && inverterNumber > 0 &&
inverterSerialNumbers.map((sn, index) => (
<div key={`inv-${index}`}>
<TextField
label={`Inverter Serial Number ${index + 1}`}
name={`inverterSN${index + 1}`}
value={sn}
onChange={(e) =>
handleInverterSerialNumberChange(index, e.target.value)
}
variant="outlined"
fullWidth
inputProps={{ readOnly: !canEdit }}
/>
}
name="dataloggerSN"
value={formValues.dataloggerSN}
onChange={handleChange}
variant="outlined"
fullWidth
inputProps={{ readOnly: !canEdit }}
/>
</div>
</div>
))}
{typeof inverterNumber === 'number' && inverterNumber > 0 &&
dataloggerSerialNumbers.map((sn, index) => (
<div key={`dl-${index}`}>
<TextField
label={`Datalogger Serial Number ${index + 1}`}
name={`dataloggerSN${index + 1}`}
value={sn}
onChange={(e) =>
handleDataloggerSerialNumberChange(index, e.target.value)
}
variant="outlined"
fullWidth
inputProps={{ readOnly: !canEdit }}
/>
</div>
))}
<div>
<TextField