From 5592a01f8a088d655f1405ba919993506dd94c56 Mon Sep 17 00:00:00 2001 From: Kallesh B S Date: Fri, 25 Jul 2025 17:24:04 +0530 Subject: [PATCH] param-table flow --- src/app/app.routes.ts | 5 + .../secured-header.component.html | 1 + src/app/core/models/param/parameters.ts | 22 ++ src/app/core/models/param/types.ts | 1 + src/app/core/services/param/param.service.ts | 113 ++++++++ .../manage-param-record.component.html | 1 + .../manage-param-record.component.scss | 0 .../manage-param-record.component.ts | 25 ++ .../manage-table-record.component.html | 1 + .../manage-table-record.component.scss | 0 .../manage-table-record.component.ts | 13 + .../param/table/param-table.component.html | 264 ++++++++++++++++++ .../param/table/param-table.component.scss | 188 +++++++++++++ src/app/param/table/param-table.component.ts | 264 ++++++++++++++++++ src/app/shared/pipes/properCase.pipe.ts | 15 + 15 files changed, 913 insertions(+) create mode 100644 src/app/core/models/param/parameters.ts create mode 100644 src/app/core/models/param/types.ts create mode 100644 src/app/core/services/param/param.service.ts create mode 100644 src/app/param/manage-param-record/manage-param-record.component.html create mode 100644 src/app/param/manage-param-record/manage-param-record.component.scss create mode 100644 src/app/param/manage-param-record/manage-param-record.component.ts create mode 100644 src/app/param/manage-table-record/manage-table-record.component.html create mode 100644 src/app/param/manage-table-record/manage-table-record.component.scss create mode 100644 src/app/param/manage-table-record/manage-table-record.component.ts create mode 100644 src/app/param/table/param-table.component.html create mode 100644 src/app/param/table/param-table.component.scss create mode 100644 src/app/param/table/param-table.component.ts create mode 100644 src/app/shared/pipes/properCase.pipe.ts diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index ec79263..65404b5 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -8,11 +8,16 @@ import { NotFoundComponent } from './shared/components/not-found/not-found.compo import { UserSettingsComponent } from './user-settings/user-settings.component'; import { RegisterComponent } from './register/register.component'; import { ForgotPasswordComponent } from './forgot-password/forgot-password.component'; +import { ParamTableComponent } from './param/table/param-table.component'; +import { ManageTableRecordComponent } from './param/manage-table-record/manage-table-record.component'; +import { ManageParamRecordComponent } from './param/manage-param-record/manage-param-record.component'; export const routes: Routes = [ { path: 'login', component: LoginComponent }, { path: 'register', component: RegisterComponent }, { path: 'forgot-password', component: ForgotPasswordComponent }, + { path: 'table-record', component: ManageTableRecordComponent }, + { path: 'param-record/:id', component: ManageParamRecordComponent }, { path: 'usersettings', component: UserSettingsComponent, canActivate: [AuthGuard] }, { path: 'home', component: HomeComponent, canActivate: [AuthGuard] }, { path: 'service-provider/:id', component: EditServiceProviderComponent, canActivate: [AuthGuard] }, diff --git a/src/app/common/secured-header/secured-header.component.html b/src/app/common/secured-header/secured-header.component.html index 02de989..5438891 100644 --- a/src/app/common/secured-header/secured-header.component.html +++ b/src/app/common/secured-header/secured-header.component.html @@ -8,6 +8,7 @@ Home Users Regions + Parameters
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Type{{ client.paramType }}Description{{ client.paramDesc || '--'}}Value{{ client.paramValue }}Additional Value 1{{ client.addlParamValue1 || '--' }}Additional Value 2{{ client.addlParamValue2 || '--'}}Additional Value 3{{ client.addlParamValue3 || '--' }}Additional Value 4{{ client.addlParamValue4 || '--' }}Additional Value 5{{ client.addlParamValue5 || '--'}}Actions +
+ + + + + + + +
+
+ info + No records found matching your criteria +
+ + + + +
+
+
+

{{ !isParamRecord ? 'Add New Table' : isEditing ? 'Edit Param' : 'Add New Param' }} +

+
+ +
+ + Param Type + + + Param Type is required + + + Maximum 10 characters allowed + + + + + {{!isParamRecord ? 'Description' : 'Description'}} + + + {{!isParamRecord ? 'Table Description' : 'Param Description'}} is required + + + Maximum 100 characters allowed + + + + +
+ +
+ + + Value + + + Param Value is required + + + Maximum 20 characters allowed + + + + + Additional Value 1 + + + Maximum 20 characters allowed + + +
+ +
+ + + Additional Value 2 + + + Maximum 20 characters allowed + + + + + Additional Value 3 + + + Maximum 20 characters allowed + + +
+ +
+ + + Additional Value 4 + + + Maximum 20 characters allowed + + + + + Additional Value 5 + + + Maximum 20 characters allowed + + +
+ + +
+
+
+ +
+ +
+ {{paramReadOnlyFields.lastChangedBy || 'N/A'}} +
+
+ +
+ +
+ {{paramReadOnlyFields.isInactive === true ? 'Yes' : 'No' }} +
+
+
+
+ + +
+ +
+ {{(paramReadOnlyFields.lastChangedDate | date:'mediumDate':'UTC') || 'N/A'}} +
+
+ + +
+ +
+ {{(paramReadOnlyFields.inactivatedDate | date:'mediumDate':'UTC') || 'N/A'}} +
+
+
+
+
+ +
+ + +
+
+
+ + \ No newline at end of file diff --git a/src/app/param/table/param-table.component.scss b/src/app/param/table/param-table.component.scss new file mode 100644 index 0000000..02ecd1c --- /dev/null +++ b/src/app/param/table/param-table.component.scss @@ -0,0 +1,188 @@ +.page-header { + margin: 0.5rem 0px; + color: var(--mat-sys-primary); + font-weight: 500; +} + +.actions-bar { + clear: both; + margin-bottom: -16px; + + &.mb-40 { + margin-bottom: 40px; + } + + &.mb-10 { + margin-bottom: 10px; + } + + mat-slide-toggle { + transform: scale(0.8); + margin-left: -1rem; + } + + button { + float: right; + } + + .icon-text { + padding-left: 10px !important; + font-size: 18px !important; + } +} + +.form-container { + background-color: white; + padding: 24px; + border-radius: 8px; + margin-top: 16px; + + .form-header { + margin-bottom: 24px; + + h3 { + margin: 0; + color: var(--mat-sys-primary); + font-weight: 500; + } + } + + form { + display: flex; + flex-direction: column; + gap: 16px; + + .form-row { + display: flex; + gap: 16px; + + mat-form-field { + flex: 1; + } + + .small-field { + max-width: 120px; + } + } + + .form-actions { + display: flex; + justify-content: flex-end; + gap: 16px; + margin-top: 16px; + } + + .readonly-section { + padding-top: 0.5rem; + border-top: 1px solid #eee; + + .readonly-fields { + display: flex; + gap: 2rem; + + .field-column { + flex: 1; + display: flex; + flex-direction: column; + gap: 1.5rem; + } + } + + .readonly-field { + label { + display: block; + font-size: 0.875rem; + color: #666; + margin-bottom: 0.25rem; + } + + .readonly-value { + padding: 0.25rem; + font-size: 0.9375rem; + display: flex; + align-items: center; + } + } + } + } +} + + +.results-section { + position: relative; + overflow: auto; + border-radius: 8px; + + .loading-shade { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255, 255, 255, 0.7); + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + } + + mat-table { + width: 100%; + + mat-icon { + cursor: pointer; + transition: all 0.2s ease; + + &:hover { + transform: scale(1.1); + } + } + + .mat-column-actions { + width: 180px; + text-align: center; + } + + .mat-column-defaultContact { + width: 80px; + text-align: center; + } + } + + .no-data-message { + text-align: center; + padding: 0.9rem; + color: rgba(0, 0, 0, 0.54); + + mat-icon { + font-size: 1rem; + width: 1rem; + height: 1rem; + margin-bottom: -3px; + } + } + + mat-paginator { + border-top: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 0 0 8px 8px; + padding-top: 4px; + } +} + +.action-container { + display: flex !important; + justify-content: center !important; + align-items: center !important; +} + +.search-bar { + display: flex; + width: 100%; + margin-top: 10px; + + + .full-width { + flex: 1; + width: 100%; + } +} \ No newline at end of file diff --git a/src/app/param/table/param-table.component.ts b/src/app/param/table/param-table.component.ts new file mode 100644 index 0000000..98a330d --- /dev/null +++ b/src/app/param/table/param-table.component.ts @@ -0,0 +1,264 @@ +import { Component, inject, Input, ViewChild } from '@angular/core'; +import { AngularMaterialModule } from '../../shared/module/angular-material.module'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { UserPreferences } from '../../core/models/user-preference'; +import { UserPreferencesService } from '../../core/services/user-preference.service'; +import { MatTableDataSource } from '@angular/material/table'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { NavigationService } from '../../core/services/common/navigation.service'; +import { ActivatedRoute } from '@angular/router'; +import { ParamService } from '../../core/services/param/param.service'; +import { ParamProperties } from '../../core/models/param/parameters'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; +import { NotificationService } from '../../core/services/common/notification.service'; +import { TABLE_MODE } from '../../core/models/param/types'; +import { ProperCasePipe } from '../../shared/pipes/properCase.pipe'; + +@Component({ + selector: 'app-param-table', + imports: [AngularMaterialModule, ReactiveFormsModule, CommonModule, MatSlideToggleModule, ProperCasePipe], + templateUrl: './param-table.component.html', + styleUrl: './param-table.component.scss' +}) +export class ParamTableComponent { + @ViewChild(MatPaginator) paginator!: MatPaginator; + @ViewChild(MatSort) sort!: MatSort; + + @Input() table_mode: TABLE_MODE = 'TABLE-RECORD'; + @Input() paramHeading: string = 'Table Records'; + + isLoading: boolean = false; + userPreferences: UserPreferences; + paramType: string | null = null; + paramData: any = []; + showInactiveData: boolean = false; + isEditing: boolean = false; + showForm: boolean = false; + currentParamid: number | null = null; + + paramReadOnlyFields: any = { + lastChangedDate: null, + lastChangedBy: null, + isInactive: null, + inactivatedDate: null + }; + + private paramService = inject(ParamService); + private errorHandler = inject(ApiErrorHandlerService); + private notificationService = inject(NotificationService); + + dataSource = new MatTableDataSource([]); + paramForm: FormGroup; + + ngAfterViewInit() { + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + this.dataSource.data = this.paramData; + } + + displayedColumns: string[] = ['ParamType', 'ParamDesc', 'paramvalue', 'addlparamvalue1', 'addlparamvalue2', 'addlparamvalue3', + 'addlparamvalue4', 'addlparamvalue5', 'actions']; + + formControls: any = {}; + + getForm(): void { + if (this.table_mode === 'PARAM-RECORD') { + this.formControls = { + paramType: ['', [Validators.required, Validators.maxLength(10)]], + paramValue: ['', [Validators.required, Validators.maxLength(20)]], + paramDesc: ['', [Validators.required, Validators.maxLength(100)]], + addlParamValue1: ['', [Validators.maxLength(20)]], + addlParamValue2: ['', [Validators.maxLength(20)]], + addlParamValue3: ['', [Validators.maxLength(20)]], + addlParamValue4: ['', [Validators.maxLength(20)]], + addlParamValue5: ['', [Validators.maxLength(20)]], + }; + } + else { + this.formControls = { + paramDesc: ['', [Validators.required, Validators.maxLength(100)]], + } + } + } + + applyFilter(event: Event) { + const filterValue = (event.target as HTMLInputElement).value; + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + get isParamRecord(): boolean { + return this.table_mode === 'PARAM-RECORD'; + } + + constructor( + private userPrefenceService: UserPreferencesService, + private navigationService: NavigationService, + private fb: FormBuilder, + ) { + this.userPreferences = this.userPrefenceService.getPreferences(); + this.getForm(); + this.paramForm = this.fb.group(this.formControls); + } + + cancelEdit(): void { + this.showForm = false; + this.isEditing = false; + this.currentParamid = null; + this.paramForm.reset(); + } + + private route = inject(ActivatedRoute); + + ngOnInit(): void { + this.paramType = this.route.snapshot.paramMap.get('id'); + this.getParameters(); + } + + toggleShowInactiveData(): void { + this.showInactiveData = !this.showInactiveData; + this.renderParamData(); + } + + onRecordClick(id: string, paramDesc: string): void { + this.navigationService.navigate(['param-record', id], { queryParams: { param: paramDesc } }); + } + + addNewParam(): void { + this.getForm(); + this.paramForm = this.fb.group(this.formControls); + this.showForm = true; + this.isEditing = false; + this.currentParamid = null; + this.paramForm.reset(); + this.paramForm.get('paramType')?.setValue(this.paramType); + } + + onEditParam(param: any): void { + this.getForm(); + this.paramForm = this.fb.group(this.formControls); + + this.showForm = true; + this.isEditing = true; + this.currentParamid = param.paramId; + this.paramForm.patchValue({ + paramType: param.paramType, + paramValue: param.paramValue, + paramDesc: param.paramDesc, + addlParamValue1: param.addlParamValue1, + addlParamValue2: param.addlParamValue2, + addlParamValue3: param.addlParamValue3, + addlParamValue4: param.addlParamValue4, + addlParamValue5: param.addlParamValue5 + }); + + this.paramForm.get('paramType')?.setValue(this.paramType); + + this.paramReadOnlyFields.lastChangedDate = param.lastUpdatedDate ?? param.dateCreated; + this.paramReadOnlyFields.lastChangedBy = param.lastUpdatedBy ?? param.createdBy; + this.paramReadOnlyFields.isInactive = param.inactiveCodeFlag === 'N' || !param.inactiveCodeFlag ? 'No' : 'Yes'; + this.paramReadOnlyFields.inactivatedDate = param.inactiveDate; + } + + renderParamData() { + if (this.showInactiveData && this.table_mode === 'PARAM-RECORD') { + this.dataSource.data = this.paramData.filter((data: any) => data?.inactiveCodeFlag === 'Y'); + } + else if (!this.showInactiveData && this.table_mode === 'PARAM-RECORD') { + this.dataSource.data = this.paramData.filter((data: any) => data?.inactiveCodeFlag === 'N' || data?.inactiveCodeFlag === null); + } + else { + this.dataSource.data = this.paramData; + } + } + + getParameters(): void { + + this.isLoading = true; + + const P_PARAMTYPE: string = this.paramType ? this.paramType : '000'; + + this.paramService.getParameters(P_PARAMTYPE).subscribe({ + next: (paramData: ParamProperties[]) => { + this.paramData = paramData + this.renderParamData() + this.isLoading = false; + }, + error: (error: any) => { + let errorMessage = this.errorHandler.handleApiError(error, 'Failed to search preparers'); + this.notificationService.showError(errorMessage); + this.isLoading = false; + console.error('Error loading preparers:', error); + } + }); + } + + saveRecord(): void { + if (this.paramForm.invalid) { + this.paramForm.markAllAsTouched(); + return; + } + + const paramData: ParamProperties = this.paramForm.value; + + paramData.paramId = this.currentParamid ?? 0; + paramData.sortSeq = 1; + + const saveObservable = this.table_mode === 'TABLE-RECORD' ? + this.paramService.createTableRecord(this.paramForm.value.paramDesc) + : + this.isEditing + ? this.paramService.updateParamRecord(paramData as ParamProperties) + : this.paramService.createParamRecord(paramData as ParamProperties); + + saveObservable.subscribe({ + next: () => { + this.notificationService.showSuccess(`Record ${this.isEditing && (this.table_mode !== 'TABLE-RECORD') ? 'updated' : 'added'} successfully`); + this.getParameters(); + if (this.table_mode === 'PARAM-RECORD') { + this.cancelEdit(); + } + }, + error: (error) => { + let errorMessage = this.errorHandler.handleApiError(error, `Failed to ${this.isEditing && (this.table_mode !== 'TABLE-RECORD') ? 'update' : 'add'} Record`); + this.notificationService.showError(errorMessage); + console.error('Error saving Record:', error); + } + }); + } + + inActivateParamRecord(paramId: number): void { + this.paramService.inActivateParamRecord(paramId).subscribe( + { + next: (data: any) => { + this.notificationService.showSuccess(`Param Inactivated successfully`); + this.getParameters(); + }, + error: (error: any) => { + let errorMessage = this.errorHandler.handleApiError(error, `Failed to Inactivate Param`); + this.notificationService.showError(errorMessage); + console.error('Error Inactivating Param:', error); + } + } + ); + } + + reActivateParamRecord(paramId: number): void { + this.paramService.reActivateParamRecord(paramId).subscribe( + { + next: (data: any) => { + this.notificationService.showSuccess(`Param Reactivated successfully`); + this.getParameters(); + }, + error: (error: any) => { + let errorMessage = this.errorHandler.handleApiError(error, `Failed to Reactivate Param`); + this.notificationService.showError(errorMessage); + console.error('Error Reactivating Param:', error); + } + } + ); + } + +} diff --git a/src/app/shared/pipes/properCase.pipe.ts b/src/app/shared/pipes/properCase.pipe.ts new file mode 100644 index 0000000..49cc838 --- /dev/null +++ b/src/app/shared/pipes/properCase.pipe.ts @@ -0,0 +1,15 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'properCase' +}) +export class ProperCasePipe implements PipeTransform { + + transform(value: string): string { + if (!value) return ''; + + return value + .toLowerCase() + .replace(/\b\w/g, char => char.toUpperCase()); + } +} -- 2.47.2