From 98f8bc494a999126a801eb7980b74715f9f63c39 Mon Sep 17 00:00:00 2001 From: David Tsay Date: Mon, 21 Oct 2024 10:42:05 -0700 Subject: [PATCH] fix input entry and validation --- .../timeConductor/ConductorComponent.vue | 9 +- src/plugins/timeConductor/TimePopupFixed.vue | 161 ++++++++---------- .../independent/IndependentTimeConductor.vue | 9 +- 3 files changed, 89 insertions(+), 90 deletions(-) diff --git a/src/plugins/timeConductor/ConductorComponent.vue b/src/plugins/timeConductor/ConductorComponent.vue index 3285a41a6d..454e13ef30 100644 --- a/src/plugins/timeConductor/ConductorComponent.vue +++ b/src/plugins/timeConductor/ConductorComponent.vue @@ -102,14 +102,19 @@ export default { setup(props) { const openmct = inject('openmct'); const { timeContext } = useTimeContext(openmct); - const { timeSystemFormatter, timeSystemDurationFormatter, isTimeSystemUTCBased } = - useTimeSystem(openmct, timeContext); + const { + timeSystemKey, + timeSystemFormatter, + timeSystemDurationFormatter, + isTimeSystemUTCBased + } = useTimeSystem(openmct, timeContext); const { timeMode, isFixedTimeMode, isRealTimeMode, getAllModeMetadata, getModeMetadata } = useTimeMode(openmct, timeContext); const { bounds, isTick } = useTimeBounds(openmct, timeContext); const { clock, getAllClockMetadata, getClockMetadata } = useClock(openmct, timeContext); const { offsets } = useClockOffsets(openmct, timeContext); + provide('timeSystemKey', timeSystemKey); provide('timeSystemFormatter', timeSystemFormatter); provide('timeSystemDurationFormatter', timeSystemDurationFormatter); provide('isTimeSystemUTCBased', isTimeSystemUTCBased); diff --git a/src/plugins/timeConductor/TimePopupFixed.vue b/src/plugins/timeConductor/TimePopupFixed.vue index 1d3fb3edf1..153cff256b 100644 --- a/src/plugins/timeConductor/TimePopupFixed.vue +++ b/src/plugins/timeConductor/TimePopupFixed.vue @@ -28,14 +28,15 @@
@@ -43,21 +44,22 @@
@@ -77,24 +79,39 @@ export default { 'openmct', 'isTimeSystemUTCBased', 'timeContext', + 'timeSystemKey', 'timeSystemFormatter', 'timeSystemDurationFormatter', 'bounds' ], - emits: ['update', 'dismiss'], + emits: ['dismiss'], data() { return { formattedBounds: {}, - isDisabled: false + inputValidityMap: { + start: { valid: true }, + end: { valid: true } + }, + logicalValidityMap: { + limit: { valid: true }, + bounds: { valid: true } + } }; }, computed: { - + hasInputValidityError() { + return Object.values(this.inputValidityMap).some((isValid) => !isValid.valid); + }, + hasLogicalValidationErrors() { + return Object.values(this.logicalValidityMap).some((isValid) => !isValid.valid); + }, + isValid() { + return !this.hasInputValidityError && !this.hasLogicalValidationErrors; + } }, watch: { bounds: { handler() { - console.log(this.bounds); this.setViewFromBounds(); } } @@ -106,15 +123,6 @@ export default { this.clearAllValidation(); }, methods: { - clearAllValidation() { - [this.$refs.startTime, this.$refs.endTime].forEach(this.clearValidationForInput); - }, - clearValidationForInput(input) { - if (input) { - input.setCustomValidity(''); - input.title = ''; - } - }, setViewFromBounds() { const start = this.timeSystemFormatter.format(this.bounds.start); const end = this.timeSystemFormatter.format(this.bounds.end); @@ -140,96 +148,77 @@ export default { return false; } }, - handleFormSubmission(shouldDismiss) { - this.validateAllBounds('startDate'); - this.validateAllBounds('endDate'); + clearAllValidation() { + Object.keys(this.inputValidityMap).forEach(this.clearValidation); + }, + clearValidation(refName) { + const input = this.getInput(refName); - if (!this.isDisabled) { + input.setCustomValidity(''); + input.title = ''; + }, + handleFormSubmission(shouldDismiss) { + this.validateLimit(); + this.reportValidity('limit'); + this.validateBounds(); + this.reportValidity('bounds'); + + if (this.isValid) { this.setBoundsFromView(shouldDismiss); } }, - validateAllBounds(ref) { - this.isDisabled = false; + validateInput(refName) { + this.clearAllValidation(); - if (!this.areBoundsFormatsValid()) { - this.isDisabled = true; - return false; - } + const validationResult = this.timeFormatter.validate(this.formattedBounds[refName]) + ? { valid: true } + : { valid: false, message: `Invalid Time` }; - let validationResult = { valid: true }; - const currentInput = this.$refs[ref]; - - return [this.$refs.startTime, this.$refs.endTime].every((input) => { - const start = this.timeSystemFormatter.parse(this.formattedBounds.start); - const end = this.timeSystemFormatter.parse(this.formattedBounds.end); - - const bounds = { - start, - end - }; - - //TODO: Do we need limits here? We have conductor limits disabled right now - // const limit = this.getBoundsLimit(); - const limit = false; - - if (this.isTimeSystemUTCBased && limit && bounds.end - bounds.start > limit) { - if (input === currentInput) { - validationResult = { - valid: false, - message: 'Start and end difference exceeds allowable limit' - }; - } - } else { - if (input === currentInput) { - validationResult = this.timeContext.validateBounds(bounds); - } - } - - return this.handleValidationResults(input, validationResult); - }); + this.inputValidityMap[refName] = validationResult; }, - areBoundsFormatsValid() { - let validationResult = { - valid: true + validateBounds() { + const bounds = { + start: this.timeSystemFormatter.parse(this.formattedBounds.start), + end: this.timeSystemFormatter.parse(this.formattedBounds.end) }; - return [this.$refs.startTime, this.$refs.endTime].every((input) => { - const formattedBounds = - input === this.$refs.startTime - ? this.formattedBounds.start - : this.formattedBounds.end; - if (!this.timeSystemFormatter.validate(formattedBounds)) { - validationResult = { - valid: false, - message: 'Invalid date' - }; - } - - return this.handleValidationResults(input, validationResult); - }); + this.logicalValidityMap.bounds = this.timeContext.validateBounds(bounds); }, - getBoundsLimit() { - const configuration = this.configuration.menuOptions - .filter((option) => option.timeSystem === this.timeSystem.key) - .find((option) => option.limit); + validateLimit(bounds) { + const limit = this.configuration?.menuOptions + ?.filter((option) => option.timeSystem === this.timeSystemKey) + ?.find((option) => option.limit)?.limit; - const limit = configuration ? configuration.limit : undefined; - - return limit; + if (this.isTimeSystemUTCBased && limit && bounds.end - bounds.start > limit) { + this.logicalValidityMap.limit = { + valid: false, + message: `Start and end difference exceeds allowable limit of ${limit}` + }; + } else { + this.logicalValidityMap.limit = { valid: true }; + } }, - handleValidationResults(input, validationResult) { + reportValidity(refName) { + const input = this.getInput(refName); + const validationResult = this.inputValidityMap[refName] ?? this.logicalValidityMap[refName]; + if (validationResult.valid !== true) { input.setCustomValidity(validationResult.message); input.title = validationResult.message; - this.isDisabled = true; + this.hasLogicalValidationErrors = true; } else { input.setCustomValidity(''); input.title = ''; } this.$refs.fixedDeltaInput.reportValidity(); + }, + getInput(refName) { + if (Object.keys(this.inputValidityMap).includes(refName)) { + return this.$refs[refName]; + } - return validationResult.valid; + return this.$refs.start; }, hide($event) { if ($event.target.className.indexOf('c-button icon-x') > -1) { diff --git a/src/plugins/timeConductor/independent/IndependentTimeConductor.vue b/src/plugins/timeConductor/independent/IndependentTimeConductor.vue index 9e36fee597..7a43e2cf40 100644 --- a/src/plugins/timeConductor/independent/IndependentTimeConductor.vue +++ b/src/plugins/timeConductor/independent/IndependentTimeConductor.vue @@ -107,8 +107,12 @@ export default { const openmct = inject('openmct'); const { timeContext } = useTimeContext(openmct, () => props.objectPath); - const { timeSystemFormatter, timeSystemDurationFormatter, isTimeSystemUTCBased } = - useTimeSystem(openmct, timeContext); + const { + timeSystemKey, + timeSystemFormatter, + timeSystemDurationFormatter, + isTimeSystemUTCBased + } = useTimeSystem(openmct, timeContext); const { timeMode, isFixedTimeMode, isRealTimeMode, getAllModeMetadata, getModeMetadata } = useTimeMode(openmct, timeContext); const { bounds, isTick } = useTimeBounds(openmct, timeContext); @@ -116,6 +120,7 @@ export default { const { offsets } = useClockOffsets(openmct, timeContext); provide('timeContext', timeContext); + provide('timeSystemKey', timeSystemKey); provide('timeSystemFormatter', timeSystemFormatter); provide('timeSystemDurationFormatter', timeSystemDurationFormatter); provide('isTimeSystemUTCBased', isTimeSystemUTCBased);