cloud-ide-academics 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. package/fesm2022/cloud-ide-academics-class-program-term-create.component-B5sVQbaC.mjs +578 -0
  2. package/fesm2022/cloud-ide-academics-class-program-term-create.component-B5sVQbaC.mjs.map +1 -0
  3. package/fesm2022/cloud-ide-academics-class-program-term-list.component-Cpbyavgd.mjs +404 -0
  4. package/fesm2022/cloud-ide-academics-class-program-term-list.component-Cpbyavgd.mjs.map +1 -0
  5. package/fesm2022/cloud-ide-academics-class-program-term.service-BW4PJQEM.mjs +111 -0
  6. package/fesm2022/cloud-ide-academics-class-program-term.service-BW4PJQEM.mjs.map +1 -0
  7. package/fesm2022/cloud-ide-academics-cloud-ide-academics-Czexp3pk.mjs +2791 -0
  8. package/fesm2022/cloud-ide-academics-cloud-ide-academics-Czexp3pk.mjs.map +1 -0
  9. package/fesm2022/cloud-ide-academics-program-class-create.component-DR31TP1Z.mjs +391 -0
  10. package/fesm2022/cloud-ide-academics-program-class-create.component-DR31TP1Z.mjs.map +1 -0
  11. package/fesm2022/cloud-ide-academics-program-class-list.component-C1iTyuQ4.mjs +433 -0
  12. package/fesm2022/cloud-ide-academics-program-class-list.component-C1iTyuQ4.mjs.map +1 -0
  13. package/fesm2022/cloud-ide-academics-program-term-section-create.component-Dg9Pjwj5.mjs +211 -0
  14. package/fesm2022/cloud-ide-academics-program-term-section-create.component-Dg9Pjwj5.mjs.map +1 -0
  15. package/fesm2022/cloud-ide-academics-program-term-section-list.component-xVeeeGDV.mjs +478 -0
  16. package/fesm2022/cloud-ide-academics-program-term-section-list.component-xVeeeGDV.mjs.map +1 -0
  17. package/fesm2022/cloud-ide-academics.mjs +1 -1535
  18. package/fesm2022/cloud-ide-academics.mjs.map +1 -1
  19. package/index.d.ts +239 -3
  20. package/package.json +1 -1
@@ -0,0 +1,578 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, DestroyRef, signal, Component } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import * as i1 from '@angular/forms';
5
+ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
6
+ import { Router, ActivatedRoute } from '@angular/router';
7
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
+ import { NotificationService, ConfirmationService, CideInputComponent, CideTextareaComponent, CideEleButtonComponent, CideIconComponent, CideSelectComponent } from 'cloud-ide-element';
9
+ import { AppStateHelperService } from 'cloud-ide-layout';
10
+ import { ENTITY_SERVICE_TOKEN } from 'cloud-ide-shared';
11
+ import { b as CideLytClassProgramBranchService, C as CideLytProgramClassService } from './cloud-ide-academics-cloud-ide-academics-Czexp3pk.mjs';
12
+ import { C as CideLytClassProgramTermService } from './cloud-ide-academics-class-program-term.service-BW4PJQEM.mjs';
13
+ import { generateObjectFromString } from 'cloud-ide-lms-model';
14
+
15
+ class ClassProgramTermCreateComponent {
16
+ // Dependency injection
17
+ destroyRef = inject(DestroyRef);
18
+ fb = inject(FormBuilder);
19
+ entityService = inject(ENTITY_SERVICE_TOKEN);
20
+ router = inject(Router);
21
+ route = inject(ActivatedRoute);
22
+ appState = inject(AppStateHelperService);
23
+ notificationService = inject(NotificationService);
24
+ confirmationService = inject(ConfirmationService);
25
+ classProgramBranchService = inject(CideLytClassProgramBranchService);
26
+ programClassService = inject(CideLytProgramClassService);
27
+ classProgramTermService = inject(CideLytClassProgramTermService);
28
+ classProgramTermForm;
29
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
30
+ error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
31
+ // Class program term information from route
32
+ classProgramTermId = signal('', ...(ngDevMode ? [{ debugName: "classProgramTermId" }] : []));
33
+ isEditMode = signal(false, ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
34
+ isViewMode = signal(false, ...(ngDevMode ? [{ debugName: "isViewMode" }] : []));
35
+ // Data signals
36
+ programClasses = signal([], ...(ngDevMode ? [{ debugName: "programClasses" }] : []));
37
+ classProgramBranches = signal([], ...(ngDevMode ? [{ debugName: "classProgramBranches" }] : []));
38
+ // Options for dropdowns
39
+ programClassOptions = signal([], ...(ngDevMode ? [{ debugName: "programClassOptions" }] : []));
40
+ branchOptions = signal([], ...(ngDevMode ? [{ debugName: "branchOptions" }] : []));
41
+ parentTermOptions = signal([], ...(ngDevMode ? [{ debugName: "parentTermOptions" }] : []));
42
+ // Route parameters
43
+ acabrnId = signal(null, ...(ngDevMode ? [{ debugName: "acabrnId" }] : []));
44
+ acacpmId = signal(null, ...(ngDevMode ? [{ debugName: "acacpmId" }] : []));
45
+ // Date constraints
46
+ endDateMinDate = signal('', ...(ngDevMode ? [{ debugName: "endDateMinDate" }] : []));
47
+ constructor() {
48
+ this.classProgramTermForm = this.fb.group({
49
+ // Basic Class Program Term Information
50
+ acapt_code: ['', [Validators.required]],
51
+ acapt_name: ['', [Validators.required]],
52
+ acapt_description: [''],
53
+ acapt_class_program_id_acacpm: ['', [Validators.required]],
54
+ acapt_class_program_branch_id_acabrn: ['', [Validators.required]],
55
+ acapt_parent_class_prog_term_acapt: [''],
56
+ acapt_start_date: [''],
57
+ acapt_end_date: [''],
58
+ acapt_isactive: [true],
59
+ acapt_islocked: [false]
60
+ });
61
+ }
62
+ ngOnInit() {
63
+ this.initializeComponent();
64
+ this.setupFormSubscriptions();
65
+ }
66
+ /**
67
+ * Setup form subscriptions for dependent dropdowns
68
+ */
69
+ setupFormSubscriptions() {
70
+ // Watch for program class changes to filter branches
71
+ this.classProgramTermForm.get('acapt_class_program_id_acacpm')?.valueChanges
72
+ .pipe(takeUntilDestroyed(this.destroyRef))
73
+ .subscribe(programClassId => {
74
+ if (programClassId) {
75
+ this.loadBranchesForProgramClass(programClassId);
76
+ // Clear branch selection when program class changes
77
+ this.classProgramTermForm.patchValue({
78
+ acapt_class_program_branch_id_acabrn: ''
79
+ });
80
+ }
81
+ else {
82
+ this.branchOptions.set([]);
83
+ }
84
+ });
85
+ // Watch for branch changes to determine parent term
86
+ this.classProgramTermForm.get('acapt_class_program_branch_id_acabrn')?.valueChanges
87
+ .pipe(takeUntilDestroyed(this.destroyRef))
88
+ .subscribe(branchId => {
89
+ if (branchId) {
90
+ this.determineParentTerm(branchId);
91
+ }
92
+ else {
93
+ // Clear parent term when branch is cleared
94
+ this.classProgramTermForm.patchValue({
95
+ acapt_parent_class_prog_term_acapt: ''
96
+ });
97
+ }
98
+ });
99
+ // Watch for parent term changes to set date constraints
100
+ this.classProgramTermForm.get('acapt_parent_class_prog_term_acapt')?.valueChanges
101
+ .pipe(takeUntilDestroyed(this.destroyRef))
102
+ .subscribe(parentTermId => {
103
+ this.loadParentTermDetails(parentTermId);
104
+ });
105
+ // Watch for start date changes to set minimum date for end date
106
+ this.classProgramTermForm.get('acapt_start_date')?.valueChanges
107
+ .pipe(takeUntilDestroyed(this.destroyRef))
108
+ .subscribe(startDate => {
109
+ this.updateEndDateMinDate(startDate);
110
+ });
111
+ }
112
+ /**
113
+ * Initialize component
114
+ */
115
+ initializeComponent() {
116
+ // Check route parameters to determine mode
117
+ this.checkRouteParams();
118
+ const url = this.router.url;
119
+ const queryParams = this.route.snapshot.queryParams;
120
+ if (url.includes('/view/')) {
121
+ this.isViewMode.set(true);
122
+ this.loadClassProgramTermForView(queryParams);
123
+ }
124
+ else if (url.includes('/edit/')) {
125
+ this.isEditMode.set(true);
126
+ this.loadClassProgramTermForEdit(queryParams);
127
+ }
128
+ else {
129
+ // Create mode
130
+ this.isEditMode.set(false);
131
+ this.isViewMode.set(false);
132
+ }
133
+ // Load dropdown options
134
+ this.loadDropdownOptions();
135
+ }
136
+ /**
137
+ * Check route parameters for acabrn_id and acacpm_id
138
+ */
139
+ checkRouteParams() {
140
+ this.route.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(params => {
141
+ const queryParams = params['query'];
142
+ console.log('🏢 Route params:', params, 'queryParams:', queryParams);
143
+ if (queryParams) {
144
+ // Query parameters passed (following page-controls pattern)
145
+ const queryData = generateObjectFromString(queryParams);
146
+ console.log('🏢 Class Program Term Create params from route:', queryData);
147
+ if (queryData?.acabrn_id) {
148
+ this.acabrnId.set(queryData.acabrn_id);
149
+ console.log('🏢 Branch ID from route:', queryData.acabrn_id);
150
+ }
151
+ if (queryData?.acacpm_id) {
152
+ this.acacpmId.set(queryData.acacpm_id);
153
+ console.log('🏢 Class Program ID from route:', queryData.acacpm_id);
154
+ }
155
+ }
156
+ });
157
+ }
158
+ /**
159
+ * Load class program term for viewing
160
+ */
161
+ loadClassProgramTermForView(queryParams) {
162
+ // Implementation for view mode
163
+ this.classProgramTermForm.disable();
164
+ }
165
+ /**
166
+ * Load class program term for editing
167
+ */
168
+ loadClassProgramTermForEdit(queryParams) {
169
+ // Implementation for edit mode
170
+ }
171
+ /**
172
+ * Load dropdown options
173
+ */
174
+ loadDropdownOptions() {
175
+ // Load program classes
176
+ this.loadProgramClasses();
177
+ // Load branches
178
+ this.loadClassProgramBranches();
179
+ }
180
+ /**
181
+ * Load program classes
182
+ */
183
+ loadProgramClasses() {
184
+ this.programClassService.getProgramClassList({ pagination: false })
185
+ .pipe(takeUntilDestroyed(this.destroyRef))
186
+ .subscribe({
187
+ next: (response) => {
188
+ console.log('✅ Program classes loaded:', response);
189
+ if (response?.success && response.data) {
190
+ this.programClassOptions.set(response.data);
191
+ // Pre-select program class if provided in route
192
+ const acacpmId = this.acacpmId();
193
+ if (acacpmId) {
194
+ this.classProgramTermForm.patchValue({
195
+ acapt_class_program_id_acacpm: acacpmId
196
+ });
197
+ }
198
+ }
199
+ else {
200
+ console.warn('⚠️ No program class data received');
201
+ this.programClassOptions.set([]);
202
+ }
203
+ },
204
+ error: (error) => {
205
+ console.error('❌ Error loading program classes:', error);
206
+ this.programClassOptions.set([]);
207
+ }
208
+ });
209
+ }
210
+ /**
211
+ * Load class program branches
212
+ */
213
+ loadClassProgramBranches() {
214
+ const acacpmId = this.acacpmId();
215
+ if (acacpmId) {
216
+ this.loadBranchesForProgramClass(acacpmId);
217
+ }
218
+ }
219
+ /**
220
+ * Load branches for a specific program class
221
+ */
222
+ loadBranchesForProgramClass(programClassId) {
223
+ const payload = {
224
+ pagination: false,
225
+ pageIndex: 0,
226
+ pageSize: 100,
227
+ acabrn_class_program_id_acacpm: programClassId
228
+ };
229
+ this.classProgramBranchService.getClassProgramBranchList(payload)
230
+ .pipe(takeUntilDestroyed(this.destroyRef))
231
+ .subscribe({
232
+ next: (response) => {
233
+ console.log('✅ Class program branches loaded for program class:', programClassId, response);
234
+ if (response?.success && response.data) {
235
+ this.branchOptions.set(response.data);
236
+ // Pre-select branch if provided in route and not already set
237
+ const acabrnId = this.acabrnId();
238
+ const currentBranchId = this.classProgramTermForm.get('acapt_class_program_branch_id_acabrn')?.value;
239
+ if (acabrnId && !currentBranchId) {
240
+ this.classProgramTermForm.patchValue({
241
+ acapt_class_program_branch_id_acabrn: acabrnId
242
+ });
243
+ }
244
+ }
245
+ else {
246
+ console.warn('⚠️ No branch data received');
247
+ this.branchOptions.set([]);
248
+ }
249
+ },
250
+ error: (error) => {
251
+ console.error('❌ Error loading branches:', error);
252
+ this.branchOptions.set([]);
253
+ }
254
+ });
255
+ }
256
+ /**
257
+ * Determine parent term based on selected branch
258
+ * This method will be called internally when branch is selected
259
+ */
260
+ determineParentTerm(branchId) {
261
+ // Find the selected branch from the options
262
+ const selectedBranch = this.branchOptions().find(branch => branch._id === branchId);
263
+ if (selectedBranch) {
264
+ console.log('🏢 Determining parent term for branch:', selectedBranch.acabrn_name);
265
+ // Load existing terms for this branch to find potential parent terms
266
+ this.loadParentTermsForBranch(branchId);
267
+ }
268
+ }
269
+ /**
270
+ * Load parent terms for a specific branch
271
+ */
272
+ loadParentTermsForBranch(branchId) {
273
+ // TODO: Implement API call to get existing terms for the branch
274
+ // This will help determine which terms can be parent terms
275
+ console.log('🏢 Loading parent terms for branch:', branchId);
276
+ // Example implementation - replace with actual API call
277
+ // const payload = {
278
+ // acabrn_id: branchId,
279
+ // pagination: false
280
+ // };
281
+ // this.classProgramTermService.getClassProgramTermList(payload)
282
+ // .pipe(takeUntilDestroyed(this.destroyRef))
283
+ // .subscribe({
284
+ // next: (response) => {
285
+ // if (response?.success && response.data) {
286
+ // // Filter terms that can be parent terms (e.g., terms without parent)
287
+ // const parentTerms = response.data.filter(term => !term.acapt_parent_class_prog_term_acapt);
288
+ // this.parentTermOptions.set(parentTerms);
289
+ // }
290
+ // },
291
+ // error: (error) => {
292
+ // console.error('❌ Error loading parent terms:', error);
293
+ // this.parentTermOptions.set([]);
294
+ // }
295
+ // });
296
+ // For now, set empty array
297
+ this.parentTermOptions.set([]);
298
+ }
299
+ /**
300
+ * Load parent term details for date validation
301
+ * This method will be called when a parent term is selected
302
+ */
303
+ loadParentTermDetails(parentTermId) {
304
+ if (!parentTermId) {
305
+ // Clear date constraints when no parent is selected
306
+ this.clearDateConstraints();
307
+ return;
308
+ }
309
+ // TODO: Implement API call to get parent term details
310
+ // For now, we'll use mock data or implement based on your API
311
+ console.log('🏢 Loading parent term details for ID:', parentTermId);
312
+ // Example implementation - replace with actual API call
313
+ // this.classProgramTermService.getClassProgramTermById({ _id: parentTermId })
314
+ // .pipe(takeUntilDestroyed(this.destroyRef))
315
+ // .subscribe({
316
+ // next: (response) => {
317
+ // if (response?.success && response.data) {
318
+ // const parentTerm = response.data;
319
+ // this.setDateConstraints(parentTerm.acapt_start_date, parentTerm.acapt_end_date);
320
+ // }
321
+ // },
322
+ // error: (error) => {
323
+ // console.error('❌ Error loading parent term details:', error);
324
+ // }
325
+ // });
326
+ }
327
+ /**
328
+ * Set date constraints based on parent term dates
329
+ */
330
+ setDateConstraints(parentStartDate, parentEndDate) {
331
+ console.log('🏢 Setting date constraints:', { parentStartDate, parentEndDate });
332
+ // Update form validation to ensure child dates are within parent range
333
+ const startDateControl = this.classProgramTermForm.get('acapt_start_date');
334
+ const endDateControl = this.classProgramTermForm.get('acapt_end_date');
335
+ if (startDateControl && endDateControl) {
336
+ // Add custom validators for date range
337
+ startDateControl.setValidators([
338
+ this.dateRangeValidator(parentStartDate, parentEndDate, 'start')
339
+ ]);
340
+ endDateControl.setValidators([
341
+ this.dateRangeValidator(parentStartDate, parentEndDate, 'end')
342
+ ]);
343
+ // Update validation
344
+ startDateControl.updateValueAndValidity();
345
+ endDateControl.updateValueAndValidity();
346
+ }
347
+ }
348
+ /**
349
+ * Clear date constraints when no parent is selected
350
+ */
351
+ clearDateConstraints() {
352
+ const startDateControl = this.classProgramTermForm.get('acapt_start_date');
353
+ const endDateControl = this.classProgramTermForm.get('acapt_end_date');
354
+ if (startDateControl && endDateControl) {
355
+ // Remove custom validators
356
+ startDateControl.clearValidators();
357
+ endDateControl.clearValidators();
358
+ // Update validation
359
+ startDateControl.updateValueAndValidity();
360
+ endDateControl.updateValueAndValidity();
361
+ }
362
+ }
363
+ /**
364
+ * Custom validator for date range constraints
365
+ */
366
+ dateRangeValidator(parentStartDate, parentEndDate, dateType) {
367
+ return (control) => {
368
+ if (!control.value || !parentStartDate || !parentEndDate) {
369
+ return null; // No validation if no date or parent dates
370
+ }
371
+ const selectedDate = new Date(control.value);
372
+ const parentStart = new Date(parentStartDate);
373
+ const parentEnd = new Date(parentEndDate);
374
+ if (dateType === 'start') {
375
+ // Start date should be >= parent start date and < parent end date
376
+ if (selectedDate < parentStart || selectedDate >= parentEnd) {
377
+ return {
378
+ dateRangeError: {
379
+ message: `Start date must be between ${parentStartDate} and ${parentEndDate}`
380
+ }
381
+ };
382
+ }
383
+ }
384
+ else if (dateType === 'end') {
385
+ // End date should be > parent start date and <= parent end date
386
+ if (selectedDate <= parentStart || selectedDate > parentEnd) {
387
+ return {
388
+ dateRangeError: {
389
+ message: `End date must be between ${parentStartDate} and ${parentEndDate}`
390
+ }
391
+ };
392
+ }
393
+ }
394
+ return null; // Valid
395
+ };
396
+ }
397
+ /**
398
+ * Update minimum date for end date based on start date
399
+ */
400
+ updateEndDateMinDate(startDate) {
401
+ if (startDate) {
402
+ // Set the minimum date for end date to be the start date
403
+ this.endDateMinDate.set(startDate);
404
+ // If end date is already set and is before the new start date, clear it
405
+ const endDate = this.classProgramTermForm.get('acapt_end_date')?.value;
406
+ if (endDate && endDate < startDate) {
407
+ this.classProgramTermForm.patchValue({
408
+ acapt_end_date: ''
409
+ });
410
+ }
411
+ console.log('🏢 Updated end date minimum date to:', startDate);
412
+ }
413
+ else {
414
+ // Clear minimum date constraint if no start date
415
+ this.endDateMinDate.set('');
416
+ }
417
+ }
418
+ onSubmit() {
419
+ if (this.isViewMode()) {
420
+ this.router.navigate(['/control-panel/program-term-section-management']);
421
+ return;
422
+ }
423
+ if (this.classProgramTermForm.invalid) {
424
+ this.notificationService.error('Please fill in all required fields correctly.');
425
+ this.markFormGroupTouched();
426
+ return;
427
+ }
428
+ this.loading.set(true);
429
+ this.error.set(null);
430
+ const formData = this.classProgramTermForm.value;
431
+ console.log('Class Program Term Form Data:', formData);
432
+ // Prepare payload for API call
433
+ const payload = {
434
+ acapt_code: formData.acapt_code,
435
+ acapt_name: formData.acapt_name,
436
+ acapt_class_program_id_acacpm: formData.acapt_class_program_id_acacpm,
437
+ acapt_class_prg_branch_acabrn: formData.acapt_class_program_branch_id_acabrn,
438
+ acapt_parent_class_prog_term_acapt: formData.acapt_parent_class_prog_term_acapt || null,
439
+ acapt_start_date: formData.acapt_start_date,
440
+ acapt_end_date: formData.acapt_end_date,
441
+ acapt_isactive: formData.acapt_isactive,
442
+ acapt_islocked: formData.acapt_islocked
443
+ };
444
+ // Add _id for edit mode
445
+ if (this.isEditMode() && this.classProgramTermId()) {
446
+ payload._id = this.classProgramTermId();
447
+ }
448
+ console.log('API Payload:', payload);
449
+ // Make API call
450
+ this.classProgramTermService.saveClassProgramTerm(payload)
451
+ .pipe(takeUntilDestroyed(this.destroyRef))
452
+ .subscribe({
453
+ next: (response) => {
454
+ console.log('✅ Class program term saved successfully:', response);
455
+ if (response?.success) {
456
+ const action = this.isEditMode() ? 'updated' : 'created';
457
+ this.notificationService.success(`Class program term has been ${action} successfully.`);
458
+ this.router.navigate(['/control-panel/program-term-section-management']);
459
+ }
460
+ else {
461
+ this.error.set(response?.message || 'Failed to save class program term');
462
+ this.notificationService.error(response?.message || 'Failed to save class program term');
463
+ }
464
+ this.loading.set(false);
465
+ },
466
+ error: (error) => {
467
+ console.error('❌ Error saving class program term:', error);
468
+ this.error.set('Failed to save class program term');
469
+ this.notificationService.error('Failed to save class program term. Please try again.');
470
+ this.loading.set(false);
471
+ }
472
+ });
473
+ }
474
+ /**
475
+ * Mark all form controls as touched to trigger validation display
476
+ */
477
+ markFormGroupTouched() {
478
+ Object.keys(this.classProgramTermForm.controls).forEach(key => {
479
+ const control = this.classProgramTermForm.get(key);
480
+ control?.markAsTouched();
481
+ });
482
+ }
483
+ resetForm() {
484
+ this.classProgramTermForm.reset({
485
+ acapt_isactive: true,
486
+ acapt_islocked: false
487
+ });
488
+ // Clear options when form is reset
489
+ this.branchOptions.set([]);
490
+ this.parentTermOptions.set([]);
491
+ // Clear date constraints
492
+ this.clearDateConstraints();
493
+ this.endDateMinDate.set('');
494
+ }
495
+ /**
496
+ * Go back to class program term list
497
+ */
498
+ goBackToClassProgramTermList() {
499
+ this.router.navigate(['/control-panel/program-term-section-management']);
500
+ }
501
+ /**
502
+ * Cancel form and optionally navigate back
503
+ */
504
+ cancelForm() {
505
+ if (this.isEditMode()) {
506
+ this.goBackToClassProgramTermList();
507
+ }
508
+ else {
509
+ this.resetForm();
510
+ }
511
+ }
512
+ /**
513
+ * Get page title based on mode
514
+ */
515
+ getPageTitle() {
516
+ if (this.isViewMode())
517
+ return 'View Class Program Term';
518
+ return this.isEditMode() ? 'Edit Class Program Term' : 'Create New Class Program Term';
519
+ }
520
+ /**
521
+ * Handle Active card click to toggle checkbox
522
+ */
523
+ onActiveCardClick() {
524
+ if (this.isViewMode()) {
525
+ return; // Don't allow changes in view mode
526
+ }
527
+ const currentValue = this.classProgramTermForm.get('acapt_isactive')?.value;
528
+ this.classProgramTermForm.patchValue({
529
+ acapt_isactive: !currentValue
530
+ });
531
+ }
532
+ /**
533
+ * Handle Locked card click to toggle checkbox
534
+ */
535
+ onLockedCardClick() {
536
+ if (this.isViewMode()) {
537
+ return; // Don't allow changes in view mode
538
+ }
539
+ const currentValue = this.classProgramTermForm.get('acapt_islocked')?.value;
540
+ this.classProgramTermForm.patchValue({
541
+ acapt_islocked: !currentValue
542
+ });
543
+ }
544
+ /**
545
+ * Cleanup when component is destroyed
546
+ */
547
+ ngOnDestroy() {
548
+ console.log('🧹 ClassProgramTermCreateComponent: Cleaning up component state');
549
+ // Reset all signals to their initial state
550
+ this.loading.set(false);
551
+ this.error.set(null);
552
+ this.classProgramTermId.set('');
553
+ this.isEditMode.set(false);
554
+ this.programClassOptions.set([]);
555
+ this.branchOptions.set([]);
556
+ this.parentTermOptions.set([]);
557
+ // Reset form to initial state
558
+ this.resetForm();
559
+ console.log('🧹 ClassProgramTermCreateComponent: Component state cleaned up');
560
+ }
561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ClassProgramTermCreateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: ClassProgramTermCreateComponent, isStandalone: true, selector: "cide-academics-class-program-term-create", ngImport: i0, template: "<!-- \r\n CLASS PROGRAM TERM MASTER FORM\r\n \r\n Enterprise-Level Styling with Tailwind CSS\r\n Features: Responsive grids, proper typography, enhanced user experience\r\n-->\r\n\r\n<div class=\"tw-w-full tw-h-full\">\r\n <form class=\"tw-w-full tw-table tw-h-full tw-bg-transparent\" [formGroup]=\"classProgramTermForm\"\r\n [class.tw-opacity-60]=\"loading()\" (ngSubmit)=\"onSubmit()\">\r\n\r\n <!-- Simple Header Section -->\r\n <div class=\"tw-table-row tw-w-full tw-h-0\">\r\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-3 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\r\n <div\r\n class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-3 sm:tw-space-y-0\">\r\n\r\n <!-- Title -->\r\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\r\n <cide-ele-icon class=\"tw-text-orange-600 tw-w-5 tw-h-5\">schedule</cide-ele-icon>\r\n <h5 class=\"tw-text-base tw-font-medium tw-text-gray-900 tw-m-0\">\r\n {{ getPageTitle() }}\r\n </h5>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <div\r\n class=\"tw-flex tw-flex-col sm:tw-flex-row tw-items-start sm:tw-items-center tw-space-y-3 sm:tw-space-y-0 sm:tw-space-x-3\">\r\n <!-- Back button or other actions can be added here if needed -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Form Content -->\r\n <div class=\"tw-table-row\">\r\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-6\">\r\n <div class=\"tw-transition-opacity tw-duration-300\" [class.tw-opacity-60]=\"loading()\">\r\n <!-- Class Program Term Information -->\r\n <div class=\"tw-space-y-6\">\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <cide-ele-input label=\"Term Code *\" formControlName=\"acapt_code\" placeholder=\"e.g., T1, T2, T3\"\r\n size=\"md\" leadingIcon=\"code\">\r\n </cide-ele-input>\r\n\r\n <cide-ele-input label=\"Term Name *\" formControlName=\"acapt_name\"\r\n placeholder=\"e.g., First Term, Second Term\" size=\"md\" leadingIcon=\"schedule\">\r\n </cide-ele-input>\r\n </div>\r\n\r\n <div>\r\n <cide-ele-textarea label=\"Description\" formControlName=\"acapt_description\"\r\n placeholder=\"Enter detailed description of the term...\" rows=\"3\" size=\"md\">\r\n </cide-ele-textarea>\r\n </div>\r\n\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <cide-ele-input id=\"acapt_start_date\" label=\"Start Date\" formControlName=\"acapt_start_date\" type=\"date\"\r\n size=\"md\" leadingIcon=\"event\">\r\n </cide-ele-input>\r\n\r\n <cide-ele-input id=\"acapt_end_date\" label=\"End Date\" formControlName=\"acapt_end_date\" type=\"date\"\r\n [min]=\"endDateMinDate()\" size=\"md\" leadingIcon=\"event\">\r\n </cide-ele-input>\r\n </div>\r\n\r\n <div class=\"tw-p-3 tw-bg-blue-50 tw-border tw-border-blue-200 tw-rounded-lg\">\r\n <div class=\"tw-flex tw-items-center tw-gap-2\">\r\n <cide-ele-icon name=\"info\" class=\"tw-w-4 tw-h-4 tw-text-blue-500\"></cide-ele-icon>\r\n <span class=\"tw-text-sm tw-text-blue-700\">\r\n Sequence will be automatically managed through drag-and-drop on the listing page\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <div class=\"tw-space-y-2\">\r\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Program Class *</label>\r\n <cide-ele-select \r\n formControlName=\"acapt_class_program_id_acacpm\" \r\n placeholder=\"Select program class\"\r\n [disabled]=\"isViewMode()\" \r\n valueKey=\"_id\" \r\n labelKey=\"acacpm_alise_title\" \r\n [options]=\"programClassOptions()\">\r\n </cide-ele-select>\r\n </div>\r\n\r\n <div class=\"tw-space-y-2\">\r\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Class Program Branch *</label>\r\n <cide-ele-select \r\n formControlName=\"acapt_class_program_branch_id_acabrn\" \r\n placeholder=\"Select branch\"\r\n [disabled]=\"isViewMode()\" \r\n valueKey=\"_id\" \r\n labelKey=\"acabrn_name\" \r\n [options]=\"branchOptions()\">\r\n </cide-ele-select>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <div\r\n class=\"tw-flex tw-items-center tw-gap-3 tw-p-4 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200 tw-cursor-pointer hover:tw-bg-gray-100 tw-transition-colors tw-duration-200\"\r\n [class.tw-cursor-not-allowed]=\"isViewMode()\"\r\n [class.tw-opacity-60]=\"isViewMode()\"\r\n (click)=\"onActiveCardClick()\">\r\n <cide-ele-input formControlName=\"acapt_isactive\" type=\"checkbox\" size=\"md\">\r\n </cide-ele-input>\r\n <div class=\"tw-flex tw-flex-col\">\r\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Active</span>\r\n <span class=\"tw-text-xs tw-text-gray-500\">Enable/disable this term</span>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"tw-flex tw-items-center tw-gap-3 tw-p-4 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200 tw-cursor-pointer hover:tw-bg-gray-100 tw-transition-colors tw-duration-200\"\r\n [class.tw-cursor-not-allowed]=\"isViewMode()\"\r\n [class.tw-opacity-60]=\"isViewMode()\"\r\n (click)=\"onLockedCardClick()\">\r\n <cide-ele-input formControlName=\"acapt_islocked\" type=\"checkbox\" size=\"md\">\r\n </cide-ele-input>\r\n <div class=\"tw-flex tw-flex-col\">\r\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\r\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Error Display -->\r\n @if (error()) {\r\n <div class=\"tw-mt-6 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-lg\">\r\n <div class=\"tw-flex tw-items-center tw-gap-2\">\r\n <cide-ele-icon variant=\"red\" size=\"sm\">error</cide-ele-icon>\r\n <span class=\"tw-text-sm tw-font-medium tw-text-red-800\">{{ error() }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Form Actions -->\r\n <div class=\"tw-table-row tw-h-0\">\r\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-2 tw-bg-gray-50 tw-border-t tw-border-gray-200\">\r\n <div class=\"tw-flex tw-justify-end tw-gap-4\">\r\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"resetForm()\" leftIcon=\"refresh\"\r\n [disabled]=\"loading()\">\r\n Reset Form\r\n </button>\r\n\r\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"cancelForm()\" leftIcon=\"close\"\r\n [disabled]=\"loading()\">\r\n Cancel\r\n </button>\r\n\r\n <button cideEleButton type=\"submit\" variant=\"primary\" [disabled]=\"loading() || classProgramTermForm.invalid\"\r\n [loading]=\"loading()\" leftIcon=\"save\">\r\n {{ isEditMode() ? 'Update Class Program Term' : 'Create Class Program Term' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n</div>\r\n\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CideInputComponent, selector: "cide-ele-input", inputs: ["fill", "label", "labelHide", "disabled", "clearInput", "labelPlacement", "labelDir", "placeholder", "leadingIcon", "trailingIcon", "helperText", "helperTextCollapse", "hideHelperAndErrorText", "errorText", "maxlength", "minlength", "required", "autocapitalize", "autocomplete", "type", "width", "id", "ngModel", "option", "min", "max", "size"], outputs: ["ngModelChange"] }, { kind: "component", type: CideTextareaComponent, selector: "cide-ele-textarea", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "minlength", "maxlength", "rows", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput"], outputs: ["ngModelChange"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading", "valueKey", "labelKey"], outputs: ["ngModelChange", "change", "searchChange"] }] });
563
+ }
564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: ClassProgramTermCreateComponent, decorators: [{
565
+ type: Component,
566
+ args: [{ selector: 'cide-academics-class-program-term-create', standalone: true, imports: [
567
+ CommonModule,
568
+ ReactiveFormsModule,
569
+ CideInputComponent,
570
+ CideTextareaComponent,
571
+ CideEleButtonComponent,
572
+ CideIconComponent,
573
+ CideSelectComponent
574
+ ], template: "<!-- \r\n CLASS PROGRAM TERM MASTER FORM\r\n \r\n Enterprise-Level Styling with Tailwind CSS\r\n Features: Responsive grids, proper typography, enhanced user experience\r\n-->\r\n\r\n<div class=\"tw-w-full tw-h-full\">\r\n <form class=\"tw-w-full tw-table tw-h-full tw-bg-transparent\" [formGroup]=\"classProgramTermForm\"\r\n [class.tw-opacity-60]=\"loading()\" (ngSubmit)=\"onSubmit()\">\r\n\r\n <!-- Simple Header Section -->\r\n <div class=\"tw-table-row tw-w-full tw-h-0\">\r\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-3 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\r\n <div\r\n class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-3 sm:tw-space-y-0\">\r\n\r\n <!-- Title -->\r\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\r\n <cide-ele-icon class=\"tw-text-orange-600 tw-w-5 tw-h-5\">schedule</cide-ele-icon>\r\n <h5 class=\"tw-text-base tw-font-medium tw-text-gray-900 tw-m-0\">\r\n {{ getPageTitle() }}\r\n </h5>\r\n </div>\r\n\r\n <!-- Actions -->\r\n <div\r\n class=\"tw-flex tw-flex-col sm:tw-flex-row tw-items-start sm:tw-items-center tw-space-y-3 sm:tw-space-y-0 sm:tw-space-x-3\">\r\n <!-- Back button or other actions can be added here if needed -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Form Content -->\r\n <div class=\"tw-table-row\">\r\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-6\">\r\n <div class=\"tw-transition-opacity tw-duration-300\" [class.tw-opacity-60]=\"loading()\">\r\n <!-- Class Program Term Information -->\r\n <div class=\"tw-space-y-6\">\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <cide-ele-input label=\"Term Code *\" formControlName=\"acapt_code\" placeholder=\"e.g., T1, T2, T3\"\r\n size=\"md\" leadingIcon=\"code\">\r\n </cide-ele-input>\r\n\r\n <cide-ele-input label=\"Term Name *\" formControlName=\"acapt_name\"\r\n placeholder=\"e.g., First Term, Second Term\" size=\"md\" leadingIcon=\"schedule\">\r\n </cide-ele-input>\r\n </div>\r\n\r\n <div>\r\n <cide-ele-textarea label=\"Description\" formControlName=\"acapt_description\"\r\n placeholder=\"Enter detailed description of the term...\" rows=\"3\" size=\"md\">\r\n </cide-ele-textarea>\r\n </div>\r\n\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <cide-ele-input id=\"acapt_start_date\" label=\"Start Date\" formControlName=\"acapt_start_date\" type=\"date\"\r\n size=\"md\" leadingIcon=\"event\">\r\n </cide-ele-input>\r\n\r\n <cide-ele-input id=\"acapt_end_date\" label=\"End Date\" formControlName=\"acapt_end_date\" type=\"date\"\r\n [min]=\"endDateMinDate()\" size=\"md\" leadingIcon=\"event\">\r\n </cide-ele-input>\r\n </div>\r\n\r\n <div class=\"tw-p-3 tw-bg-blue-50 tw-border tw-border-blue-200 tw-rounded-lg\">\r\n <div class=\"tw-flex tw-items-center tw-gap-2\">\r\n <cide-ele-icon name=\"info\" class=\"tw-w-4 tw-h-4 tw-text-blue-500\"></cide-ele-icon>\r\n <span class=\"tw-text-sm tw-text-blue-700\">\r\n Sequence will be automatically managed through drag-and-drop on the listing page\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <div class=\"tw-space-y-2\">\r\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Program Class *</label>\r\n <cide-ele-select \r\n formControlName=\"acapt_class_program_id_acacpm\" \r\n placeholder=\"Select program class\"\r\n [disabled]=\"isViewMode()\" \r\n valueKey=\"_id\" \r\n labelKey=\"acacpm_alise_title\" \r\n [options]=\"programClassOptions()\">\r\n </cide-ele-select>\r\n </div>\r\n\r\n <div class=\"tw-space-y-2\">\r\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Class Program Branch *</label>\r\n <cide-ele-select \r\n formControlName=\"acapt_class_program_branch_id_acabrn\" \r\n placeholder=\"Select branch\"\r\n [disabled]=\"isViewMode()\" \r\n valueKey=\"_id\" \r\n labelKey=\"acabrn_name\" \r\n [options]=\"branchOptions()\">\r\n </cide-ele-select>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\r\n <div\r\n class=\"tw-flex tw-items-center tw-gap-3 tw-p-4 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200 tw-cursor-pointer hover:tw-bg-gray-100 tw-transition-colors tw-duration-200\"\r\n [class.tw-cursor-not-allowed]=\"isViewMode()\"\r\n [class.tw-opacity-60]=\"isViewMode()\"\r\n (click)=\"onActiveCardClick()\">\r\n <cide-ele-input formControlName=\"acapt_isactive\" type=\"checkbox\" size=\"md\">\r\n </cide-ele-input>\r\n <div class=\"tw-flex tw-flex-col\">\r\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Active</span>\r\n <span class=\"tw-text-xs tw-text-gray-500\">Enable/disable this term</span>\r\n </div>\r\n </div>\r\n\r\n <div\r\n class=\"tw-flex tw-items-center tw-gap-3 tw-p-4 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200 tw-cursor-pointer hover:tw-bg-gray-100 tw-transition-colors tw-duration-200\"\r\n [class.tw-cursor-not-allowed]=\"isViewMode()\"\r\n [class.tw-opacity-60]=\"isViewMode()\"\r\n (click)=\"onLockedCardClick()\">\r\n <cide-ele-input formControlName=\"acapt_islocked\" type=\"checkbox\" size=\"md\">\r\n </cide-ele-input>\r\n <div class=\"tw-flex tw-flex-col\">\r\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\r\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Error Display -->\r\n @if (error()) {\r\n <div class=\"tw-mt-6 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-lg\">\r\n <div class=\"tw-flex tw-items-center tw-gap-2\">\r\n <cide-ele-icon variant=\"red\" size=\"sm\">error</cide-ele-icon>\r\n <span class=\"tw-text-sm tw-font-medium tw-text-red-800\">{{ error() }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Form Actions -->\r\n <div class=\"tw-table-row tw-h-0\">\r\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-2 tw-bg-gray-50 tw-border-t tw-border-gray-200\">\r\n <div class=\"tw-flex tw-justify-end tw-gap-4\">\r\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"resetForm()\" leftIcon=\"refresh\"\r\n [disabled]=\"loading()\">\r\n Reset Form\r\n </button>\r\n\r\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"cancelForm()\" leftIcon=\"close\"\r\n [disabled]=\"loading()\">\r\n Cancel\r\n </button>\r\n\r\n <button cideEleButton type=\"submit\" variant=\"primary\" [disabled]=\"loading() || classProgramTermForm.invalid\"\r\n [loading]=\"loading()\" leftIcon=\"save\">\r\n {{ isEditMode() ? 'Update Class Program Term' : 'Create Class Program Term' }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n</div>\r\n\r\n" }]
575
+ }], ctorParameters: () => [] });
576
+
577
+ export { ClassProgramTermCreateComponent };
578
+ //# sourceMappingURL=cloud-ide-academics-class-program-term-create.component-B5sVQbaC.mjs.map