Skip to content

Commit e876894

Browse files
committed
fix(meetings): resolve past meeting edit validation issue
When editing meetings with past start dates, form validation prevented saving even when keeping the original date unchanged. This blocked users from editing meeting details like description or attendees. - Add editModeDateTimeValidator for conditional past date validation - Allow past dates only if they match original meeting start time - Maintain strict future date validation for new meetings - Update meeting-manage component to use appropriate validator Fixes LFXV2-532 Generated with [Claude Code](https://claude.ai/code) Signed-off-by: Asitha de Silva <asithade@gmail.com>
1 parent 949e84a commit e876894

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

apps/lfx-one/src/app/modules/project/meetings/components/meeting-manage/meeting-manage.component.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
getUserTimezone,
3939
mapRecurrenceToFormValue,
4040
} from '@lfx-one/shared/utils';
41-
import { futureDateTimeValidator } from '@lfx-one/shared/validators';
41+
import { editModeDateTimeValidator, futureDateTimeValidator } from '@lfx-one/shared/validators';
4242
import { MeetingService } from '@services/meeting.service';
4343
import { ProjectService } from '@services/project.service';
4444
import { ConfirmationService, MessageService } from 'primeng/api';
@@ -85,6 +85,7 @@ export class MeetingManageComponent {
8585
public mode = signal<'create' | 'edit'>('create');
8686
public meetingId = signal<string | null>(null);
8787
public isEditMode = computed(() => this.mode() === 'edit');
88+
public originalStartTime = signal<string | null>(null);
8889
public registrantUpdates = signal<RegistrantPendingChanges>({
8990
toAdd: [],
9091
toUpdate: [],
@@ -508,6 +509,9 @@ export class MeetingManageComponent {
508509
}
509510

510511
private populateFormWithMeetingData(meeting: Meeting): void {
512+
// Store the original start time for validation
513+
this.originalStartTime.set(meeting.start_time);
514+
511515
// Parse start_time to separate date and time
512516
let startDate = null;
513517
let startTime = '';
@@ -593,6 +597,9 @@ export class MeetingManageComponent {
593597
endTypeUI: endTypeUI,
594598
});
595599
}
600+
601+
// Update the form validator to use edit mode validator with original start time
602+
this.updateFormValidator();
596603
}
597604

598605
private canNavigateToStep(step: number): boolean {
@@ -875,4 +882,18 @@ export class MeetingManageComponent {
875882

876883
return false;
877884
}
885+
886+
private updateFormValidator(): void {
887+
const currentForm = this.form();
888+
889+
// Apply appropriate validator based on mode
890+
if (this.isEditMode() && this.originalStartTime()) {
891+
currentForm.setValidators(editModeDateTimeValidator(this.originalStartTime()!));
892+
} else {
893+
currentForm.setValidators(futureDateTimeValidator());
894+
}
895+
896+
// Update form validity
897+
currentForm.updateValueAndValidity();
898+
}
878899
}

packages/shared/src/validators/meeting.validators.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,52 @@ export function futureDateTimeValidator(): ValidatorFn {
3535
};
3636
}
3737

38+
/**
39+
* Validator for edit mode - allows past dates only if they match the original meeting start time
40+
*/
41+
export function editModeDateTimeValidator(originalStartTime?: string): ValidatorFn {
42+
return (control: AbstractControl): ValidationErrors | null => {
43+
const formGroup = control as any; // FormGroup
44+
const startDate = formGroup.get?.('startDate')?.value;
45+
const startTime = formGroup.get?.('startTime')?.value;
46+
const timezone = formGroup.get?.('timezone')?.value;
47+
48+
if (!startDate || !startTime || !timezone) {
49+
return null; // Don't validate if values are not set
50+
}
51+
52+
// Combine the date and time with timezone awareness
53+
const combinedDateTime = combineDateTime(startDate, startTime, timezone);
54+
if (!combinedDateTime) {
55+
return null; // Invalid time format
56+
}
57+
58+
// Check if the datetime is in the future for the specified timezone
59+
const isInFuture = isDateTimeInFutureForTimezone(combinedDateTime, timezone);
60+
61+
if (!isInFuture) {
62+
// If in the past, check if it matches the original start time
63+
if (originalStartTime) {
64+
// Compare the combined datetime with the original start time
65+
const originalDate = new Date(originalStartTime);
66+
const newDate = new Date(combinedDateTime);
67+
68+
// Allow past date only if it matches the original (within 1 minute to account for formatting differences)
69+
const timeDifferenceMs = Math.abs(originalDate.getTime() - newDate.getTime());
70+
const oneMinuteMs = 60 * 1000;
71+
72+
if (timeDifferenceMs <= oneMinuteMs) {
73+
return null; // Allow the original date/time even if in the past
74+
}
75+
}
76+
77+
return { futureDateTime: true };
78+
}
79+
80+
return null;
81+
};
82+
}
83+
3884
/**
3985
* Validator to check if a time string is in valid 12-hour format
4086
*/

0 commit comments

Comments
 (0)