diff --git a/e2e/appActions.js b/e2e/appActions.js index 6cd901fb4d..99ee63cdb5 100644 --- a/e2e/appActions.js +++ b/e2e/appActions.js @@ -510,6 +510,10 @@ async function setTimeConductorBounds(page, { submitChanges = true, ...bounds }) // Open the time conductor popup await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click(); + // FIXME: https://github.com/nasa/openmct/pull/7818 + // eslint-disable-next-line playwright/no-wait-for-timeout + await page.waitForTimeout(500); + if (startDate) { await page.getByLabel('Start date').fill(startDate); } diff --git a/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js b/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js index 9aea26f395..e98e694b00 100644 --- a/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js +++ b/e2e/tests/functional/plugins/telemetryTable/telemetryTable.e2e.spec.js @@ -117,7 +117,8 @@ test.describe('Telemetry Table', () => { endTimeStamp.setUTCMinutes(endTimeStamp.getUTCMinutes() - 5); const endDate = endTimeStamp.toISOString().split('T')[0]; - const endTime = endTimeStamp.toISOString().split('T')[1]; + const milliseconds = endTimeStamp.getMilliseconds(); + const endTime = endTimeStamp.toISOString().split('T')[1].replace(`.${milliseconds}Z`, ''); await setTimeConductorBounds(page, { endDate, endTime }); diff --git a/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js b/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js index 79346f382e..9fe41e588f 100644 --- a/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js +++ b/e2e/tests/functional/plugins/timeConductor/timeConductor.e2e.spec.js @@ -24,65 +24,210 @@ import { setEndOffset, setFixedTimeMode, setRealTimeMode, - setStartOffset, - setTimeConductorBounds + setStartOffset } from '../../../../appActions.js'; import { expect, test } from '../../../../pluginFixtures.js'; test.describe('Time conductor operations', () => { - test('validate start time does not exceed end time', async ({ page }) => { + const DAY = '2024-01-01'; + const DAY_AFTER = '2024-01-02'; + const ONE_O_CLOCK = '01:00:00'; + const TWO_O_CLOCK = '02:00:00'; + + test.beforeEach(async ({ page }) => { // Go to baseURL await page.goto('./', { waitUntil: 'domcontentloaded' }); - const year = new Date().getFullYear(); + }); - // Set initial valid time bounds - const startDate = `${year}-01-01`; - const startTime = '01:00:00'; - const endDate = `${year}-01-01`; - const endTime = '02:00:00'; - await setTimeConductorBounds(page, { startDate, startTime, endDate, endTime }); + test('validate date and time inputs are validated on input event', async ({ page }) => { + const submitButtonLocator = page.getByLabel('Submit time bounds'); // Open the time conductor popup await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click(); - // Test invalid start date - const invalidStartDate = `${year}-01-02`; - await page.getByLabel('Start date').fill(invalidStartDate); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('Start date').fill(startDate); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); + await test.step('invalid start date disables submit button', async () => { + const initialStartDate = await page.getByLabel('Start date').inputValue(); + const invalidStartDate = `${initialStartDate.substring(0, 5)}${initialStartDate.substring(6)}`; - // Test invalid end date - const invalidEndDate = `${year - 1}-12-31`; - await page.getByLabel('End date').fill(invalidEndDate); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('End date').fill(endDate); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); + await page.getByLabel('Start date').fill(invalidStartDate); + await expect(submitButtonLocator).toBeDisabled(); + await page.getByLabel('Start date').fill(initialStartDate); + await expect(submitButtonLocator).toBeEnabled(); + }); - // Test invalid start time - const invalidStartTime = '42:00:00'; - await page.getByLabel('Start time').fill(invalidStartTime); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('Start time').fill(startTime); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); + await test.step('invalid start time disables submit button', async () => { + const initialStartTime = await page.getByLabel('Start time').inputValue(); + const invalidStartTime = `${initialStartTime.substring(0, 5)}${initialStartTime.substring(6)}`; - // Test invalid end time - const invalidEndTime = '43:00:00'; - await page.getByLabel('End time').fill(invalidEndTime); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('End time').fill(endTime); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); + await page.getByLabel('Start time').fill(invalidStartTime); + await expect(submitButtonLocator).toBeDisabled(); + await page.getByLabel('Start time').fill(initialStartTime); + await expect(submitButtonLocator).toBeEnabled(); + }); - // Submit valid time bounds + await test.step('disable/enable submit button also works with multiple invalid inputs', async () => { + const initialEndDate = await page.getByLabel('End date').inputValue(); + const invalidEndDate = `${initialEndDate.substring(0, 5)}${initialEndDate.substring(6)}`; + const initialStartTime = await page.getByLabel('Start time').inputValue(); + const invalidStartTime = `${initialStartTime.substring(0, 5)}${initialStartTime.substring(6)}`; + + await page.getByLabel('Start time').fill(invalidStartTime); + await expect(submitButtonLocator).toBeDisabled(); + await page.getByLabel('End date').fill(invalidEndDate); + await expect(submitButtonLocator).toBeDisabled(); + await page.getByLabel('End date').fill(initialEndDate); + await expect(submitButtonLocator).toBeDisabled(); + await page.getByLabel('Start time').fill(initialStartTime); + await expect(submitButtonLocator).toBeEnabled(); + }); + }); + + test('validate date and time inputs validation is reported on change event', async ({ page }) => { + // Open the time conductor popup + await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click(); + + await test.step('invalid start date is reported on change event, not on input event', async () => { + const initialStartDate = await page.getByLabel('Start date').inputValue(); + const invalidStartDate = `${initialStartDate.substring(0, 5)}${initialStartDate.substring(6)}`; + + await page.getByLabel('Start date').fill(invalidStartDate); + await expect(page.getByLabel('Start date')).not.toHaveAttribute('title', 'Invalid Date'); + await page.getByLabel('Start date').press('Tab'); + await expect(page.getByLabel('Start date')).toHaveAttribute('title', 'Invalid Date'); + await page.getByLabel('Start date').fill(initialStartDate); + await expect(page.getByLabel('Start date')).not.toHaveAttribute('title', 'Invalid Date'); + }); + + await test.step('invalid start time is reported on change event, not on input event', async () => { + const initialStartTime = await page.getByLabel('Start time').inputValue(); + const invalidStartTime = `${initialStartTime.substring(0, 5)}${initialStartTime.substring(6)}`; + + await page.getByLabel('Start time').fill(invalidStartTime); + await expect(page.getByLabel('Start time')).not.toHaveAttribute('title', 'Invalid Time'); + await page.getByLabel('Start time').press('Tab'); + await expect(page.getByLabel('Start time')).toHaveAttribute('title', 'Invalid Time'); + await page.getByLabel('Start time').fill(initialStartTime); + await expect(page.getByLabel('Start time')).not.toHaveAttribute('title', 'Invalid Time'); + }); + + await test.step('invalid end date is reported on change event, not on input event', async () => { + const initialEndDate = await page.getByLabel('End date').inputValue(); + const invalidEndDate = `${initialEndDate.substring(0, 5)}${initialEndDate.substring(6)}`; + + await page.getByLabel('End date').fill(invalidEndDate); + await expect(page.getByLabel('End date')).not.toHaveAttribute('title', 'Invalid Date'); + await page.getByLabel('End date').press('Tab'); + await expect(page.getByLabel('End date')).toHaveAttribute('title', 'Invalid Date'); + await page.getByLabel('End date').fill(initialEndDate); + await expect(page.getByLabel('End date')).not.toHaveAttribute('title', 'Invalid Date'); + }); + + await test.step('invalid end time is reported on change event, not on input event', async () => { + const initialEndTime = await page.getByLabel('End time').inputValue(); + const invalidEndTime = `${initialEndTime.substring(0, 5)}${initialEndTime.substring(6)}`; + + await page.getByLabel('End time').fill(invalidEndTime); + await expect(page.getByLabel('End time')).not.toHaveAttribute('title', 'Invalid Time'); + await page.getByLabel('End time').press('Tab'); + await expect(page.getByLabel('End time')).toHaveAttribute('title', 'Invalid Time'); + await page.getByLabel('End time').fill(initialEndTime); + await expect(page.getByLabel('End time')).not.toHaveAttribute('title', 'Invalid Time'); + }); + }); + + test('validate start time does not exceed end time on submit', async ({ page }) => { + // Open the time conductor popup + await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click(); + + // FIXME: https://github.com/nasa/openmct/pull/7818 + // eslint-disable-next-line playwright/no-wait-for-timeout + await page.waitForTimeout(500); + + await page.getByLabel('Start date').fill(DAY); + await page.getByLabel('Start time').fill(TWO_O_CLOCK); + await page.getByLabel('End date').fill(DAY); + await page.getByLabel('End time').fill(ONE_O_CLOCK); await page.getByLabel('Submit time bounds').click(); - // Verify the submitted time bounds - await expect(page.getByLabel('Start bounds')).toHaveText( - new RegExp(`${startDate} ${startTime}.000Z`) + await expect(page.getByLabel('Start date')).toHaveAttribute( + 'title', + 'Specified start date exceeds end bound' ); - await expect(page.getByLabel('End bounds')).toHaveText( - new RegExp(`${endDate} ${endTime}.000Z`) + await expect(page.getByLabel('Start bounds')).not.toHaveText(`${DAY} ${TWO_O_CLOCK}.000Z`); + await expect(page.getByLabel('End bounds')).not.toHaveText(`${DAY} ${ONE_O_CLOCK}.000Z`); + + await page.getByLabel('Start date').fill(DAY); + await page.getByLabel('Start time').fill(ONE_O_CLOCK); + await page.getByLabel('End date').fill(DAY); + await page.getByLabel('End time').fill(TWO_O_CLOCK); + await page.getByLabel('Submit time bounds').click(); + + await expect(page.getByLabel('Start bounds')).toHaveText(`${DAY} ${ONE_O_CLOCK}.000Z`); + await expect(page.getByLabel('End bounds')).toHaveText(`${DAY} ${TWO_O_CLOCK}.000Z`); + }); + + test('validate start datetime does not exceed end datetime on submit', async ({ page }) => { + // Open the time conductor popup + await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click(); + + // FIXME: https://github.com/nasa/openmct/pull/7818 + // eslint-disable-next-line playwright/no-wait-for-timeout + await page.waitForTimeout(500); + + await page.getByLabel('Start date').fill(DAY_AFTER); + await page.getByLabel('Start time').fill(ONE_O_CLOCK); + await page.getByLabel('End date').fill(DAY); + await page.getByLabel('End time').fill(ONE_O_CLOCK); + await page.getByLabel('Submit time bounds').click(); + + await expect(page.getByLabel('Start date')).toHaveAttribute( + 'title', + 'Specified start date exceeds end bound' ); + await expect(page.getByLabel('Start bounds')).not.toHaveText( + `${DAY_AFTER} ${ONE_O_CLOCK}.000Z` + ); + await expect(page.getByLabel('End bounds')).not.toHaveText(`${DAY} ${ONE_O_CLOCK}.000Z`); + + await page.getByLabel('Start date').fill(DAY); + await page.getByLabel('Start time').fill(ONE_O_CLOCK); + await page.getByLabel('End date').fill(DAY_AFTER); + await page.getByLabel('End time').fill(ONE_O_CLOCK); + await page.getByLabel('Submit time bounds').click(); + + await expect(page.getByLabel('Start bounds')).toHaveText(`${DAY} ${ONE_O_CLOCK}.000Z`); + await expect(page.getByLabel('End bounds')).toHaveText(`${DAY_AFTER} ${ONE_O_CLOCK}.000Z`); + }); + + test('cancelling form does not set bounds', async ({ page }) => { + test.info().annotations.push({ + type: 'issue', + description: 'https://github.com/nasa/openmct/issues/7791' + }); + + // Open the time conductor popup + await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click(); + + await page.getByLabel('Start date').fill(DAY); + await page.getByLabel('Start time').fill(ONE_O_CLOCK); + await page.getByLabel('End date').fill(DAY_AFTER); + await page.getByLabel('End time').fill(ONE_O_CLOCK); + await page.getByLabel('Discard changes and close time popup').click(); + + await expect(page.getByLabel('Start bounds')).not.toHaveText(`${DAY} ${ONE_O_CLOCK}.000Z`); + await expect(page.getByLabel('End bounds')).not.toHaveText(`${DAY_AFTER} ${ONE_O_CLOCK}.000Z`); + + // Open the time conductor popup + await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click(); + + await page.getByLabel('Start date').fill(DAY); + await page.getByLabel('Start time').fill(ONE_O_CLOCK); + await page.getByLabel('End date').fill(DAY_AFTER); + await page.getByLabel('End time').fill(ONE_O_CLOCK); + await page.getByLabel('Submit time bounds').click(); + + await expect(page.getByLabel('Start bounds')).toHaveText(`${DAY} ${ONE_O_CLOCK}.000Z`); + await expect(page.getByLabel('End bounds')).toHaveText(`${DAY_AFTER} ${ONE_O_CLOCK}.000Z`); }); }); @@ -131,77 +276,6 @@ test.describe('Global Time Conductor', () => { await expect(page.getByLabel('End offset: 01:30:31')).toBeVisible(); }); - test('Input field validation: fixed time mode', async ({ page }) => { - test.info().annotations.push({ - type: 'issue', - description: 'https://github.com/nasa/openmct/issues/7791' - }); - // Switch to fixed time mode - await setFixedTimeMode(page); - - // Define valid time bounds for testing - const validBounds = { - startDate: '2024-04-20', - startTime: '00:04:20', - endDate: '2024-04-20', - endTime: '16:04:20' - }; - // Set valid time conductor bounds ✌️ - await setTimeConductorBounds(page, validBounds); - - // Verify that the time bounds are set correctly - await expect(page.getByLabel(`Start bounds: 2024-04-20 00:04:20.000Z`)).toBeVisible(); - await expect(page.getByLabel(`End bounds: 2024-04-20 16:04:20.000Z`)).toBeVisible(); - - // Open the Time Conductor Mode popup - await page.getByLabel('Time Conductor Mode').click(); - - // Test invalid start date - const invalidStartDate = '2024-04-21'; - await page.getByLabel('Start date').fill(invalidStartDate); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('Start date').fill(validBounds.startDate); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); - - // Test invalid end date - const invalidEndDate = '2024-04-19'; - await page.getByLabel('End date').fill(invalidEndDate); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('End date').fill(validBounds.endDate); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); - - // Test invalid start time - const invalidStartTime = '16:04:21'; - await page.getByLabel('Start time').fill(invalidStartTime); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('Start time').fill(validBounds.startTime); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); - - // Test invalid end time - const invalidEndTime = '00:04:19'; - await page.getByLabel('End time').fill(invalidEndTime); - await expect(page.getByLabel('Submit time bounds')).toBeDisabled(); - await page.getByLabel('End time').fill(validBounds.endTime); - await expect(page.getByLabel('Submit time bounds')).toBeEnabled(); - - // Verify that the time bounds remain unchanged after invalid inputs - await expect(page.getByLabel(`Start bounds: 2024-04-20 00:04:20.000Z`)).toBeVisible(); - await expect(page.getByLabel(`End bounds: 2024-04-20 16:04:20.000Z`)).toBeVisible(); - - // Discard changes and verify that bounds remain unchanged - await setTimeConductorBounds(page, { - startDate: validBounds.startDate, - startTime: '04:20:00', - endDate: validBounds.endDate, - endTime: '04:20:20', - submitChanges: false - }); - - // Verify that the original time bounds are still displayed after discarding changes - await expect(page.getByLabel(`Start bounds: 2024-04-20 00:04:20.000Z`)).toBeVisible(); - await expect(page.getByLabel(`End bounds: 2024-04-20 16:04:20.000Z`)).toBeVisible(); - }); - /** * Verify that offsets and url params are preserved when switching * between fixed timespan and real-time mode. diff --git a/src/plugins/timeConductor/TimePopupFixed.vue b/src/plugins/timeConductor/TimePopupFixed.vue index 7c098e4462..652df767e3 100644 --- a/src/plugins/timeConductor/TimePopupFixed.vue +++ b/src/plugins/timeConductor/TimePopupFixed.vue @@ -11,18 +11,19 @@ > @@ -37,7 +38,8 @@ autocorrect="off" spellcheck="false" aria-label="Start time" - @input="validateAllBounds('startDate')" + @input="validateInput('startTime')" + @change="reportValidity('startTime')" /> @@ -48,18 +50,19 @@ > @@ -74,14 +77,15 @@ autocorrect="off" spellcheck="false" aria-label="End time" - @input="validateAllBounds('endDate')" + @input="validateInput('endTime')" + @change="reportValidity('endTime')" />
@@ -125,6 +129,7 @@ export default { return { timeFormatter: this.getFormatter(timeSystem.timeFormat), durationFormatter: this.getFormatter(timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER), + timeSystemKey: timeSystem.key, bounds: { start: bounds.start, end: bounds.end @@ -136,9 +141,29 @@ export default { endTime: '' }, isUTCBased: timeSystem.isUTCBased, - isDisabled: false + inputValidityMap: { + startDate: { valid: true }, + startTime: { valid: true }, + endDate: { valid: true }, + endTime: { 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: { inputBounds: { handler(newBounds) { @@ -168,25 +193,17 @@ export default { this.setBounds(bounds); this.setViewFromBounds(bounds); }, - clearAllValidation() { - [this.$refs.startDate, this.$refs.endDate].forEach(this.clearValidationForInput); - }, - clearValidationForInput(input) { - if (input) { - input.setCustomValidity(''); - input.title = ''; - } - }, setBounds(bounds) { this.bounds = bounds; }, setViewFromBounds(bounds) { - this.formattedBounds.start = this.timeFormatter.format(bounds.start).split(' ')[0]; - this.formattedBounds.end = this.timeFormatter.format(bounds.end).split(' ')[0]; + this.formattedBounds.startDate = this.timeFormatter.format(bounds.start).split(' ')[0]; + this.formattedBounds.endDate = this.timeFormatter.format(bounds.end).split(' ')[0]; this.formattedBounds.startTime = this.durationFormatter.format(Math.abs(bounds.start)); this.formattedBounds.endTime = this.durationFormatter.format(Math.abs(bounds.end)); }, setTimeSystem(timeSystem) { + this.timeSystemKey = timeSystem.key; this.timeFormatter = this.getFormatter(timeSystem.timeFormat); this.durationFormatter = this.getFormatter( timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER @@ -201,10 +218,10 @@ export default { setBoundsFromView(dismiss) { if (this.$refs.fixedDeltaInput.checkValidity()) { let start = this.timeFormatter.parse( - `${this.formattedBounds.start} ${this.formattedBounds.startTime}` + `${this.formattedBounds.startDate} ${this.formattedBounds.startTime}` ); let end = this.timeFormatter.parse( - `${this.formattedBounds.end} ${this.formattedBounds.endTime}` + `${this.formattedBounds.endDate} ${this.formattedBounds.endTime}` ); this.$emit('update', { start, end }); @@ -215,96 +232,93 @@ 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 inputType = refName.includes('Date') ? 'Date' : 'Time'; + const formatter = inputType === 'Date' ? this.timeFormatter : this.durationFormatter; + const validationResult = formatter.validate(this.formattedBounds[refName]) + ? { valid: true } + : { valid: false, message: `Invalid ${inputType}` }; - let validationResult = { valid: true }; - const currentInput = this.$refs[ref]; + this.inputValidityMap[refName] = validationResult; + }, + validateBounds() { + const bounds = { + start: this.timeFormatter.parse( + `${this.formattedBounds.startDate} ${this.formattedBounds.startTime}` + ), + end: this.timeFormatter.parse( + `${this.formattedBounds.endDate} ${this.formattedBounds.endTime}` + ) + }; - return [this.$refs.startDate, this.$refs.endDate].every((input) => { - let boundsValues = { - start: this.timeFormatter.parse( - `${this.formattedBounds.start} ${this.formattedBounds.startTime}` - ), - end: this.timeFormatter.parse( - `${this.formattedBounds.end} ${this.formattedBounds.endTime}` - ) + this.logicalValidityMap.bounds = this.openmct.time.validateBounds(bounds); + }, + validateLimit(bounds) { + const limit = this.configuration?.menuOptions + ?.filter((option) => option.timeSystem === this.timeSystemKey) + ?.find((option) => option.limit)?.limit; + + if (this.isUTCBased && limit && bounds.end - bounds.start > limit) { + this.logicalValidityMap.limit = { + valid: false, + message: 'Start and end difference exceeds allowable limit' }; - //TODO: Do we need limits here? We have conductor limits disabled right now - // const limit = this.getBoundsLimit(); - const limit = false; - - if (this.isUTCBased && limit && boundsValues.end - boundsValues.start > limit) { - if (input === currentInput) { - validationResult = { - valid: false, - message: 'Start and end difference exceeds allowable limit' - }; - } - } else if (input === currentInput) { - validationResult = this.openmct.time.validateBounds(boundsValues); - } - - return this.handleValidationResults(input, validationResult); - }); + } else { + this.logicalValidityMap.limit = { valid: true }; + } }, - areBoundsFormatsValid() { - return [this.$refs.startDate, this.$refs.endDate].every((input) => { - const formattedDate = - input === this.$refs.startDate - ? `${this.formattedBounds.start} ${this.formattedBounds.startTime}` - : `${this.formattedBounds.end} ${this.formattedBounds.endTime}`; + reportValidity(refName) { + const input = this.getInput(refName); + const validationResult = this.inputValidityMap[refName] ?? this.logicalValidityMap[refName]; - const validationResult = this.timeFormatter.validate(formattedDate) - ? { valid: true } - : { valid: false, message: 'Invalid date' }; - - return this.handleValidationResults(input, validationResult); - }); - }, - getBoundsLimit() { - const configuration = this.configuration.menuOptions - .filter((option) => option.timeSystem === this.timeSystem.key) - .find((option) => option.limit); - - const limit = configuration ? configuration.limit : undefined; - - return limit; - }, - handleValidationResults(input, validationResult) { 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.startDate; }, startDateSelected(date) { - this.formattedBounds.start = this.timeFormatter.format(date).split(' ')[0]; - this.validateAllBounds('startDate'); + this.formattedBounds.startDate = this.timeFormatter.format(date).split(' ')[0]; + this.validateInput('startDate'); + this.reportValidity('startDate'); }, endDateSelected(date) { - this.formattedBounds.end = this.timeFormatter.format(date).split(' ')[0]; - this.validateAllBounds('endDate'); + this.formattedBounds.endDate = this.timeFormatter.format(date).split(' ')[0]; + this.validateInput('endDate'); + this.reportValidity('endDate'); }, hide($event) { if ($event.target.className.indexOf('c-button icon-x') > -1) {