diff options
author | Vitalii Lysak <v.lysak@dunice.net> | 2022-08-17 15:27:13 +0300 |
---|---|---|
committer | Vitalii Lysak <v.lysak@dunice.net> | 2022-08-17 15:27:13 +0300 |
commit | f73b682a5cc44f2b4e60a4b22622b0c59a9b4a9a (patch) | |
tree | 48a407a81c5bbaa71682d5b19f0265105a14b423 | |
parent | 67dab376eb97139c5dba14b441c6d9cede62fb2e (diff) | |
download | webui-vue-f73b682a5cc44f2b4e60a4b22622b0c59a9b4a9a.tar.xz |
SILABMC-256: add validation and upd limits layout
-rw-r--r-- | src/assets/styles/bmc/_sila/_forms.scss | 5 | ||||
-rw-r--r-- | src/components/_sila/Global/Chart.vue | 105 | ||||
-rw-r--r-- | src/store/modules/HardwareStatus/MemoryStore.js | 22 | ||||
-rw-r--r-- | src/store/modules/HardwareStatus/MotherboardStore.js | 22 | ||||
-rw-r--r-- | src/store/modules/HardwareStatus/PowerSupplyStore.js | 38 | ||||
-rw-r--r-- | src/store/modules/HardwareStatus/ProcessorStore.js | 22 | ||||
-rw-r--r-- | src/views/_sila/Memory/Dynamic/MemoryTemp.vue | 113 | ||||
-rw-r--r-- | src/views/_sila/Motherboard/Dynamic/MotherboardTemp.vue | 78 | ||||
-rw-r--r-- | src/views/_sila/Power/Dynamic/PowerTemp.vue | 115 | ||||
-rw-r--r-- | src/views/_sila/Processors/Dynamic/CpuTemp.vue | 115 |
10 files changed, 408 insertions, 227 deletions
diff --git a/src/assets/styles/bmc/_sila/_forms.scss b/src/assets/styles/bmc/_sila/_forms.scss index e07c8da9..78866762 100644 --- a/src/assets/styles/bmc/_sila/_forms.scss +++ b/src/assets/styles/bmc/_sila/_forms.scss @@ -168,6 +168,11 @@ div:not(.search-global) > .form-group { .invalid-feedback { font-size: $form-label-font-size; line-height: $form-line-height; + &.absolute { + position: absolute; + z-index: 1; + margin-top: 0; + } } .custom-checkbox ::before { diff --git a/src/components/_sila/Global/Chart.vue b/src/components/_sila/Global/Chart.vue index 01e54071..f68cb140 100644 --- a/src/components/_sila/Global/Chart.vue +++ b/src/components/_sila/Global/Chart.vue @@ -53,7 +53,6 @@ export default { minRange: null, yMax: null, minTickInterval: null, - plotBands: null, }; }, computed: { @@ -183,55 +182,25 @@ export default { plotLines() { let plotLines = [ { - color: '#E11717', + color: '#F0AC0C', dashStyle: 'solid', value: this.warning, zIndex: '1000', width: 2, - label: { - text: this.$t('chart.thresholdWarning'), - align: 'right', - style: { - fontFamily: 'Inter, sans-serif', - fontSize: '12px', - fontStyle: 'normal', - fontWeight: '400', - lineHeight: '16px', - color: '#0C1C2999', - }, - }, }, ]; switch (this.type) { case 'fans': - plotLines.push({ - color: '#1A3E5B', - dashStyle: 'solid', - value: this.shutdown, - width: 2, - label: { - text: this.$t('chart.thresholdFailure'), - align: 'right', - style: { - fontFamily: 'Inter', - fontSize: '12px', - fontStyle: 'normal', - fontWeight: '400', - lineHeight: '16px', - color: '#0C1C2999', - }, - }, - }); - break; + case 'processors': case 'power': plotLines.push({ - color: '#1A3E5B', + color: '#E11717', dashStyle: 'solid', - value: this.shutdown, + value: this.critical, width: 2, label: { - text: this.$t('chart.thresholdWarning'), + text: this.$t('chart.thresholdFailure'), align: 'right', style: { fontFamily: 'Inter', @@ -326,6 +295,42 @@ export default { } return plotLines; }, + + plotBands() { + let plotBands = null; + + switch (this.type) { + case 'motherboard': + plotBands = [ + { + color: '#F0AC0C1A', + dashStyle: 'solid', + from: this.warning, + to: Infinity, + }, + ]; + break; + case 'memory': + case 'processors': + case 'power': + plotBands = [ + { + color: '#F0AC0C1A', + dashStyle: 'solid', + from: this.warning, + to: this.critical, + }, + { + color: '#FF41411A', + dashStyle: 'solid', + from: this.critical, + to: Infinity, + }, + ]; + break; + } + return plotBands; + }, }, async created() { @@ -344,39 +349,11 @@ export default { this.categories = this.setCategories(101, 'С°'); this.yMax = 100; this.minTickInterval = 25; - this.plotBands = [ - { - color: '#F0AC0C1A', - dashStyle: 'solid', - from: this.notNormal, - to: this.critical, - }, - { - color: '#FF41411A', - dashStyle: 'solid', - from: this.critical, - to: this.warning, - }, - ]; break; case 'processors': this.categories = this.setCategories(101, 'С°'); this.yMax = 100; this.minTickInterval = 25; - this.plotBands = [ - { - color: '#F0AC0C1A', - dashStyle: 'solid', - from: this.notNormal, - to: this.critical, - }, - { - color: '#FF41411A', - dashStyle: 'solid', - from: this.critical, - to: this.warning, - }, - ]; break; case 'motherboard': this.categories = this.setCategories(101, 'С°'); diff --git a/src/store/modules/HardwareStatus/MemoryStore.js b/src/store/modules/HardwareStatus/MemoryStore.js index dd6c9a51..ae30752d 100644 --- a/src/store/modules/HardwareStatus/MemoryStore.js +++ b/src/store/modules/HardwareStatus/MemoryStore.js @@ -71,19 +71,15 @@ const MemoryStore = { }, actions: { async patchLimits({ dispatch }, { warning, groups }) { - return Promise.all( - groups.map( - async (group) => - await api.patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { - Temperatures: [ - { - MemberId: group, - UpperThresholdNonCritical: warning, - }, - ], - }) - ) - ) + return await api + .patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { + Temperatures: groups.map((group) => { + return { + MemberId: group, + UpperThresholdNonCritical: warning, + }; + }), + }) .catch((error) => { console.log(error); throw new Error(i18n.t('pageMemory.toast.errorLimitUpdate')); diff --git a/src/store/modules/HardwareStatus/MotherboardStore.js b/src/store/modules/HardwareStatus/MotherboardStore.js index e565eaa0..0f54b529 100644 --- a/src/store/modules/HardwareStatus/MotherboardStore.js +++ b/src/store/modules/HardwareStatus/MotherboardStore.js @@ -26,19 +26,15 @@ const MotherboardStore = { }, actions: { async patchLimits({ dispatch }, { warning, groups }) { - return Promise.all( - groups.map( - async (group) => - await api.patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { - Temperatures: [ - { - MemberId: group, - UpperThresholdNonCritical: warning, - }, - ], - }) - ) - ) + return await api + .patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { + Temperatures: groups.map((group) => { + return { + MemberId: group, + UpperThresholdNonCritical: warning, + }; + }), + }) .catch((error) => { console.log(error); throw new Error(i18n.t('pageMotherboard.toast.errorLimitUpdate')); diff --git a/src/store/modules/HardwareStatus/PowerSupplyStore.js b/src/store/modules/HardwareStatus/PowerSupplyStore.js index 379bb3d1..567908f2 100644 --- a/src/store/modules/HardwareStatus/PowerSupplyStore.js +++ b/src/store/modules/HardwareStatus/PowerSupplyStore.js @@ -27,7 +27,7 @@ const PowerSupplyStore = { psuCurrent: (state) => state.psuCurrent, psuCurrentLastHour: (state) => state.psuCurrentLastHour, limitsTemp: (state) => state.limitsTemp, - limitsVol: (state) => state.limitsTemp, + limitsVol: (state) => state.limitsVol, }, mutations: { setPowerSupply: (state, data) => { @@ -93,24 +93,30 @@ const PowerSupplyStore = { state.limitsTemp = data; }, setLimitsVol: (state, data) => { - state.limitsTemp = data; + state.limitsVol = data; }, }, actions: { - async patchLimitsTemp({ dispatch }, { warning, groups }) { - return Promise.all( - groups.map( - async (group) => - await api.patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { - Temperatures: [ - { - MemberId: group, - UpperThresholdNonCritical: warning, - }, - ], - }) - ) - ) + async patchLimitsTemp({ dispatch }, { warning, critical, groups }) { + return await api + .patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { + Temperatures: groups.map((group) => { + return { + MemberId: group, + UpperThresholdNonCritical: warning, + }; + }), + }) + .then(async () => { + return await api.patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { + Temperatures: groups.map((group) => { + return { + MemberId: group, + UpperThresholdCritical: critical, + }; + }), + }); + }) .catch((error) => { console.log(error); throw new Error(i18n.t('pagePowerSup.toast.errorLimitUpdate')); diff --git a/src/store/modules/HardwareStatus/ProcessorStore.js b/src/store/modules/HardwareStatus/ProcessorStore.js index 9a09dff4..9dede45e 100644 --- a/src/store/modules/HardwareStatus/ProcessorStore.js +++ b/src/store/modules/HardwareStatus/ProcessorStore.js @@ -87,19 +87,15 @@ const ProcessorStore = { }, actions: { async patchLimitsTemp({ dispatch }, { warning, groups }) { - return Promise.all( - groups.map( - async (group) => - await api.patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { - Temperatures: [ - { - MemberId: group, - UpperThresholdNonCritical: warning, - }, - ], - }) - ) - ) + return await api + .patch('/redfish/v1/Chassis/SILA_Baseboard/Thermal', { + Temperatures: groups.map((group) => { + return { + MemberId: group, + UpperThresholdNonCritical: warning, + }; + }), + }) .catch((error) => { console.log(error); throw new Error(i18n.t('pageProcessor.toast.errorLimitUpdate')); diff --git a/src/views/_sila/Memory/Dynamic/MemoryTemp.vue b/src/views/_sila/Memory/Dynamic/MemoryTemp.vue index f69e797a..2bc9f06f 100644 --- a/src/views/_sila/Memory/Dynamic/MemoryTemp.vue +++ b/src/views/_sila/Memory/Dynamic/MemoryTemp.vue @@ -4,34 +4,61 @@ <img src="@/assets/images/_sila/collapsed/temperature.svg" /> {{ $t('pageMemory.temperature') }} </b-col> - <b-row class="align-items-end limit-container"> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-form-group :label="$t('pageMemory.labels.warning')"> - <b-form-input - v-model.number="warning" - type="number" - :min="0" - :max="critical" - ></b-form-input> - </b-form-group> - </b-col> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-form-group :label="$t('pageMemory.labels.critical')"> - <b-form-input - v-model.number="critical" - type="number" - :min="warning" - :max="100" + <b-form novalidate> + <b-row class="align-items-end limit-container"> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-form-group :label="$t('pageMemory.labels.warning')"> + <b-form-input + v-model.number="warning" + type="number" + :min="1" + :max="critical" + :state="getValidationState($v.warning)" + @blur="$v.warning.$touch()" + ></b-form-input> + <b-form-invalid-feedback class="absolute" role="alert"> + <div v-if="!$v.warning.between"> + {{ $t('global.form.invalidValue') }} + </div> + <div v-if="!$v.warning.required"> + {{ $t('global.form.fieldRequired') }} + </div> + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-form-group :label="$t('pageMemory.labels.critical')"> + <b-form-input + v-model.number="critical" + type="number" + :min="warning" + :max="100" + :state="getValidationState($v.critical)" + @blur="$v.critical.$touch()" + > + </b-form-input> + <b-form-invalid-feedback class="absolute" role="alert"> + <div v-if="!$v.critical.between"> + {{ $t('global.form.invalidValue') }} + </div> + <div v-if="!$v.critical.required"> + {{ $t('global.form.fieldRequired') }} + </div> + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-button + variant="primary" + style="height: 35px" + :disabled="loading" + @click="saveLimit" > - </b-form-input> - </b-form-group> - </b-col> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-button variant="primary" style="height: 35px" @click="saveLimit"> - {{ $t('global.action.save') }} - </b-button> - </b-col> - </b-row> + {{ $t('global.action.save') }} + </b-button> + </b-col> + </b-row> + </b-form> <chart type="memory" :colors="colors" @@ -80,15 +107,25 @@ import Chart from '@/components/_sila/Global/Chart'; import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin'; -import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin'; +import LoadingBarMixin, { + loading, +} from '@/components/_sila/Mixins/LoadingBarMixin'; import TableFilterMixin from '@/components/_sila/Mixins/TableFilterMixin'; import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin'; +import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js'; import { getGroups, getItems } from '@/utilities/_sila/metricProperties'; +import { between, required } from 'vuelidate/lib/validators'; export default { components: { Chart }, - mixins: [DataFormatterMixin, LoadingBarMixin, TableFilterMixin, BVToastMixin], + mixins: [ + DataFormatterMixin, + LoadingBarMixin, + TableFilterMixin, + BVToastMixin, + VuelidateMixin, + ], props: { timeScale: { type: String, @@ -97,6 +134,7 @@ export default { }, data() { return { + loading, warning: null, critical: null, isBusy: true, @@ -133,6 +171,19 @@ export default { }; }, + validations() { + return { + warning: { + required, + between: between(1, this.critical), + }, + critical: { + required, + between: between(this.warning, 100), + }, + }; + }, + computed: { groups() { return getGroups(this.filteredSensors); @@ -193,10 +244,14 @@ export default { methods: { saveLimit() { + this.$v.$touch(); + if (this.$v.$invalid) return; + this.startLoader(); this.$store .dispatch('memory/patchLimits', { warning: this.warning, + critical: this.critical, groups: this.groups, }) .catch(({ message }) => this.errorToast(message)) diff --git a/src/views/_sila/Motherboard/Dynamic/MotherboardTemp.vue b/src/views/_sila/Motherboard/Dynamic/MotherboardTemp.vue index 5fac0a89..fc962f11 100644 --- a/src/views/_sila/Motherboard/Dynamic/MotherboardTemp.vue +++ b/src/views/_sila/Motherboard/Dynamic/MotherboardTemp.vue @@ -5,23 +5,40 @@ {{ $t('pageMotherboard.temperature') }} </b-col> - <b-row class="align-items-end limit-container"> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-form-group :label="$t('pageMotherboard.labels.warning')"> - <b-form-input - v-model.number="warning" - type="number" - :min="0" - :max="100" - ></b-form-input> - </b-form-group> - </b-col> - <b-col xs="12" sm="6" class="pt-4"> - <b-button variant="primary" style="height: 35px" @click="saveLimit"> - {{ $t('global.action.save') }} - </b-button> - </b-col> - </b-row> + <b-form novalidate> + <b-row class="align-items-end limit-container"> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-form-group :label="$t('pageMotherboard.labels.warning')"> + <b-form-input + v-model.number="warning" + type="number" + :min="1" + :max="100" + :state="getValidationState($v.warning)" + @blur="$v.warning.$touch()" + ></b-form-input> + <b-form-invalid-feedback class="absolute" role="alert"> + <div v-if="!$v.warning.between"> + {{ $t('global.form.invalidValue') }} + </div> + <div v-if="!$v.warning.required"> + {{ $t('global.form.fieldRequired') }} + </div> + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col xs="12" sm="6" class="pt-4"> + <b-button + variant="primary" + style="height: 35px" + :disabled="loading" + @click="saveLimit" + > + {{ $t('global.action.save') }} + </b-button> + </b-col> + </b-row> + </b-form> <chart type="motherboard" :time-scale="timeScale" @@ -69,15 +86,25 @@ import Chart from '@/components/_sila/Global/Chart'; import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin'; -import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin'; +import LoadingBarMixin, { + loading, +} from '@/components/_sila/Mixins/LoadingBarMixin'; import TableFilterMixin from '@/components/_sila/Mixins/TableFilterMixin'; import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin'; +import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js'; import { getItems, getGroups } from '@/utilities/_sila/metricProperties'; +import { between, required } from 'vuelidate/lib/validators'; export default { components: { Chart }, - mixins: [DataFormatterMixin, LoadingBarMixin, TableFilterMixin, BVToastMixin], + mixins: [ + DataFormatterMixin, + LoadingBarMixin, + TableFilterMixin, + BVToastMixin, + VuelidateMixin, + ], props: { timeScale: { type: String, @@ -86,6 +113,7 @@ export default { }, data() { return { + loading, warning: null, isBusy: true, fields: [ @@ -121,6 +149,15 @@ export default { }; }, + validations() { + return { + warning: { + required, + between: between(1, 100), + }, + }; + }, + computed: { groups() { return getGroups(this.filteredSensors); @@ -174,6 +211,9 @@ export default { methods: { saveLimit() { + this.$v.$touch(); + if (this.$v.$invalid) return; + this.startLoader(); this.$store .dispatch('motherboard/patchLimits', { diff --git a/src/views/_sila/Power/Dynamic/PowerTemp.vue b/src/views/_sila/Power/Dynamic/PowerTemp.vue index 1d18e8b1..18c2cc53 100644 --- a/src/views/_sila/Power/Dynamic/PowerTemp.vue +++ b/src/views/_sila/Power/Dynamic/PowerTemp.vue @@ -8,35 +8,62 @@ <img src="@/assets/images/_sila/collapsed/temperature.svg" /> </template> <page-section> - <b-row class="align-items-end limit-container"> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-form-group :label="$t('pagePowerSup.labels.warning')"> - <b-form-input - v-model.number="warning" - type="number" - :min="0" - :max="100" + <b-form novalidate> + <b-row class="align-items-end limit-container"> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-form-group :label="$t('pagePowerSup.labels.warning')"> + <b-form-input + v-model.number="warning" + type="number" + :min="1" + :max="critical" + :state="getValidationState($v.warning)" + @blur="$v.warning.$touch()" + > + </b-form-input> + <b-form-invalid-feedback class="absolute" role="alert"> + <div v-if="!$v.warning.between"> + {{ $t('global.form.invalidValue') }} + </div> + <div v-if="!$v.warning.required"> + {{ $t('global.form.fieldRequired') }} + </div> + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-form-group :label="$t('pagePowerSup.labels.critical')"> + <b-form-input + v-model.number="critical" + type="number" + :min="warning" + :max="100" + :state="getValidationState($v.critical)" + @blur="$v.critical.$touch()" + > + </b-form-input> + <b-form-invalid-feedback class="absolute" role="alert"> + <div v-if="!$v.critical.between"> + {{ $t('global.form.invalidValue') }} + </div> + <div v-if="!$v.critical.required"> + {{ $t('global.form.fieldRequired') }} + </div> + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-button + variant="primary" + style="height: 35px" + :disabled="loading" + @click="saveLimit" > - </b-form-input> - </b-form-group> - </b-col> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-form-group :label="$t('pagePowerSup.labels.critical')"> - <b-form-input - v-model.number="critical" - type="number" - :min="0" - :max="100" - > - </b-form-input> - </b-form-group> - </b-col> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-button variant="primary" style="height: 35px" @click="saveLimit"> - {{ $t('global.action.save') }} - </b-button> - </b-col> - </b-row> + {{ $t('global.action.save') }} + </b-button> + </b-col> + </b-row> + </b-form> <chart type="processors" :time-scale="timeScale" @@ -87,16 +114,26 @@ import Chart from '@/components/_sila/Global/Chart'; import PageSection from '@/components/Global/PageSection'; import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin'; +import LoadingBarMixin, { + loading, +} from '@/components/_sila/Mixins/LoadingBarMixin'; import TableFilterMixin from '@/components/_sila/Mixins/TableFilterMixin'; -import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin'; import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin'; +import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js'; import Collapse from '@/components/_sila/Global/Collapse'; import { getGroups, getItems } from '@/utilities/_sila/metricProperties'; +import { between, required } from 'vuelidate/lib/validators'; export default { components: { PageSection, Chart, Collapse }, - mixins: [DataFormatterMixin, TableFilterMixin, LoadingBarMixin, BVToastMixin], + mixins: [ + DataFormatterMixin, + TableFilterMixin, + LoadingBarMixin, + BVToastMixin, + VuelidateMixin, + ], props: { timeScale: { type: String, @@ -105,6 +142,7 @@ export default { }, data() { return { + loading, warning: null, critical: null, isBusy: true, @@ -142,6 +180,19 @@ export default { }; }, + validations() { + return { + warning: { + required, + between: between(1, this.critical), + }, + critical: { + required, + between: between(this.warning, 100), + }, + }; + }, + computed: { groups() { return getGroups(this.allSensors); @@ -196,10 +247,14 @@ export default { }, methods: { saveLimit() { + this.$v.$touch(); + if (this.$v.$invalid) return; + this.startLoader(); this.$store .dispatch('powerSupply/patchLimitsTemp', { warning: this.warning, + critical: this.critical, groups: this.groups, }) .catch(({ message }) => this.errorToast(message)) diff --git a/src/views/_sila/Processors/Dynamic/CpuTemp.vue b/src/views/_sila/Processors/Dynamic/CpuTemp.vue index e3185aaa..0a630367 100644 --- a/src/views/_sila/Processors/Dynamic/CpuTemp.vue +++ b/src/views/_sila/Processors/Dynamic/CpuTemp.vue @@ -8,35 +8,62 @@ <img src="@/assets/images/_sila/collapsed/temperature.svg" /> </template> <page-section> - <b-row class="align-items-end limit-container"> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-form-group :label="$t('pageProcessors.labels.warning')"> - <b-form-input - v-model.number="warning" - type="number" - :min="0" - :max="100" + <b-form novalidate> + <b-row class="align-items-end limit-container"> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-form-group :label="$t('pageProcessors.labels.warning')"> + <b-form-input + v-model.number="warning" + type="number" + :min="1" + :max="critical" + :state="getValidationState($v.warning)" + @blur="$v.warning.$touch()" + > + </b-form-input> + <b-form-invalid-feedback class="absolute" role="alert"> + <div v-if="!$v.warning.between"> + {{ $t('global.form.invalidValue') }} + </div> + <div v-if="!$v.warning.required"> + {{ $t('global.form.fieldRequired') }} + </div> + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-form-group :label="$t('pageProcessors.labels.critical')"> + <b-form-input + v-model.number="critical" + type="number" + :min="warning" + :max="100" + :state="getValidationState($v.critical)" + @blur="$v.critical.$touch()" + > + </b-form-input> + <b-form-invalid-feedback class="absolute" role="alert"> + <div v-if="!$v.critical.between"> + {{ $t('global.form.invalidValue') }} + </div> + <div v-if="!$v.critical.required"> + {{ $t('global.form.fieldRequired') }} + </div> + </b-form-invalid-feedback> + </b-form-group> + </b-col> + <b-col xs="12" sm="6" xl="3" class="pt-4"> + <b-button + variant="primary" + style="height: 35px" + :disabled="loading" + @click="saveLimit" > - </b-form-input> - </b-form-group> - </b-col> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-form-group :label="$t('pageProcessors.labels.critical')"> - <b-form-input - v-model.number="critical" - type="number" - :min="0" - :max="100" - > - </b-form-input> - </b-form-group> - </b-col> - <b-col xs="12" sm="6" xl="3" class="pt-4"> - <b-button variant="primary" style="height: 35px" @click="saveLimit"> - {{ $t('global.action.save') }} - </b-button> - </b-col> - </b-row> + {{ $t('global.action.save') }} + </b-button> + </b-col> + </b-row> + </b-form> <chart type="processors" :time-scale="timeScale" @@ -87,16 +114,26 @@ import Chart from '@/components/_sila/Global/Chart'; import PageSection from '@/components/Global/PageSection'; import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin'; -import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin'; +import LoadingBarMixin, { + loading, +} from '@/components/_sila/Mixins/LoadingBarMixin'; import TableFilterMixin from '@/components/_sila/Mixins/TableFilterMixin'; import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin'; +import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js'; import Collapse from '@/components/_sila/Global/Collapse'; import { getGroups, getItems } from '@/utilities/_sila/metricProperties'; +import { between, required } from 'vuelidate/lib/validators'; export default { components: { PageSection, Chart, Collapse }, - mixins: [DataFormatterMixin, LoadingBarMixin, TableFilterMixin, BVToastMixin], + mixins: [ + DataFormatterMixin, + LoadingBarMixin, + TableFilterMixin, + BVToastMixin, + VuelidateMixin, + ], props: { timeScale: { type: String, @@ -105,6 +142,7 @@ export default { }, data() { return { + loading, warning: null, critical: null, isBusy: true, @@ -142,6 +180,19 @@ export default { }; }, + validations() { + return { + warning: { + required, + between: between(1, this.critical), + }, + critical: { + required, + between: between(this.warning, 100), + }, + }; + }, + computed: { groups() { return getGroups(this.filteredSensors); @@ -201,10 +252,14 @@ export default { }, methods: { saveLimit() { + this.$v.$touch(); + if (this.$v.$invalid) return; + this.startLoader(); this.$store .dispatch('processors/patchLimitsTemp', { warning: this.warning, + critical: this.critical, groups: this.groups, }) .catch(({ message }) => this.errorToast(message)) |