Skip to content

Commit 735f1d7

Browse files
committed
MBS-10663: Fix date/duration view switch not being idempotent
Refactored updateTargetTime into two separate functions: - updateTargetTimeFromCurrentView(): reads value from visible view - updateDisplayValues(): syncs both UI elements from stored time This ensures switching between date and duration views preserves the exact same target time without rounding drift.
1 parent 516adb3 commit 735f1d7

File tree

2 files changed

+38
-22
lines changed

2 files changed

+38
-22
lines changed

amd/build/ai_control_config.min.js

Lines changed: 1 addition & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

amd/src/ai_control_config.js

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,16 @@ export const init = async(element, aiconfigObject) => {
8080

8181
baseElement.querySelectorAll('[data-aicontrol-item^="switchexpiryview"]').forEach(button => {
8282
button.addEventListener('click', () => {
83-
updateTargetTime();
83+
// First read the value from the currently visible view and update currentTargetTime.
84+
updateTargetTimeFromCurrentView();
85+
// Then toggle visibility.
8486
const elementsToToggleVisibility = baseElement.querySelectorAll('[data-aicontrol-show]');
8587
elementsToToggleVisibility.forEach(element => {
8688
element.dataset.aiconfigShow = element.dataset.aiconfigShow === '1' ? '0' : '1';
8789
element.classList.toggle('d-none');
8890
});
91+
// Finally update both display values based on the stored currentTargetTime.
92+
updateDisplayValues();
8993
});
9094
});
9195

@@ -173,32 +177,54 @@ const dispatchChangedEvent = (refreshedAiconfig) => {
173177
}));
174178
};
175179

176-
const updateTargetTime = () => {
177-
const durationElement = baseElement.querySelector('[data-aicontrol-item="expiryduration"]');
180+
/**
181+
* Updates the display values for both date and duration inputs based on currentTargetTime.
182+
* This does NOT recalculate currentTargetTime, it only syncs the UI.
183+
*/
184+
const updateDisplayValues = () => {
178185
const expirydurationDays = baseElement.querySelector('[data-aicontrol-item="expiryduration_days"]');
179186
const expirydurationHours = baseElement.querySelector('[data-aicontrol-item="expiryduration_hours"]');
180187
const expirydurationMinutes = baseElement.querySelector('[data-aicontrol-item="expiryduration_minutes"]');
188+
const dateElement = baseElement.querySelector('[data-aicontrol-item="expirydate"]');
189+
190+
dateElement.value = convertUnixtimeToDateElementFormat(currentTargetTime);
181191

192+
const {days, hours, minutes} = convertTargetUnixTimeToCountdown(currentTargetTime);
193+
expirydurationDays.value = days;
194+
expirydurationHours.value = hours;
195+
expirydurationMinutes.value = minutes;
196+
};
197+
198+
/**
199+
* Reads the value from the currently visible view and updates currentTargetTime.
200+
*/
201+
const updateTargetTimeFromCurrentView = () => {
202+
const durationElement = baseElement.querySelector('[data-aicontrol-item="expiryduration"]');
203+
const expirydurationDays = baseElement.querySelector('[data-aicontrol-item="expiryduration_days"]');
204+
const expirydurationHours = baseElement.querySelector('[data-aicontrol-item="expiryduration_hours"]');
205+
const expirydurationMinutes = baseElement.querySelector('[data-aicontrol-item="expiryduration_minutes"]');
182206
const dateElement = baseElement.querySelector('[data-aicontrol-item="expirydate"]');
183207

184208
if (durationElement.dataset.aiconfigShow === '1') {
209+
// Duration view is visible, calculate target time from duration.
185210
const currentTime = new Date();
186211
currentTargetTime = currentTime.getTime()
187212
+ (expirydurationDays.value * 24 * 60 * 60 * 1000)
188213
+ (expirydurationHours.value * 60 * 60 * 1000)
189214
+ (expirydurationMinutes.value * 60 * 1000);
190215
currentTargetTime = Math.round(currentTargetTime / 1000);
191216
} else {
192-
currentTargetTime = Math.round(parseInt(+new Date(dateElement.value)) / 1000);
217+
// Date view is visible, read directly from the date input.
218+
currentTargetTime = Math.round(new Date(dateElement.value).getTime() / 1000);
193219
}
220+
};
194221

195-
// Now our global time is set correctly, we can update both UI elements.
196-
dateElement.value = convertUnixtimeToDateElementFormat(currentTargetTime);
197-
198-
const {days, hours, minutes} = convertTargetUnixTimeToCountdown(currentTargetTime);
199-
expirydurationDays.value = days;
200-
expirydurationHours.value = hours;
201-
expirydurationMinutes.value = minutes;
222+
/**
223+
* Updates the target time based on the currently visible view and syncs all UI elements.
224+
*/
225+
const updateTargetTime = () => {
226+
updateTargetTimeFromCurrentView();
227+
updateDisplayValues();
202228
};
203229

204230
/**

0 commit comments

Comments
 (0)