cloud-ide-academics 0.0.28 → 0.0.30

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 (26) hide show
  1. package/fesm2022/cloud-ide-academics-class-program-term-create.component-B-7JRpVE.mjs +1196 -0
  2. package/fesm2022/cloud-ide-academics-class-program-term-create.component-B-7JRpVE.mjs.map +1 -0
  3. package/fesm2022/{cloud-ide-academics-class-program-term-list.component-CP2vlRBP.mjs → cloud-ide-academics-class-program-term-list.component-DObKkh-y.mjs} +186 -48
  4. package/fesm2022/cloud-ide-academics-class-program-term-list.component-DObKkh-y.mjs.map +1 -0
  5. package/fesm2022/cloud-ide-academics-cloud-ide-academics-FwQEJSnJ.mjs +6127 -0
  6. package/fesm2022/cloud-ide-academics-cloud-ide-academics-FwQEJSnJ.mjs.map +1 -0
  7. package/fesm2022/{cloud-ide-academics-program-class-create.component-KijRP6Nl.mjs → cloud-ide-academics-program-class-create.component-x0rh1ESo.mjs} +45 -23
  8. package/fesm2022/cloud-ide-academics-program-class-create.component-x0rh1ESo.mjs.map +1 -0
  9. package/fesm2022/{cloud-ide-academics-program-class-list.component-B5cy2Gpk.mjs → cloud-ide-academics-program-class-list.component-CkzH8u8u.mjs} +10 -9
  10. package/fesm2022/cloud-ide-academics-program-class-list.component-CkzH8u8u.mjs.map +1 -0
  11. package/fesm2022/cloud-ide-academics.mjs +1 -1
  12. package/index.d.ts +500 -18
  13. package/package.json +1 -1
  14. package/fesm2022/cloud-ide-academics-class-program-term-create.component-BRbHViJN.mjs +0 -659
  15. package/fesm2022/cloud-ide-academics-class-program-term-create.component-BRbHViJN.mjs.map +0 -1
  16. package/fesm2022/cloud-ide-academics-class-program-term-list.component-CP2vlRBP.mjs.map +0 -1
  17. package/fesm2022/cloud-ide-academics-class-program-term.service-BW4PJQEM.mjs +0 -111
  18. package/fesm2022/cloud-ide-academics-class-program-term.service-BW4PJQEM.mjs.map +0 -1
  19. package/fesm2022/cloud-ide-academics-cloud-ide-academics-g9qZGJtG.mjs +0 -3102
  20. package/fesm2022/cloud-ide-academics-cloud-ide-academics-g9qZGJtG.mjs.map +0 -1
  21. package/fesm2022/cloud-ide-academics-program-class-create.component-KijRP6Nl.mjs.map +0 -1
  22. package/fesm2022/cloud-ide-academics-program-class-list.component-B5cy2Gpk.mjs.map +0 -1
  23. package/fesm2022/cloud-ide-academics-program-term-section-create.component-DHrTb-XI.mjs +0 -248
  24. package/fesm2022/cloud-ide-academics-program-term-section-create.component-DHrTb-XI.mjs.map +0 -1
  25. package/fesm2022/cloud-ide-academics-program-term-section-list.component-ktIAxvxR.mjs +0 -495
  26. package/fesm2022/cloud-ide-academics-program-term-section-list.component-ktIAxvxR.mjs.map +0 -1
@@ -1,3102 +0,0 @@
1
- import { authGuard } from 'cloud-ide-auth';
2
- import * as i0 from '@angular/core';
3
- import { inject, Injectable, DestroyRef, signal, Component, viewChild, computed } from '@angular/core';
4
- import * as i1$1 from '@angular/common';
5
- import { CommonModule, Location } from '@angular/common';
6
- import * as i1 from '@angular/forms';
7
- import { FormBuilder, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
8
- import { Router, ActivatedRoute } from '@angular/router';
9
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
10
- import { of, forkJoin } from 'rxjs';
11
- import { switchMap, catchError, map } from 'rxjs/operators';
12
- import { CideInputComponent, CideTextareaComponent, CideEleButtonComponent, CideEleTabComponent, CideIconComponent, CideSelectComponent, CideFormFieldErrorComponent, ConfirmationService, NotificationService, CideEleDataGridComponent, CideEleDropdownComponent } from 'cloud-ide-element';
13
- import { HttpClient } from '@angular/common/http';
14
- import { generateStringFromObject, cidePath, hostManagerRoutesUrl, academicsRoutesUrl, generateObjectFromString, AcaClassPrgBranchListPayload } from 'cloud-ide-lms-model';
15
- import { ENTITY_SERVICE_TOKEN, CideCoreGeneralMasterService } from 'cloud-ide-shared';
16
- import { AppStateHelperService, CideLytSharedWrapperComponent } from 'cloud-ide-layout';
17
-
18
- const academicsRoutes = [
19
- // Academic Year Management Routes
20
- {
21
- path: 'academic_year',
22
- loadComponent: () => Promise.resolve().then(function () { return academicYearList_component; }).then(c => c.AcademicYearListComponent),
23
- title: 'Academic Year Management',
24
- canActivate: [authGuard],
25
- data: {
26
- reuseTab: true,
27
- sypg_page_code: "academic_year_list"
28
- }
29
- },
30
- {
31
- path: 'academic_year/create',
32
- loadComponent: () => Promise.resolve().then(function () { return academicYearCreate_component; }).then(c => c.AcademicYearCreateComponent),
33
- title: 'Create Academic Year',
34
- canActivate: [authGuard],
35
- data: {
36
- reuseTab: true,
37
- sypg_page_code: "academic_year_list"
38
- }
39
- },
40
- {
41
- path: 'academic_year/edit/:query',
42
- loadComponent: () => Promise.resolve().then(function () { return academicYearCreate_component; }).then(c => c.AcademicYearCreateComponent),
43
- title: 'Edit Academic Year',
44
- canActivate: [authGuard],
45
- data: {
46
- reuseTab: true,
47
- sypg_page_code: "academic_year_list"
48
- }
49
- },
50
- {
51
- path: 'academic_year/view/:query',
52
- loadComponent: () => Promise.resolve().then(function () { return academicYearCreate_component; }).then(c => c.AcademicYearCreateComponent),
53
- title: 'View Academic Year',
54
- canActivate: [authGuard],
55
- data: {
56
- reuseTab: true,
57
- sypg_page_code: "academic_year_list"
58
- }
59
- },
60
- {
61
- path: 'program-class-management',
62
- loadComponent: () => import('./cloud-ide-academics-program-class-list.component-B5cy2Gpk.mjs').then(c => c.ProgramClassListComponent),
63
- title: 'Program Class Management',
64
- canActivate: [authGuard],
65
- data: {
66
- reuseTab: false,
67
- sypg_page_code: "program_class"
68
- }
69
- },
70
- {
71
- path: 'program-class-management/create',
72
- loadComponent: () => import('./cloud-ide-academics-program-class-create.component-KijRP6Nl.mjs').then(c => c.ProgramClassCreateComponent),
73
- title: 'Create Program Class',
74
- canActivate: [authGuard],
75
- data: {
76
- reuseTab: false,
77
- sypg_page_code: "program_class"
78
- }
79
- },
80
- {
81
- path: 'program-class-management/edit/:query',
82
- loadComponent: () => import('./cloud-ide-academics-program-class-create.component-KijRP6Nl.mjs').then(c => c.ProgramClassCreateComponent),
83
- title: 'Edit Program Class',
84
- canActivate: [authGuard],
85
- data: {
86
- reuseTab: false,
87
- sypg_page_code: "program_class"
88
- }
89
- },
90
- {
91
- path: 'program-class-management/view/:query',
92
- loadComponent: () => import('./cloud-ide-academics-program-class-create.component-KijRP6Nl.mjs').then(c => c.ProgramClassCreateComponent),
93
- title: 'View Program Class',
94
- canActivate: [authGuard],
95
- data: {
96
- reuseTab: false,
97
- sypg_page_code: "program_class"
98
- }
99
- },
100
- {
101
- path: 'program-term-management/create',
102
- loadComponent: () => import('./cloud-ide-academics-class-program-term-create.component-BRbHViJN.mjs').then(c => c.ClassProgramTermCreateComponent),
103
- title: 'Create Class Program Term',
104
- canActivate: [authGuard],
105
- data: {
106
- reuseTab: true,
107
- sypg_page_code: "class_program_term"
108
- }
109
- },
110
- {
111
- path: 'program-term-management/edit/:query',
112
- loadComponent: () => import('./cloud-ide-academics-class-program-term-create.component-BRbHViJN.mjs').then(c => c.ClassProgramTermCreateComponent),
113
- title: 'Edit Class Program Term',
114
- canActivate: [authGuard],
115
- data: {
116
- reuseTab: true,
117
- sypg_page_code: "class_program_term"
118
- }
119
- },
120
- {
121
- path: 'program-term-management/view/:query',
122
- loadComponent: () => import('./cloud-ide-academics-class-program-term-create.component-BRbHViJN.mjs').then(c => c.ClassProgramTermCreateComponent),
123
- title: 'View Class Program Term',
124
- canActivate: [authGuard],
125
- data: {
126
- reuseTab: true,
127
- sypg_page_code: "class_program_term"
128
- }
129
- },
130
- {
131
- path: 'program-term-management',
132
- loadComponent: () => import('./cloud-ide-academics-class-program-term-list.component-CP2vlRBP.mjs').then(c => c.ClassProgramTermListComponent),
133
- title: 'Class Program Term Management',
134
- canActivate: [authGuard],
135
- data: {
136
- reuseTab: true,
137
- sypg_page_code: "class_program_term"
138
- }
139
- },
140
- {
141
- path: 'program-term-management/:query',
142
- loadComponent: () => import('./cloud-ide-academics-class-program-term-list.component-CP2vlRBP.mjs').then(c => c.ClassProgramTermListComponent),
143
- title: 'Class Program Term Management',
144
- canActivate: [authGuard],
145
- data: {
146
- reuseTab: true,
147
- sypg_page_code: "class_program_term"
148
- }
149
- },
150
- {
151
- path: 'class-program-term',
152
- loadComponent: () => import('./cloud-ide-academics-program-term-section-list.component-ktIAxvxR.mjs').then(c => c.ProgramTermSectionListComponent),
153
- title: 'Program Term Section Management',
154
- canActivate: [authGuard],
155
- data: {
156
- reuseTab: true,
157
- sypg_page_code: "program_term_section"
158
- }
159
- },
160
- {
161
- path: 'class-program-term/:query',
162
- loadComponent: () => import('./cloud-ide-academics-program-term-section-list.component-ktIAxvxR.mjs').then(c => c.ProgramTermSectionListComponent),
163
- title: 'Program Term Section Management',
164
- canActivate: [authGuard],
165
- data: {
166
- reuseTab: true,
167
- sypg_page_code: "program_term_section"
168
- }
169
- },
170
- {
171
- path: 'class-program-term/create',
172
- loadComponent: () => import('./cloud-ide-academics-program-term-section-create.component-DHrTb-XI.mjs').then(c => c.ProgramTermSectionCreateComponent),
173
- title: 'Create Program Term Section',
174
- canActivate: [authGuard],
175
- data: {
176
- reuseTab: true,
177
- sypg_page_code: "program_term_section"
178
- }
179
- },
180
- {
181
- path: 'class-program-term/edit/:query',
182
- loadComponent: () => import('./cloud-ide-academics-program-term-section-create.component-DHrTb-XI.mjs').then(c => c.ProgramTermSectionCreateComponent),
183
- title: 'Edit Program Term Section',
184
- canActivate: [authGuard],
185
- data: {
186
- reuseTab: true,
187
- sypg_page_code: "program_term_section"
188
- }
189
- },
190
- {
191
- path: 'class-program-term/view/:query',
192
- loadComponent: () => import('./cloud-ide-academics-program-term-section-create.component-DHrTb-XI.mjs').then(c => c.ProgramTermSectionCreateComponent),
193
- title: 'View Program Term Section',
194
- canActivate: [authGuard],
195
- data: {
196
- reuseTab: true,
197
- sypg_page_code: "program_term_section"
198
- }
199
- },
200
- // Class Program Branch Management Routes
201
- {
202
- path: 'program_specialization/:query',
203
- loadComponent: () => Promise.resolve().then(function () { return classProgramBranchList_component; }).then(c => c.CideLytClassProgramBranchListComponent),
204
- title: 'Class Program Branch Management',
205
- canActivate: [authGuard],
206
- data: {
207
- reuseTab: true,
208
- sypg_page_code: "class_program_branch"
209
- }
210
- },
211
- {
212
- path: 'program_specialization',
213
- loadComponent: () => Promise.resolve().then(function () { return classProgramBranchList_component; }).then(c => c.CideLytClassProgramBranchListComponent),
214
- title: 'Class Program Branch Management',
215
- canActivate: [authGuard],
216
- data: {
217
- reuseTab: true,
218
- sypg_page_code: "class_program_branch"
219
- }
220
- },
221
- {
222
- path: 'program_specialization/create/:query?',
223
- loadComponent: () => Promise.resolve().then(function () { return classProgramBranchForm_component; }).then(c => c.CideLytClassProgramBranchFormComponent),
224
- title: 'Create Class Program Branch',
225
- canActivate: [authGuard],
226
- data: {
227
- reuseTab: true,
228
- sypg_page_code: "class_program_branch"
229
- }
230
- },
231
- {
232
- path: 'program_specialization/edit/:query',
233
- loadComponent: () => Promise.resolve().then(function () { return classProgramBranchForm_component; }).then(c => c.CideLytClassProgramBranchFormComponent),
234
- title: 'Edit Class Program Branch',
235
- canActivate: [authGuard],
236
- data: {
237
- reuseTab: true,
238
- sypg_page_code: "class_program_branch"
239
- }
240
- },
241
- {
242
- path: 'program_specialization/view/:query',
243
- loadComponent: () => Promise.resolve().then(function () { return classProgramBranchForm_component; }).then(c => c.CideLytClassProgramBranchFormComponent),
244
- title: 'View Class Program Branch',
245
- canActivate: [authGuard],
246
- data: {
247
- reuseTab: true,
248
- sypg_page_code: "class_program_branch"
249
- }
250
- }
251
- ];
252
-
253
- class CideLytAcademicYearService {
254
- http = inject(HttpClient);
255
- /**
256
- * Get list of academic years
257
- * @param payload - Query parameters for filtering/pagination
258
- * @returns Observable of academic year list response
259
- */
260
- getAcademicYearList(payload) {
261
- console.log("payload", payload);
262
- const query = generateStringFromObject(payload);
263
- const url = cidePath.join([
264
- hostManagerRoutesUrl.cideSuiteHost,
265
- academicsRoutesUrl.module,
266
- academicsRoutesUrl.academicYear,
267
- query
268
- ]);
269
- return this.http.get(url);
270
- }
271
- /**
272
- * Get academic year by ID
273
- * @param payload - Academic year ID payload
274
- * @returns Observable of academic year data
275
- */
276
- getAcademicYearById(payload) {
277
- const query = generateStringFromObject(payload);
278
- const url = cidePath.join([
279
- hostManagerRoutesUrl.cideSuiteHost,
280
- academicsRoutesUrl.module,
281
- academicsRoutesUrl.academicYear,
282
- 'byId',
283
- query
284
- ]);
285
- return this.http.get(url);
286
- }
287
- /**
288
- * Create or update academic year
289
- * @param data - Academic year data to save
290
- * @returns Observable of the save response
291
- */
292
- saveUpdateAcademicYear(data) {
293
- const url = cidePath.join([
294
- hostManagerRoutesUrl.cideSuiteHost,
295
- academicsRoutesUrl.module,
296
- academicsRoutesUrl.academicYear
297
- ]);
298
- return this.http.post(url, data);
299
- }
300
- /**
301
- * Create or update academic year with mappings
302
- * @param data - Academic year data with mappings
303
- * @returns Observable of the save response
304
- */
305
- saveUpdateAcademicYearWithMappings(data) {
306
- // Extract mappings from the data
307
- const mappings = data.acayr_academic_year_mappings || [];
308
- const academicYearData = { ...data };
309
- delete academicYearData.acayr_academic_year_mappings;
310
- // First save/update the academic year
311
- return this.saveUpdateAcademicYear(academicYearData).pipe(switchMap((academicYearResponse) => {
312
- if (!academicYearResponse.success || !academicYearResponse.data) {
313
- return of(academicYearResponse);
314
- }
315
- const academicYearId = academicYearResponse.data._id;
316
- // If no mappings, return the academic year response
317
- if (mappings.length === 0) {
318
- return of(academicYearResponse);
319
- }
320
- // Process mappings
321
- const mappingObservables = mappings.map((mapping) => {
322
- const mappingPayload = {
323
- _id: mapping._id && !mapping._id.startsWith('temp_') ? mapping._id : undefined,
324
- acayrmp_academic_year_id_acayr: academicYearId,
325
- acayrmp_entity_id_syen: mapping.acayrmp_entity_id_syen,
326
- acayrmp_islocked: mapping.acayrmp_islocked || false,
327
- acayrmp_iscurrent: mapping.acayrmp_iscurrent || false
328
- };
329
- const mappingUrl = cidePath.join([
330
- hostManagerRoutesUrl.cideSuiteHost,
331
- academicsRoutesUrl.module,
332
- academicsRoutesUrl.academicYearMapping
333
- ]);
334
- return this.http.post(mappingUrl, mappingPayload).pipe(catchError((error) => {
335
- console.error('Error saving mapping:', error);
336
- return of({ success: false, error });
337
- }));
338
- });
339
- // Execute all mapping operations
340
- return forkJoin(mappingObservables).pipe(map((mappingResponses) => {
341
- // Check if all mappings were successful
342
- const allMappingsSuccessful = mappingResponses.every((response) => response.success);
343
- if (allMappingsSuccessful) {
344
- return {
345
- ...academicYearResponse,
346
- message: 'Academic year and mappings saved successfully'
347
- };
348
- }
349
- else {
350
- return {
351
- ...academicYearResponse,
352
- message: 'Academic year saved but some mappings failed',
353
- mappingErrors: mappingResponses.filter((response) => !response.success)
354
- };
355
- }
356
- }));
357
- }), catchError((error) => {
358
- console.error('Error in saveUpdateAcademicYearWithMappings:', error);
359
- return of({
360
- success: false,
361
- code: 500,
362
- message: 'Error saving academic year with mappings',
363
- error
364
- });
365
- }));
366
- }
367
- /**
368
- * Delete academic year
369
- * @param payload - Academic year ID payload
370
- * @returns Observable of the delete response
371
- */
372
- deleteAcademicYear(payload) {
373
- const query = generateStringFromObject(payload);
374
- const url = cidePath.join([
375
- hostManagerRoutesUrl.cideSuiteHost,
376
- academicsRoutesUrl.module,
377
- academicsRoutesUrl.academicYear,
378
- 'delete',
379
- query
380
- ]);
381
- return this.http.delete(url);
382
- }
383
- /**
384
- * Toggle academic year status
385
- * @param payload - Academic year ID payload
386
- * @returns Observable of the toggle response
387
- */
388
- toggleAcademicYearStatus(payload) {
389
- const url = cidePath.join([
390
- hostManagerRoutesUrl.cideSuiteHost,
391
- academicsRoutesUrl.module,
392
- academicsRoutesUrl.academicYear,
393
- 'toggle-status'
394
- ]);
395
- console.log('🔄 Making PATCH request to toggle academic year status:', { url, payload });
396
- return this.http.patch(url, payload);
397
- }
398
- /**
399
- * Delete academic year mapping
400
- * @param payload - Academic year mapping ID payload
401
- * @returns Observable of the delete response
402
- */
403
- deleteAcademicYearMapping(payload) {
404
- const url = cidePath.join([
405
- hostManagerRoutesUrl.cideSuiteHost,
406
- academicsRoutesUrl.module,
407
- academicsRoutesUrl.academicYearMapping
408
- ]);
409
- return this.http.delete(url, { body: payload });
410
- }
411
- /**
412
- * Toggle academic year mapping status
413
- * @param payload - Academic year mapping ID payload
414
- * @returns Observable of the toggle response
415
- */
416
- toggleAcademicYearMappingStatus(payload) {
417
- const url = cidePath.join([
418
- hostManagerRoutesUrl.cideSuiteHost,
419
- academicsRoutesUrl.module,
420
- academicsRoutesUrl.academicYearMapping,
421
- 'toggle-status'
422
- ]);
423
- console.log('🔄 Making PATCH request to toggle academic year mapping status:', { url, payload });
424
- return this.http.patch(url, payload);
425
- }
426
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytAcademicYearService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
427
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytAcademicYearService, providedIn: 'root' });
428
- }
429
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytAcademicYearService, decorators: [{
430
- type: Injectable,
431
- args: [{
432
- providedIn: 'root'
433
- }]
434
- }] });
435
-
436
- class CideLytAcademicYearMappingService {
437
- http = inject(HttpClient);
438
- /**
439
- * Get list of academic year mappings
440
- * @param payload - Query parameters for filtering/pagination
441
- * @returns Observable of academic year mapping list response
442
- */
443
- getAcademicYearMappingList(payload) {
444
- const query = generateStringFromObject(payload);
445
- const url = cidePath.join([
446
- hostManagerRoutesUrl.cideSuiteHost,
447
- academicsRoutesUrl.module,
448
- academicsRoutesUrl.academicYearMapping,
449
- query
450
- ]);
451
- return this.http.get(url);
452
- }
453
- /**
454
- * Get academic year mapping by ID
455
- * @param payload - Academic year mapping ID payload
456
- * @returns Observable of academic year mapping data
457
- */
458
- getAcademicYearMappingById(payload) {
459
- const query = generateStringFromObject(payload);
460
- const url = cidePath.join([
461
- hostManagerRoutesUrl.cideSuiteHost,
462
- academicsRoutesUrl.module,
463
- academicsRoutesUrl.academicYearMapping,
464
- 'byId',
465
- query
466
- ]);
467
- return this.http.get(url);
468
- }
469
- /**
470
- * Create or update academic year mapping
471
- * @param data - Academic year mapping data to save
472
- * @returns Observable of the save response
473
- */
474
- saveUpdateAcademicYearMapping(data) {
475
- const url = cidePath.join([
476
- hostManagerRoutesUrl.cideSuiteHost,
477
- academicsRoutesUrl.module,
478
- academicsRoutesUrl.academicYearMapping
479
- ]);
480
- return this.http.post(url, data);
481
- }
482
- /**
483
- * Delete academic year mapping
484
- * @param payload - Academic year mapping ID payload
485
- * @returns Observable of the delete response
486
- */
487
- deleteAcademicYearMapping(payload) {
488
- const query = generateStringFromObject(payload);
489
- const url = cidePath.join([
490
- hostManagerRoutesUrl.cideSuiteHost,
491
- academicsRoutesUrl.module,
492
- academicsRoutesUrl.academicYearMapping,
493
- 'delete',
494
- query
495
- ]);
496
- return this.http.delete(url);
497
- }
498
- /**
499
- * Toggle academic year mapping status
500
- * @param payload - Academic year mapping ID payload
501
- * @returns Observable of the toggle response
502
- */
503
- toggleAcademicYearMappingStatus(payload) {
504
- const url = cidePath.join([
505
- hostManagerRoutesUrl.cideSuiteHost,
506
- academicsRoutesUrl.module,
507
- academicsRoutesUrl.academicYearMapping,
508
- 'toggle-status'
509
- ]);
510
- return this.http.post(url, payload);
511
- }
512
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytAcademicYearMappingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
513
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytAcademicYearMappingService, providedIn: 'root' });
514
- }
515
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytAcademicYearMappingService, decorators: [{
516
- type: Injectable,
517
- args: [{
518
- providedIn: 'root'
519
- }]
520
- }] });
521
-
522
- class AcademicYearCreateComponent {
523
- // Modern Angular 20+ dependency injection
524
- destroyRef = inject(DestroyRef);
525
- fb = inject(FormBuilder);
526
- academicYearService = inject(CideLytAcademicYearService);
527
- academicYearMappingService = inject(CideLytAcademicYearMappingService);
528
- entityService = inject(ENTITY_SERVICE_TOKEN);
529
- router = inject(Router);
530
- route = inject(ActivatedRoute);
531
- // Form and state management with proper typing
532
- academicYearForm;
533
- activeTab = signal('basic', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
534
- loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
535
- // Academic year information from route
536
- academicYearId = signal('', ...(ngDevMode ? [{ debugName: "academicYearId" }] : []));
537
- isEditMode = signal(false, ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
538
- originalMappings = signal([], ...(ngDevMode ? [{ debugName: "originalMappings" }] : [])); // Track original mappings for deletion
539
- // Entity options for dropdown
540
- entityOptions = signal([], ...(ngDevMode ? [{ debugName: "entityOptions" }] : []));
541
- constructor() {
542
- this.academicYearForm = this.fb.group({
543
- // Basic Academic Year Information
544
- acayr_code: ['', [Validators.required]],
545
- acayr_name: ['', [Validators.required]],
546
- acayr_description: [''],
547
- acayr_from_date: ['', [Validators.required]],
548
- acayr_to_date: ['', [Validators.required]],
549
- acayr_isactive: [true],
550
- acayr_iscurrent: [false],
551
- acayr_islocked: [false],
552
- // Academic Year Mapping Information
553
- acayr_academic_year_mappings: this.fb.array([])
554
- });
555
- }
556
- ngOnInit() {
557
- this.initializeComponent();
558
- }
559
- /**
560
- * Initialize component
561
- */
562
- initializeComponent() {
563
- // Get academic year information from route (for edit mode)
564
- this.route.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(params => {
565
- const queryParams = params['query'];
566
- console.log(queryParams, 'queryParams');
567
- if (queryParams) {
568
- // Query parameters passed (following page-controls pattern)
569
- const queryData = generateObjectFromString(queryParams);
570
- if (queryData?.acayr_id) {
571
- this.academicYearId.set(queryData.acayr_id);
572
- this.isEditMode.set(true);
573
- this.loadAcademicYearData(queryData.acayr_id);
574
- }
575
- }
576
- else {
577
- // Create mode
578
- this.isEditMode.set(false);
579
- }
580
- // Always load dropdown options
581
- this.loadDropdownOptions();
582
- });
583
- }
584
- /**
585
- * Load dropdown options
586
- */
587
- loadDropdownOptions() {
588
- console.log('🏢 Loading dropdown options');
589
- // Load entity options
590
- this.entityService.getEntityList({}).subscribe({
591
- next: (response) => {
592
- if (response?.success) {
593
- console.log(`🏢 entities:`, response.data);
594
- this.entityOptions.set(response.data || []);
595
- }
596
- },
597
- error: (error) => console.error('Error loading entities:', error)
598
- });
599
- }
600
- /**
601
- * Load academic year data for edit mode
602
- */
603
- loadAcademicYearData(academicYearId) {
604
- this.loading.set(true);
605
- const payload = {
606
- acayr_id: academicYearId
607
- };
608
- // Load academic year data
609
- this.academicYearService.getAcademicYearById(payload).subscribe({
610
- next: (response) => {
611
- if (response?.success && response.data) {
612
- console.log('📚 Academic year data loaded:', response.data);
613
- this.populateFormWithAcademicYearData(response.data);
614
- // Load existing mappings for this academic year
615
- this.loadAcademicYearMappings(academicYearId);
616
- }
617
- else {
618
- console.error('❌ Failed to load academic year data');
619
- this.loading.set(false);
620
- }
621
- },
622
- error: (error) => {
623
- console.error('❌ Error loading academic year data:', error);
624
- this.loading.set(false);
625
- }
626
- });
627
- }
628
- /**
629
- * Load academic year mappings for edit mode
630
- */
631
- loadAcademicYearMappings(academicYearId) {
632
- const mappingPayload = {
633
- acayrmp_academic_year_id_acayr: academicYearId
634
- };
635
- this.academicYearMappingService.getAcademicYearMappingList(mappingPayload).subscribe({
636
- next: (response) => {
637
- if (response?.success && response.data) {
638
- console.log('🔗 Academic year mappings loaded:', response.data);
639
- this.populateFormWithMappingsData(response.data);
640
- }
641
- else {
642
- console.warn('⚠️ No mappings found for this academic year');
643
- }
644
- this.loading.set(false);
645
- },
646
- error: (error) => {
647
- console.error('❌ Error loading academic year mappings:', error);
648
- this.loading.set(false);
649
- }
650
- });
651
- }
652
- /**
653
- * Populate form with academic year data
654
- */
655
- populateFormWithAcademicYearData(data) {
656
- if (data) {
657
- this.academicYearForm.patchValue({
658
- acayr_code: data.acayr_code || '',
659
- acayr_name: data.acayr_name || '',
660
- acayr_description: data.acayr_description || '',
661
- acayr_from_date: data.acayr_from_date ? new Date(data.acayr_from_date).toISOString().split('T')[0] : '',
662
- acayr_to_date: data.acayr_to_date ? new Date(data.acayr_to_date).toISOString().split('T')[0] : '',
663
- acayr_isactive: data.acayr_isactive ?? true,
664
- acayr_iscurrent: data.acayr_iscurrent ?? false,
665
- acayr_islocked: data.acayr_islocked ?? false
666
- });
667
- }
668
- }
669
- /**
670
- * Populate form with mappings data
671
- */
672
- populateFormWithMappingsData(mappings) {
673
- if (mappings && Array.isArray(mappings)) {
674
- // Store original mappings for deletion tracking
675
- this.originalMappings.set([...mappings]);
676
- // Clear existing mappings
677
- while (this.academicYearMappingsArray.length !== 0) {
678
- this.academicYearMappingsArray.removeAt(0);
679
- }
680
- // Add existing mappings
681
- mappings.forEach((mapping) => {
682
- const mappingGroup = this.fb.group({
683
- _id: [mapping._id || ''],
684
- acayrmp_academic_year_id_acayr: [mapping.acayrmp_academic_year_id_acayr || this.academicYearId() || '', [Validators.required]],
685
- acayrmp_entity_id_syen: [mapping.acayrmp_entity_id_syen || '', [Validators.required]],
686
- acayrmp_islocked: [mapping.acayrmp_islocked ?? false],
687
- acayrmp_iscurrent: [mapping.acayrmp_iscurrent ?? false]
688
- });
689
- this.academicYearMappingsArray.push(mappingGroup);
690
- });
691
- }
692
- }
693
- /**
694
- * Tab configuration
695
- */
696
- academicYearTabs() {
697
- return [
698
- { id: 'basic', label: 'Academic Year Details', icon: 'school' },
699
- { id: 'mapping', label: 'Mapping Configuration', icon: 'link' }
700
- ];
701
- }
702
- onTabChange(tab) {
703
- this.activeTab.set(tab.id);
704
- }
705
- onSubmit() {
706
- if (this.academicYearForm.valid && this.validateMappings()) {
707
- this.loading.set(true);
708
- const formData = this.academicYearForm.value;
709
- // Prepare payload with mappings
710
- const payload = {
711
- ...formData,
712
- _id: this.isEditMode() ? this.academicYearId() : undefined,
713
- acayr_academic_year_mappings: this.getAcademicYearMappingsValue()
714
- };
715
- console.log('📤 Submitting academic year with mappings:', payload);
716
- // First delete removed mappings, then save/update academic year
717
- this.deleteRemovedMappings().pipe(switchMap(() => {
718
- // After deleting removed mappings, save/update the academic year
719
- return this.academicYearService.saveUpdateAcademicYearWithMappings(payload);
720
- })).subscribe({
721
- next: (response) => {
722
- if (response?.success) {
723
- console.log('✅ Academic year and mappings saved successfully:', response.data);
724
- // Check if there were any mapping errors
725
- if (response.mappingErrors && response.mappingErrors.length > 0) {
726
- console.warn('⚠️ Some mappings failed:', response.mappingErrors);
727
- }
728
- else {
729
- this.goBackToAcademicYearList();
730
- }
731
- }
732
- else {
733
- console.error('❌ Failed to save academic year');
734
- }
735
- this.loading.set(false);
736
- },
737
- error: (error) => {
738
- console.error('❌ Error saving academic year:', error);
739
- this.loading.set(false);
740
- }
741
- });
742
- }
743
- else {
744
- console.warn('Form is invalid');
745
- this.markFormGroupTouched();
746
- }
747
- }
748
- /**
749
- * Mark all form controls as touched to trigger validation display
750
- */
751
- markFormGroupTouched() {
752
- Object.keys(this.academicYearForm.controls).forEach(key => {
753
- const control = this.academicYearForm.get(key);
754
- control?.markAsTouched();
755
- });
756
- }
757
- resetForm() {
758
- this.academicYearForm.reset({
759
- acayr_isactive: true,
760
- acayr_iscurrent: false,
761
- acayr_islocked: false
762
- });
763
- // Clear the mappings array
764
- while (this.academicYearMappingsArray.length !== 0) {
765
- this.academicYearMappingsArray.removeAt(0);
766
- }
767
- // Reset academic year ID
768
- this.academicYearId.set('');
769
- this.isEditMode.set(false);
770
- this.originalMappings.set([]);
771
- // Reset entity options to show all entities again
772
- this.updateEntityOptionsForMappings();
773
- }
774
- /**
775
- * Go back to academic year list
776
- */
777
- goBackToAcademicYearList() {
778
- this.router.navigate(['/control-panel/academic-year']);
779
- }
780
- /**
781
- * Cancel form and optionally navigate back
782
- */
783
- cancelForm() {
784
- if (this.isEditMode()) {
785
- this.goBackToAcademicYearList();
786
- }
787
- else {
788
- this.resetForm();
789
- }
790
- }
791
- /**
792
- * Get page title based on mode
793
- */
794
- getPageTitle() {
795
- return this.isEditMode() ? 'Edit Academic Year' : 'Create New Academic Year';
796
- }
797
- /**
798
- * Getter methods for form arrays
799
- */
800
- get academicYearMappingsArray() {
801
- return this.academicYearForm.get('acayr_academic_year_mappings');
802
- }
803
- /**
804
- * Add new academic year mapping
805
- */
806
- addAcademicYearMapping() {
807
- // Check if there are any available entities to map
808
- const availableEntities = this.getAvailableEntityCount(this.academicYearMappingsArray.length);
809
- if (availableEntities === 0) {
810
- console.warn('No available entities to map');
811
- return;
812
- }
813
- // Generate a temporary ID for new mappings
814
- const tempId = 'temp_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
815
- const academicYearMapping = this.fb.group({
816
- _id: [tempId],
817
- acayrmp_academic_year_id_acayr: [this.academicYearId() || '', [Validators.required]],
818
- acayrmp_entity_id_syen: ['', [Validators.required]],
819
- acayrmp_islocked: [false],
820
- acayrmp_iscurrent: [false]
821
- });
822
- this.academicYearMappingsArray.push(academicYearMapping);
823
- }
824
- /**
825
- * Update academic year ID in all existing mappings when academic year ID changes
826
- */
827
- updateMappingsAcademicYearId(newAcademicYearId) {
828
- const mappingsArray = this.academicYearMappingsArray;
829
- mappingsArray.controls.forEach((control) => {
830
- if (control.get('acayrmp_academic_year_id_acayr')) {
831
- control.get('acayrmp_academic_year_id_acayr').setValue(newAcademicYearId);
832
- }
833
- });
834
- }
835
- /**
836
- * Get form array value for validation or submission
837
- */
838
- getAcademicYearMappingsValue() {
839
- return this.academicYearMappingsArray.value;
840
- }
841
- /**
842
- * Check if mappings array has any invalid controls
843
- */
844
- isMappingsArrayValid() {
845
- return this.academicYearMappingsArray.valid;
846
- }
847
- /**
848
- * Set academic year ID for all existing mappings
849
- * This is useful when the academic year ID is generated after creation
850
- */
851
- setAcademicYearIdForMappings(academicYearId) {
852
- this.academicYearId.set(academicYearId);
853
- this.updateMappingsAcademicYearId(academicYearId);
854
- }
855
- /**
856
- * Validate that all mappings have required fields
857
- */
858
- validateMappings() {
859
- const mappings = this.academicYearMappingsArray.controls;
860
- // Check if there are any mappings
861
- if (mappings.length === 0) {
862
- return true; // No mappings is valid
863
- }
864
- // Validate each mapping
865
- for (let i = 0; i < mappings.length; i++) {
866
- const mapping = mappings[i];
867
- // Check required fields
868
- if (!mapping.get('acayrmp_entity_id_syen')?.value) {
869
- console.warn(`Mapping ${i + 1} is missing entity selection`);
870
- return false;
871
- }
872
- // Check for duplicate entity selections
873
- const currentEntityId = mapping.get('acayrmp_entity_id_syen')?.value;
874
- const duplicateIndex = this.findDuplicateEntitySelection(currentEntityId, i);
875
- if (duplicateIndex !== -1) {
876
- console.warn(`Mapping ${i + 1} has duplicate entity selection with mapping ${duplicateIndex + 1}`);
877
- return false;
878
- }
879
- }
880
- return true;
881
- }
882
- /**
883
- * Find duplicate entity selection in mappings
884
- */
885
- findDuplicateEntitySelection(entityId, currentIndex) {
886
- const mappings = this.academicYearMappingsArray.controls;
887
- for (let i = 0; i < mappings.length; i++) {
888
- if (i !== currentIndex) {
889
- const mapping = mappings[i];
890
- if (mapping.get('acayrmp_entity_id_syen')?.value === entityId) {
891
- return i;
892
- }
893
- }
894
- }
895
- return -1;
896
- }
897
- /**
898
- * Remove academic year mapping
899
- */
900
- removeAcademicYearMapping(index) {
901
- this.academicYearMappingsArray.removeAt(index);
902
- // Update entity options after removal to re-enable previously selected entities
903
- this.updateEntityOptionsForMappings();
904
- }
905
- /**
906
- * Handle entity selection change for a specific mapping
907
- */
908
- onMappingEntityChange(event, mappingIndex) {
909
- const selectedEntityId = event?.value || event;
910
- if (selectedEntityId) {
911
- console.log(`🏢 Entity selected for mapping ${mappingIndex}:`, selectedEntityId);
912
- // Trigger change detection to update other mappings' entity options
913
- this.updateEntityOptionsForMappings();
914
- }
915
- }
916
- /**
917
- * Get filtered entity options excluding already selected entities in other mappings
918
- * @param currentMappingIndex The index of the current mapping being edited
919
- * @returns Entity options excluding already selected entities
920
- */
921
- getFilteredEntityOptions(currentMappingIndex) {
922
- const allEntities = this.entityOptions();
923
- if (!allEntities || allEntities.length === 0) {
924
- return [];
925
- }
926
- // Get all currently selected entity IDs from other mappings (excluding current mapping)
927
- const selectedEntityIds = this.getSelectedEntityIds(currentMappingIndex);
928
- console.log(`🔍 Filtering entities for mapping ${currentMappingIndex}:`, {
929
- totalEntities: allEntities.length,
930
- selectedEntityIds,
931
- availableEntities: allEntities.length - selectedEntityIds.length
932
- });
933
- // Return only entities that are not already selected in other mappings
934
- return allEntities.filter((entity) => {
935
- const entityId = entity._id;
936
- const isAlreadySelected = selectedEntityIds.includes(entityId);
937
- if (isAlreadySelected) {
938
- console.log(`🚫 Entity "${entity.syen_name}" (${entityId}) is already selected in another mapping - excluding from options`);
939
- }
940
- return !isAlreadySelected;
941
- });
942
- }
943
- /**
944
- * Get all currently selected entity IDs from other mappings
945
- */
946
- getSelectedEntityIds(excludeMappingIndex) {
947
- const mappingsArray = this.academicYearMappingsArray;
948
- const selectedIds = [];
949
- mappingsArray.controls.forEach((control, index) => {
950
- if (index !== excludeMappingIndex) {
951
- const entityId = control.get('acayrmp_entity_id_syen')?.value;
952
- if (entityId) {
953
- selectedIds.push(entityId);
954
- }
955
- }
956
- });
957
- return selectedIds;
958
- }
959
- /**
960
- * Update entity options for all mappings to prevent duplicates
961
- */
962
- updateEntityOptionsForMappings() {
963
- // This method triggers change detection to update the UI
964
- // The actual filtering is done in getEntityOptionsForMapping method
965
- console.log('🔄 Updating entity options for all mappings');
966
- }
967
- /**
968
- * Check if an entity is disabled for a specific mapping
969
- */
970
- isEntityDisabled(entityId, mappingIndex) {
971
- const selectedEntityIds = this.getSelectedEntityIds(mappingIndex);
972
- return selectedEntityIds.includes(entityId);
973
- }
974
- /**
975
- * Get the count of available entities for a specific mapping
976
- */
977
- getAvailableEntityCount(mappingIndex) {
978
- const availableEntities = this.getFilteredEntityOptions(mappingIndex);
979
- return availableEntities.length;
980
- }
981
- /**
982
- * Get the count of total entities
983
- */
984
- getTotalEntityCount() {
985
- return this.entityOptions().length;
986
- }
987
- /**
988
- * Check if all entities are already selected in other mappings
989
- * @param currentMappingIndex The index of the current mapping being edited
990
- * @returns True if all entities are already selected
991
- */
992
- isAllEntitiesSelected(currentMappingIndex) {
993
- const allEntities = this.entityOptions();
994
- const currentMappings = this.academicYearMappingsArray.value;
995
- // Get all selected entity IDs from other mappings (excluding current mapping)
996
- const selectedEntityIds = currentMappings
997
- .map((mapping, index) => {
998
- if (index !== currentMappingIndex && mapping.acayrmp_entity_id_syen) {
999
- return mapping.acayrmp_entity_id_syen;
1000
- }
1001
- return null;
1002
- })
1003
- .filter((id) => id !== null && id !== '');
1004
- // Check if all entities are selected
1005
- return allEntities.length > 0 && selectedEntityIds.length >= allEntities.length;
1006
- }
1007
- /**
1008
- * Check if all entities are already mapped (for disabling Add Entity Mapping button)
1009
- * @returns True if all entities are already mapped
1010
- */
1011
- isAllEntitiesMapped() {
1012
- const allEntities = this.entityOptions();
1013
- const currentMappings = this.academicYearMappingsArray.value;
1014
- // Get all selected entity IDs
1015
- const selectedEntityIds = currentMappings
1016
- .map((mapping) => {
1017
- if (mapping.acayrmp_entity_id_syen) {
1018
- return mapping.acayrmp_entity_id_syen;
1019
- }
1020
- return null;
1021
- })
1022
- .filter((id) => id !== null && id !== '');
1023
- // Check if all entities are selected
1024
- return allEntities.length > 0 && selectedEntityIds.length >= allEntities.length;
1025
- }
1026
- /**
1027
- * Cleanup when component is destroyed
1028
- * This ensures that when the component is destroyed (e.g., tab closed),
1029
- * all state is properly reset to prevent old data from persisting
1030
- */
1031
- ngOnDestroy() {
1032
- console.log('🧹 AcademicYearCreateComponent: Cleaning up component state');
1033
- // Reset all signals to their initial state
1034
- this.activeTab.set('basic');
1035
- this.loading.set(false);
1036
- this.academicYearId.set('');
1037
- this.isEditMode.set(false);
1038
- this.originalMappings.set([]);
1039
- this.entityOptions.set([]);
1040
- // Reset form to initial state
1041
- this.resetForm();
1042
- console.log('🧹 AcademicYearCreateComponent: Component state cleaned up');
1043
- }
1044
- /**
1045
- * Delete removed academic year mappings
1046
- */
1047
- deleteRemovedMappings() {
1048
- const originalMappings = this.originalMappings();
1049
- const currentMappings = this.getAcademicYearMappingsValue();
1050
- // Find mappings that were removed (exist in original but not in current)
1051
- const removedMappings = originalMappings.filter(originalMapping => {
1052
- return !currentMappings.some(currentMapping => currentMapping._id === originalMapping._id && originalMapping._id);
1053
- });
1054
- console.log('🗑️ Mappings to delete:', removedMappings);
1055
- if (removedMappings.length === 0) {
1056
- return of([]);
1057
- }
1058
- // Create delete observables for each removed mapping
1059
- const deleteObservables = removedMappings.map(mapping => {
1060
- return this.academicYearService.deleteAcademicYearMapping({
1061
- acayrmp_id: mapping._id || ''
1062
- }).pipe(catchError(error => {
1063
- console.error('❌ Error deleting mapping:', error);
1064
- return of({ success: false, error, mappingId: mapping._id });
1065
- }));
1066
- });
1067
- return forkJoin(deleteObservables);
1068
- }
1069
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AcademicYearCreateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1070
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: AcademicYearCreateComponent, isStandalone: true, selector: "cide-core-academic-year-create", ngImport: i0, template: "<!-- \n ACADEMIC YEAR MASTER FORM\n \n Enterprise-Level Styling with Tailwind CSS\n Features: Responsive grids, proper typography, enhanced user experience\n-->\n\n<div class=\"tw-w-full tw-h-full\">\n <form class=\"tw-w-full tw-table tw-h-full tw-bg-transparent\" [formGroup]=\"academicYearForm\" [class.tw-opacity-60]=\"loading()\"\n (ngSubmit)=\"onSubmit()\">\n\n <!-- Simple Header Section -->\n <div class=\"tw-table-row tw-w-full tw-h-0\">\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\">\n <div 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\">\n \n <!-- Title -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <cide-ele-icon class=\"tw-text-blue-600 tw-w-5 tw-h-5\">school</cide-ele-icon>\n <h5 class=\"tw-text-base tw-font-medium tw-text-gray-900 tw-m-0\">\n {{ isEditMode() ? 'Edit Academic Year' : 'Create Academic Year' }}\n </h5>\n </div>\n\n <!-- Actions -->\n <div 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\">\n <!-- Back button or other actions can be added here if needed -->\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tw-table-row tw-h-0\">\n <div class=\"tw-table-cell tw-w-full tw-px-2 tw-py-0\">\n <cide-ele-tab [tabs]=\"academicYearTabs()\" [activeTabId]=\"activeTab()\" size=\"md\" variant=\"default\"\n (tabChange)=\"onTabChange($event)\">\n </cide-ele-tab>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tw-table-row\">\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-6\">\n <div class=\"tw-transition-opacity tw-duration-300\" [class.tw-opacity-60]=\"loading()\">\n @switch (activeTab()) {\n\n @case ('basic') {\n <!-- Basic Academic Year Information -->\n <div class=\"tw-space-y-6\">\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <cide-ele-input label=\"Academic Year Code *\" formControlName=\"acayr_code\"\n placeholder=\"e.g., AY2024-25\" size=\"md\" leadingIcon=\"code\">\n </cide-ele-input>\n\n <cide-ele-input label=\"Academic Year Name *\" formControlName=\"acayr_name\"\n placeholder=\"e.g., Academic Year 2024-2025\" size=\"md\" leadingIcon=\"school\">\n </cide-ele-input>\n </div>\n\n <div>\n <cide-ele-textarea label=\"Description\" formControlName=\"acayr_description\"\n placeholder=\"Enter detailed description of the academic year...\"\n rows=\"3\" size=\"md\">\n </cide-ele-textarea>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <cide-ele-input label=\"From Date *\" formControlName=\"acayr_from_date\" type=\"date\" size=\"md\"\n leadingIcon=\"calendar_today\" id=\"acayr_from_date\">\n </cide-ele-input>\n\n <cide-ele-input label=\"To Date *\" formControlName=\"acayr_to_date\" type=\"date\" size=\"md\"\n leadingIcon=\"calendar_today\" id=\"acayr_to_date\">\n </cide-ele-input>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-3 tw-gap-6\">\n <div 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\">\n <cide-ele-input formControlName=\"acayr_isactive\" type=\"checkbox\" size=\"md\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Active</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Enable/disable this academic year</span>\n </div>\n </div>\n\n <div 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\">\n <cide-ele-input formControlName=\"acayr_iscurrent\" type=\"checkbox\" size=\"md\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Current</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Mark as current academic year</span>\n </div>\n </div>\n\n <div 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\">\n <cide-ele-input formControlName=\"acayr_islocked\" type=\"checkbox\" size=\"md\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\n </div>\n </div>\n </div>\n </div>\n }\n\n @case ('mapping') {\n <!-- Academic Year Mapping Configuration -->\n <div class=\"tw-bg-gradient-to-r tw-from-blue-50 tw-to-indigo-50 tw-border tw-border-blue-200 tw-rounded-xl tw-p-6\">\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-6\">\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"tw-bg-blue-100 tw-p-2 tw-rounded-lg\">\n <cide-ele-icon class=\"tw-text-blue-600 tw-w-6 tw-h-6\">link</cide-ele-icon>\n </div>\n <div>\n <h6 class=\"tw-text-lg tw-font-semibold tw-text-blue-900 tw-m-0\">Academic Year Mapping</h6>\n <p class=\"tw-text-sm tw-text-blue-600 tw-m-0\">Configure entity mappings for this academic year</p>\n </div>\n </div>\n <button cideEleButton type=\"button\" variant=\"primary\" size=\"md\" leftIcon=\"add\"\n (click)=\"addAcademicYearMapping()\"\n class=\"tw-shadow-md hover:tw-shadow-lg tw-transition-shadow\">\n Add New Mapping\n </button>\n </div>\n \n @if (academicYearMappingsArray.length === 0) {\n <div class=\"tw-text-center tw-py-12 tw-text-gray-500\">\n <div class=\"tw-bg-white tw-p-4 tw-rounded-full tw-w-16 tw-h-16 tw-mx-auto tw-mb-4 tw-flex tw-items-center tw-justify-center\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">link</cide-ele-icon>\n </div>\n <h6 class=\"tw-text-base tw-font-medium tw-text-gray-600 tw-mb-2\">No Mappings Yet</h6>\n <p class=\"tw-text-sm tw-text-gray-500\">Click \"Add New Mapping\" to start configuring entity relationships for this academic year.</p>\n </div>\n } @else {\n <div class=\"tw-space-y-4\" formArrayName=\"acayr_academic_year_mappings\">\n @for (mapping of academicYearMappingsArray.controls; track $index) {\n <div class=\"tw-bg-white tw-rounded-xl tw-border tw-border-gray-200 tw-shadow-sm hover:tw-shadow-md tw-transition-shadow tw-p-6\">\n <div class=\"tw-flex tw-items-start tw-justify-between tw-mb-4\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <div class=\"tw-bg-blue-100 tw-p-2 tw-rounded-lg\">\n <cide-ele-icon class=\"tw-text-blue-600 tw-w-5 tw-h-5\">settings</cide-ele-icon>\n </div>\n <h6 class=\"tw-text-sm tw-font-semibold tw-text-gray-900\">Mapping #{{ $index + 1 }}</h6>\n </div>\n <button cideEleButton type=\"button\" variant=\"danger\" size=\"sm\" leftIcon=\"delete\"\n (click)=\"removeAcademicYearMapping($index)\"\n class=\"tw-opacity-80 hover:tw-opacity-100 tw-transition-opacity\">\n Remove\n </button>\n </div>\n \n <div class=\"tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-4\" [formGroupName]=\"$index\">\n <!-- Hidden Academic Year ID field (internal use only) -->\n <input type=\"hidden\" formControlName=\"acayrmp_academic_year_id_acayr\">\n \n <!-- Entity Selection -->\n <div class=\"tw-space-y-2\">\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Select Entity *</label>\n <cide-ele-select \n [options]=\"entityOptions()\"\n formControlName=\"acayrmp_entity_id_syen\"\n placeholder=\"Choose entity for this mapping\" \n size=\"md\"\n valueKey=\"_id\"\n labelKey=\"syen_name\"\n class=\"tw-min-w-full\"\n (change)=\"onMappingEntityChange($event, $index)\">\n </cide-ele-select>\n </div>\n \n <!-- Status Controls -->\n <div class=\"tw-space-y-2\">\n <div class=\"tw-grid tw-grid-cols-1 tw-gap-3\">\n <div class=\"tw-flex tw-items-center tw-gap-2 tw-p-3 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200\">\n <cide-ele-input \n formControlName=\"acayrmp_islocked\" \n type=\"checkbox\" \n size=\"sm\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\n </div>\n </div>\n \n <div class=\"tw-flex tw-items-center tw-gap-2 tw-p-3 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200\">\n <cide-ele-input \n formControlName=\"acayrmp_iscurrent\" \n type=\"checkbox\" \n size=\"sm\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Current</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Mark as current mapping</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Mapping Validation Messages -->\n @if (academicYearMappingsArray.length > 0 && !isMappingsArrayValid()) {\n <div class=\"tw-mt-4 tw-p-4 tw-bg-yellow-50 tw-border tw-border-yellow-200 tw-rounded-lg\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <cide-ele-icon variant=\"warning\" size=\"sm\">warning</cide-ele-icon>\n <span class=\"tw-text-sm tw-font-medium tw-text-yellow-800\">\n Please ensure all mappings have required fields filled in.\n </span>\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"tw-table-row tw-h-0\">\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\">\n <div class=\"tw-flex tw-justify-between tw-items-center tw-gap-4\">\n <!-- Form Validation Errors -->\n <cide-form-field-error [formGroup]=\"academicYearForm\"></cide-form-field-error>\n \n <!-- Action Buttons -->\n <div class=\"tw-flex tw-justify-end tw-gap-4\">\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"resetForm()\" leftIcon=\"refresh\"\n [disabled]=\"loading()\">\n Reset Form\n </button>\n\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"cancelForm()\" leftIcon=\"close\"\n [disabled]=\"loading()\">\n Cancel\n </button>\n\n <button cideEleButton type=\"submit\" variant=\"primary\" [disabled]=\"loading() || academicYearForm.invalid\"\n [loading]=\"loading()\" leftIcon=\"save\">\n {{ isEditMode() ? 'Update Academic Year' : 'Create Academic Year' }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </form>\n </div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { 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], cide-ele-button", 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: CideEleTabComponent, selector: "cide-ele-tab", inputs: ["tabs", "activeTabId", "size", "variant", "fullWidth", "disabled"], outputs: ["tabChange"] }, { 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"] }, { kind: "component", type: CideFormFieldErrorComponent, selector: "cide-form-field-error", inputs: ["control", "formGroup", "fieldName", "customMessages"] }] });
1071
- }
1072
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AcademicYearCreateComponent, decorators: [{
1073
- type: Component,
1074
- args: [{ selector: 'cide-core-academic-year-create', standalone: true, imports: [
1075
- CommonModule,
1076
- ReactiveFormsModule,
1077
- CideInputComponent,
1078
- CideTextareaComponent,
1079
- CideEleButtonComponent,
1080
- CideEleTabComponent,
1081
- CideIconComponent,
1082
- CideSelectComponent,
1083
- CideFormFieldErrorComponent
1084
- ], template: "<!-- \n ACADEMIC YEAR MASTER FORM\n \n Enterprise-Level Styling with Tailwind CSS\n Features: Responsive grids, proper typography, enhanced user experience\n-->\n\n<div class=\"tw-w-full tw-h-full\">\n <form class=\"tw-w-full tw-table tw-h-full tw-bg-transparent\" [formGroup]=\"academicYearForm\" [class.tw-opacity-60]=\"loading()\"\n (ngSubmit)=\"onSubmit()\">\n\n <!-- Simple Header Section -->\n <div class=\"tw-table-row tw-w-full tw-h-0\">\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\">\n <div 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\">\n \n <!-- Title -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <cide-ele-icon class=\"tw-text-blue-600 tw-w-5 tw-h-5\">school</cide-ele-icon>\n <h5 class=\"tw-text-base tw-font-medium tw-text-gray-900 tw-m-0\">\n {{ isEditMode() ? 'Edit Academic Year' : 'Create Academic Year' }}\n </h5>\n </div>\n\n <!-- Actions -->\n <div 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\">\n <!-- Back button or other actions can be added here if needed -->\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tw-table-row tw-h-0\">\n <div class=\"tw-table-cell tw-w-full tw-px-2 tw-py-0\">\n <cide-ele-tab [tabs]=\"academicYearTabs()\" [activeTabId]=\"activeTab()\" size=\"md\" variant=\"default\"\n (tabChange)=\"onTabChange($event)\">\n </cide-ele-tab>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tw-table-row\">\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-6\">\n <div class=\"tw-transition-opacity tw-duration-300\" [class.tw-opacity-60]=\"loading()\">\n @switch (activeTab()) {\n\n @case ('basic') {\n <!-- Basic Academic Year Information -->\n <div class=\"tw-space-y-6\">\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <cide-ele-input label=\"Academic Year Code *\" formControlName=\"acayr_code\"\n placeholder=\"e.g., AY2024-25\" size=\"md\" leadingIcon=\"code\">\n </cide-ele-input>\n\n <cide-ele-input label=\"Academic Year Name *\" formControlName=\"acayr_name\"\n placeholder=\"e.g., Academic Year 2024-2025\" size=\"md\" leadingIcon=\"school\">\n </cide-ele-input>\n </div>\n\n <div>\n <cide-ele-textarea label=\"Description\" formControlName=\"acayr_description\"\n placeholder=\"Enter detailed description of the academic year...\"\n rows=\"3\" size=\"md\">\n </cide-ele-textarea>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <cide-ele-input label=\"From Date *\" formControlName=\"acayr_from_date\" type=\"date\" size=\"md\"\n leadingIcon=\"calendar_today\" id=\"acayr_from_date\">\n </cide-ele-input>\n\n <cide-ele-input label=\"To Date *\" formControlName=\"acayr_to_date\" type=\"date\" size=\"md\"\n leadingIcon=\"calendar_today\" id=\"acayr_to_date\">\n </cide-ele-input>\n </div>\n\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-3 tw-gap-6\">\n <div 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\">\n <cide-ele-input formControlName=\"acayr_isactive\" type=\"checkbox\" size=\"md\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Active</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Enable/disable this academic year</span>\n </div>\n </div>\n\n <div 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\">\n <cide-ele-input formControlName=\"acayr_iscurrent\" type=\"checkbox\" size=\"md\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Current</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Mark as current academic year</span>\n </div>\n </div>\n\n <div 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\">\n <cide-ele-input formControlName=\"acayr_islocked\" type=\"checkbox\" size=\"md\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\n </div>\n </div>\n </div>\n </div>\n }\n\n @case ('mapping') {\n <!-- Academic Year Mapping Configuration -->\n <div class=\"tw-bg-gradient-to-r tw-from-blue-50 tw-to-indigo-50 tw-border tw-border-blue-200 tw-rounded-xl tw-p-6\">\n <div class=\"tw-flex tw-items-center tw-justify-between tw-mb-6\">\n <div class=\"tw-flex tw-items-center tw-gap-3\">\n <div class=\"tw-bg-blue-100 tw-p-2 tw-rounded-lg\">\n <cide-ele-icon class=\"tw-text-blue-600 tw-w-6 tw-h-6\">link</cide-ele-icon>\n </div>\n <div>\n <h6 class=\"tw-text-lg tw-font-semibold tw-text-blue-900 tw-m-0\">Academic Year Mapping</h6>\n <p class=\"tw-text-sm tw-text-blue-600 tw-m-0\">Configure entity mappings for this academic year</p>\n </div>\n </div>\n <button cideEleButton type=\"button\" variant=\"primary\" size=\"md\" leftIcon=\"add\"\n (click)=\"addAcademicYearMapping()\"\n class=\"tw-shadow-md hover:tw-shadow-lg tw-transition-shadow\">\n Add New Mapping\n </button>\n </div>\n \n @if (academicYearMappingsArray.length === 0) {\n <div class=\"tw-text-center tw-py-12 tw-text-gray-500\">\n <div class=\"tw-bg-white tw-p-4 tw-rounded-full tw-w-16 tw-h-16 tw-mx-auto tw-mb-4 tw-flex tw-items-center tw-justify-center\">\n <cide-ele-icon class=\"tw-w-8 tw-h-8 tw-text-gray-400\">link</cide-ele-icon>\n </div>\n <h6 class=\"tw-text-base tw-font-medium tw-text-gray-600 tw-mb-2\">No Mappings Yet</h6>\n <p class=\"tw-text-sm tw-text-gray-500\">Click \"Add New Mapping\" to start configuring entity relationships for this academic year.</p>\n </div>\n } @else {\n <div class=\"tw-space-y-4\" formArrayName=\"acayr_academic_year_mappings\">\n @for (mapping of academicYearMappingsArray.controls; track $index) {\n <div class=\"tw-bg-white tw-rounded-xl tw-border tw-border-gray-200 tw-shadow-sm hover:tw-shadow-md tw-transition-shadow tw-p-6\">\n <div class=\"tw-flex tw-items-start tw-justify-between tw-mb-4\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <div class=\"tw-bg-blue-100 tw-p-2 tw-rounded-lg\">\n <cide-ele-icon class=\"tw-text-blue-600 tw-w-5 tw-h-5\">settings</cide-ele-icon>\n </div>\n <h6 class=\"tw-text-sm tw-font-semibold tw-text-gray-900\">Mapping #{{ $index + 1 }}</h6>\n </div>\n <button cideEleButton type=\"button\" variant=\"danger\" size=\"sm\" leftIcon=\"delete\"\n (click)=\"removeAcademicYearMapping($index)\"\n class=\"tw-opacity-80 hover:tw-opacity-100 tw-transition-opacity\">\n Remove\n </button>\n </div>\n \n <div class=\"tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-4\" [formGroupName]=\"$index\">\n <!-- Hidden Academic Year ID field (internal use only) -->\n <input type=\"hidden\" formControlName=\"acayrmp_academic_year_id_acayr\">\n \n <!-- Entity Selection -->\n <div class=\"tw-space-y-2\">\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Select Entity *</label>\n <cide-ele-select \n [options]=\"entityOptions()\"\n formControlName=\"acayrmp_entity_id_syen\"\n placeholder=\"Choose entity for this mapping\" \n size=\"md\"\n valueKey=\"_id\"\n labelKey=\"syen_name\"\n class=\"tw-min-w-full\"\n (change)=\"onMappingEntityChange($event, $index)\">\n </cide-ele-select>\n </div>\n \n <!-- Status Controls -->\n <div class=\"tw-space-y-2\">\n <div class=\"tw-grid tw-grid-cols-1 tw-gap-3\">\n <div class=\"tw-flex tw-items-center tw-gap-2 tw-p-3 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200\">\n <cide-ele-input \n formControlName=\"acayrmp_islocked\" \n type=\"checkbox\" \n size=\"sm\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\n </div>\n </div>\n \n <div class=\"tw-flex tw-items-center tw-gap-2 tw-p-3 tw-bg-gray-50 tw-rounded-lg tw-border tw-border-gray-200\">\n <cide-ele-input \n formControlName=\"acayrmp_iscurrent\" \n type=\"checkbox\" \n size=\"sm\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Current</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Mark as current mapping</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Mapping Validation Messages -->\n @if (academicYearMappingsArray.length > 0 && !isMappingsArrayValid()) {\n <div class=\"tw-mt-4 tw-p-4 tw-bg-yellow-50 tw-border tw-border-yellow-200 tw-rounded-lg\">\n <div class=\"tw-flex tw-items-center tw-gap-2\">\n <cide-ele-icon variant=\"warning\" size=\"sm\">warning</cide-ele-icon>\n <span class=\"tw-text-sm tw-font-medium tw-text-yellow-800\">\n Please ensure all mappings have required fields filled in.\n </span>\n </div>\n </div>\n }\n </div>\n }\n }\n </div>\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"tw-table-row tw-h-0\">\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\">\n <div class=\"tw-flex tw-justify-between tw-items-center tw-gap-4\">\n <!-- Form Validation Errors -->\n <cide-form-field-error [formGroup]=\"academicYearForm\"></cide-form-field-error>\n \n <!-- Action Buttons -->\n <div class=\"tw-flex tw-justify-end tw-gap-4\">\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"resetForm()\" leftIcon=\"refresh\"\n [disabled]=\"loading()\">\n Reset Form\n </button>\n\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"cancelForm()\" leftIcon=\"close\"\n [disabled]=\"loading()\">\n Cancel\n </button>\n\n <button cideEleButton type=\"submit\" variant=\"primary\" [disabled]=\"loading() || academicYearForm.invalid\"\n [loading]=\"loading()\" leftIcon=\"save\">\n {{ isEditMode() ? 'Update Academic Year' : 'Create Academic Year' }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </form>\n </div>" }]
1085
- }], ctorParameters: () => [] });
1086
-
1087
- var academicYearCreate_component = /*#__PURE__*/Object.freeze({
1088
- __proto__: null,
1089
- AcademicYearCreateComponent: AcademicYearCreateComponent
1090
- });
1091
-
1092
- class AcademicYearListComponent {
1093
- // Modern Angular 20+ dependency injection using inject()
1094
- destroyRef = inject(DestroyRef);
1095
- academicYearService = inject(CideLytAcademicYearService);
1096
- router = inject(Router);
1097
- appState = inject(AppStateHelperService);
1098
- confirmationService = inject(ConfirmationService);
1099
- notificationService = inject(NotificationService);
1100
- // Modern ViewChild signals for template renderers (Angular 20 approach)
1101
- academicYearDetailsRendererTemplate = viewChild.required('academicYearDetailsRendererTemplate');
1102
- dateRangeRendererTemplate = viewChild.required('dateRangeRendererTemplate');
1103
- statusRendererTemplate = viewChild.required('statusRendererTemplate');
1104
- actionsDropdownRendererTemplate = viewChild.required('actionsDropdownRendererTemplate');
1105
- // Modern Angular 20+ state management using signals with proper typing
1106
- academicYears = signal([], ...(ngDevMode ? [{ debugName: "academicYears" }] : []));
1107
- loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1108
- error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
1109
- // Server-side pagination state using signals
1110
- currentPage = signal(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
1111
- pageSize = signal(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
1112
- totalItems = signal(0, ...(ngDevMode ? [{ debugName: "totalItems" }] : []));
1113
- totalPages = signal(0, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
1114
- // Server-side search state using signals
1115
- searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
1116
- // Server-side sorting state using signals
1117
- sortColumn = signal('acayr_name', ...(ngDevMode ? [{ debugName: "sortColumn" }] : []));
1118
- sortDirection = signal('asc', ...(ngDevMode ? [{ debugName: "sortDirection" }] : []));
1119
- // Server-side filtering state using signals
1120
- selectedStatusFilter = signal('', ...(ngDevMode ? [{ debugName: "selectedStatusFilter" }] : []));
1121
- // Filter options using computed signal for better performance
1122
- statusFilterOptions = computed(() => [
1123
- { value: '', label: 'All Status' },
1124
- { value: 'active', label: 'Active Years' },
1125
- { value: 'inactive', label: 'Inactive Years' },
1126
- { value: 'current', label: 'Current Year' },
1127
- { value: 'locked', label: 'Locked Years' }
1128
- ], ...(ngDevMode ? [{ debugName: "statusFilterOptions" }] : []));
1129
- // Modern Angular 20+ grid configuration using computed signal with proper typing
1130
- gridConfig = computed(() => ({
1131
- id: 'academic-year-list-grid',
1132
- columns: [
1133
- {
1134
- key: 'acayr_code',
1135
- header: 'Academic Year Code',
1136
- type: 'text',
1137
- width: '140px',
1138
- truncate: true,
1139
- align: 'left',
1140
- sortable: true
1141
- },
1142
- {
1143
- key: 'details',
1144
- header: 'Academic Year Details',
1145
- type: 'custom',
1146
- width: 'auto',
1147
- truncate: true,
1148
- align: 'left',
1149
- renderer: 'academicYearDetailsRenderer',
1150
- sortable: true
1151
- },
1152
- {
1153
- key: 'date_range',
1154
- header: 'Date Range',
1155
- type: 'custom',
1156
- width: '200px',
1157
- truncate: false,
1158
- align: 'left',
1159
- renderer: 'dateRangeRenderer',
1160
- sortable: true
1161
- },
1162
- {
1163
- key: 'acayr_isactive',
1164
- header: 'Status',
1165
- type: 'custom',
1166
- width: '140px',
1167
- truncate: false,
1168
- align: 'center',
1169
- renderer: 'statusRenderer'
1170
- },
1171
- {
1172
- key: 'actions',
1173
- header: 'Actions',
1174
- type: 'custom',
1175
- width: '80px',
1176
- truncate: false,
1177
- align: 'center',
1178
- renderer: 'actionsDropdownRenderer'
1179
- }
1180
- ],
1181
- data: this.academicYears(),
1182
- trackBy: '_id',
1183
- pagination: {
1184
- enabled: true,
1185
- pageSize: this.pageSize(),
1186
- pageSizeOptions: [10, 25, 50, 100],
1187
- showQuickJump: true,
1188
- showPageInfo: true,
1189
- showRefresh: true
1190
- },
1191
- search: {
1192
- enabled: true,
1193
- placeholder: 'Search by code, name, or description...',
1194
- searchableColumns: ['acayr_code', 'acayr_name', 'acayr_description'],
1195
- debounceMs: 300,
1196
- showClearButton: true
1197
- },
1198
- loading: {
1199
- useDefer: true,
1200
- skeletonRows: 5,
1201
- showOverlay: this.loading()
1202
- },
1203
- scroll: {
1204
- enabled: true,
1205
- maxHeight: '',
1206
- minHeight: '',
1207
- stickyHeader: true,
1208
- virtualScroll: false,
1209
- rowHeight: 50
1210
- },
1211
- export: {
1212
- enabled: true,
1213
- formats: ['csv', 'excel', 'pdf'],
1214
- filename: 'academic-years',
1215
- includeHeaders: true
1216
- },
1217
- responsive: true,
1218
- striped: false,
1219
- bordered: true,
1220
- compact: false,
1221
- tableClass: 'tw-table-fixed tw-w-full tw-rounded-none'
1222
- }), ...(ngDevMode ? [{ debugName: "gridConfig" }] : []));
1223
- ngOnInit() {
1224
- console.log('🎓 Academic Year List Component initialized');
1225
- this.loadAcademicYears();
1226
- }
1227
- ngOnDestroy() {
1228
- // Cleanup if needed
1229
- }
1230
- /**
1231
- * Load academic years from API
1232
- */
1233
- loadAcademicYears() {
1234
- this.loading.set(true);
1235
- this.error.set(null);
1236
- const payload = {
1237
- pageIndex: this.currentPage(),
1238
- pageSize: this.pageSize(),
1239
- query: this.searchQuery() || "",
1240
- sort: {
1241
- key: this.sortColumn(),
1242
- order: this.sortDirection()
1243
- }
1244
- };
1245
- this.academicYearService.getAcademicYearList(payload)
1246
- .pipe(takeUntilDestroyed(this.destroyRef))
1247
- .subscribe({
1248
- next: (response) => {
1249
- if (response?.success && response.data) {
1250
- console.log('📚 Academic years loaded:', response.data);
1251
- console.log('📊 Pagination info:', {
1252
- total: response.total,
1253
- pageIndex: response.pageIndex,
1254
- pageSize: response.pageSize
1255
- });
1256
- this.academicYears.set(response.data);
1257
- this.totalItems.set(response.total || 0);
1258
- this.totalPages.set(Math.ceil((response.total || 0) / this.pageSize()));
1259
- // Show success notification if data was loaded successfully
1260
- if (response.data.length > 0) {
1261
- this.notificationService.success(`Loaded ${response.data.length} academic year(s) successfully.`);
1262
- }
1263
- }
1264
- else {
1265
- console.warn('⚠️ No academic year data received');
1266
- this.academicYears.set([]);
1267
- this.totalItems.set(0);
1268
- this.totalPages.set(0);
1269
- this.notificationService.warning('No academic years found.');
1270
- }
1271
- this.loading.set(false);
1272
- },
1273
- error: (error) => {
1274
- console.error('❌ Error loading academic years:', error);
1275
- this.error.set('Failed to load academic years. Please try again.');
1276
- this.academicYears.set([]);
1277
- this.totalItems.set(0);
1278
- this.totalPages.set(0);
1279
- this.notificationService.error('Failed to load academic years. Please try again.');
1280
- this.loading.set(false);
1281
- }
1282
- });
1283
- }
1284
- // Computed template renderers for grid
1285
- templateRenderers = computed(() => ({
1286
- academicYearDetailsRenderer: this.academicYearDetailsRendererTemplate(),
1287
- dateRangeRenderer: this.dateRangeRendererTemplate(),
1288
- statusRenderer: this.statusRendererTemplate(),
1289
- actionsDropdownRenderer: this.actionsDropdownRendererTemplate()
1290
- }), ...(ngDevMode ? [{ debugName: "templateRenderers" }] : []));
1291
- /**
1292
- * Handle grid events
1293
- */
1294
- onGridEvent(event) {
1295
- switch (event.type) {
1296
- case 'pageChange':
1297
- if (event.data && typeof event.data === 'object' && 'pageIndex' in event.data && 'pageSize' in event.data) {
1298
- this.currentPage.set(event.data['pageIndex']);
1299
- this.pageSize.set(event.data['pageSize']);
1300
- this.loadAcademicYears();
1301
- }
1302
- break;
1303
- case 'search':
1304
- this.searchQuery.set(event.data);
1305
- this.currentPage.set(1);
1306
- this.loadAcademicYears();
1307
- break;
1308
- case 'refresh':
1309
- this.loadAcademicYears();
1310
- break;
1311
- case 'action':
1312
- // Handle action events if needed
1313
- console.log('Action event:', event);
1314
- break;
1315
- case 'rowClick':
1316
- // Handle row click events if needed
1317
- console.log('Row click event:', event);
1318
- break;
1319
- case 'sort':
1320
- if (event.data && typeof event.data === 'object' && 'column' in event.data && 'direction' in event.data) {
1321
- this.sortColumn.set(event.data['column']);
1322
- this.sortDirection.set(event.data['direction']);
1323
- this.currentPage.set(1); // Reset to first page when sorting
1324
- this.loadAcademicYears();
1325
- }
1326
- break;
1327
- case 'export':
1328
- if (event.data && typeof event.data === 'string') {
1329
- this.handleExport(event.data);
1330
- }
1331
- break;
1332
- default:
1333
- console.log('🔄 Unhandled grid event:', event.type);
1334
- }
1335
- }
1336
- // Filter handlers
1337
- onStatusFilterChange() {
1338
- console.log('🔍 Status filter changed:', this.selectedStatusFilter());
1339
- this.currentPage.set(1); // Reset to first page when filtering
1340
- this.loadAcademicYears();
1341
- }
1342
- clearFilters() {
1343
- console.log('🧹 Clearing filters');
1344
- this.selectedStatusFilter.set('');
1345
- this.searchQuery.set('');
1346
- this.currentPage.set(1);
1347
- this.loadAcademicYears();
1348
- }
1349
- // Academic Year actions with proper typing
1350
- createAcademicYear() {
1351
- console.log('➕ Navigating to create academic year');
1352
- this.notificationService.info('Opening form to create a new academic year.');
1353
- this.router.navigate(['/control-panel/academic_year/create']);
1354
- }
1355
- viewAcademicYear(academicYear) {
1356
- console.log('👁️ Viewing academic year:', academicYear);
1357
- this.notificationService.info(`Opening academic year "${academicYear.acayr_name}" for viewing.`);
1358
- const queryParams = generateStringFromObject({ acayr_id: academicYear._id });
1359
- this.router.navigate(['/control-panel/academic_year/view', queryParams]);
1360
- }
1361
- editAcademicYear(academicYear) {
1362
- console.log('✏️ Editing academic year:', academicYear);
1363
- // Check if the academic year is locked
1364
- if (academicYear.acayr_islocked) {
1365
- this.notificationService.error(`Cannot edit "${academicYear.acayr_name}" - This academic year is locked and cannot be modified. Please contact an administrator to unlock it first.`);
1366
- return;
1367
- }
1368
- this.notificationService.info(`Opening academic year "${academicYear.acayr_name}" for editing.`);
1369
- const queryParams = generateStringFromObject({ acayr_id: academicYear._id });
1370
- this.router.navigate(['/control-panel/academic_year/edit', queryParams]);
1371
- }
1372
- /**
1373
- * Get dropdown configuration
1374
- */
1375
- getDropdownConfig() {
1376
- return {
1377
- triggerIcon: 'more_vert',
1378
- triggerSize: 'sm',
1379
- // menuPosition: 'right' as const,
1380
- // forcePosition: 'bottom' as const,
1381
- // offsetX: 0,
1382
- // offsetY: 1,
1383
- // usePortal: true,
1384
- // showArrow: false
1385
- };
1386
- }
1387
- /**
1388
- * Get action dropdown items
1389
- */
1390
- getActionDropdownItems(academicYear) {
1391
- console.log('🔽 Generating dropdown items for:', academicYear.acayr_name);
1392
- console.log('🔽 Academic year data:', {
1393
- isCurrent: academicYear.acayr_iscurrent,
1394
- isLocked: academicYear.acayr_islocked,
1395
- isActive: academicYear.acayr_isactive
1396
- });
1397
- const items = [
1398
- {
1399
- id: 'view',
1400
- label: 'View Details',
1401
- icon: 'visibility',
1402
- iconColor: 'tw-text-gray-400',
1403
- textColor: 'tw-text-gray-700',
1404
- hoverBgColor: 'hover:tw-bg-gray-100'
1405
- },
1406
- {
1407
- id: 'edit',
1408
- label: 'Edit',
1409
- icon: 'edit',
1410
- iconColor: academicYear?.acayr_islocked ? 'tw-text-gray-300' : 'tw-text-blue-400',
1411
- textColor: academicYear?.acayr_islocked ? 'tw-text-gray-400' : 'tw-text-blue-600',
1412
- hoverBgColor: academicYear?.acayr_islocked ? 'hover:tw-bg-gray-50' : 'hover:tw-bg-blue-50'
1413
- },
1414
- {
1415
- id: 'toggle-status',
1416
- label: academicYear.acayr_isactive ? 'Deactivate' : 'Activate',
1417
- icon: academicYear.acayr_isactive ? 'toggle_off' : 'toggle_on',
1418
- iconColor: academicYear?.acayr_islocked ? 'tw-text-gray-300' : 'tw-text-gray-400',
1419
- textColor: academicYear?.acayr_islocked ? 'tw-text-gray-400' : 'tw-text-gray-700',
1420
- hoverBgColor: academicYear?.acayr_islocked ? 'hover:tw-bg-gray-50' : 'hover:tw-bg-gray-100'
1421
- }
1422
- ];
1423
- return items;
1424
- }
1425
- /**
1426
- * Handle dropdown item click
1427
- */
1428
- onDropdownItemClick(item, academicYear) {
1429
- console.log('🖱️ Dropdown item clicked:', item.id, 'for academic year:', academicYear.acayr_name);
1430
- // Check if item is disabled
1431
- if (item.disabled) {
1432
- console.log('⚠️ Item is disabled, ignoring click');
1433
- return;
1434
- }
1435
- switch (item.id) {
1436
- case 'view':
1437
- this.viewAcademicYear(academicYear);
1438
- break;
1439
- case 'edit':
1440
- this.editAcademicYear(academicYear);
1441
- break;
1442
- case 'toggle-status':
1443
- this.toggleAcademicYearStatus(academicYear);
1444
- break;
1445
- default:
1446
- console.log('❓ Unknown dropdown item clicked:', item.id);
1447
- }
1448
- }
1449
- /**
1450
- * Toggle academic year status (active/inactive)
1451
- */
1452
- toggleAcademicYearStatus(academicYear) {
1453
- console.log('🔄 Toggling academic year status:', academicYear);
1454
- // Check if the academic year is locked
1455
- if (academicYear.acayr_islocked) {
1456
- this.notificationService.error(`Cannot ${academicYear.acayr_isactive ? 'deactivate' : 'activate'} "${academicYear.acayr_name}" - This academic year is locked and its status cannot be changed. Please contact an administrator to unlock it first.`);
1457
- return;
1458
- }
1459
- const action = academicYear.acayr_isactive ? 'deactivate' : 'activate';
1460
- const actionText = academicYear.acayr_isactive ? 'Deactivate' : 'Activate';
1461
- // Show confirmation dialog
1462
- console.log('🔔 Showing confirmation dialog for toggle status');
1463
- this.confirmationService.ask({
1464
- title: `${actionText} Academic Year`,
1465
- message: `Are you sure you want to ${action} the academic year "${academicYear.acayr_name}"?${!academicYear.acayr_isactive ? '\n\nThis will also deactivate all associated mappings.' : ''}`,
1466
- confirmText: actionText,
1467
- cancelText: 'Cancel',
1468
- type: academicYear.acayr_isactive ? 'warning' : 'info'
1469
- }).then((confirmed) => {
1470
- console.log('🔔 Confirmation dialog result:', confirmed);
1471
- if (confirmed) {
1472
- this.loading.set(true);
1473
- // First toggle the academic year status
1474
- console.log('🔄 Calling toggleAcademicYearStatus with ID:', academicYear._id);
1475
- this.academicYearService.toggleAcademicYearStatus({ acayr_id: academicYear._id }).subscribe({
1476
- next: (response) => {
1477
- console.log('🔄 Toggle academic year status response:', response);
1478
- if (response?.success) {
1479
- console.log('✅ Academic year status toggled successfully');
1480
- // If deactivating, also toggle status of all academic year mappings
1481
- if (!academicYear.acayr_isactive) { // If we're deactivating (was active, now inactive)
1482
- this.toggleAcademicYearMappingsStatus(academicYear._id || '', false);
1483
- }
1484
- else {
1485
- // If activating, just reload the list
1486
- this.notificationService.success(`Academic year "${academicYear.acayr_name}" has been activated successfully.`);
1487
- this.loadAcademicYears();
1488
- }
1489
- }
1490
- else {
1491
- console.error('❌ Failed to toggle academic year status');
1492
- this.notificationService.error(response?.message || 'Failed to toggle academic year status');
1493
- this.loading.set(false);
1494
- }
1495
- },
1496
- error: (error) => {
1497
- console.error('❌ Error toggling academic year status:', error);
1498
- console.error('❌ Error details:', {
1499
- status: error.status,
1500
- message: error.message,
1501
- error: error.error
1502
- });
1503
- this.notificationService.error('Failed to toggle academic year status. Please try again.');
1504
- this.loading.set(false);
1505
- }
1506
- });
1507
- }
1508
- });
1509
- }
1510
- /**
1511
- * Toggle status of all academic year mappings for a specific academic year
1512
- */
1513
- toggleAcademicYearMappingsStatus(academicYearId, isActive) {
1514
- console.log(`🔄 Toggling mappings status for academic year ${academicYearId} to ${isActive ? 'active' : 'inactive'}`);
1515
- // Get all mappings for this academic year and toggle their status
1516
- // For now, we'll reload the academic year data to get the mappings
1517
- // In a real implementation, you might want to get mappings separately
1518
- this.academicYearService.getAcademicYearById({ acayr_id: academicYearId }).subscribe({
1519
- next: (response) => {
1520
- if (response?.success && response.data && response.data.acayr_academic_year_mappings) {
1521
- const mappings = response.data.acayr_academic_year_mappings;
1522
- console.log('📋 Found mappings to toggle:', mappings);
1523
- // Toggle each mapping's status
1524
- const toggleObservables = mappings.map((mapping) => {
1525
- return this.academicYearService.toggleAcademicYearMappingStatus({
1526
- acayrmp_id: mapping._id
1527
- }).pipe(catchError(error => {
1528
- console.error('❌ Error toggling mapping status:', error);
1529
- return of({ success: false, error, mappingId: mapping._id });
1530
- }));
1531
- });
1532
- if (toggleObservables.length > 0) {
1533
- forkJoin(toggleObservables).subscribe((results) => {
1534
- console.log('✅ All mapping statuses toggled:', results);
1535
- const resultsArray = results;
1536
- const failedCount = resultsArray.filter((result) => !result.success).length;
1537
- if (failedCount === 0) {
1538
- this.notificationService.success(`Academic year and all ${resultsArray.length} associated mappings have been deactivated successfully.`);
1539
- }
1540
- else {
1541
- this.notificationService.warning(`Academic year deactivated, but ${failedCount} out of ${resultsArray.length} mappings failed to update.`);
1542
- }
1543
- this.loadAcademicYears(); // Reload the list
1544
- }, (error) => {
1545
- console.error('❌ Error toggling mapping statuses:', error);
1546
- this.notificationService.error('Academic year deactivated, but failed to update some mappings.');
1547
- this.loadAcademicYears(); // Still reload the list
1548
- });
1549
- }
1550
- else {
1551
- this.notificationService.success('Academic year has been deactivated successfully.');
1552
- this.loadAcademicYears(); // No mappings to toggle, just reload
1553
- }
1554
- }
1555
- else {
1556
- this.notificationService.success('Academic year has been deactivated successfully.');
1557
- this.loadAcademicYears(); // No mappings found, just reload
1558
- }
1559
- },
1560
- error: (error) => {
1561
- console.error('❌ Error getting academic year mappings:', error);
1562
- this.notificationService.error('Academic year deactivated, but failed to update mappings.');
1563
- this.loadAcademicYears(); // Still reload the list
1564
- }
1565
- });
1566
- }
1567
- // Export handler
1568
- handleExport(format) {
1569
- console.log(`📤 Exporting academic years as ${format}`);
1570
- const data = this.academicYears().map(item => ({
1571
- 'Academic Year Code': item.acayr_code,
1572
- 'Academic Year Name': item.acayr_name,
1573
- 'Description': item.acayr_description,
1574
- 'From Date': this.formatDate(item?.acayr_from_date || ""),
1575
- 'To Date': this.formatDate(item?.acayr_to_date || ""),
1576
- 'Duration': this.getDuration(item?.acayr_from_date || "", item?.acayr_to_date || ""),
1577
- 'Status': this.getStatusText(item),
1578
- 'Is Current': item.acayr_iscurrent ? 'Yes' : 'No',
1579
- 'Is Active': item.acayr_isactive ? 'Yes' : 'No',
1580
- 'Is Locked': item.acayr_islocked ? 'Yes' : 'No'
1581
- }));
1582
- // Create filename with timestamp
1583
- const timestamp = new Date().toISOString().split('T')[0];
1584
- const filename = `academic-years-${timestamp}`;
1585
- switch (format.toLowerCase()) {
1586
- case 'csv':
1587
- this.exportToCSV(data, filename);
1588
- break;
1589
- case 'excel':
1590
- this.exportToExcel(data, filename);
1591
- break;
1592
- case 'pdf':
1593
- this.exportToPDF(data, filename);
1594
- break;
1595
- default:
1596
- console.warn(`Unsupported export format: ${format}`);
1597
- }
1598
- }
1599
- exportToCSV(data, filename) {
1600
- const headers = Object.keys(data[0] || {});
1601
- const csvContent = [
1602
- headers.join(','),
1603
- ...data.map(row => headers.map(header => `"${row[header] || ''}"`).join(','))
1604
- ].join('\n');
1605
- this.downloadFile(csvContent, `${filename}.csv`, 'text/csv');
1606
- }
1607
- exportToExcel(data, filename) {
1608
- // For Excel export, you might want to use a library like xlsx
1609
- // For now, we'll export as CSV with .xlsx extension
1610
- this.exportToCSV(data, filename);
1611
- }
1612
- exportToPDF(data, filename) {
1613
- // For PDF export, you might want to use a library like jsPDF
1614
- // For now, we'll export as CSV
1615
- this.exportToCSV(data, filename);
1616
- }
1617
- downloadFile(content, filename, mimeType) {
1618
- const blob = new Blob([content], { type: mimeType });
1619
- const url = window.URL.createObjectURL(blob);
1620
- const link = document.createElement('a');
1621
- link.href = url;
1622
- link.download = filename;
1623
- document.body.appendChild(link);
1624
- link.click();
1625
- document.body.removeChild(link);
1626
- window.URL.revokeObjectURL(url);
1627
- }
1628
- // Utility methods with proper typing
1629
- formatDate(date) {
1630
- if (!date)
1631
- return '-';
1632
- return new Date(date).toLocaleDateString('en-US', {
1633
- year: 'numeric',
1634
- month: 'short',
1635
- day: 'numeric'
1636
- });
1637
- }
1638
- getDuration(fromDate, toDate) {
1639
- if (!fromDate || !toDate)
1640
- return '';
1641
- const from = new Date(fromDate);
1642
- const to = new Date(toDate);
1643
- const diffTime = Math.abs(to.getTime() - from.getTime());
1644
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
1645
- const months = Math.floor(diffDays / 30);
1646
- const years = Math.floor(months / 12);
1647
- if (years > 0) {
1648
- return `${years} year${years > 1 ? 's' : ''}`;
1649
- }
1650
- else if (months > 0) {
1651
- return `${months} month${months > 1 ? 's' : ''}`;
1652
- }
1653
- else {
1654
- return `${diffDays} day${diffDays > 1 ? 's' : ''}`;
1655
- }
1656
- }
1657
- getStatusBadgeClass(academicYear) {
1658
- if (academicYear.acayr_iscurrent)
1659
- return 'tw-bg-green-100 tw-text-green-800';
1660
- if (academicYear.acayr_islocked)
1661
- return 'tw-bg-red-100 tw-text-red-800';
1662
- if (academicYear.acayr_isactive)
1663
- return 'tw-bg-blue-100 tw-text-blue-800';
1664
- return 'tw-bg-gray-100 tw-text-gray-800';
1665
- }
1666
- getActiveStatusBadgeClass(academicYear) {
1667
- if (academicYear.acayr_isactive) {
1668
- return 'tw-bg-green-100 tw-text-green-800';
1669
- }
1670
- else {
1671
- return 'tw-bg-orange-100 tw-text-orange-800';
1672
- }
1673
- }
1674
- getStatusText(academicYear) {
1675
- if (academicYear.acayr_iscurrent)
1676
- return 'Current';
1677
- if (academicYear.acayr_islocked)
1678
- return 'Locked';
1679
- if (academicYear.acayr_isactive)
1680
- return 'Active';
1681
- return 'Inactive';
1682
- }
1683
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AcademicYearListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1684
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: AcademicYearListComponent, isStandalone: true, selector: "cide-core-academic-year-list", viewQueries: [{ propertyName: "academicYearDetailsRendererTemplate", first: true, predicate: ["academicYearDetailsRendererTemplate"], descendants: true, isSignal: true }, { propertyName: "dateRangeRendererTemplate", first: true, predicate: ["dateRangeRendererTemplate"], descendants: true, isSignal: true }, { propertyName: "statusRendererTemplate", first: true, predicate: ["statusRendererTemplate"], descendants: true, isSignal: true }, { propertyName: "actionsDropdownRendererTemplate", first: true, predicate: ["actionsDropdownRendererTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Academic Year Container -->\r\n<div class=\"tw-table tw-w-full tw-h-full\">\r\n\r\n <!-- Header Section with Filters -->\r\n <div class=\"tw-table-row tw-h-0\">\r\n <div class=\"tw-table-cell 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-blue-600 tw-w-5 tw-h-5\">school</cide-ele-icon>\r\n <h5 class=\"tw-text-base tw-font-medium tw-text-gray-900 tw-m-0\">Academic Year Management</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 <button cideEleButton variant=\"primary\" size=\"sm\" leftIcon=\"add\" (click)=\"createAcademicYear()\">\r\n Create Academic Year\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Main Content Area -->\r\n <div class=\"tw-table-row\">\r\n <div class=\"tw-table-cell tw-h-full tw-relative\">\r\n\r\n <!-- Data Grid Component -->\r\n <div class=\"tw-h-full tw-overflow-auto\">\r\n <cide-ele-data-grid [config]=\"gridConfig()\" [templateRenderers]=\"templateRenderers()\"\r\n (gridEvent)=\"onGridEvent($event)\">\r\n </cide-ele-data-grid>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<!-- Template Renderers -->\r\n<ng-template #academicYearDetailsRendererTemplate let-row=\"row\">\r\n <div class=\"tw-flex tw-flex-col tw-w-full\">\r\n <div class=\"tw-font-medium tw-text-gray-900\">{{ row.acayr_name || 'N/A' }}</div>\r\n <div class=\"tw-text-sm tw-text-gray-500 tw-truncate\">{{ row.acayr_description || 'No description' }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dateRangeRendererTemplate let-row=\"row\">\r\n <div class=\"tw-flex tw-flex-col tw-text-sm\">\r\n <span class=\"tw-text-gray-900 tw-font-medium\">{{ formatDate(row.acayr_from_date) }}</span>\r\n <span class=\"tw-text-gray-500\">to {{ formatDate(row.acayr_to_date) }}</span>\r\n <span class=\"tw-text-xs tw-text-gray-400\">{{ getDuration(row.acayr_from_date, row.acayr_to_date) }}</span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #statusRendererTemplate let-row=\"row\">\r\n <div class=\"tw-flex tw-flex-col tw-gap-1 tw-items-center\">\r\n <!-- Current Year Badge (Priority) -->\r\n @if (row.acayr_iscurrent) {\r\n <span\r\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-px-2.5 tw-py-1 tw-rounded-full tw-text-xs tw-font-medium tw-bg-yellow-100 tw-text-yellow-800 tw-text-center\">\r\n <cide-ele-icon size=\"2xs\" class=\"tw-mr-1\">star</cide-ele-icon>\r\n Current Year\r\n </span>\r\n }\r\n \r\n <!-- Active/Inactive Status Badge -->\r\n <span class=\"tw-inline-flex tw-items-center tw-justify-center tw-px-2.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-text-center\"\r\n [ngClass]=\"getActiveStatusBadgeClass(row)\">\r\n <cide-ele-icon size=\"2xs\" class=\"tw-mr-1\">\r\n {{ row.acayr_isactive ? 'check_circle' : 'cancel' }}\r\n </cide-ele-icon>\r\n {{ row.acayr_isactive ? 'Active' : 'Inactive' }}\r\n </span>\r\n \r\n <!-- Locked Status Badge (Additional info) -->\r\n @if (row.acayr_islocked) {\r\n <span\r\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-px-2 tw-py-1 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800 tw-text-center\">\r\n <cide-ele-icon size=\"2xs\" class=\"tw-mr-1\">lock</cide-ele-icon>\r\n Locked\r\n </span>\r\n }\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #actionsDropdownRendererTemplate let-row=\"row\" let-value=\"value\">\r\n <cide-ele-dropdown \r\n [items]=\"getActionDropdownItems(row)\"\r\n [config]=\"{ triggerIcon: 'more_vert', triggerSize: 'sm' }\"\r\n (itemClick)=\"onDropdownItemClick($event, row)\">\r\n </cide-ele-dropdown>\r\n</ng-template>", styles: [".academic-year-listing-container{@apply tw-w-full tw-h-full;}:host{@apply tw-w-full tw-h-full tw-flex tw-flex-col;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", 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: CideEleDataGridComponent, selector: "cide-ele-data-grid", inputs: ["config", "templateRenderers", "customFormatters", "actionHandlers", "serverSidePagination", "totalServerItems", "currentServerPage", "currentServerPageSize", "dragDropEnabled"], outputs: ["gridEvent"] }, { kind: "component", type: CideEleDropdownComponent, selector: "cide-ele-dropdown", inputs: ["items", "config", "triggerTemplate", "menuTemplate"], outputs: ["itemClick", "dropdownToggle"] }] });
1685
- }
1686
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AcademicYearListComponent, decorators: [{
1687
- type: Component,
1688
- args: [{ selector: 'cide-core-academic-year-list', standalone: true, imports: [
1689
- CommonModule,
1690
- FormsModule,
1691
- CideIconComponent,
1692
- CideEleButtonComponent,
1693
- CideEleDataGridComponent,
1694
- CideEleDropdownComponent
1695
- ], template: "<!-- Academic Year Container -->\r\n<div class=\"tw-table tw-w-full tw-h-full\">\r\n\r\n <!-- Header Section with Filters -->\r\n <div class=\"tw-table-row tw-h-0\">\r\n <div class=\"tw-table-cell 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-blue-600 tw-w-5 tw-h-5\">school</cide-ele-icon>\r\n <h5 class=\"tw-text-base tw-font-medium tw-text-gray-900 tw-m-0\">Academic Year Management</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 <button cideEleButton variant=\"primary\" size=\"sm\" leftIcon=\"add\" (click)=\"createAcademicYear()\">\r\n Create Academic Year\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Main Content Area -->\r\n <div class=\"tw-table-row\">\r\n <div class=\"tw-table-cell tw-h-full tw-relative\">\r\n\r\n <!-- Data Grid Component -->\r\n <div class=\"tw-h-full tw-overflow-auto\">\r\n <cide-ele-data-grid [config]=\"gridConfig()\" [templateRenderers]=\"templateRenderers()\"\r\n (gridEvent)=\"onGridEvent($event)\">\r\n </cide-ele-data-grid>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n</div>\r\n\r\n<!-- Template Renderers -->\r\n<ng-template #academicYearDetailsRendererTemplate let-row=\"row\">\r\n <div class=\"tw-flex tw-flex-col tw-w-full\">\r\n <div class=\"tw-font-medium tw-text-gray-900\">{{ row.acayr_name || 'N/A' }}</div>\r\n <div class=\"tw-text-sm tw-text-gray-500 tw-truncate\">{{ row.acayr_description || 'No description' }}</div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dateRangeRendererTemplate let-row=\"row\">\r\n <div class=\"tw-flex tw-flex-col tw-text-sm\">\r\n <span class=\"tw-text-gray-900 tw-font-medium\">{{ formatDate(row.acayr_from_date) }}</span>\r\n <span class=\"tw-text-gray-500\">to {{ formatDate(row.acayr_to_date) }}</span>\r\n <span class=\"tw-text-xs tw-text-gray-400\">{{ getDuration(row.acayr_from_date, row.acayr_to_date) }}</span>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #statusRendererTemplate let-row=\"row\">\r\n <div class=\"tw-flex tw-flex-col tw-gap-1 tw-items-center\">\r\n <!-- Current Year Badge (Priority) -->\r\n @if (row.acayr_iscurrent) {\r\n <span\r\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-px-2.5 tw-py-1 tw-rounded-full tw-text-xs tw-font-medium tw-bg-yellow-100 tw-text-yellow-800 tw-text-center\">\r\n <cide-ele-icon size=\"2xs\" class=\"tw-mr-1\">star</cide-ele-icon>\r\n Current Year\r\n </span>\r\n }\r\n \r\n <!-- Active/Inactive Status Badge -->\r\n <span class=\"tw-inline-flex tw-items-center tw-justify-center tw-px-2.5 tw-py-0.5 tw-rounded-full tw-text-xs tw-font-medium tw-text-center\"\r\n [ngClass]=\"getActiveStatusBadgeClass(row)\">\r\n <cide-ele-icon size=\"2xs\" class=\"tw-mr-1\">\r\n {{ row.acayr_isactive ? 'check_circle' : 'cancel' }}\r\n </cide-ele-icon>\r\n {{ row.acayr_isactive ? 'Active' : 'Inactive' }}\r\n </span>\r\n \r\n <!-- Locked Status Badge (Additional info) -->\r\n @if (row.acayr_islocked) {\r\n <span\r\n class=\"tw-inline-flex tw-items-center tw-justify-center tw-px-2 tw-py-1 tw-rounded-full tw-text-xs tw-font-medium tw-bg-red-100 tw-text-red-800 tw-text-center\">\r\n <cide-ele-icon size=\"2xs\" class=\"tw-mr-1\">lock</cide-ele-icon>\r\n Locked\r\n </span>\r\n }\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #actionsDropdownRendererTemplate let-row=\"row\" let-value=\"value\">\r\n <cide-ele-dropdown \r\n [items]=\"getActionDropdownItems(row)\"\r\n [config]=\"{ triggerIcon: 'more_vert', triggerSize: 'sm' }\"\r\n (itemClick)=\"onDropdownItemClick($event, row)\">\r\n </cide-ele-dropdown>\r\n</ng-template>", styles: [".academic-year-listing-container{@apply tw-w-full tw-h-full;}:host{@apply tw-w-full tw-h-full tw-flex tw-flex-col;}\n"] }]
1696
- }] });
1697
-
1698
- var academicYearList_component = /*#__PURE__*/Object.freeze({
1699
- __proto__: null,
1700
- AcademicYearListComponent: AcademicYearListComponent
1701
- });
1702
-
1703
- // Academic Year Management Components
1704
-
1705
- class CideLytClassProgramBranchService {
1706
- http = inject(HttpClient);
1707
- /**
1708
- * Get list of class program branches
1709
- * @param payload - Query parameters for filtering/pagination
1710
- * @returns Observable of class program branch list response
1711
- */
1712
- getClassProgramBranchList(payload) {
1713
- console.log("Class Program Branch List Payload:", payload);
1714
- const query = generateStringFromObject(payload);
1715
- const url = cidePath.join([
1716
- hostManagerRoutesUrl.cideSuiteHost,
1717
- academicsRoutesUrl.module,
1718
- academicsRoutesUrl.classProgramBranch,
1719
- query
1720
- ]);
1721
- return this.http.get(url);
1722
- }
1723
- /**
1724
- * Get class program branch by ID
1725
- * @param payload - Class program branch ID payload
1726
- * @returns Observable of class program branch data
1727
- */
1728
- getClassProgramBranchById(payload) {
1729
- const query = generateStringFromObject(payload);
1730
- const url = cidePath.join([
1731
- hostManagerRoutesUrl.cideSuiteHost,
1732
- academicsRoutesUrl.module,
1733
- academicsRoutesUrl.classProgramBranch,
1734
- 'byId',
1735
- query
1736
- ]);
1737
- return this.http.get(url);
1738
- }
1739
- /**
1740
- * Create or update class program branch
1741
- * @param data - Class program branch data to save
1742
- * @returns Observable of the save response
1743
- */
1744
- saveClassProgramBranch(data) {
1745
- const url = cidePath.join([
1746
- hostManagerRoutesUrl.cideSuiteHost,
1747
- academicsRoutesUrl.module,
1748
- academicsRoutesUrl.classProgramBranch
1749
- ]);
1750
- return this.http.post(url, data);
1751
- }
1752
- /**
1753
- * Delete class program branch
1754
- * @param payload - Class program branch delete payload
1755
- * @returns Observable of the delete response
1756
- */
1757
- deleteClassProgramBranch(payload) {
1758
- const query = generateStringFromObject(payload);
1759
- const url = cidePath.join([
1760
- hostManagerRoutesUrl.cideSuiteHost,
1761
- academicsRoutesUrl.module,
1762
- academicsRoutesUrl.classProgramBranch,
1763
- query
1764
- ]);
1765
- return this.http.delete(url);
1766
- }
1767
- /**
1768
- * Toggle class program branch status (active/inactive)
1769
- * @param payload - Class program branch toggle status payload
1770
- * @returns Observable of the toggle status response
1771
- */
1772
- toggleClassProgramBranchStatus(payload) {
1773
- const query = generateStringFromObject(payload);
1774
- const url = cidePath.join([
1775
- hostManagerRoutesUrl.cideSuiteHost,
1776
- academicsRoutesUrl.module,
1777
- academicsRoutesUrl.classProgramBranch,
1778
- 'toggleStatus',
1779
- query
1780
- ]);
1781
- return this.http.put(url, {});
1782
- }
1783
- /**
1784
- * Toggle class program branch lock
1785
- * @param payload - Class program branch toggle lock payload
1786
- * @returns Observable of the toggle lock response
1787
- */
1788
- toggleClassProgramBranchLock(payload) {
1789
- const query = generateStringFromObject(payload);
1790
- const url = cidePath.join([
1791
- hostManagerRoutesUrl.cideSuiteHost,
1792
- academicsRoutesUrl.module,
1793
- academicsRoutesUrl.classProgramBranch,
1794
- 'toggleLock',
1795
- query
1796
- ]);
1797
- return this.http.put(url, {});
1798
- }
1799
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytClassProgramBranchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1800
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytClassProgramBranchService, providedIn: 'root' });
1801
- }
1802
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytClassProgramBranchService, decorators: [{
1803
- type: Injectable,
1804
- args: [{
1805
- providedIn: 'root'
1806
- }]
1807
- }] });
1808
-
1809
- class CideLytProgramClassService {
1810
- http = inject(HttpClient);
1811
- /**
1812
- * Get list of program classes
1813
- * @param payload - Query parameters for filtering/pagination
1814
- * @returns Observable of program class list response
1815
- */
1816
- getProgramClassList(payload) {
1817
- console.log("Program Class List Payload:", payload);
1818
- const query = generateStringFromObject(payload);
1819
- const url = cidePath.join([
1820
- hostManagerRoutesUrl.cideSuiteHost,
1821
- academicsRoutesUrl.module,
1822
- academicsRoutesUrl.classProgramMaster,
1823
- query
1824
- ]);
1825
- return this.http.get(url);
1826
- }
1827
- /**
1828
- * Get program class by ID
1829
- * @param payload - Program class ID payload
1830
- * @returns Observable of program class data
1831
- */
1832
- getProgramClassById(payload) {
1833
- const query = generateStringFromObject(payload);
1834
- const url = cidePath.join([
1835
- hostManagerRoutesUrl.cideSuiteHost,
1836
- academicsRoutesUrl.module,
1837
- academicsRoutesUrl.classProgramMaster,
1838
- 'byId',
1839
- query
1840
- ]);
1841
- return this.http.get(url);
1842
- }
1843
- /**
1844
- * Create or update program class
1845
- * @param data - Program class data to save
1846
- * @returns Observable of the save response
1847
- */
1848
- saveProgramClass(data) {
1849
- const url = cidePath.join([
1850
- hostManagerRoutesUrl.cideSuiteHost,
1851
- academicsRoutesUrl.module,
1852
- academicsRoutesUrl.classProgramMaster
1853
- ]);
1854
- return this.http.post(url, data);
1855
- }
1856
- /**
1857
- * Delete program class
1858
- * @param payload - Program class delete payload
1859
- * @returns Observable of the delete response
1860
- */
1861
- deleteProgramClass(payload) {
1862
- const query = generateStringFromObject(payload);
1863
- const url = cidePath.join([
1864
- hostManagerRoutesUrl.cideSuiteHost,
1865
- academicsRoutesUrl.module,
1866
- academicsRoutesUrl.classProgramMaster,
1867
- query
1868
- ]);
1869
- return this.http.delete(url);
1870
- }
1871
- /**
1872
- * Toggle program class status (active/inactive)
1873
- * @param payload - Program class toggle status payload
1874
- * @returns Observable of the toggle status response
1875
- */
1876
- toggleProgramClassStatus(payload) {
1877
- const query = generateStringFromObject(payload);
1878
- const url = cidePath.join([
1879
- hostManagerRoutesUrl.cideSuiteHost,
1880
- academicsRoutesUrl.module,
1881
- academicsRoutesUrl.classProgramMaster,
1882
- 'toggleStatus',
1883
- query
1884
- ]);
1885
- return this.http.put(url, {});
1886
- }
1887
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytProgramClassService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1888
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytProgramClassService, providedIn: 'root' });
1889
- }
1890
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytProgramClassService, decorators: [{
1891
- type: Injectable,
1892
- args: [{
1893
- providedIn: 'root'
1894
- }]
1895
- }] });
1896
-
1897
- class CideLytClassProgramBranchListComponent {
1898
- // Dependency injection
1899
- destroyRef = inject(DestroyRef);
1900
- router = inject(Router);
1901
- route = inject(ActivatedRoute);
1902
- appState = inject(AppStateHelperService);
1903
- notificationService = inject(NotificationService);
1904
- confirmationService = inject(ConfirmationService);
1905
- classProgramBranchService = inject(CideLytClassProgramBranchService);
1906
- programClassService = inject(CideLytProgramClassService);
1907
- // State management
1908
- loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1909
- error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
1910
- branches = signal([], ...(ngDevMode ? [{ debugName: "branches" }] : []));
1911
- totalCount = signal(0, ...(ngDevMode ? [{ debugName: "totalCount" }] : []));
1912
- programId = signal(null, ...(ngDevMode ? [{ debugName: "programId" }] : []));
1913
- programClasses = signal([], ...(ngDevMode ? [{ debugName: "programClasses" }] : []));
1914
- selectedProgramClassId = signal(null, ...(ngDevMode ? [{ debugName: "selectedProgramClassId" }] : []));
1915
- // Signal for breadcrumb data that will be passed to shared wrapper
1916
- breadcrumbData = signal([], ...(ngDevMode ? [{ debugName: "breadcrumbData" }] : []));
1917
- // Template renderers
1918
- dragHandleRendererTemplate = viewChild('dragHandleRendererTemplate', ...(ngDevMode ? [{ debugName: "dragHandleRendererTemplate" }] : []));
1919
- classProgramRendererTemplate = viewChild('classProgramRendererTemplate', ...(ngDevMode ? [{ debugName: "classProgramRendererTemplate" }] : []));
1920
- actionsDropdownRendererTemplate = viewChild('actionsDropdownRendererTemplate', ...(ngDevMode ? [{ debugName: "actionsDropdownRendererTemplate" }] : []));
1921
- // Grid configuration
1922
- gridConfig = signal({
1923
- id: 'class-program-branch-list-grid',
1924
- title: '',
1925
- subtitle: '',
1926
- columns: [
1927
- {
1928
- key: 'drag',
1929
- header: '',
1930
- type: 'custom',
1931
- width: '40px',
1932
- truncate: false,
1933
- align: 'center',
1934
- renderer: 'dragHandleRenderer'
1935
- },
1936
- {
1937
- key: 'acabrn_name',
1938
- header: 'Branch Name',
1939
- type: 'text',
1940
- width: '300px',
1941
- truncate: true,
1942
- align: 'left'
1943
- },
1944
- {
1945
- key: 'acabrn_code',
1946
- header: 'Code',
1947
- type: 'text',
1948
- width: '150px',
1949
- truncate: true,
1950
- align: 'left'
1951
- },
1952
- {
1953
- key: 'acabrn_class_program_id_acacpm',
1954
- header: 'Class Program',
1955
- type: 'custom',
1956
- width: '200px',
1957
- truncate: true,
1958
- align: 'left',
1959
- renderer: 'classProgramRenderer'
1960
- },
1961
- {
1962
- key: 'acabrn_isactive',
1963
- header: 'Status',
1964
- type: 'status',
1965
- width: '100px',
1966
- truncate: false,
1967
- align: 'center',
1968
- statusConfig: {
1969
- activeValue: true,
1970
- activeLabel: 'Active',
1971
- inactiveLabel: 'Inactive',
1972
- activeClass: 'tw-bg-green-100 tw-text-green-800',
1973
- inactiveClass: 'tw-bg-red-100 tw-text-red-800'
1974
- }
1975
- },
1976
- {
1977
- key: 'acabrn_islocked',
1978
- header: 'Locked',
1979
- type: 'status',
1980
- width: '100px',
1981
- truncate: false,
1982
- align: 'center',
1983
- statusConfig: {
1984
- activeValue: true,
1985
- activeLabel: 'Locked',
1986
- inactiveLabel: 'Unlocked',
1987
- activeClass: 'tw-bg-yellow-100 tw-text-yellow-800',
1988
- inactiveClass: 'tw-bg-gray-100 tw-text-gray-800'
1989
- }
1990
- },
1991
- {
1992
- key: 'actions',
1993
- header: '',
1994
- type: 'custom',
1995
- width: '80px',
1996
- truncate: false,
1997
- align: 'center',
1998
- renderer: 'actionsDropdownRenderer'
1999
- }
2000
- ],
2001
- data: [],
2002
- trackBy: '_id',
2003
- pagination: {
2004
- enabled: true,
2005
- pageSize: 10,
2006
- pageSizeOptions: [10, 25, 50, 100],
2007
- showQuickJump: true,
2008
- showPageInfo: true,
2009
- showRefresh: true
2010
- },
2011
- search: {
2012
- enabled: true,
2013
- placeholder: 'Search branches...',
2014
- searchableColumns: ['acabrn_name', 'acabrn_code'],
2015
- debounceMs: 300
2016
- },
2017
- loading: {
2018
- useDefer: true,
2019
- skeletonRows: 5,
2020
- showOverlay: false
2021
- },
2022
- scroll: {
2023
- enabled: true,
2024
- stickyHeader: true,
2025
- virtualScroll: false,
2026
- rowHeight: 50
2027
- },
2028
- fullHeight: true,
2029
- responsive: true,
2030
- striped: true,
2031
- bordered: true,
2032
- compact: false,
2033
- tableClass: 'tw-table-fixed tw-w-full',
2034
- dragDrop: {
2035
- enabled: true
2036
- },
2037
- onRefresh: 'onRefresh',
2038
- onPageChange: 'onPageChange',
2039
- onSearch: 'onSearch',
2040
- onRowReorder: 'onRowReorder'
2041
- }, ...(ngDevMode ? [{ debugName: "gridConfig" }] : []));
2042
- // Computed template renderers
2043
- templateRenderers = computed(() => {
2044
- const renderers = {};
2045
- if (this.dragHandleRendererTemplate()) {
2046
- renderers['dragHandleRenderer'] = this.dragHandleRendererTemplate();
2047
- }
2048
- if (this.classProgramRendererTemplate()) {
2049
- renderers['classProgramRenderer'] = this.classProgramRendererTemplate();
2050
- }
2051
- if (this.actionsDropdownRendererTemplate()) {
2052
- renderers['actionsDropdownRenderer'] = this.actionsDropdownRendererTemplate();
2053
- }
2054
- return renderers;
2055
- }, ...(ngDevMode ? [{ debugName: "templateRenderers" }] : []));
2056
- ngOnInit() {
2057
- console.log('🏢 Class Program Branch List Component initialized');
2058
- this.initializeBreadcrumbData();
2059
- this.loadProgramClasses();
2060
- this.checkRouteParams();
2061
- // Load branches will be called when programId is set in checkRouteParams
2062
- }
2063
- /**
2064
- * Initialize breadcrumb data for list view
2065
- */
2066
- initializeBreadcrumbData() {
2067
- // The shared wrapper will automatically add:
2068
- // 1. Module (Academics) from app state
2069
- // 2. Current page (Class Program Branch Management) from page config
2070
- // We can add additional items here if needed
2071
- this.breadcrumbData.set([
2072
- {
2073
- id: 'list',
2074
- label: 'List',
2075
- icon: 'list',
2076
- url: undefined
2077
- }
2078
- ]);
2079
- }
2080
- /**
2081
- * Load program classes for dropdown
2082
- */
2083
- loadProgramClasses() {
2084
- const payload = {
2085
- pagination: false,
2086
- acacpm_isactive: true
2087
- };
2088
- this.programClassService.getProgramClassList(payload)
2089
- .pipe(takeUntilDestroyed(this.destroyRef))
2090
- .subscribe({
2091
- next: (response) => {
2092
- console.log('✅ Program classes loaded:', response);
2093
- if (response?.success && response.data) {
2094
- this.programClasses.set(response.data);
2095
- }
2096
- else {
2097
- console.warn('⚠️ No program class data received');
2098
- this.programClasses.set([]);
2099
- }
2100
- },
2101
- error: (error) => {
2102
- console.error('❌ Error loading program classes:', error);
2103
- this.programClasses.set([]);
2104
- }
2105
- });
2106
- }
2107
- /**
2108
- * Handle Program Class selection change
2109
- */
2110
- onProgramClassChange(programClassId) {
2111
- const programId = typeof programClassId === 'string' ? programClassId : (programClassId ? String(programClassId) : null);
2112
- console.log('🔄 Program Class changed:', programId);
2113
- if (!programId) {
2114
- // Class program is required, show error if cleared
2115
- this.notificationService.warning('Class Program is required to view branches');
2116
- return;
2117
- }
2118
- this.selectedProgramClassId.set(programId);
2119
- this.programId.set(programId);
2120
- this.loadBranches();
2121
- }
2122
- /**
2123
- * Check route parameters for program ID
2124
- */
2125
- checkRouteParams() {
2126
- this.route.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(params => {
2127
- const queryParams = params['query'];
2128
- console.log('🏢 Route params:', params, 'queryParams:', queryParams);
2129
- if (queryParams) {
2130
- // Query parameters passed (following page-controls pattern)
2131
- const queryData = generateObjectFromString(queryParams);
2132
- console.log('🏢 Query data from route:', queryData);
2133
- // Check for programId in various possible formats
2134
- const programId = queryData?.programId;
2135
- if (programId) {
2136
- this.programId.set(programId);
2137
- this.selectedProgramClassId.set(programId);
2138
- console.log('🏢 Program Class ID extracted from route:', programId);
2139
- console.log('🏢 Will filter branches by acabrn_class_program_id_acacpm:', programId);
2140
- this.loadBranches();
2141
- }
2142
- else {
2143
- // No program ID in route params, check query params
2144
- this.checkQueryParams();
2145
- }
2146
- }
2147
- else {
2148
- // No route query params, check direct query parameters
2149
- this.checkQueryParams();
2150
- }
2151
- });
2152
- }
2153
- /**
2154
- * Check direct query parameters for program ID
2155
- */
2156
- checkQueryParams() {
2157
- const queryParams = this.route.snapshot.queryParams;
2158
- const programId = queryParams['programId'];
2159
- if (programId) {
2160
- this.programId.set(programId);
2161
- this.selectedProgramClassId.set(programId);
2162
- console.log('🏢 Program Class ID from query params:', programId);
2163
- console.log('🏢 Will filter branches by acabrn_class_program_id_acacpm:', programId);
2164
- this.loadBranches();
2165
- }
2166
- else {
2167
- // No program ID provided - class program is required
2168
- console.log('🏢 No program class ID provided - class program is required');
2169
- this.programId.set(null);
2170
- this.selectedProgramClassId.set(null);
2171
- // Don't load branches if no program ID - wait for user selection
2172
- this.branches.set([]);
2173
- this.updateGridData();
2174
- }
2175
- }
2176
- /**
2177
- * Load branches from API
2178
- */
2179
- loadBranches() {
2180
- this.loading.set(true);
2181
- this.error.set(null);
2182
- // Build payload with program ID - required field
2183
- const currentProgramId = this.programId();
2184
- // Class program is required, so we must have a program ID
2185
- if (!currentProgramId) {
2186
- this.loading.set(false);
2187
- this.error.set('Class Program is required');
2188
- this.branches.set([]);
2189
- this.updateGridData();
2190
- return;
2191
- }
2192
- const payload = new AcaClassPrgBranchListPayload({
2193
- acabrn_class_program_id_acacpm: currentProgramId,
2194
- pagination: true,
2195
- pageIndex: 0,
2196
- pageSize: 10
2197
- });
2198
- console.log('🏢 API Payload:', payload);
2199
- this.classProgramBranchService.getClassProgramBranchList(payload)
2200
- .pipe(takeUntilDestroyed(this.destroyRef))
2201
- .subscribe({
2202
- next: (response) => {
2203
- console.log('✅ Branches loaded:', response);
2204
- if (response?.success && response.data) {
2205
- this.branches.set(response.data);
2206
- this.totalCount.set(response.total || 0);
2207
- this.updateGridData();
2208
- }
2209
- else {
2210
- this.error.set('Failed to load branches');
2211
- this.notificationService.error('Failed to load branches');
2212
- }
2213
- this.loading.set(false);
2214
- },
2215
- error: (error) => {
2216
- console.error('❌ Error loading branches:', error);
2217
- this.error.set('Failed to load branches');
2218
- this.loading.set(false);
2219
- this.notificationService.error('Failed to load branches');
2220
- }
2221
- });
2222
- }
2223
- /**
2224
- * Update grid data
2225
- */
2226
- updateGridData() {
2227
- this.gridConfig.update(config => ({
2228
- ...config,
2229
- data: this.branches()
2230
- }));
2231
- }
2232
- /**
2233
- * Handle grid events
2234
- */
2235
- onGridEvent(event) {
2236
- console.log('Grid Event:', event);
2237
- switch (event.type) {
2238
- case 'refresh':
2239
- this.onRefresh();
2240
- break;
2241
- case 'pageChange':
2242
- this.onPageChange(event.data);
2243
- break;
2244
- case 'search':
2245
- this.onSearch(event.data);
2246
- break;
2247
- case 'rowReorder':
2248
- this.onRowReorder(event.data);
2249
- break;
2250
- }
2251
- }
2252
- /**
2253
- * Handle refresh
2254
- */
2255
- onRefresh() {
2256
- this.loadBranches();
2257
- }
2258
- /**
2259
- * Handle page change
2260
- */
2261
- onPageChange(event) {
2262
- console.log('Page change:', event);
2263
- // Implement pagination logic here
2264
- }
2265
- /**
2266
- * Handle search
2267
- */
2268
- onSearch(event) {
2269
- console.log('Search:', event);
2270
- // Implement search logic here
2271
- }
2272
- /**
2273
- * Handle row reorder (drag and drop)
2274
- */
2275
- onRowReorder(event) {
2276
- console.log('Row reorder:', event);
2277
- if (event && event.newOrder) {
2278
- // Update the sequence order based on the new drag and drop order
2279
- this.updateSequenceOrder(event.newOrder);
2280
- }
2281
- }
2282
- /**
2283
- * Update sequence order for branches
2284
- */
2285
- updateSequenceOrder(branches) {
2286
- // Update sequence numbers based on new order
2287
- const updatedBranches = branches.map((branch, index) => ({
2288
- ...branch,
2289
- acabrn_sequence: index + 1
2290
- }));
2291
- // Update local state
2292
- this.branches.set(updatedBranches);
2293
- this.updateGridData();
2294
- // TODO: Implement API call to update sequence order on server
2295
- // This would typically be a bulk update API call
2296
- console.log('Updated sequence order:', updatedBranches.map(b => ({ id: b._id, sequence: b.acabrn_sequence })));
2297
- this.notificationService.success('Sequence order updated successfully');
2298
- }
2299
- /**
2300
- * Navigate to create branch
2301
- */
2302
- onCreateBranch(event) {
2303
- console.log('🏢 Create Branch button clicked', event);
2304
- const currentProgramId = this.programId();
2305
- console.log('🏢 Current Program ID:', currentProgramId);
2306
- if (!currentProgramId) {
2307
- // Class program is required
2308
- this.notificationService.warning('Please select a Class Program first before creating a branch');
2309
- return;
2310
- }
2311
- // Use generateStringFromObject to pass programId as route parameter
2312
- const queryParams = generateStringFromObject({ programId: currentProgramId });
2313
- console.log('🏢 Navigating to create with programId:', queryParams);
2314
- this.router.navigate(['/control-panel/program_specialization/create', queryParams]).then((success) => {
2315
- console.log('✅ Navigation successful:', success);
2316
- }, (error) => {
2317
- console.error('❌ Navigation failed:', error);
2318
- this.notificationService.error('Failed to navigate to create branch page');
2319
- });
2320
- }
2321
- /**
2322
- * Navigate to view branch
2323
- */
2324
- onViewBranch(branch) {
2325
- if (branch._id) {
2326
- const currentProgramId = this.programId();
2327
- const queryParams = generateStringFromObject({ acabrn_id: branch._id });
2328
- // Add programId as query parameter if available
2329
- const navigationExtras = {};
2330
- if (currentProgramId) {
2331
- navigationExtras.queryParams = { programId: currentProgramId };
2332
- }
2333
- this.router.navigate(['/control-panel/program_specialization/view', queryParams], navigationExtras);
2334
- }
2335
- }
2336
- /**
2337
- * Navigate to edit branch
2338
- */
2339
- onEditBranch(branch) {
2340
- if (branch._id) {
2341
- const currentProgramId = this.programId();
2342
- const queryParams = generateStringFromObject({ acabrn_id: branch._id });
2343
- this.router.navigate(['/control-panel/program_specialization/edit', queryParams]);
2344
- }
2345
- }
2346
- /**
2347
- * Navigate to manage term for branch
2348
- */
2349
- onManageTerm(branch) {
2350
- if (branch._id) {
2351
- const currentProgramId = this.programId();
2352
- const queryParams = generateStringFromObject({
2353
- acabrn_id: branch._id,
2354
- acacpm_id: currentProgramId
2355
- });
2356
- // Navigate to term management page
2357
- this.router.navigate(['/control-panel/program-term-management', queryParams]);
2358
- }
2359
- }
2360
- /**
2361
- * Get dropdown items for branch actions
2362
- */
2363
- getBranchActionDropdownItems(branch) {
2364
- return [
2365
- {
2366
- id: 'view',
2367
- label: 'View',
2368
- icon: 'visibility'
2369
- },
2370
- {
2371
- id: 'edit',
2372
- label: 'Edit',
2373
- icon: 'edit'
2374
- },
2375
- {
2376
- id: 'manage-term',
2377
- label: 'Manage Term',
2378
- icon: 'school'
2379
- },
2380
- {
2381
- id: 'toggle-status',
2382
- label: branch.acabrn_isactive ? 'Deactivate' : 'Activate',
2383
- icon: branch.acabrn_isactive ? 'block' : 'check_circle'
2384
- },
2385
- {
2386
- id: 'toggle-lock',
2387
- label: branch.acabrn_islocked ? 'Unlock' : 'Lock',
2388
- icon: branch.acabrn_islocked ? 'lock_open' : 'lock'
2389
- },
2390
- {
2391
- id: 'delete',
2392
- label: 'Delete',
2393
- icon: 'delete',
2394
- }
2395
- ];
2396
- }
2397
- /**
2398
- * Handle dropdown item click
2399
- */
2400
- onDropdownItemClick(item, branch) {
2401
- switch (item.id) {
2402
- case 'view':
2403
- this.onViewBranch(branch);
2404
- break;
2405
- case 'edit':
2406
- this.onEditBranch(branch);
2407
- break;
2408
- case 'manage-term':
2409
- this.onManageTerm(branch);
2410
- break;
2411
- case 'toggle-status':
2412
- this.toggleBranchStatus(branch);
2413
- break;
2414
- case 'toggle-lock':
2415
- this.toggleBranchLock(branch);
2416
- break;
2417
- case 'delete':
2418
- this.deleteBranch(branch);
2419
- break;
2420
- }
2421
- }
2422
- /**
2423
- * Toggle branch status
2424
- */
2425
- toggleBranchStatus(branch) {
2426
- if (!branch._id)
2427
- return;
2428
- const action = branch.acabrn_isactive ? 'deactivate' : 'activate';
2429
- this.confirmationService.ask({
2430
- title: `${action.charAt(0).toUpperCase() + action.slice(1)} Branch`,
2431
- message: `Are you sure you want to ${action} this branch?`,
2432
- confirmText: action.charAt(0).toUpperCase() + action.slice(1),
2433
- cancelText: 'Cancel',
2434
- type: 'warning'
2435
- }).then((confirmed) => {
2436
- if (confirmed) {
2437
- const payload = {
2438
- acabrn_id: branch._id
2439
- };
2440
- this.classProgramBranchService.toggleClassProgramBranchStatus(payload)
2441
- .pipe(takeUntilDestroyed(this.destroyRef))
2442
- .subscribe({
2443
- next: (response) => {
2444
- if (response?.success) {
2445
- this.notificationService.success(`Branch ${action}d successfully`);
2446
- this.loadBranches();
2447
- }
2448
- else {
2449
- this.notificationService.error(`Failed to ${action} branch`);
2450
- }
2451
- },
2452
- error: (error) => {
2453
- console.error('❌ Error toggling branch status:', error);
2454
- this.notificationService.error(`Failed to ${action} branch`);
2455
- }
2456
- });
2457
- }
2458
- });
2459
- }
2460
- /**
2461
- * Toggle branch lock
2462
- */
2463
- toggleBranchLock(branch) {
2464
- if (!branch._id)
2465
- return;
2466
- const action = branch.acabrn_islocked ? 'unlock' : 'lock';
2467
- this.confirmationService.ask({
2468
- title: `${action.charAt(0).toUpperCase() + action.slice(1)} Branch`,
2469
- message: `Are you sure you want to ${action} this branch?`,
2470
- confirmText: action.charAt(0).toUpperCase() + action.slice(1),
2471
- cancelText: 'Cancel',
2472
- type: 'warning'
2473
- }).then((confirmed) => {
2474
- if (confirmed) {
2475
- const payload = {
2476
- acabrn_id: branch._id
2477
- };
2478
- this.classProgramBranchService.toggleClassProgramBranchLock(payload)
2479
- .pipe(takeUntilDestroyed(this.destroyRef))
2480
- .subscribe({
2481
- next: (response) => {
2482
- if (response?.success) {
2483
- this.notificationService.success(`Branch ${action}ed successfully`);
2484
- this.loadBranches();
2485
- }
2486
- else {
2487
- this.notificationService.error(`Failed to ${action} branch`);
2488
- }
2489
- },
2490
- error: (error) => {
2491
- console.error('❌ Error toggling branch lock:', error);
2492
- this.notificationService.error(`Failed to ${action} branch`);
2493
- }
2494
- });
2495
- }
2496
- });
2497
- }
2498
- /**
2499
- * Delete branch
2500
- */
2501
- deleteBranch(branch) {
2502
- if (!branch._id)
2503
- return;
2504
- this.confirmationService.ask({
2505
- title: 'Delete Branch',
2506
- message: `Are you sure you want to delete "${branch.acabrn_name}"? This action cannot be undone.`,
2507
- confirmText: 'Delete',
2508
- cancelText: 'Cancel',
2509
- type: 'danger'
2510
- }).then((confirmed) => {
2511
- if (confirmed) {
2512
- const payload = {
2513
- acabrn_id: branch._id
2514
- };
2515
- this.classProgramBranchService.deleteClassProgramBranch(payload)
2516
- .pipe(takeUntilDestroyed(this.destroyRef))
2517
- .subscribe({
2518
- next: (response) => {
2519
- if (response?.success) {
2520
- this.notificationService.success('Branch deleted successfully');
2521
- this.loadBranches();
2522
- }
2523
- else {
2524
- this.notificationService.error('Failed to delete branch');
2525
- }
2526
- },
2527
- error: (error) => {
2528
- console.error('❌ Error deleting branch:', error);
2529
- this.notificationService.error('Failed to delete branch');
2530
- }
2531
- });
2532
- }
2533
- });
2534
- }
2535
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytClassProgramBranchListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2536
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.7", type: CideLytClassProgramBranchListComponent, isStandalone: true, selector: "cide-academics-class-program-branch-list", viewQueries: [{ propertyName: "dragHandleRendererTemplate", first: true, predicate: ["dragHandleRendererTemplate"], descendants: true, isSignal: true }, { propertyName: "classProgramRendererTemplate", first: true, predicate: ["classProgramRendererTemplate"], descendants: true, isSignal: true }, { propertyName: "actionsDropdownRendererTemplate", first: true, predicate: ["actionsDropdownRendererTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Class Program Branch List Component -->\n<cide-lyt-shared-wrapper [shared_wrapper_setup_param]=\"{ sypg_page_code: 'class_program_branch' }\"\n [breadcrumb_data]=\"breadcrumbData()\">\n \n <!-- Action Buttons in Breadcrumb Area -->\n <div breadcrumb-actions>\n <button cideEleButton type=\"button\" variant=\"primary\" size=\"sm\" leftIcon=\"add\" (btnClick)=\"onCreateBranch($event)\">\n Create Branch\n </button>\n </div>\n\n <!-- Main Content -->\n <div class=\"tw-flex tw-flex-col tw-w-full tw-h-full\">\n <!-- Filter Section -->\n <div class=\"tw-flex-shrink-0 tw-px-6 tw-py-3 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\n <div class=\"tw-flex tw-items-center tw-gap-4\">\n <div class=\"tw-w-64\">\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-2\">Class Program *</label>\n <cide-ele-select\n [options]=\"programClasses()\"\n [ngModel]=\"selectedProgramClassId() || ''\"\n (ngModelChange)=\"onProgramClassChange($event)\"\n placeholder=\"Select Class Program\"\n valueKey=\"_id\"\n labelKey=\"acacpm_alise_title\"\n [required]=\"true\">\n </cide-ele-select>\n </div>\n </div>\n </div>\n\n <!-- Data Grid Section -->\n <div class=\"tw-flex-1 tw-min-h-0 tw-p-0\">\n <cide-ele-data-grid\n [config]=\"gridConfig()\"\n [templateRenderers]=\"templateRenderers()\"\n (gridEvent)=\"onGridEvent($event)\">\n </cide-ele-data-grid>\n </div>\n </div>\n</cide-lyt-shared-wrapper>\n\n<!-- Template Renderers -->\n<ng-template #dragHandleRendererTemplate let-row=\"row\">\n <div class=\"tw-flex tw-justify-center tw-cursor-move drag-handle\" title=\"Drag to reorder\">\n <cide-ele-icon name=\"drag_indicator\" class=\"tw-w-4 tw-h-4 tw-text-gray-400 hover:tw-text-gray-600\"></cide-ele-icon>\n </div>\n</ng-template>\n\n\n<ng-template #classProgramRendererTemplate let-row=\"row\">\n <div class=\"tw-text-sm tw-text-gray-900\">\n {{ row.acabrn_class_program_id_acacpm?.acacpm_alise_title || 'N/A' }}\n </div>\n</ng-template>\n\n<ng-template #actionsDropdownRendererTemplate let-row=\"row\">\n <div class=\"tw-relative tw-inline-block\">\n <cide-ele-dropdown \n [items]=\"getBranchActionDropdownItems(row)\" \n (itemClick)=\"onDropdownItemClick($event, row)\">\n </cide-ele-dropdown>\n </div>\n</ng-template>\n\n", styles: [".drag-handle{cursor:move}.drag-handle:hover{background-color:#0000000d;border-radius:4px}.tw-table tbody tr{cursor:pointer}.tw-table tbody tr:hover{background-color:#00000005}.tw-table tbody tr.selected{background-color:#3b82f61a}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CideEleDataGridComponent, selector: "cide-ele-data-grid", inputs: ["config", "templateRenderers", "customFormatters", "actionHandlers", "serverSidePagination", "totalServerItems", "currentServerPage", "currentServerPageSize", "dragDropEnabled"], outputs: ["gridEvent"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", 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: CideEleDropdownComponent, selector: "cide-ele-dropdown", inputs: ["items", "config", "triggerTemplate", "menuTemplate"], outputs: ["itemClick", "dropdownToggle"] }, { 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"] }, { kind: "component", type: CideLytSharedWrapperComponent, selector: "cide-lyt-shared-wrapper", inputs: ["shared_wrapper_setup_param", "breadcrumb_data"] }] });
2537
- }
2538
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytClassProgramBranchListComponent, decorators: [{
2539
- type: Component,
2540
- args: [{ selector: 'cide-academics-class-program-branch-list', standalone: true, imports: [
2541
- CommonModule,
2542
- FormsModule,
2543
- CideEleDataGridComponent,
2544
- CideIconComponent,
2545
- CideEleButtonComponent,
2546
- CideEleDropdownComponent,
2547
- CideSelectComponent,
2548
- CideLytSharedWrapperComponent
2549
- ], template: "<!-- Class Program Branch List Component -->\n<cide-lyt-shared-wrapper [shared_wrapper_setup_param]=\"{ sypg_page_code: 'class_program_branch' }\"\n [breadcrumb_data]=\"breadcrumbData()\">\n \n <!-- Action Buttons in Breadcrumb Area -->\n <div breadcrumb-actions>\n <button cideEleButton type=\"button\" variant=\"primary\" size=\"sm\" leftIcon=\"add\" (btnClick)=\"onCreateBranch($event)\">\n Create Branch\n </button>\n </div>\n\n <!-- Main Content -->\n <div class=\"tw-flex tw-flex-col tw-w-full tw-h-full\">\n <!-- Filter Section -->\n <div class=\"tw-flex-shrink-0 tw-px-6 tw-py-3 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\n <div class=\"tw-flex tw-items-center tw-gap-4\">\n <div class=\"tw-w-64\">\n <label class=\"tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-2\">Class Program *</label>\n <cide-ele-select\n [options]=\"programClasses()\"\n [ngModel]=\"selectedProgramClassId() || ''\"\n (ngModelChange)=\"onProgramClassChange($event)\"\n placeholder=\"Select Class Program\"\n valueKey=\"_id\"\n labelKey=\"acacpm_alise_title\"\n [required]=\"true\">\n </cide-ele-select>\n </div>\n </div>\n </div>\n\n <!-- Data Grid Section -->\n <div class=\"tw-flex-1 tw-min-h-0 tw-p-0\">\n <cide-ele-data-grid\n [config]=\"gridConfig()\"\n [templateRenderers]=\"templateRenderers()\"\n (gridEvent)=\"onGridEvent($event)\">\n </cide-ele-data-grid>\n </div>\n </div>\n</cide-lyt-shared-wrapper>\n\n<!-- Template Renderers -->\n<ng-template #dragHandleRendererTemplate let-row=\"row\">\n <div class=\"tw-flex tw-justify-center tw-cursor-move drag-handle\" title=\"Drag to reorder\">\n <cide-ele-icon name=\"drag_indicator\" class=\"tw-w-4 tw-h-4 tw-text-gray-400 hover:tw-text-gray-600\"></cide-ele-icon>\n </div>\n</ng-template>\n\n\n<ng-template #classProgramRendererTemplate let-row=\"row\">\n <div class=\"tw-text-sm tw-text-gray-900\">\n {{ row.acabrn_class_program_id_acacpm?.acacpm_alise_title || 'N/A' }}\n </div>\n</ng-template>\n\n<ng-template #actionsDropdownRendererTemplate let-row=\"row\">\n <div class=\"tw-relative tw-inline-block\">\n <cide-ele-dropdown \n [items]=\"getBranchActionDropdownItems(row)\" \n (itemClick)=\"onDropdownItemClick($event, row)\">\n </cide-ele-dropdown>\n </div>\n</ng-template>\n\n", styles: [".drag-handle{cursor:move}.drag-handle:hover{background-color:#0000000d;border-radius:4px}.tw-table tbody tr{cursor:pointer}.tw-table tbody tr:hover{background-color:#00000005}.tw-table tbody tr.selected{background-color:#3b82f61a}\n"] }]
2550
- }] });
2551
-
2552
- var classProgramBranchList_component = /*#__PURE__*/Object.freeze({
2553
- __proto__: null,
2554
- CideLytClassProgramBranchListComponent: CideLytClassProgramBranchListComponent
2555
- });
2556
-
2557
- class CideLytClassProgramBranchFormComponent {
2558
- // Dependency injection
2559
- destroyRef = inject(DestroyRef);
2560
- fb = inject(FormBuilder);
2561
- router = inject(Router);
2562
- route = inject(ActivatedRoute);
2563
- location = inject(Location);
2564
- appState = inject(AppStateHelperService);
2565
- notificationService = inject(NotificationService);
2566
- confirmationService = inject(ConfirmationService);
2567
- classProgramBranchService = inject(CideLytClassProgramBranchService);
2568
- programClassService = inject(CideLytProgramClassService);
2569
- generalMasterService = inject(CideCoreGeneralMasterService);
2570
- // Form and state management
2571
- branchForm;
2572
- loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
2573
- error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
2574
- isEditMode = signal(false, ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
2575
- isViewMode = signal(false, ...(ngDevMode ? [{ debugName: "isViewMode" }] : []));
2576
- branchId = signal(null, ...(ngDevMode ? [{ debugName: "branchId" }] : []));
2577
- // Data signals
2578
- programClasses = signal([], ...(ngDevMode ? [{ debugName: "programClasses" }] : []));
2579
- branchMasters = signal([], ...(ngDevMode ? [{ debugName: "branchMasters" }] : []));
2580
- // Signal for breadcrumb data that will be passed to shared wrapper
2581
- breadcrumbData = signal([], ...(ngDevMode ? [{ debugName: "breadcrumbData" }] : []));
2582
- // Signal to control Program Class dropdown visibility
2583
- showProgramClassDropdown = signal(true, ...(ngDevMode ? [{ debugName: "showProgramClassDropdown" }] : []));
2584
- // Flag to prevent auto-populate during data load
2585
- isLoadingData = false;
2586
- constructor() {
2587
- this.branchForm = this.fb.group({
2588
- acabrn_name: ['', [Validators.required, Validators.minLength(2)]],
2589
- acabrn_code: ['', [Validators.required, Validators.minLength(2)]],
2590
- acabrn_sequence: [0, [Validators.required, Validators.min(0)]],
2591
- acabrn_class_program_id_acacpm: ['', [Validators.required]],
2592
- acabrn_branch_id_sygms: [''],
2593
- acabrn_isactive: [true],
2594
- acabrn_islocked: [false]
2595
- });
2596
- }
2597
- ngOnInit() {
2598
- console.log('🏢 Class Program Branch Form Component initialized');
2599
- this.initializeComponent();
2600
- this.setupFormListeners();
2601
- }
2602
- /**
2603
- * Setup form control listeners
2604
- */
2605
- setupFormListeners() {
2606
- // Listen to SYGMS field changes
2607
- this.branchForm.get('acabrn_branch_id_sygms')?.valueChanges
2608
- .pipe(takeUntilDestroyed(this.destroyRef))
2609
- .subscribe((sygmsId) => {
2610
- // Only auto-populate if not loading existing data
2611
- if (sygmsId && !this.isLoadingData) {
2612
- this.onBranchMasterChange(sygmsId);
2613
- }
2614
- });
2615
- // Listen to Program Class field changes
2616
- this.branchForm.get('acabrn_class_program_id_acacpm')?.valueChanges
2617
- .pipe(takeUntilDestroyed(this.destroyRef))
2618
- .subscribe((programClassId) => {
2619
- // Only trigger if not loading existing data and dropdown is visible
2620
- if (programClassId && !this.isLoadingData && this.showProgramClassDropdown()) {
2621
- this.onProgramClassChange(programClassId);
2622
- }
2623
- });
2624
- }
2625
- /**
2626
- * Handle Program Class selection change
2627
- * This can be used to filter or update dependent lists
2628
- */
2629
- onProgramClassChange(programClassId) {
2630
- if (!programClassId) {
2631
- return;
2632
- }
2633
- console.log('🔄 Program Class changed:', programClassId);
2634
- // Add any logic here to update dependent lists based on Program Class selection
2635
- // For example, you could filter branch masters or load additional data
2636
- }
2637
- ngOnDestroy() {
2638
- console.log('🏢 Class Program Branch Form Component destroyed');
2639
- }
2640
- /**
2641
- * Initialize component
2642
- */
2643
- initializeComponent() {
2644
- this.loadMasterData();
2645
- this.checkRouteParams();
2646
- }
2647
- /**
2648
- * Check route parameters to determine mode
2649
- */
2650
- checkRouteParams() {
2651
- const url = this.router.url;
2652
- const queryParams = this.route.snapshot.queryParams;
2653
- const routeParams = this.route.snapshot.params;
2654
- // Check for program ID from route parameters or query parameters
2655
- let programId = null;
2656
- // Check route parameters for programId or acacpm_id (for create operations)
2657
- if (routeParams['query']) {
2658
- const params = generateObjectFromString(routeParams['query']);
2659
- console.log('🏢 Params:generateObjectFromString', params);
2660
- programId = params?.programId || params?.acacpm_id || null;
2661
- }
2662
- // Also check queryParams for programId or acacpm_id
2663
- if (!programId) {
2664
- programId = queryParams['programId'] || queryParams['acacpm_id'] || null;
2665
- }
2666
- if (programId) {
2667
- console.log('🏢 Program Class Management ID from URL:', programId);
2668
- // Hide the dropdown and set the value
2669
- this.showProgramClassDropdown.set(false);
2670
- this.branchForm.patchValue({
2671
- acabrn_class_program_id_acacpm: programId
2672
- });
2673
- // Keep the field enabled so it's included in form.value, but it will be hidden
2674
- }
2675
- else {
2676
- // Show the dropdown if no ID from URL
2677
- this.showProgramClassDropdown.set(true);
2678
- }
2679
- if (url.includes('/view/')) {
2680
- this.isViewMode.set(true);
2681
- this.loadBranchForView(queryParams);
2682
- }
2683
- else if (url.includes('/edit/')) {
2684
- this.isEditMode.set(true);
2685
- this.loadBranchForEdit(queryParams);
2686
- }
2687
- else {
2688
- // Create mode
2689
- this.isEditMode.set(false);
2690
- this.isViewMode.set(false);
2691
- // Initialize breadcrumb for create mode
2692
- this.updateBreadcrumbData();
2693
- }
2694
- }
2695
- /**
2696
- * Load master data
2697
- */
2698
- loadMasterData() {
2699
- console.log('🔄 Loading master data for Class Program Branch Form...');
2700
- // Load program classes
2701
- this.loadProgramClasses();
2702
- // Load branch masters (SYGMS)
2703
- this.loadBranchMasters();
2704
- }
2705
- /**
2706
- * Load program classes
2707
- */
2708
- loadProgramClasses() {
2709
- this.programClassService.getProgramClassList({ pagination: false })
2710
- .pipe(takeUntilDestroyed(this.destroyRef))
2711
- .subscribe({
2712
- next: (response) => {
2713
- console.log('✅ Program classes loaded:', response);
2714
- if (response?.success && response.data) {
2715
- this.programClasses.set(response.data);
2716
- }
2717
- else {
2718
- console.warn('⚠️ No program class data received');
2719
- this.programClasses.set([]);
2720
- }
2721
- },
2722
- error: (error) => {
2723
- console.error('❌ Error loading program classes:', error);
2724
- this.programClasses.set([]);
2725
- }
2726
- });
2727
- }
2728
- /**
2729
- * Load branch masters from SYGMS (General Master)
2730
- * Filter by type code 'BRANCH' or similar
2731
- */
2732
- loadBranchMasters() {
2733
- const payload = {
2734
- sygmt_code: 'BRANCH' // Assuming 'BRANCH' is the type code for branch masters
2735
- };
2736
- this.generalMasterService.getMasterList(payload)
2737
- .pipe(takeUntilDestroyed(this.destroyRef))
2738
- .subscribe({
2739
- next: (response) => {
2740
- console.log('✅ Branch masters loaded:', response);
2741
- if (response?.success && response.data) {
2742
- const masters = response.data.map((master) => ({
2743
- ...master,
2744
- value: master._id,
2745
- label: master.sygms_title
2746
- }));
2747
- this.branchMasters.set(masters);
2748
- }
2749
- else {
2750
- console.warn('⚠️ No branch master data received');
2751
- this.branchMasters.set([]);
2752
- }
2753
- },
2754
- error: (error) => {
2755
- console.error('❌ Error loading branch masters:', error);
2756
- this.branchMasters.set([]);
2757
- }
2758
- });
2759
- }
2760
- /**
2761
- * Handle SYGMS selection change - auto-populate name and code
2762
- */
2763
- onBranchMasterChange(sygmsId) {
2764
- if (!sygmsId) {
2765
- return;
2766
- }
2767
- const selectedMaster = this.branchMasters().find(m => m._id === sygmsId);
2768
- if (selectedMaster) {
2769
- // Auto-populate name from SYGMS title
2770
- if (selectedMaster.sygms_title) {
2771
- this.branchForm.patchValue({
2772
- acabrn_name: selectedMaster.sygms_title
2773
- });
2774
- }
2775
- // Auto-populate code from SYGMS configuration or code
2776
- if (selectedMaster.sygms_configuration && typeof selectedMaster.sygms_configuration === 'object') {
2777
- const config = selectedMaster.sygms_configuration;
2778
- if (config.code) {
2779
- this.branchForm.patchValue({
2780
- acabrn_code: config.code
2781
- });
2782
- }
2783
- else if (selectedMaster.sygms_code) {
2784
- this.branchForm.patchValue({
2785
- acabrn_code: selectedMaster.sygms_code
2786
- });
2787
- }
2788
- }
2789
- else if (selectedMaster.sygms_code) {
2790
- this.branchForm.patchValue({
2791
- acabrn_code: selectedMaster.sygms_code
2792
- });
2793
- }
2794
- }
2795
- }
2796
- /**
2797
- * Load branch for viewing
2798
- */
2799
- loadBranchForView(queryParams) {
2800
- const routeParams = this.route.snapshot.params;
2801
- // Check query parameters first
2802
- let params = generateObjectFromString(routeParams['query']);
2803
- console.log('🏢 Params:generateObjectFromString', params);
2804
- if (params?.acabrn_id) {
2805
- console.log('🏢 Branch ID for view:', params.acabrn_id);
2806
- this.branchId.set(params.acabrn_id);
2807
- this.loadBranchData(params.acabrn_id, true);
2808
- }
2809
- else {
2810
- console.error('❌ No branch ID found in route parameters');
2811
- this.error.set('Branch ID not found in route parameters');
2812
- }
2813
- }
2814
- /**
2815
- * Load branch for editing
2816
- */
2817
- loadBranchForEdit(queryParams) {
2818
- const routeParams = this.route.snapshot.params;
2819
- // Check query parameters first
2820
- let params = generateObjectFromString(routeParams['query']);
2821
- console.log('🏢 Params:generateObjectFromString', params);
2822
- if (params?.acabrn_id) {
2823
- console.log('🏢 Branch ID for edit:', params.acabrn_id);
2824
- this.branchId.set(params.acabrn_id);
2825
- this.loadBranchData(params.acabrn_id, false);
2826
- }
2827
- else {
2828
- console.error('❌ No branch ID found in route parameters');
2829
- this.error.set('Branch ID not found in route parameters');
2830
- }
2831
- }
2832
- /**
2833
- * Load branch data
2834
- */
2835
- loadBranchData(branchId, isViewMode) {
2836
- this.loading.set(true);
2837
- this.error.set(null);
2838
- this.isLoadingData = true; // Set flag to prevent auto-populate
2839
- const payload = {
2840
- acabrn_id: branchId
2841
- };
2842
- this.classProgramBranchService.getClassProgramBranchById(payload)
2843
- .pipe(takeUntilDestroyed(this.destroyRef))
2844
- .subscribe({
2845
- next: (response) => {
2846
- if (response?.success && response.data) {
2847
- const branchData = response.data;
2848
- // Check if program class ID is in URL - if so, hide dropdown
2849
- const routeParams = this.route.snapshot.params;
2850
- const queryParams = this.route.snapshot.queryParams;
2851
- let programIdFromUrl = null;
2852
- if (routeParams['query']) {
2853
- const params = generateObjectFromString(routeParams['query']);
2854
- programIdFromUrl = params?.programId || params?.acacpm_id || null;
2855
- }
2856
- if (!programIdFromUrl) {
2857
- programIdFromUrl = queryParams['programId'] || queryParams['acacpm_id'] || null;
2858
- }
2859
- if (programIdFromUrl) {
2860
- this.showProgramClassDropdown.set(false);
2861
- // Keep the field enabled so it's included in form.value
2862
- }
2863
- // Populate form with branch data
2864
- this.branchForm.patchValue({
2865
- acabrn_name: branchData.acabrn_name,
2866
- acabrn_code: branchData.acabrn_code,
2867
- acabrn_sequence: branchData.acabrn_sequence,
2868
- acabrn_class_program_id_acacpm: branchData.acabrn_class_program_id_acacpm?._id || branchData.acabrn_class_program_id_acacpm,
2869
- acabrn_branch_id_sygms: branchData.acabrn_branch_id_sygms?._id || branchData.acabrn_branch_id_sygms || '',
2870
- acabrn_isactive: (branchData).acabrn_isactive,
2871
- acabrn_islocked: branchData.acabrn_islocked
2872
- });
2873
- // Reset flag after data is loaded
2874
- this.isLoadingData = false;
2875
- // Disable form if in view mode
2876
- if (isViewMode) {
2877
- this.branchForm.disable();
2878
- }
2879
- // Update breadcrumb for edit/view mode
2880
- this.updateBreadcrumbData(branchData, isViewMode);
2881
- this.notificationService.success('Branch data loaded successfully.');
2882
- }
2883
- else {
2884
- this.error.set('Failed to load branch data.');
2885
- this.notificationService.error('Failed to load branch data.');
2886
- this.isLoadingData = false;
2887
- }
2888
- this.loading.set(false);
2889
- },
2890
- error: (error) => {
2891
- console.error('❌ Error loading branch data:', error);
2892
- this.error.set('Failed to load branch data. Please try again.');
2893
- this.loading.set(false);
2894
- this.isLoadingData = false;
2895
- this.notificationService.error('Failed to load branch data. Please try again.');
2896
- }
2897
- });
2898
- }
2899
- /**
2900
- * Get form title
2901
- */
2902
- get formTitle() {
2903
- if (this.isViewMode())
2904
- return 'View Program Specialization';
2905
- if (this.isEditMode())
2906
- return 'Edit Program Specialization';
2907
- return 'Create Program Specialization';
2908
- }
2909
- /**
2910
- * Get submit button text
2911
- */
2912
- get submitButtonText() {
2913
- if (this.isViewMode())
2914
- return 'Close';
2915
- if (this.isEditMode())
2916
- return 'Update Branch';
2917
- return 'Create Branch';
2918
- }
2919
- /**
2920
- * Handle form submission
2921
- */
2922
- onSubmit() {
2923
- if (this.isViewMode()) {
2924
- this.location.back();
2925
- return;
2926
- }
2927
- if (this.branchForm.invalid) {
2928
- this.notificationService.error('Please fill in all required fields correctly.');
2929
- return;
2930
- }
2931
- const formData = this.branchForm.value;
2932
- const payload = {
2933
- _id: this.branchId() || undefined,
2934
- acabrn_name: formData.acabrn_name,
2935
- acabrn_code: formData.acabrn_code,
2936
- acabrn_sequence: formData.acabrn_sequence,
2937
- acabrn_class_program_id_acacpm: formData.acabrn_class_program_id_acacpm,
2938
- acabrn_branch_id_sygms: formData.acabrn_branch_id_sygms || undefined,
2939
- acabrn_isactive: formData.acabrn_isactive,
2940
- acabrn_islocked: formData.acabrn_islocked
2941
- };
2942
- this.saveBranch(payload);
2943
- }
2944
- /**
2945
- * Save branch
2946
- */
2947
- saveBranch(payload) {
2948
- this.loading.set(true);
2949
- this.classProgramBranchService.saveClassProgramBranch(payload)
2950
- .pipe(takeUntilDestroyed(this.destroyRef))
2951
- .subscribe({
2952
- next: (response) => {
2953
- if (response?.success) {
2954
- const action = this.isEditMode() ? 'updated' : 'created';
2955
- this.notificationService.success(`Branch has been ${action} successfully.`);
2956
- this.location.back();
2957
- }
2958
- else {
2959
- this.notificationService.error(response?.message || 'Failed to save branch.');
2960
- }
2961
- this.loading.set(false);
2962
- },
2963
- error: (error) => {
2964
- console.error('❌ Error saving branch:', error);
2965
- this.notificationService.error('Failed to save branch. Please try again.');
2966
- this.loading.set(false);
2967
- }
2968
- });
2969
- }
2970
- /**
2971
- * Handle cancel
2972
- */
2973
- onCancel() {
2974
- if (this.branchForm.dirty && !this.isViewMode()) {
2975
- this.confirmationService.ask({
2976
- title: 'Discard Changes',
2977
- message: 'You have unsaved changes. Are you sure you want to discard them?',
2978
- confirmText: 'Discard',
2979
- cancelText: 'Keep Editing',
2980
- type: 'warning'
2981
- }).then((confirmed) => {
2982
- if (confirmed) {
2983
- this.location.back();
2984
- }
2985
- });
2986
- }
2987
- else {
2988
- this.location.back();
2989
- }
2990
- }
2991
- /**
2992
- * Reset form to initial state
2993
- */
2994
- resetForm() {
2995
- this.branchForm.reset();
2996
- this.branchForm.patchValue({
2997
- acabrn_isactive: true,
2998
- acabrn_islocked: false,
2999
- acabrn_sequence: 0,
3000
- acabrn_branch_id_sygms: ''
3001
- });
3002
- this.notificationService.info('Form has been reset to initial values.');
3003
- }
3004
- /**
3005
- * Toggle active status on card click
3006
- */
3007
- onActiveCardClick() {
3008
- if (this.isViewMode())
3009
- return;
3010
- const currentValue = this.branchForm.get('acabrn_isactive')?.value;
3011
- this.branchForm.patchValue({
3012
- acabrn_isactive: !currentValue
3013
- });
3014
- }
3015
- /**
3016
- * Toggle locked status on card click
3017
- */
3018
- onLockedCardClick() {
3019
- if (this.isViewMode())
3020
- return;
3021
- const currentValue = this.branchForm.get('acabrn_islocked')?.value;
3022
- this.branchForm.patchValue({
3023
- acabrn_islocked: !currentValue
3024
- });
3025
- }
3026
- /**
3027
- * Update breadcrumb data based on mode
3028
- */
3029
- updateBreadcrumbData(branchData, isViewMode = false) {
3030
- const additionalItems = [];
3031
- if (this.isEditMode() || isViewMode) {
3032
- if (branchData) {
3033
- additionalItems.push({
3034
- id: branchData._id || 'branch',
3035
- label: branchData.acabrn_name || 'Branch',
3036
- icon: undefined,
3037
- url: undefined
3038
- });
3039
- }
3040
- if (isViewMode) {
3041
- additionalItems.push({
3042
- id: 'view',
3043
- label: 'View',
3044
- icon: 'visibility',
3045
- url: undefined
3046
- });
3047
- }
3048
- else {
3049
- additionalItems.push({
3050
- id: 'edit',
3051
- label: 'Edit',
3052
- icon: 'edit',
3053
- url: undefined
3054
- });
3055
- }
3056
- }
3057
- else {
3058
- // Create mode
3059
- additionalItems.push({
3060
- id: 'create',
3061
- label: 'Create',
3062
- icon: 'add',
3063
- url: undefined
3064
- });
3065
- }
3066
- this.breadcrumbData.set(additionalItems);
3067
- }
3068
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytClassProgramBranchFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3069
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.7", type: CideLytClassProgramBranchFormComponent, isStandalone: true, selector: "cide-academics-class-program-branch-form", ngImport: i0, template: "<!-- \n CLASS PROGRAM BRANCH FORM COMPONENT\n \n Enterprise-Level Styling with Tailwind CSS\n Features: Responsive grids, proper typography, enhanced user experience\n-->\n\n<cide-lyt-shared-wrapper [shared_wrapper_setup_param]=\"{ sypg_page_code: 'class_program_branch' }\"\n [breadcrumb_data]=\"breadcrumbData()\">\n <div class=\"tw-w-full tw-h-full\">\n <form class=\"tw-w-full tw-table tw-h-full tw-bg-transparent\" [formGroup]=\"branchForm\"\n [class.tw-opacity-60]=\"loading()\" (ngSubmit)=\"onSubmit()\">\n\n <!-- Form Content -->\n <div class=\"tw-table-row\">\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-6\">\n <div class=\"tw-transition-opacity tw-duration-300\" [class.tw-opacity-60]=\"loading()\">\n\n <!-- Error Message -->\n @if (error()) {\n <div class=\"tw-mb-6 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-md\">\n <div class=\"tw-flex tw-items-start\">\n <cide-ele-icon name=\"error\"\n class=\"tw-text-red-400 tw-w-5 tw-h-5 tw-mt-0.5 tw-flex-shrink-0\"></cide-ele-icon>\n <div class=\"tw-ml-3\">\n <h3 class=\"tw-text-sm tw-font-medium tw-text-red-800 tw-m-0\">Error</h3>\n <p class=\"tw-text-sm tw-text-red-700 tw-mt-1 tw-m-0\">{{ error() }}</p>\n </div>\n </div>\n </div>\n }\n\n <!-- Basic Branch Information -->\n <div class=\"tw-space-y-6\">\n <!-- Class Program Selection -->\n @if (showProgramClassDropdown()) {\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-1 tw-gap-6\">\n <div class=\"tw-space-y-2\">\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Class Program *</label>\n <cide-ele-select formControlName=\"acabrn_class_program_id_acacpm\" placeholder=\"Select class program\"\n [disabled]=\"isViewMode()\" valueKey=\"_id\" labelKey=\"acacpm_alise_title\" [options]=\"programClasses()\">\n </cide-ele-select>\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">\n <cide-ele-icon name=\"info\" class=\"tw-w-4 tw-h-4 tw-mr-1\"></cide-ele-icon>\n Sequence will be automatically assigned based on the order in the listing\n </p>\n </div>\n </div>\n }\n\n <!-- Standard Branch Name (SYGMS) -->\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-1 tw-gap-6\">\n <div class=\"tw-space-y-2\">\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Standard Branch Name</label>\n <cide-ele-select formControlName=\"acabrn_branch_id_sygms\" placeholder=\"Select standard branch name\"\n [disabled]=\"isViewMode()\" valueKey=\"_id\" labelKey=\"sygms_title\" [options]=\"branchMasters()\">\n </cide-ele-select>\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">\n <cide-ele-icon name=\"info\" class=\"tw-w-4 tw-h-4 tw-mr-1\"></cide-ele-icon>\n Selecting a standard branch will auto-populate the branch name and code\n </p>\n </div>\n </div>\n\n <!-- Branch Name and Code -->\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <div>\n <cide-ele-input label=\"Branch Name *\" formControlName=\"acabrn_name\"\n placeholder=\"e.g., Computer Science Branch\" size=\"md\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n </div>\n\n <div>\n <cide-ele-input label=\"Branch Code *\" formControlName=\"acabrn_code\" placeholder=\"e.g., CS\" size=\"md\"\n leadingIcon=\"code\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n </div>\n </div>\n\n <!-- Status and Lock Options -->\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <div\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\"\n [class.tw-cursor-not-allowed]=\"isViewMode()\" [class.tw-opacity-60]=\"isViewMode()\"\n (click)=\"onActiveCardClick()\">\n <cide-ele-input formControlName=\"acabrn_isactive\" type=\"checkbox\" size=\"md\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Active</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Enable/disable this branch</span>\n </div>\n </div>\n\n <div\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\"\n [class.tw-cursor-not-allowed]=\"isViewMode()\" [class.tw-opacity-60]=\"isViewMode()\"\n (click)=\"onLockedCardClick()\">\n <cide-ele-input formControlName=\"acabrn_islocked\" type=\"checkbox\" size=\"md\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"tw-table-row tw-h-0\">\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\">\n <div class=\"tw-flex tw-justify-end tw-gap-4\">\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"resetForm()\" leftIcon=\"refresh\"\n [disabled]=\"loading()\">\n Reset Form\n </button>\n\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"onCancel()\" leftIcon=\"close\"\n [disabled]=\"loading()\">\n {{ isViewMode() ? 'Close' : 'Cancel' }}\n </button>\n\n @if (!isViewMode()) {\n <button cideEleButton type=\"submit\" variant=\"primary\" [disabled]=\"loading() || branchForm.invalid\"\n [loading]=\"loading()\" leftIcon=\"save\">\n {{ submitButtonText }}\n </button>\n }\n </div>\n </div>\n </div>\n </form>\n </div>\n</cide-lyt-shared-wrapper>", 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: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton], cide-ele-button", 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"] }, { kind: "component", type: CideLytSharedWrapperComponent, selector: "cide-lyt-shared-wrapper", inputs: ["shared_wrapper_setup_param", "breadcrumb_data"] }] });
3070
- }
3071
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: CideLytClassProgramBranchFormComponent, decorators: [{
3072
- type: Component,
3073
- args: [{ selector: 'cide-academics-class-program-branch-form', standalone: true, imports: [
3074
- CommonModule,
3075
- ReactiveFormsModule,
3076
- CideInputComponent,
3077
- CideEleButtonComponent,
3078
- CideIconComponent,
3079
- CideSelectComponent,
3080
- CideLytSharedWrapperComponent,
3081
- ], template: "<!-- \n CLASS PROGRAM BRANCH FORM COMPONENT\n \n Enterprise-Level Styling with Tailwind CSS\n Features: Responsive grids, proper typography, enhanced user experience\n-->\n\n<cide-lyt-shared-wrapper [shared_wrapper_setup_param]=\"{ sypg_page_code: 'class_program_branch' }\"\n [breadcrumb_data]=\"breadcrumbData()\">\n <div class=\"tw-w-full tw-h-full\">\n <form class=\"tw-w-full tw-table tw-h-full tw-bg-transparent\" [formGroup]=\"branchForm\"\n [class.tw-opacity-60]=\"loading()\" (ngSubmit)=\"onSubmit()\">\n\n <!-- Form Content -->\n <div class=\"tw-table-row\">\n <div class=\"tw-table-cell tw-w-full tw-px-6 tw-py-6\">\n <div class=\"tw-transition-opacity tw-duration-300\" [class.tw-opacity-60]=\"loading()\">\n\n <!-- Error Message -->\n @if (error()) {\n <div class=\"tw-mb-6 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-md\">\n <div class=\"tw-flex tw-items-start\">\n <cide-ele-icon name=\"error\"\n class=\"tw-text-red-400 tw-w-5 tw-h-5 tw-mt-0.5 tw-flex-shrink-0\"></cide-ele-icon>\n <div class=\"tw-ml-3\">\n <h3 class=\"tw-text-sm tw-font-medium tw-text-red-800 tw-m-0\">Error</h3>\n <p class=\"tw-text-sm tw-text-red-700 tw-mt-1 tw-m-0\">{{ error() }}</p>\n </div>\n </div>\n </div>\n }\n\n <!-- Basic Branch Information -->\n <div class=\"tw-space-y-6\">\n <!-- Class Program Selection -->\n @if (showProgramClassDropdown()) {\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-1 tw-gap-6\">\n <div class=\"tw-space-y-2\">\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Class Program *</label>\n <cide-ele-select formControlName=\"acabrn_class_program_id_acacpm\" placeholder=\"Select class program\"\n [disabled]=\"isViewMode()\" valueKey=\"_id\" labelKey=\"acacpm_alise_title\" [options]=\"programClasses()\">\n </cide-ele-select>\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">\n <cide-ele-icon name=\"info\" class=\"tw-w-4 tw-h-4 tw-mr-1\"></cide-ele-icon>\n Sequence will be automatically assigned based on the order in the listing\n </p>\n </div>\n </div>\n }\n\n <!-- Standard Branch Name (SYGMS) -->\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-1 tw-gap-6\">\n <div class=\"tw-space-y-2\">\n <label class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Standard Branch Name</label>\n <cide-ele-select formControlName=\"acabrn_branch_id_sygms\" placeholder=\"Select standard branch name\"\n [disabled]=\"isViewMode()\" valueKey=\"_id\" labelKey=\"sygms_title\" [options]=\"branchMasters()\">\n </cide-ele-select>\n <p class=\"tw-text-xs tw-text-gray-500 tw-mt-1\">\n <cide-ele-icon name=\"info\" class=\"tw-w-4 tw-h-4 tw-mr-1\"></cide-ele-icon>\n Selecting a standard branch will auto-populate the branch name and code\n </p>\n </div>\n </div>\n\n <!-- Branch Name and Code -->\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <div>\n <cide-ele-input label=\"Branch Name *\" formControlName=\"acabrn_name\"\n placeholder=\"e.g., Computer Science Branch\" size=\"md\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n </div>\n\n <div>\n <cide-ele-input label=\"Branch Code *\" formControlName=\"acabrn_code\" placeholder=\"e.g., CS\" size=\"md\"\n leadingIcon=\"code\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n </div>\n </div>\n\n <!-- Status and Lock Options -->\n <div class=\"tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6\">\n <div\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\"\n [class.tw-cursor-not-allowed]=\"isViewMode()\" [class.tw-opacity-60]=\"isViewMode()\"\n (click)=\"onActiveCardClick()\">\n <cide-ele-input formControlName=\"acabrn_isactive\" type=\"checkbox\" size=\"md\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Active</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Enable/disable this branch</span>\n </div>\n </div>\n\n <div\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\"\n [class.tw-cursor-not-allowed]=\"isViewMode()\" [class.tw-opacity-60]=\"isViewMode()\"\n (click)=\"onLockedCardClick()\">\n <cide-ele-input formControlName=\"acabrn_islocked\" type=\"checkbox\" size=\"md\" [disabled]=\"isViewMode()\">\n </cide-ele-input>\n <div class=\"tw-flex tw-flex-col\">\n <span class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Locked</span>\n <span class=\"tw-text-xs tw-text-gray-500\">Prevent modifications</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"tw-table-row tw-h-0\">\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\">\n <div class=\"tw-flex tw-justify-end tw-gap-4\">\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"resetForm()\" leftIcon=\"refresh\"\n [disabled]=\"loading()\">\n Reset Form\n </button>\n\n <button cideEleButton type=\"button\" variant=\"secondary\" (click)=\"onCancel()\" leftIcon=\"close\"\n [disabled]=\"loading()\">\n {{ isViewMode() ? 'Close' : 'Cancel' }}\n </button>\n\n @if (!isViewMode()) {\n <button cideEleButton type=\"submit\" variant=\"primary\" [disabled]=\"loading() || branchForm.invalid\"\n [loading]=\"loading()\" leftIcon=\"save\">\n {{ submitButtonText }}\n </button>\n }\n </div>\n </div>\n </div>\n </form>\n </div>\n</cide-lyt-shared-wrapper>" }]
3082
- }], ctorParameters: () => [] });
3083
-
3084
- var classProgramBranchForm_component = /*#__PURE__*/Object.freeze({
3085
- __proto__: null,
3086
- CideLytClassProgramBranchFormComponent: CideLytClassProgramBranchFormComponent
3087
- });
3088
-
3089
- // Class Program Branch Management Module
3090
- // This module provides components and services for managing class program branches
3091
- // Components
3092
-
3093
- /*
3094
- * Public API Surface of cloud-ide-academics
3095
- */
3096
-
3097
- /**
3098
- * Generated bundle index. Do not edit.
3099
- */
3100
-
3101
- export { AcademicYearCreateComponent as A, CideLytProgramClassService as C, CideLytAcademicYearService as a, CideLytClassProgramBranchService as b, academicsRoutes as c, AcademicYearListComponent as d, CideLytAcademicYearMappingService as e, CideLytClassProgramBranchListComponent as f, CideLytClassProgramBranchFormComponent as g };
3102
- //# sourceMappingURL=cloud-ide-academics-cloud-ide-academics-g9qZGJtG.mjs.map