From dddcf8d9e6b21e48c9ffbbfaa6b86ab64502f5c5 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:11:34 +0200 Subject: [PATCH 1/5] feat(config): warn on array entry type mismatch --- .../Data/Config/AddArrayEntryDialog.react.js | 51 +++++++++++++++++-- src/dashboard/Data/Config/Config.react.js | 30 ++++++++++- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js index 28791993c6..082362a01d 100644 --- a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js +++ b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js @@ -14,7 +14,7 @@ import TextInput from 'components/TextInput/TextInput.react'; export default class AddArrayEntryDialog extends React.Component { constructor() { super(); - this.state = { value: '' }; + this.state = { value: '', showWarning: false, parsedValue: null, parsedType: '' }; this.inputRef = React.createRef(); } @@ -36,8 +36,30 @@ export default class AddArrayEntryDialog extends React.Component { } } + getType(value) { + if (Array.isArray(value)) { + return 'array'; + } + if (value === null) { + return 'null'; + } + return typeof value; + } + + handleConfirm() { + const parsed = this.getValue(); + const entryType = this.getType(parsed); + const lastType = this.props.lastType; + if (lastType && entryType !== lastType && !this.state.showWarning) { + this.setState({ showWarning: true, parsedValue: parsed, parsedType: entryType }); + return; + } + this.props.onConfirm(parsed); + this.setState({ showWarning: false, parsedValue: null, parsedType: '' }); + } + render() { - return ( + const addEntryModal = ( this.props.onConfirm(this.getValue())} + onConfirm={this.handleConfirm.bind(this)} disabled={!this.valid()} > ); + + const warningModal = this.state.showWarning ? ( + this.setState({ showWarning: false })} + onConfirm={() => this.handleConfirm()} + > +
+ The type of the previous item ({this.props.lastType}) does not correspond to the type of the entry ({this.state.parsedType}). Do you want to proceed? +
+
+ ) : null; + + return ( + <> + {addEntryModal} + {warningModal} + + ); } } diff --git a/src/dashboard/Data/Config/Config.react.js b/src/dashboard/Data/Config/Config.react.js index c6c1145530..6981cfcf5c 100644 --- a/src/dashboard/Data/Config/Config.react.js +++ b/src/dashboard/Data/Config/Config.react.js @@ -48,6 +48,7 @@ class Config extends TableView { lastNote: null, showAddEntryDialog: false, addEntryParam: '', + addEntryLastType: null, }; this.noteTimeout = null; } @@ -122,6 +123,7 @@ class Config extends TableView { onConfirm={value => this.addArrayEntry(this.state.addEntryParam, value) } + lastType={this.state.addEntryLastType} /> ); } @@ -207,6 +209,16 @@ class Config extends TableView { }; } + getEntryType(value) { + if (Array.isArray(value)) { + return 'array'; + } + if (value === null) { + return 'null'; + } + return typeof value; + } + renderRow(data) { // Parse modal data const { value, modalValue, type } = this.parseValueForModal(data.value); @@ -491,11 +503,25 @@ class Config extends TableView { } openAddEntryDialog(param) { - this.setState({ showAddEntryDialog: true, addEntryParam: param }); + const params = this.props.config.data.get('params'); + const arr = params?.get(param); + let lastType = null; + if (Array.isArray(arr) && arr.length > 0) { + lastType = this.getEntryType(arr[arr.length - 1]); + } + this.setState({ + showAddEntryDialog: true, + addEntryParam: param, + addEntryLastType: lastType, + }); } closeAddEntryDialog() { - this.setState({ showAddEntryDialog: false, addEntryParam: '' }); + this.setState({ + showAddEntryDialog: false, + addEntryParam: '', + addEntryLastType: null, + }); } async addArrayEntry(param, value) { From 88d4ef2fd25449990d3ecb2ec66c0bd0db4e7049 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:21:35 +0200 Subject: [PATCH 2/5] Refine type mismatch warning --- .../Data/Config/AddArrayEntryDialog.react.js | 87 ++++++++++++------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js index 082362a01d..8707343c60 100644 --- a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js +++ b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js @@ -10,11 +10,17 @@ import Label from 'components/Label/Label.react'; import Modal from 'components/Modal/Modal.react'; import React from 'react'; import TextInput from 'components/TextInput/TextInput.react'; +import Checkbox from 'components/Checkbox/Checkbox.react'; export default class AddArrayEntryDialog extends React.Component { constructor() { super(); - this.state = { value: '', showWarning: false, parsedValue: null, parsedType: '' }; + this.state = { + value: '', + showMismatchRow: false, + mismatchConfirmed: false, + parsedType: '', + }; this.inputRef = React.createRef(); } @@ -25,7 +31,13 @@ export default class AddArrayEntryDialog extends React.Component { } valid() { - return this.state.value !== ''; + if (this.state.value === '') { + return false; + } + if (this.state.showMismatchRow && !this.state.mismatchConfirmed) { + return false; + } + return true; } getValue() { @@ -50,12 +62,28 @@ export default class AddArrayEntryDialog extends React.Component { const parsed = this.getValue(); const entryType = this.getType(parsed); const lastType = this.props.lastType; - if (lastType && entryType !== lastType && !this.state.showWarning) { - this.setState({ showWarning: true, parsedValue: parsed, parsedType: entryType }); - return; + + if (lastType && entryType !== lastType) { + if (!this.state.showMismatchRow) { + this.setState({ + showMismatchRow: true, + mismatchConfirmed: false, + parsedType: entryType, + }); + return; + } + if (!this.state.mismatchConfirmed) { + return; + } } + this.props.onConfirm(parsed); - this.setState({ showWarning: false, parsedValue: null, parsedType: '' }); + this.setState({ + value: '', + showMismatchRow: false, + mismatchConfirmed: false, + parsedType: '', + }); } render() { @@ -82,34 +110,35 @@ export default class AddArrayEntryDialog extends React.Component { placeholder={'Enter value'} ref={this.inputRef} value={this.state.value} - onChange={value => this.setState({ value })} + onChange={value => + this.setState({ + value, + showMismatchRow: false, + mismatchConfirmed: false, + }) + } /> } /> + {this.state.showMismatchRow && ( + + } + input={ + this.setState({ mismatchConfirmed: checked })} + /> + } + /> + )} ); - const warningModal = this.state.showWarning ? ( - this.setState({ showWarning: false })} - onConfirm={() => this.handleConfirm()} - > -
- The type of the previous item ({this.props.lastType}) does not correspond to the type of the entry ({this.state.parsedType}). Do you want to proceed? -
-
- ) : null; - - return ( - <> - {addEntryModal} - {warningModal} - - ); + return addEntryModal; } } From fcbb13f1e591a1d634559e87233037ecc378a4a1 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:35:08 +0200 Subject: [PATCH 3/5] fix mismatch row disables confirm --- .../Data/Config/AddArrayEntryDialog.react.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js index 8707343c60..06fcac2c74 100644 --- a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js +++ b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js @@ -30,15 +30,6 @@ export default class AddArrayEntryDialog extends React.Component { } } - valid() { - if (this.state.value === '') { - return false; - } - if (this.state.showMismatchRow && !this.state.mismatchConfirmed) { - return false; - } - return true; - } getValue() { try { @@ -87,6 +78,10 @@ export default class AddArrayEntryDialog extends React.Component { } render() { + const confirmDisabled = + this.state.value === '' || + (this.state.showMismatchRow && !this.state.mismatchConfirmed); + const addEntryModal = ( Date: Wed, 9 Jul 2025 02:48:13 +0200 Subject: [PATCH 4/5] Fix confirm button style on mismatch --- .../Data/Config/AddArrayEntryDialog.react.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js index 06fcac2c74..c63ea9250e 100644 --- a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js +++ b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js @@ -56,11 +56,18 @@ export default class AddArrayEntryDialog extends React.Component { if (lastType && entryType !== lastType) { if (!this.state.showMismatchRow) { - this.setState({ - showMismatchRow: true, - mismatchConfirmed: false, - parsedType: entryType, - }); + this.setState( + { + showMismatchRow: true, + mismatchConfirmed: false, + parsedType: entryType, + }, + () => { + if (document.activeElement instanceof HTMLElement) { + document.activeElement.blur(); + } + } + ); return; } if (!this.state.mismatchConfirmed) { From ced15cce126ad326501444e558dcbff205572db0 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Wed, 9 Jul 2025 02:58:58 +0200 Subject: [PATCH 5/5] Update AddArrayEntryDialog.react.js --- src/dashboard/Data/Config/AddArrayEntryDialog.react.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js index c63ea9250e..be1b392986 100644 --- a/src/dashboard/Data/Config/AddArrayEntryDialog.react.js +++ b/src/dashboard/Data/Config/AddArrayEntryDialog.react.js @@ -126,8 +126,12 @@ export default class AddArrayEntryDialog extends React.Component { + Previous item type is {this.props.lastType}, new entry type is {this.state.parsedType}. + + } /> } input={