-
+
{{ description }}
{{ moreInfoText }}
diff --git a/web/app/src/components/settings/FormInputText.vue b/web/app/src/components/settings/FormInputText.vue
index 3314b4a8..1c537fcc 100644
--- a/web/app/src/components/settings/FormInputText.vue
+++ b/web/app/src/components/settings/FormInputText.vue
@@ -2,7 +2,7 @@
import NotificationBar from '@/components/footer/NotificationBar.vue';
import UpdateListener from '@/components/UpdateListener.vue';
-import DropdownSelect from '@/components/settings/DropdownSelect.vue';
+import FormInputDropdownSelect from '@/components/settings/FormInputDropdownSelect.vue';
import FormInputSwitchCheckbox from '@/components/settings/FormInputSwitchCheckbox.vue';
import FormInputText from '@/components/settings/FormInputText.vue';
import FormInputNumber from '@/components/settings/FormInputNumber.vue';
@@ -91,16 +91,19 @@ const initialFormValues = {
type: inputTypes.string,
label: 'Database',
value: null,
+ required: true,
},
database_check_period: {
type: inputTypes.timeDuration,
label: 'Database Check Period',
value: null,
+ required: true,
},
listen: {
type: inputTypes.string,
label: 'Listening IP and Port Number',
value: null,
+ required: true,
},
autodiscoverable: {
type: inputTypes.boolean,
@@ -120,6 +123,7 @@ const initialFormValues = {
type: inputTypes.string,
label: 'Shared Storage Path',
value: null,
+ required: true,
},
shaman: {
enabled: {
@@ -136,8 +140,8 @@ const initialFormValues = {
moreInfoLinkLabel: `Shaman Storage System`,
},
garbageCollect: {
- period: { type: inputTypes.timeDuration, label: 'Period', value: null },
- maxAge: { type: inputTypes.timeDuration, label: 'Max Age', value: null },
+ period: { type: inputTypes.timeDuration, label: 'Period', value: null, required: true },
+ maxAge: { type: inputTypes.timeDuration, label: 'Max Age', value: null, required: true },
},
},
@@ -146,21 +150,25 @@ const initialFormValues = {
type: inputTypes.timeDuration,
label: 'Task Timeout',
value: null,
+ required: true,
},
worker_timeout: {
type: inputTypes.timeDuration,
label: 'Worker Timeout',
value: null,
+ required: true,
},
blocklist_threshold: {
type: inputTypes.number,
label: 'Blocklist Threshold',
value: null,
+ required: true,
},
task_fail_after_softfail_count: {
type: inputTypes.number,
label: 'Task Fail after Soft Fail Count',
value: null,
+ required: true,
},
// MQTT
@@ -198,16 +206,18 @@ export default {
components: {
NotificationBar,
UpdateListener,
- DropdownSelect,
FormInputText,
FormInputNumber,
FormInputSwitchCheckbox,
+ FormInputDropdownSelect,
},
data: () => ({
// Make a deep copy so it can be compared to the original for isDirty check to work
config: JSON.parse(JSON.stringify(initialFormValues)),
originalConfig: JSON.parse(JSON.stringify(initialFormValues)),
newVariableName: '',
+ newVariableErrorMessage: '',
+ newVariableTouched: false,
metaAPI: new MetaApi(getAPIClient()),
// Static data
@@ -226,18 +236,36 @@ export default {
},
},
methods: {
+ addVariableOnInput() {
+ this.newVariableTouched = true;
+ },
canAddVariable() {
+ // Don't show an error message if the field is blank e.g. after a user adds a variable name
+ // but still prevent variable addition
+ if (this.newVariableName === '') {
+ this.newVariableErrorMessage = '';
+ return false;
+ }
+
// Duplicate variable name
if (this.newVariableName in this.config.variables) {
- // TODO: add error message here
+ this.newVariableErrorMessage = 'Duplicate variable name found.';
return false;
}
// Whitespace only
if (!this.newVariableName.trim()) {
- // TODO: add error message here
+ this.newVariableErrorMessage = 'Must have at least one non-whitespace character.';
return false;
}
+
+ // Curly brace detection
+ if (this.newVariableName.match(/[{}]/)) {
+ this.newVariableErrorMessage =
+ 'Variable name cannot contain any of the following characters: {}';
+ return false;
+ }
+ this.newVariableErrorMessage = '';
return true;
},
handleAddVariable() {
@@ -444,25 +472,31 @@ export default {
{{ category.label }}
-