Skip to content

Commit 9f91f27

Browse files
committed
[CORE-8026] add setTimer to delay validation check before form is populated
1 parent 2223cdb commit 9f91f27

File tree

3 files changed

+448
-48
lines changed

3 files changed

+448
-48
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
═══════════════════════════════════════════════════════════════════════════════════════
2+
btnDisabled$ BehaviorSubject Flow Diagram
3+
═══════════════════════════════════════════════════════════════════════════════════════
4+
5+
┌─────────────────────────────────────┐
6+
│ activity-desktop.page.ts │
7+
│ (Parent Component) │
8+
└─────────────────────────────────────┘
9+
10+
│ Creates & Passes btnDisabled$
11+
│ as @Input to assessment.component
12+
13+
┌─────────────────────────────────────┐
14+
│ assessment.component.ts │
15+
│ (Child Component) │
16+
│ │
17+
@Input() btnDisabled$: │
18+
│ BehaviorSubject<boolean> │
19+
└─────────────────────────────────────┘
20+
21+
═══════════════════════════════════════════════════════════════════════════════════════
22+
TRIGGER POINTS IN assessment.component.ts
23+
═══════════════════════════════════════════════════════════════════════════════════════
24+
25+
1. ngOnChanges() - Component Lifecycle
26+
└── btnDisabled$.next(false) ──────────► RESET on assessment change
27+
28+
2. _populateQuestionsForm() - Form Setup
29+
├── If no questions exist:
30+
│ └── btnDisabled$.next(true) ───────► DISABLE (empty form)
31+
32+
└── questionsForm.valueChanges.subscribe()
33+
└── setSubmissionDisabled() ───────► CHECK & UPDATE based on validation
34+
35+
3. _handleSubmissionData() - Submission State Handler
36+
└── If submission.isLocked:
37+
└── btnDisabled$.next(true) ───────► DISABLE (locked by another user)
38+
39+
4. _handleReviewData() - Review State Handler
40+
└── If isPendingReview && review.status === 'in progress':
41+
└── btnDisabled$.next(false) ──────► ENABLE for review
42+
43+
5. continueToNextTask() - Submit Action
44+
└── If _btnAction === 'submit':
45+
└── btnDisabled$.next(true) ───────► DISABLE during submission
46+
47+
6. _submitAnswer() - Answer Submission
48+
└── If required questions missing:
49+
└── btnDisabled$.next(false) ──────► RE-ENABLE after validation fail
50+
51+
7. resubmit() - Resubmission Flow
52+
├── Start: btnDisabled$.next(true) ────► DISABLE during resubmit
53+
└── End: btnDisabled$.next(false) ─────► RE-ENABLE after completion
54+
55+
8. setSubmissionDisabled() - Main Validation Logic
56+
├── Only runs if (doAssessment || isPendingReview)
57+
├── If form invalid & not disabled:
58+
│ └── btnDisabled$.next(true) ───────► DISABLE
59+
└── If form valid & disabled:
60+
└── btnDisabled$.next(false) ──────► ENABLE
61+
62+
9. _prefillForm() - Form Population
63+
├── After populating form with answers
64+
├── questionsForm.updateValueAndValidity()
65+
└── If edit mode (doAssessment || isPendingReview):
66+
└── setSubmissionDisabled() ───────► CHECK & UPDATE validation
67+
└── If read-only mode:
68+
└── btnDisabled$.next(false) ──────► ENSURE enabled
69+
70+
10. Page Navigation Methods
71+
├── goToPage()
72+
├── nextPage()
73+
└── prevPage()
74+
└── setSubmissionDisabled() ──────► CHECK & UPDATE for new page
75+
76+
═══════════════════════════════════════════════════════════════════════════════════════
77+
TRIGGER CONDITIONS SUMMARY
78+
═══════════════════════════════════════════════════════════════════════════════════════
79+
80+
DISABLE CONDITIONS (btnDisabled$.next(true)):
81+
├── No questions in assessment
82+
├── Assessment is locked by another user
83+
├── Form is invalid (required fields empty)
84+
├── During submission process
85+
└── During resubmit process
86+
87+
ENABLE CONDITIONS (btnDisabled$.next(false)):
88+
├── Assessment changes (reset)
89+
├── Form becomes valid
90+
├── Review in progress
91+
├── After failed validation alert
92+
├── After resubmit completion
93+
└── Read-only mode (not doAssessment && not isPendingReview)
94+
95+
═══════════════════════════════════════════════════════════════════════════════════════
96+
PROBLEM SCENARIO
97+
═══════════════════════════════════════════════════════════════════════════════════════
98+
99+
User Flow - Original Issue (RESOLVED):
100+
1. User visits Assessment A (has required fields)
101+
└── Form invalid → btnDisabled$.next(true) ✓
102+
103+
2. User navigates to Assessment B via activity-desktop
104+
└── ngOnChanges() → btnDisabled$.next(false) ✓
105+
└── _populateQuestionsForm() → questionsForm created
106+
└── _populateFormWithAnswers() → form populated
107+
└── setSubmissionDisabled() → checks validation
108+
└── BUT: Timing issue - form may not be fully populated
109+
└── Result: btnDisabled$ may remain false even if invalid
110+
111+
3. RESOLVED: State synchronization fixed
112+
└── _prefillForm() now properly checks validation after form population
113+
114+
═══════════════════════════════════════════════════════════════════════════════════════
115+
SOLUTION IMPLEMENTATION (COMPLETED)
116+
═══════════════════════════════════════════════════════════════════════════════════════
117+
118+
IMPLEMENTED FIXES:
119+
1. ✅ Reset state in ngOnChanges when assessment changes
120+
└── btnDisabled$.next(false) in ngOnChanges()
121+
122+
2. ✅ Proper validation after form population in _prefillForm()
123+
├── questionsForm.updateValueAndValidity()
124+
├── Edit mode: setSubmissionDisabled() checks validation
125+
└── Read-only mode: btnDisabled$.next(false) ensures enabled
126+
127+
3. ✅ Check validation when changing pages
128+
├── prevPage() → setSubmissionDisabled()
129+
├── nextPage() → setSubmissionDisabled()
130+
└── goToPage() → setSubmissionDisabled()
131+
132+
4. ✅ Apply validation rules only when in edit mode
133+
└── setSubmissionDisabled() has guard: (!doAssessment && !isPendingReview)
134+
135+
5. ✅ Replaced _populateFormWithAnswers() with _prefillForm()
136+
└── Better state management and validation synchronization
137+
138+
RESULT: btnDisabled$ now accurately reflects form state at all times
139+
═══════════════════════════════════════════════════════════════════════════════════════
140+
141+
═══════════════════════════════════════════════════════════════════════════════════════
142+
KEY LEARNINGS
143+
═══════════════════════════════════════════════════════════════════════════════════════
144+
145+
1. BEHAVIORSUBJECT STATE PERSISTENCE
146+
└── BehaviorSubject remembers last value across component input changes
147+
└── Must explicitly reset when navigating between assessments
148+
149+
2. FORM VALIDATION TIMING
150+
└── Validation must happen AFTER form population is complete
151+
└── updateValueAndValidity() is crucial for proper validation state
152+
153+
3. SEPARATION OF CONCERNS
154+
└── setSubmissionDisabled() handles validation-based enabling/disabling
155+
└── _prefillForm() handles initial state setup after population
156+
└── Each method has clear responsibility boundaries
157+
158+
4. EDIT VS READ-ONLY MODES
159+
└── Only apply validation rules when user can edit
160+
└── Read-only mode should always have enabled button for navigation
161+
└── Guard clauses prevent unnecessary state changes
162+
163+
═══════════════════════════════════════════════════════════════════════════════════════

0 commit comments

Comments
 (0)