From aa4eb9139c7f1f6b4d82110caa1692f16620746f Mon Sep 17 00:00:00 2001 From: mikezzb Date: Fri, 22 Mar 2024 01:21:29 -0400 Subject: [PATCH] Reimplement input mirroring for OT milestone fields #3173 --- .../elements/chromedash-guide-stage-page.js | 42 +++++++++++++++++-- client-src/elements/form-definition.js | 7 ++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/client-src/elements/chromedash-guide-stage-page.js b/client-src/elements/chromedash-guide-stage-page.js index 8ae22997c78..b93f7033176 100644 --- a/client-src/elements/chromedash-guide-stage-page.js +++ b/client-src/elements/chromedash-guide-stage-page.js @@ -9,6 +9,7 @@ import { import './chromedash-form-table'; import './chromedash-form-field'; import { + COPY_ON_EDIT, FLAT_TRIAL_EXTENSION_FIELDS, formatFeatureForEdit, FORMS_BY_STAGE_TYPE} from './form-definition'; @@ -67,6 +68,17 @@ export class ChromedashGuideStagePage extends LitElement { this.fetchData(); } + // Helper to update a field with value + _updateFieldValues(index, value) { + // The field has been updated, so it is considered touched. + this.fieldValues[index].touched = true; + this.fieldValues[index].value = value; + } + + _getFieldIndexByName(name) { + return this.fieldValues.findIndex(field => field.name === name); + } + // Handler to update form values when a field update event is fired. handleFormFieldUpdate(event) { const value = event.detail.value; @@ -75,11 +87,35 @@ export class ChromedashGuideStagePage extends LitElement { if (index >= this.fieldValues.length) { throw new Error('Out of bounds index when updating field values.'); } - // The field has been updated, so it is considered touched. - this.fieldValues[index].touched = true; - this.fieldValues[index].value = value; + const fieldKey = this.fieldValues[index].name; + // If the OT/DT desktop milestone start field is updated, and the android/webview milestone start fields are either empty or previously matched the desktop milestone, they're updated to match as well. + if (COPY_ON_EDIT.hasOwnProperty(fieldKey)) { + const copyDestFields = COPY_ON_EDIT[fieldKey]; + const oldSrcFieldValue = this.fieldValues[index].value; + for (const copyDestField of copyDestFields) { + const copyDestIndex = this._getFieldIndexByName(copyDestField); + if (copyDestIndex === -1) { + continue; + } + // If the field is already touched and has a different value, don't update it + if (this.fieldValues[copyDestIndex].touched && + this.fieldValues[copyDestIndex].value !== oldSrcFieldValue) { + continue; + } + // Update dest DOM element and field value + const copyDestEl = this.shadowRoot.querySelector(`#id_${copyDestField}`); + if (!copyDestEl) { + continue; + } + this._updateFieldValues(copyDestIndex, value); + copyDestEl.value = value; + } + } + + this._updateFieldValues(index, value); }; + fetchData() { this.loading = true; Promise.all([ diff --git a/client-src/elements/form-definition.js b/client-src/elements/form-definition.js index 1431026a6d3..ba826180406 100644 --- a/client-src/elements/form-definition.js +++ b/client-src/elements/form-definition.js @@ -887,3 +887,10 @@ export const GATE_QUESTIONNAIRES = { [enums.GATE_TYPES.TESTING_SHIP]: TESTING_SHIP_QUESTIONNAIRE, [enums.GATE_TYPES.TESTING_PLAN]: TESTING_SHIP_QUESTIONNAIRE, }; + +/** Copy field SRC to DST if SRC is edited and DST was empty and has not been edited */ +export const COPY_ON_EDIT = Object.freeze({ + 'ot_milestone_desktop_start': ['ot_milestone_android_start', 'ot_milestone_webview_start'], + 'ot_milestone_desktop_end': ['ot_milestone_android_end', 'ot_milestone_webview_end'], + 'dt_milestone_desktop_start': ['dt_milestone_android_start', 'dt_milestone_webview_start'], +});