allow multiple inverter SN regiter
This commit is contained in:
parent
758ad30890
commit
897f3137f5
|
|
@ -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 = [
|
const DeviceTypes = [
|
||||||
{ id: 3, name: 'Growatt' },
|
{ id: 3, name: 'Growatt' },
|
||||||
{ id: 4, name: 'Sinexcel' }
|
{ 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 = () => {
|
const handleSubmit = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(false);
|
setError(false);
|
||||||
|
|
@ -495,35 +592,54 @@ function InformationSodistorehome(props: InformationSodistorehomeProps) {
|
||||||
<TextField
|
<TextField
|
||||||
label={
|
label={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id="inverterSN"
|
id="inverterNumber"
|
||||||
defaultMessage="Inverter Serial Number"
|
defaultMessage="Inverter Number"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
name="inverterSN"
|
name="inverterNumber"
|
||||||
value={formValues.inverterSN}
|
type="text"
|
||||||
onChange={handleChange}
|
value={inverterNumber}
|
||||||
|
onChange={handleInverterNumberChange}
|
||||||
|
onBlur={handleInverterNumberBlur}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
fullWidth
|
fullWidth
|
||||||
inputProps={{ readOnly: !canEdit }}
|
inputProps={{ readOnly: !canEdit }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
{typeof inverterNumber === 'number' && inverterNumber > 0 &&
|
||||||
<TextField
|
inverterSerialNumbers.map((sn, index) => (
|
||||||
label={
|
<div key={`inv-${index}`}>
|
||||||
<FormattedMessage
|
<TextField
|
||||||
id="dataloggerSN"
|
label={`Inverter Serial Number ${index + 1}`}
|
||||||
defaultMessage="Datalogger Serial Number"
|
name={`inverterSN${index + 1}`}
|
||||||
|
value={sn}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleInverterSerialNumberChange(index, e.target.value)
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
inputProps={{ readOnly: !canEdit }}
|
||||||
/>
|
/>
|
||||||
}
|
</div>
|
||||||
name="dataloggerSN"
|
))}
|
||||||
value={formValues.dataloggerSN}
|
|
||||||
onChange={handleChange}
|
{typeof inverterNumber === 'number' && inverterNumber > 0 &&
|
||||||
variant="outlined"
|
dataloggerSerialNumbers.map((sn, index) => (
|
||||||
fullWidth
|
<div key={`dl-${index}`}>
|
||||||
inputProps={{ readOnly: !canEdit }}
|
<TextField
|
||||||
/>
|
label={`Datalogger Serial Number ${index + 1}`}
|
||||||
</div>
|
name={`dataloggerSN${index + 1}`}
|
||||||
|
value={sn}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleDataloggerSerialNumberChange(index, e.target.value)
|
||||||
|
}
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
inputProps={{ readOnly: !canEdit }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue