@nettyapps/ntybase 21.1.38 → 21.1.40

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.
@@ -1,14 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, Injectable, inject, NgModule, signal, input, computed, effect, output, afterRenderEffect, linkedSignal, ViewChild, model, Input, InjectionToken, Optional, Inject } from '@angular/core';
3
- import * as i1$3 from '@angular/common/http';
4
- import { HttpErrorResponse, HttpResponse, HTTP_INTERCEPTORS, HttpClient, HttpHeaders } from '@angular/common/http';
5
- import { of, throwError, Subject, lastValueFrom, map, catchError as catchError$1, finalize, take as take$1, takeUntil } from 'rxjs';
6
- import { catchError, map as map$1, take, finalize as finalize$1 } from 'rxjs/operators';
7
- import { Router, ActivatedRoute } from '@angular/router';
8
- import * as i2$1 from '@nettyapps/ntycontract';
9
- import { EnvironmentProxy, injectNettyStandardProxy, injectNettyStandardLogProxy, injectNettyStandardFilterProxy } from '@nettyapps/ntycontract';
10
- import { DatePipe, CommonModule, Location, DecimalPipe } from '@angular/common';
2
+ import { inject, Component, Injectable, signal, input, computed, effect, model, output, afterRenderEffect, NgModule, linkedSignal, ViewChild, Input, InjectionToken, Optional, Inject } from '@angular/core';
11
3
  import { Buffer } from 'buffer';
4
+ import { Subject, lastValueFrom, map, catchError, throwError, of, finalize, take as take$1, takeUntil } from 'rxjs';
12
5
  import * as i1 from '@angular/material/dialog';
13
6
  import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
14
7
  import * as i3 from '@angular/material/divider';
@@ -19,420 +12,155 @@ import * as i1$2 from '@angular/material/snack-bar';
19
12
  import { MatSnackBarModule } from '@angular/material/snack-bar';
20
13
  import * as i1$1 from '@ngx-translate/core';
21
14
  import { TranslateModule, TranslateService } from '@ngx-translate/core';
15
+ import * as i1$5 from '@angular/common';
16
+ import { CommonModule, DatePipe, Location, DecimalPipe } from '@angular/common';
22
17
  import { Title } from '@angular/platform-browser';
23
- import { Mutex } from 'async-mutex';
24
- import { themeQuartz, StatusBarModule, ClipboardModule, ExcelExportModule, ColumnMenuModule, ContextMenuModule, CellSelectionModule, RowSelectionModule, SetFilterModule, MultiFilterModule } from 'ag-grid-enterprise';
25
- import { toSignal } from '@angular/core/rxjs-interop';
18
+ import * as i2$2 from '@nettyapps/ntycontract';
19
+ import { injectNettyStandardFilterProxy, EnvironmentProxy, injectNettyStandardProxy, injectNettyStandardLogProxy } from '@nettyapps/ntycontract';
20
+ import { I18nService } from '@nettyapps/ntyi18n';
21
+ import { ExcelLogViewer as ExcelLogViewer$1 } from '@nettyapps/ntyux';
22
+ import { Router, ActivatedRoute } from '@angular/router';
26
23
  import { ModuleRegistry, AllCommunityModule, ClientSideRowModelModule, HighlightChangesModule, TextFilterModule, NumberFilterModule, DateFilterModule } from 'ag-grid-community';
27
- import * as i2$2 from '@angular/material/tooltip';
24
+ import { themeQuartz, StatusBarModule, ClipboardModule, ExcelExportModule, ColumnMenuModule, ContextMenuModule, CellSelectionModule, RowSelectionModule, SetFilterModule, MultiFilterModule } from 'ag-grid-enterprise';
25
+ import * as i2$1 from '@angular/material/tooltip';
28
26
  import { MatTooltipModule } from '@angular/material/tooltip';
29
27
  import * as i2$3 from '@angular/material/menu';
30
28
  import { MatMenuModule } from '@angular/material/menu';
31
- import { ExcelLogViewer } from '@nettyapps/ntyux';
32
- import { I18nService } from '@nettyapps/ntyi18n';
29
+ import * as i1$3 from '@angular/common/http';
30
+ import { HttpClient, HttpErrorResponse, HttpResponse, HTTP_INTERCEPTORS, HttpHeaders } from '@angular/common/http';
31
+ import { Mutex } from 'async-mutex';
32
+ import { toSignal } from '@angular/core/rxjs-interop';
33
+ import { catchError as catchError$1, map as map$1, take, finalize as finalize$1 } from 'rxjs/operators';
33
34
  import * as i1$4 from '@angular/forms';
34
35
  import { FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
35
36
  import * as i3$1 from '@angular/material/input';
36
37
  import { MatInputModule } from '@angular/material/input';
37
38
  import { MatFormFieldModule } from '@angular/material/form-field';
39
+ import { AgGridAngular } from 'ag-grid-angular';
40
+ import { NettyUIButton, NettyUIFilterButton } from '@nettyapps/ntyui';
38
41
 
39
- class Ntybase {
40
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Ntybase, deps: [], target: i0.ɵɵFactoryTarget.Component });
41
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: Ntybase, isStandalone: false, selector: "lib-ntybase", ngImport: i0, template: `
42
- <p>
43
- ntybase works!
44
- </p>
45
- `, isInline: true, styles: [""] });
42
+ class ConfirmDialog {
43
+ dialogRef = inject((MatDialogRef));
44
+ data = inject(MAT_DIALOG_DATA);
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ConfirmDialog, isStandalone: true, selector: "ntybase-confirm-dialog", ngImport: i0, template: "<div class=\"dialog-container\">\n <h2 mat-dialog-title class=\"dialog-title\">\n <mat-icon color=\"warn\" class=\"warning-icon\">warning</mat-icon>\n <span>{{data.title | translate}}</span>\n </h2>\n\n <mat-divider class=\"divider\"></mat-divider>\n\n <mat-dialog-content class=\"dialog-content\">\n <p class=\"message\">{{data.message | translate}}</p>\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button mat-stroked-button [mat-dialog-close]=\"false\" class=\"btn-cancel\">\n {{'@btnCancel' | translate}}\n </button>\n <button\n mat-flat-button\n color=\"warn\"\n [mat-dialog-close]=\"true\"\n class=\"btn-ok\"\n >\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{display:flex;flex-direction:column;min-width:400px;max-width:90vw;padding:24px;border-radius:12px!important}.dialog-title{display:flex;align-items:center;margin:0 0 12px;padding:0;color:var(--mat-sys-primary)}.dialog-title span{margin-left:8px}.warning-icon{color:var(--mat-sys-primary);transform:scale(1.2)}.divider{margin:8px 0 16px;border-top-color:var(--mat-sys-primary)}.dialog-content{padding:8px 0 24px;margin:0;color:var(--mat-sys-primary);line-height:1.6}.dialog-content .message{margin:0;white-space:pre-wrap}.dialog-actions{padding:16px 0 0;margin:0;gap:8px}.btn-ok{padding:8px 16px;border-radius:6px;font-weight:500;background-color:var(--mat-sys-primary);color:var(--mat-sys-primary-container)}.btn-cancel{padding:8px 16px;border-radius:6px;color:var(--mat-sys-secondary-container);background-color:var(--mat-sys-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
46
47
  }
47
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Ntybase, decorators: [{
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ConfirmDialog, decorators: [{
48
49
  type: Component,
49
- args: [{ selector: 'lib-ntybase', standalone: false, template: `
50
- <p>
51
- ntybase works!
52
- </p>
53
- ` }]
50
+ args: [{ selector: 'ntybase-confirm-dialog', imports: [MatDialogModule, MatSnackBarModule, MatIconModule, MatDividerModule, TranslateModule], template: "<div class=\"dialog-container\">\n <h2 mat-dialog-title class=\"dialog-title\">\n <mat-icon color=\"warn\" class=\"warning-icon\">warning</mat-icon>\n <span>{{data.title | translate}}</span>\n </h2>\n\n <mat-divider class=\"divider\"></mat-divider>\n\n <mat-dialog-content class=\"dialog-content\">\n <p class=\"message\">{{data.message | translate}}</p>\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button mat-stroked-button [mat-dialog-close]=\"false\" class=\"btn-cancel\">\n {{'@btnCancel' | translate}}\n </button>\n <button\n mat-flat-button\n color=\"warn\"\n [mat-dialog-close]=\"true\"\n class=\"btn-ok\"\n >\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{display:flex;flex-direction:column;min-width:400px;max-width:90vw;padding:24px;border-radius:12px!important}.dialog-title{display:flex;align-items:center;margin:0 0 12px;padding:0;color:var(--mat-sys-primary)}.dialog-title span{margin-left:8px}.warning-icon{color:var(--mat-sys-primary);transform:scale(1.2)}.divider{margin:8px 0 16px;border-top-color:var(--mat-sys-primary)}.dialog-content{padding:8px 0 24px;margin:0;color:var(--mat-sys-primary);line-height:1.6}.dialog-content .message{margin:0;white-space:pre-wrap}.dialog-actions{padding:16px 0 0;margin:0;gap:8px}.btn-ok{padding:8px 16px;border-radius:6px;font-weight:500;background-color:var(--mat-sys-primary);color:var(--mat-sys-primary-container)}.btn-cancel{padding:8px 16px;border-radius:6px;color:var(--mat-sys-secondary-container);background-color:var(--mat-sys-secondary)}\n"] }]
54
51
  }] });
55
52
 
56
- const credentialsKey = 'credentials';
57
- class CredentialsService {
58
- _credentials = null;
59
- constructor() {
60
- const savedCredentials = sessionStorage.getItem(credentialsKey) ||
61
- localStorage.getItem(credentialsKey);
62
- if (savedCredentials) {
63
- this._credentials = JSON.parse(savedCredentials);
64
- }
53
+ class ErrorAlert {
54
+ dialogRef = inject((MatDialogRef));
55
+ data = inject(MAT_DIALOG_DATA);
56
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ErrorAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
57
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ErrorAlert, isStandalone: true, selector: "ntybase-error-alert", ngImport: i0, template: "<div class=\"error-dialog-container\">\n <div class=\"header\">\n <mat-icon color=\"error\">error_outline</mat-icon>\n <h2 class=\"error-title\">{{ data.title }}</h2>\n </div>\n\n <div class=\"error-content\">\n <p>{{ data.message }}</p>\n </div>\n\n <mat-dialog-actions class=\"dialog-actions\">\n <button mat-flat-button [mat-dialog-close]=\"true\" class=\"btn-ok\">\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".error-dialog-container{padding:40px 32px;text-align:center;min-width:380px;max-width:450px;background:var(--mat-sys-primary);border-radius:20px;box-shadow:0 15px 35px #00000012}.error-dialog-container .header{display:flex;flex-direction:column;align-items:center;gap:12px}.error-dialog-container .header mat-icon{font-size:52px;width:52px;height:52px;color:var(--mat-sys-inverse-primary);margin-bottom:8px}.error-dialog-container .header .error-title{margin:0;font-size:1.4rem;font-weight:700;color:var(--mat-sys-surface);letter-spacing:-.02em}.error-dialog-container .error-content{margin:24px 0 32px;font-size:1rem;line-height:1.6;color:var(--mat-sys-surface)}.error-dialog-container .dialog-actions{display:flex;justify-content:center;padding:0;margin:0}.error-dialog-container .btn-ok{min-width:120px;padding:12px 24px;font-weight:600;font-size:1rem;border-radius:10px;background:var(--mat-sys-inverse-primary);color:var(--mat-sys-primary);border:none;cursor:pointer;transition:all .2s ease}.error-dialog-container .btn-ok:hover{background:var(--mat-sys-inverse-primary);opacity:.9;box-shadow:0 5px 15px #0000001a}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
58
+ }
59
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ErrorAlert, decorators: [{
60
+ type: Component,
61
+ args: [{ selector: 'ntybase-error-alert', imports: [MatDialogModule, MatIconModule, CommonModule, TranslateModule], template: "<div class=\"error-dialog-container\">\n <div class=\"header\">\n <mat-icon color=\"error\">error_outline</mat-icon>\n <h2 class=\"error-title\">{{ data.title }}</h2>\n </div>\n\n <div class=\"error-content\">\n <p>{{ data.message }}</p>\n </div>\n\n <mat-dialog-actions class=\"dialog-actions\">\n <button mat-flat-button [mat-dialog-close]=\"true\" class=\"btn-ok\">\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".error-dialog-container{padding:40px 32px;text-align:center;min-width:380px;max-width:450px;background:var(--mat-sys-primary);border-radius:20px;box-shadow:0 15px 35px #00000012}.error-dialog-container .header{display:flex;flex-direction:column;align-items:center;gap:12px}.error-dialog-container .header mat-icon{font-size:52px;width:52px;height:52px;color:var(--mat-sys-inverse-primary);margin-bottom:8px}.error-dialog-container .header .error-title{margin:0;font-size:1.4rem;font-weight:700;color:var(--mat-sys-surface);letter-spacing:-.02em}.error-dialog-container .error-content{margin:24px 0 32px;font-size:1rem;line-height:1.6;color:var(--mat-sys-surface)}.error-dialog-container .dialog-actions{display:flex;justify-content:center;padding:0;margin:0}.error-dialog-container .btn-ok{min-width:120px;padding:12px 24px;font-weight:600;font-size:1rem;border-radius:10px;background:var(--mat-sys-inverse-primary);color:var(--mat-sys-primary);border:none;cursor:pointer;transition:all .2s ease}.error-dialog-container .btn-ok:hover{background:var(--mat-sys-inverse-primary);opacity:.9;box-shadow:0 5px 15px #0000001a}\n"] }]
62
+ }] });
63
+
64
+ // alert.service.ts
65
+ class AlertService {
66
+ snackBar;
67
+ dialog;
68
+ translate;
69
+ constructor(snackBar, dialog, translate) {
70
+ this.snackBar = snackBar;
71
+ this.dialog = dialog;
72
+ this.translate = translate;
65
73
  }
66
- /**
67
- * Checks is the user is authenticated.
68
- * @return True if the user is authenticated.
69
- */
70
- isAuthenticated() {
71
- return !!this.credentials;
74
+ // For simple notifications
75
+ showAlert(message, action, duration = 3000) {
76
+ const actionText = action ? action : '@btnOK';
77
+ this.snackBar.open(this.translate.instant(message), this.translate.instant(actionText), { duration });
72
78
  }
73
- /**
74
- * Gets the user credentials.
75
- * @return The user credentials or null if the user is not authenticated.
76
- */
77
- get credentials() {
78
- return this._credentials;
79
+ showWarning(message, action, duration = 3000) {
80
+ const actionText = action ? action : '@btnOK';
81
+ this.snackBar.open(this.translate.instant(message), this.translate.instant(actionText), { duration });
79
82
  }
80
- get token() {
81
- return this._credentials?.token ?? null;
83
+ // For confirmation dialogs
84
+ showConfirm(message) {
85
+ return new Promise((resolve) => {
86
+ const dialogRef = this.dialog.open(ConfirmDialog, {
87
+ width: 'auto',
88
+ height: 'auto',
89
+ data: {
90
+ message: message,
91
+ title: '@confirmation',
92
+ },
93
+ });
94
+ dialogRef.afterClosed().subscribe((result) => {
95
+ resolve(!!result);
96
+ });
97
+ });
82
98
  }
83
- /**
84
- * Sets the user credentials.
85
- * The credentials may be persisted across sessions by setting the `remember` parameter to true.
86
- * Otherwise, the credentials are only persisted for the current session.
87
- * @param credentials The user credentials.
88
- * @param remember True to remember credentials across sessions.
89
- */
90
- setCredentials(credentials, remember) {
91
- this._credentials = credentials || null;
92
- if (credentials) {
93
- const storage = remember ? localStorage : sessionStorage;
94
- storage.setItem(credentialsKey, JSON.stringify(credentials));
95
- }
96
- else {
97
- sessionStorage.removeItem(credentialsKey);
98
- localStorage.removeItem(credentialsKey);
99
- }
99
+ // For success notifications
100
+ showSuccess(message, duration = 3000) {
101
+ this.snackBar.open(this.translate.instant(message), this.translate.instant('@btnOK'), {
102
+ duration,
103
+ panelClass: ['success-snackbar'],
104
+ horizontalPosition: 'right',
105
+ verticalPosition: 'bottom',
106
+ });
100
107
  }
101
- /** Get Credentials
102
- *
103
- * @returns
104
- */
105
- getCredentials() {
106
- let _credentialsString = sessionStorage.getItem(credentialsKey);
107
- if (_credentialsString == null || _credentialsString == '') {
108
- _credentialsString = localStorage.getItem(credentialsKey);
109
- }
110
- return JSON.parse(_credentialsString ?? '');
108
+ /**
109
+ * Displays an error dialog with flexible parameters.
110
+ * Intelligently extracts meaningful C# error messages or falls back to a translation key.
111
+ * * Supported usages:
112
+ * - showError('@fallbackKey', err)
113
+ * - showError(err)
114
+ * - showError(err, '@fallbackKey')
115
+ * - showError('@fallbackKey')
116
+ */
117
+ showError(arg1, arg2, customComponent = ErrorAlert, width = 'auto', height = 'auto') {
118
+ const isArg1Str = typeof arg1 === 'string';
119
+ const fallbackKey = isArg1Str ? arg1 : (typeof arg2 === 'string' ? arg2 : '');
120
+ const errorObj = isArg1Str ? arg2 : arg1;
121
+ // Open the Dialog
122
+ return new Promise((resolve) => {
123
+ this.dialog.open(customComponent, {
124
+ width, height, maxWidth: '95vw',
125
+ data: {
126
+ message: this.getErrorMessage(errorObj, fallbackKey),
127
+ title: this.translate.instant('@errorOccurred'),
128
+ },
129
+ }).afterClosed().subscribe(() => resolve());
130
+ });
111
131
  }
112
- /** Get the token if available otherwise return empty string
113
- *
114
- * @returns
115
- */
116
- getToken() {
117
- try {
118
- let _credentials = this.getCredentials();
119
- return _credentials.token;
132
+ getErrorMessage(errorObj, fallbackKey) {
133
+ if (!errorObj) {
134
+ return fallbackKey ? this.translate.instant(fallbackKey) : this.translate.instant('@errorOccurred');
120
135
  }
121
- catch (error) {
122
- return '';
136
+ const data = errorObj.error ?? errorObj;
137
+ const isStr = typeof data === 'string';
138
+ const backendMessage = isStr ? data : (data?.message || data?.details || JSON.stringify(data));
139
+ const isMeaningful = isStr ? !data.startsWith('<') : !!(data?.message || data?.details);
140
+ if (fallbackKey) {
141
+ return isMeaningful ? backendMessage : this.translate.instant(fallbackKey);
123
142
  }
143
+ return backendMessage;
124
144
  }
125
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
126
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, providedIn: 'root' });
145
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, deps: [{ token: i1$2.MatSnackBar }, { token: i1.MatDialog }, { token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
146
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, providedIn: 'root' });
127
147
  }
128
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, decorators: [{
148
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, decorators: [{
129
149
  type: Injectable,
130
150
  args: [{
131
151
  providedIn: 'root',
132
152
  }]
133
- }], ctorParameters: () => [] });
153
+ }], ctorParameters: () => [{ type: i1$2.MatSnackBar }, { type: i1.MatDialog }, { type: i1$1.TranslateService }] });
134
154
 
135
- class UrlHelperService {
136
- router = inject(Router);
137
- cleanUrl(url) {
138
- let result = url
139
- .replace('/mfalogin?redirect=', '')
140
- .replace('/mfalogin?redirect=', '')
141
- .replace('/mfalogin?redirect=', '')
142
- .replace('/login?redirect=', '')
143
- .replace('/login?redirect=', '')
144
- .replace('/login?redirect=', '')
145
- .replace(new RegExp('%25', 'g'), '%')
146
- .replace(new RegExp('%25', 'g'), '%')
147
- .replace(new RegExp('%25', 'g'), '%')
148
- .replace(new RegExp('%25', 'g'), '%')
149
- .replace(new RegExp('%25', 'g'), '%')
150
- .replace(new RegExp('%25', 'g'), '%')
151
- .replace(new RegExp('%22', 'g'), '"')
152
- .replace(new RegExp('%3F', 'g'), '?')
153
- .replace(new RegExp('%3D', 'g'), '=')
154
- .replace(new RegExp('%2F', 'g'), '/')
155
- .replace(new RegExp('%26', 'g'), '&')
156
- .replace(new RegExp('/mfalogin?redirect=', 'g'), '')
157
- .replace(new RegExp('/login?redirect=', 'g'), '');
158
- console.log('url:', url);
159
- console.log('result:', result);
160
- // return url;
161
- return result;
162
- }
163
- navigate(url) {
164
- let urlParts = url.split('?');
165
- if (urlParts.length == 1) {
166
- return this.router.navigate(urlParts, { replaceUrl: true });
167
- }
168
- let parameters = urlParts[1].split('&');
169
- return this.router.navigate([urlParts[0]], {
170
- queryParams: {
171
- parameters: parameters[0]?.replace('parameters=', '') ?? '',
172
- type: parameters[1]?.replace('type=', '') ?? '',
173
- },
174
- replaceUrl: true,
175
- });
155
+ class PageTitle {
156
+ title = signal('', ...(ngDevMode ? [{ debugName: "title" }] : []));
157
+ setTitle(newTitle) {
158
+ this.title.set(newTitle);
176
159
  }
177
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
178
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, providedIn: 'root' });
160
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
161
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, providedIn: 'root' });
179
162
  }
180
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, decorators: [{
181
- type: Injectable,
182
- args: [{
183
- providedIn: 'root',
184
- }]
185
- }] });
186
-
187
- class AuthenticationInterceptor {
188
- router = inject(Router);
189
- credentialsService = inject(CredentialsService);
190
- environmentProxy = inject(EnvironmentProxy);
191
- urlHelperService = inject(UrlHelperService);
192
- intercept(req, next) {
193
- if (req.headers.get('No-Auth') == 'True')
194
- return next.handle(req.clone());
195
- let token = this.credentialsService.token;
196
- if (token != null) {
197
- let appName = this.environmentProxy.getApplicationName();
198
- const clonedreq = req.clone({
199
- headers: req.headers.set('Authorization', 'Bearer ' + token),
200
- // .set("NettyAppName",appName)
201
- });
202
- return next.handle(clonedreq).pipe(catchError((error) => {
203
- if (error instanceof HttpErrorResponse && error.status === 401) {
204
- // Handle 401 error, e.g., navigate to the login page
205
- this.router.navigate(['/login'], {
206
- queryParams: {
207
- redirect: this.urlHelperService.cleanUrl(this.router.url),
208
- },
209
- replaceUrl: true,
210
- });
211
- // Return an observable with a successful response
212
- return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
213
- }
214
- if (error instanceof HttpErrorResponse && error.status === 403) {
215
- this.router.navigate(['/forbidden'], {
216
- state: { attemptedUrl: this.router.url }, // Orijinal URL'i state olarak geçme
217
- });
218
- return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
219
- }
220
- if (error instanceof HttpErrorResponse && error.status === 428) {
221
- // Handle 428 error, e.g., navigate to the login page
222
- this.router.navigate(['/mfalogin'], {
223
- queryParams: {
224
- redirect: this.urlHelperService.cleanUrl(this.router.url),
225
- },
226
- replaceUrl: true,
227
- });
228
- // Return an observable with a successful response
229
- return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
230
- }
231
- // For other errors, re-throw the error to propagate it further
232
- return throwError(() => error);
233
- }));
234
- }
235
- else {
236
- return next.handle(req.clone()).pipe(catchError((error) => {
237
- if (error instanceof HttpErrorResponse && error.status === 401) {
238
- // Handle 401 error, e.g., navigate to the login page
239
- this.router.navigate(['/login'], {
240
- queryParams: {
241
- redirect: this.urlHelperService.cleanUrl(this.router.url),
242
- },
243
- replaceUrl: true,
244
- });
245
- // Return an observable with a successful response
246
- return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
247
- }
248
- if (error instanceof HttpErrorResponse && error.status === 403) {
249
- this.router.navigate(['/forbidden'], {
250
- state: { attemptedUrl: this.router.url }, // Orijinal URL'i state olarak geçme
251
- });
252
- return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
253
- }
254
- if (error instanceof HttpErrorResponse && error.status === 428) {
255
- // Handle 428 error, e.g., navigate to the login page
256
- this.router.navigate(['/mfalogin'], {
257
- queryParams: {
258
- redirect: this.urlHelperService.cleanUrl(this.router.url),
259
- },
260
- replaceUrl: true,
261
- });
262
- // Return an observable with a successful response
263
- return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
264
- }
265
- // For other errors, re-throw the error to propagate it further
266
- return throwError(() => error);
267
- }));
268
- }
269
- }
270
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
271
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor });
272
- }
273
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor, decorators: [{
274
- type: Injectable
275
- }] });
276
-
277
- class CanDeactivateGuard {
278
- canDeactivate(component) {
279
- return component.canDeactivate ? component.canDeactivate() : true;
280
- }
281
- }
282
-
283
- class NtybaseModule {
284
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
285
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, declarations: [Ntybase], exports: [Ntybase] });
286
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, providers: [
287
- {
288
- provide: HTTP_INTERCEPTORS,
289
- useClass: AuthenticationInterceptor,
290
- multi: true,
291
- },
292
- [CanDeactivateGuard],
293
- DatePipe,
294
- ] });
295
- }
296
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, decorators: [{
297
- type: NgModule,
298
- args: [{
299
- declarations: [Ntybase],
300
- imports: [],
301
- exports: [Ntybase],
302
- providers: [
303
- {
304
- provide: HTTP_INTERCEPTORS,
305
- useClass: AuthenticationInterceptor,
306
- multi: true,
307
- },
308
- [CanDeactivateGuard],
309
- DatePipe,
310
- ],
311
- }]
312
- }] });
313
-
314
- class ConfirmDialog {
315
- dialogRef = inject((MatDialogRef));
316
- data = inject(MAT_DIALOG_DATA);
317
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
318
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ConfirmDialog, isStandalone: true, selector: "ntybase-confirm-dialog", ngImport: i0, template: "<div class=\"dialog-container\">\n <h2 mat-dialog-title class=\"dialog-title\">\n <mat-icon color=\"warn\" class=\"warning-icon\">warning</mat-icon>\n <span>{{data.title | translate}}</span>\n </h2>\n\n <mat-divider class=\"divider\"></mat-divider>\n\n <mat-dialog-content class=\"dialog-content\">\n <p class=\"message\">{{data.message | translate}}</p>\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button mat-stroked-button [mat-dialog-close]=\"false\" class=\"btn-cancel\">\n {{'@btnCancel' | translate}}\n </button>\n <button\n mat-flat-button\n color=\"warn\"\n [mat-dialog-close]=\"true\"\n class=\"btn-ok\"\n >\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{display:flex;flex-direction:column;min-width:400px;max-width:90vw;padding:24px;border-radius:12px!important}.dialog-title{display:flex;align-items:center;margin:0 0 12px;padding:0;color:var(--mat-sys-primary)}.dialog-title span{margin-left:8px}.warning-icon{color:var(--mat-sys-primary);transform:scale(1.2)}.divider{margin:8px 0 16px;border-top-color:var(--mat-sys-primary)}.dialog-content{padding:8px 0 24px;margin:0;color:var(--mat-sys-primary);line-height:1.6}.dialog-content .message{margin:0;white-space:pre-wrap}.dialog-actions{padding:16px 0 0;margin:0;gap:8px}.btn-ok{padding:8px 16px;border-radius:6px;font-weight:500;background-color:var(--mat-sys-primary);color:var(--mat-sys-primary-container)}.btn-cancel{padding:8px 16px;border-radius:6px;color:var(--mat-sys-secondary-container);background-color:var(--mat-sys-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
319
- }
320
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ConfirmDialog, decorators: [{
321
- type: Component,
322
- args: [{ selector: 'ntybase-confirm-dialog', imports: [MatDialogModule, MatSnackBarModule, MatIconModule, MatDividerModule, TranslateModule], template: "<div class=\"dialog-container\">\n <h2 mat-dialog-title class=\"dialog-title\">\n <mat-icon color=\"warn\" class=\"warning-icon\">warning</mat-icon>\n <span>{{data.title | translate}}</span>\n </h2>\n\n <mat-divider class=\"divider\"></mat-divider>\n\n <mat-dialog-content class=\"dialog-content\">\n <p class=\"message\">{{data.message | translate}}</p>\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button mat-stroked-button [mat-dialog-close]=\"false\" class=\"btn-cancel\">\n {{'@btnCancel' | translate}}\n </button>\n <button\n mat-flat-button\n color=\"warn\"\n [mat-dialog-close]=\"true\"\n class=\"btn-ok\"\n >\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{display:flex;flex-direction:column;min-width:400px;max-width:90vw;padding:24px;border-radius:12px!important}.dialog-title{display:flex;align-items:center;margin:0 0 12px;padding:0;color:var(--mat-sys-primary)}.dialog-title span{margin-left:8px}.warning-icon{color:var(--mat-sys-primary);transform:scale(1.2)}.divider{margin:8px 0 16px;border-top-color:var(--mat-sys-primary)}.dialog-content{padding:8px 0 24px;margin:0;color:var(--mat-sys-primary);line-height:1.6}.dialog-content .message{margin:0;white-space:pre-wrap}.dialog-actions{padding:16px 0 0;margin:0;gap:8px}.btn-ok{padding:8px 16px;border-radius:6px;font-weight:500;background-color:var(--mat-sys-primary);color:var(--mat-sys-primary-container)}.btn-cancel{padding:8px 16px;border-radius:6px;color:var(--mat-sys-secondary-container);background-color:var(--mat-sys-secondary)}\n"] }]
323
- }] });
324
-
325
- class ErrorAlert {
326
- dialogRef = inject((MatDialogRef));
327
- data = inject(MAT_DIALOG_DATA);
328
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ErrorAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
329
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ErrorAlert, isStandalone: true, selector: "ntybase-error-alert", ngImport: i0, template: "<div class=\"error-dialog-container\">\n <div class=\"header\">\n <mat-icon color=\"error\">error_outline</mat-icon>\n <h2 class=\"error-title\">{{ data.title }}</h2>\n </div>\n\n <div class=\"error-content\">\n <p>{{ data.message }}</p>\n </div>\n\n <mat-dialog-actions class=\"dialog-actions\">\n <button mat-flat-button [mat-dialog-close]=\"true\" class=\"btn-ok\">\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".error-dialog-container{padding:40px 32px;text-align:center;min-width:380px;max-width:450px;background:var(--mat-sys-primary);border-radius:20px;box-shadow:0 15px 35px #00000012}.error-dialog-container .header{display:flex;flex-direction:column;align-items:center;gap:12px}.error-dialog-container .header mat-icon{font-size:52px;width:52px;height:52px;color:var(--mat-sys-inverse-primary);margin-bottom:8px}.error-dialog-container .header .error-title{margin:0;font-size:1.4rem;font-weight:700;color:var(--mat-sys-surface);letter-spacing:-.02em}.error-dialog-container .error-content{margin:24px 0 32px;font-size:1rem;line-height:1.6;color:var(--mat-sys-surface)}.error-dialog-container .dialog-actions{display:flex;justify-content:center;padding:0;margin:0}.error-dialog-container .btn-ok{min-width:120px;padding:12px 24px;font-weight:600;font-size:1rem;border-radius:10px;background:var(--mat-sys-inverse-primary);color:var(--mat-sys-primary);border:none;cursor:pointer;transition:all .2s ease}.error-dialog-container .btn-ok:hover{background:var(--mat-sys-inverse-primary);opacity:.9;box-shadow:0 5px 15px #0000001a}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
330
- }
331
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ErrorAlert, decorators: [{
332
- type: Component,
333
- args: [{ selector: 'ntybase-error-alert', imports: [MatDialogModule, MatIconModule, CommonModule, TranslateModule], template: "<div class=\"error-dialog-container\">\n <div class=\"header\">\n <mat-icon color=\"error\">error_outline</mat-icon>\n <h2 class=\"error-title\">{{ data.title }}</h2>\n </div>\n\n <div class=\"error-content\">\n <p>{{ data.message }}</p>\n </div>\n\n <mat-dialog-actions class=\"dialog-actions\">\n <button mat-flat-button [mat-dialog-close]=\"true\" class=\"btn-ok\">\n {{'@btnOK' | translate}}\n </button>\n </mat-dialog-actions>\n</div>\n", styles: [".error-dialog-container{padding:40px 32px;text-align:center;min-width:380px;max-width:450px;background:var(--mat-sys-primary);border-radius:20px;box-shadow:0 15px 35px #00000012}.error-dialog-container .header{display:flex;flex-direction:column;align-items:center;gap:12px}.error-dialog-container .header mat-icon{font-size:52px;width:52px;height:52px;color:var(--mat-sys-inverse-primary);margin-bottom:8px}.error-dialog-container .header .error-title{margin:0;font-size:1.4rem;font-weight:700;color:var(--mat-sys-surface);letter-spacing:-.02em}.error-dialog-container .error-content{margin:24px 0 32px;font-size:1rem;line-height:1.6;color:var(--mat-sys-surface)}.error-dialog-container .dialog-actions{display:flex;justify-content:center;padding:0;margin:0}.error-dialog-container .btn-ok{min-width:120px;padding:12px 24px;font-weight:600;font-size:1rem;border-radius:10px;background:var(--mat-sys-inverse-primary);color:var(--mat-sys-primary);border:none;cursor:pointer;transition:all .2s ease}.error-dialog-container .btn-ok:hover{background:var(--mat-sys-inverse-primary);opacity:.9;box-shadow:0 5px 15px #0000001a}\n"] }]
334
- }] });
335
-
336
- // alert.service.ts
337
- class AlertService {
338
- snackBar;
339
- dialog;
340
- translate;
341
- constructor(snackBar, dialog, translate) {
342
- this.snackBar = snackBar;
343
- this.dialog = dialog;
344
- this.translate = translate;
345
- }
346
- // For simple notifications
347
- showAlert(message, action, duration = 3000) {
348
- const actionText = action ? action : '@btnOK';
349
- this.snackBar.open(this.translate.instant(message), this.translate.instant(actionText), { duration });
350
- }
351
- showWarning(message, action, duration = 3000) {
352
- const actionText = action ? action : '@btnOK';
353
- this.snackBar.open(this.translate.instant(message), this.translate.instant(actionText), { duration });
354
- }
355
- // For confirmation dialogs
356
- showConfirm(message) {
357
- return new Promise((resolve) => {
358
- const dialogRef = this.dialog.open(ConfirmDialog, {
359
- width: 'auto',
360
- height: 'auto',
361
- data: {
362
- message: message,
363
- title: '@confirmation',
364
- },
365
- });
366
- dialogRef.afterClosed().subscribe((result) => {
367
- resolve(!!result);
368
- });
369
- });
370
- }
371
- // For success notifications
372
- showSuccess(message, duration = 3000) {
373
- this.snackBar.open(this.translate.instant(message), this.translate.instant('@btnOK'), {
374
- duration,
375
- panelClass: ['success-snackbar'],
376
- horizontalPosition: 'right',
377
- verticalPosition: 'bottom',
378
- });
379
- }
380
- /**
381
- * Displays an error dialog with flexible parameters.
382
- * Intelligently extracts meaningful C# error messages or falls back to a translation key.
383
- * * Supported usages:
384
- * - showError('@fallbackKey', err)
385
- * - showError(err)
386
- * - showError(err, '@fallbackKey')
387
- * - showError('@fallbackKey')
388
- */
389
- showError(arg1, arg2, customComponent = ErrorAlert, width = 'auto', height = 'auto') {
390
- const isArg1Str = typeof arg1 === 'string';
391
- const fallbackKey = isArg1Str ? arg1 : (typeof arg2 === 'string' ? arg2 : '');
392
- const errorObj = isArg1Str ? arg2 : arg1;
393
- // Open the Dialog
394
- return new Promise((resolve) => {
395
- this.dialog.open(customComponent, {
396
- width, height, maxWidth: '95vw',
397
- data: {
398
- message: this.getErrorMessage(errorObj, fallbackKey),
399
- title: this.translate.instant('@errorOccurred'),
400
- },
401
- }).afterClosed().subscribe(() => resolve());
402
- });
403
- }
404
- getErrorMessage(errorObj, fallbackKey) {
405
- if (!errorObj) {
406
- return fallbackKey ? this.translate.instant(fallbackKey) : this.translate.instant('@errorOccurred');
407
- }
408
- const data = errorObj.error ?? errorObj;
409
- const isStr = typeof data === 'string';
410
- const backendMessage = isStr ? data : (data?.message || data?.details || JSON.stringify(data));
411
- const isMeaningful = isStr ? !data.startsWith('<') : !!(data?.message || data?.details);
412
- if (fallbackKey) {
413
- return isMeaningful ? backendMessage : this.translate.instant(fallbackKey);
414
- }
415
- return backendMessage;
416
- }
417
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, deps: [{ token: i1$2.MatSnackBar }, { token: i1.MatDialog }, { token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
418
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, providedIn: 'root' });
419
- }
420
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, decorators: [{
421
- type: Injectable,
422
- args: [{
423
- providedIn: 'root',
424
- }]
425
- }], ctorParameters: () => [{ type: i1$2.MatSnackBar }, { type: i1.MatDialog }, { type: i1$1.TranslateService }] });
426
-
427
- class PageTitle {
428
- title = signal('', ...(ngDevMode ? [{ debugName: "title" }] : []));
429
- setTitle(newTitle) {
430
- this.title.set(newTitle);
431
- }
432
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
433
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, providedIn: 'root' });
434
- }
435
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, decorators: [{
163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, decorators: [{
436
164
  type: Injectable,
437
165
  args: [{
438
166
  providedIn: 'root',
@@ -596,31 +324,432 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
596
324
  args: [{ selector: 'ntybase-netty-apps-base', imports: [], template: `` }]
597
325
  }], ctorParameters: () => [], propDecorators: { embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }] } });
598
326
 
599
- class NettyHelper {
600
- /**
601
- * Returns null if fields are equal otherwise return second field
602
- * @param firstField
603
- * @param secondField
604
- * @returns
605
- */
606
- static difference(firstField, secondField) {
607
- if (firstField != secondField) {
608
- return secondField;
609
- }
610
- return null;
611
- }
612
- /**
613
- * Returns null if fields are equal otherwise return second field
614
- * @param firstField
615
- * @param secondField
616
- * @param format
617
- * @returns
618
- */
619
- static dateDifference(firstField, secondField, format) {
620
- let culture = localStorage.getItem('languageApiCode') ?? 'tr-TR';
621
- let datePipe = new DatePipe(culture);
622
- if (datePipe.transform(firstField, format) !=
623
- datePipe.transform(secondField, format)) {
327
+ class NettyAppsFilterBase extends NettyAppsBase {
328
+ // *********************************************************
329
+ // *** Input / Output ***
330
+ // *********************************************************
331
+ isFilterExpanded = model(true, ...(ngDevMode ? [{ debugName: "isFilterExpanded" }] : []));
332
+ filteredRecords = output();
333
+ filterSelectionChanged = output();
334
+ refresh = input(0, ...(ngDevMode ? [{ debugName: "refresh" }] : []));
335
+ fileName = input('nettyapps_', ...(ngDevMode ? [{ debugName: "fileName" }] : []));
336
+ // *********************************************************
337
+ // *** Service ***
338
+ // *********************************************************
339
+ filterProxy = injectNettyStandardFilterProxy(this.componentName());
340
+ // *********************************************************
341
+ // *** Signals ***
342
+ // *********************************************************
343
+ currentItem = signal(this.createNewFilter(), ...(ngDevMode ? [{ debugName: "currentItem" }] : []));
344
+ // *********************************************************
345
+ // *** Constructor ***
346
+ // *********************************************************
347
+ constructor() {
348
+ super();
349
+ effect(() => {
350
+ if (this.refresh() > 0) {
351
+ this.onApply();
352
+ }
353
+ });
354
+ }
355
+ // *********************************************************
356
+ // *** Functions ***
357
+ // *********************************************************
358
+ async ngOnInit() {
359
+ this.afterOnInit();
360
+ }
361
+ onApply() {
362
+ this.filterSelectionChanged.emit(this.currentItem());
363
+ this.filterProxy.selectFilter(this.currentItem()).subscribe({
364
+ next: (result) => {
365
+ this.filteredRecords.emit(result);
366
+ this.isFilterExpanded.set(false);
367
+ },
368
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
369
+ });
370
+ }
371
+ onReset() {
372
+ this.filterProxy.initFilter().subscribe({
373
+ next: (filter) => {
374
+ this.currentItem.set(filter);
375
+ this.filterSelectionChanged.emit(this.currentItem());
376
+ },
377
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
378
+ });
379
+ }
380
+ onExport() {
381
+ this.filterSelectionChanged.emit(this.currentItem());
382
+ this.filterProxy.downloadXLS(this.currentItem()).subscribe({
383
+ next: (response) => {
384
+ this.downloadBlobFile(response, 'application/zip', this.translateService.instant('@00000072') + '.zip');
385
+ },
386
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
387
+ });
388
+ }
389
+ async afterOnInit() { }
390
+ // *****************************************
391
+ // *** Logging Functions ***
392
+ // *****************************************
393
+ logInputs(message) {
394
+ if (!message || message.length < 1) {
395
+ message = 'NettyAppsFilterBase - Inputs log';
396
+ }
397
+ const inputs = {
398
+ "isFilterExpanded": this.isFilterExpanded(),
399
+ "refresh": this.refresh(),
400
+ "fileName": this.fileName(),
401
+ };
402
+ console.log(message, inputs);
403
+ }
404
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAppsFilterBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
405
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: NettyAppsFilterBase, isStandalone: true, selector: "ntybase-netty-apps-base", inputs: { isFilterExpanded: { classPropertyName: "isFilterExpanded", publicName: "isFilterExpanded", isSignal: true, isRequired: false, transformFunction: null }, refresh: { classPropertyName: "refresh", publicName: "refresh", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isFilterExpanded: "isFilterExpandedChange", filteredRecords: "filteredRecords", filterSelectionChanged: "filterSelectionChanged" }, usesInheritance: true, ngImport: i0, template: ``, isInline: true });
406
+ }
407
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAppsFilterBase, decorators: [{
408
+ type: Component,
409
+ args: [{ selector: 'ntybase-netty-apps-base', imports: [], template: `` }]
410
+ }], ctorParameters: () => [], propDecorators: { isFilterExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "isFilterExpanded", required: false }] }, { type: i0.Output, args: ["isFilterExpandedChange"] }], filteredRecords: [{ type: i0.Output, args: ["filteredRecords"] }], filterSelectionChanged: [{ type: i0.Output, args: ["filterSelectionChanged"] }], refresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "refresh", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }] } });
411
+
412
+ class NettyBaseApp {
413
+ i18nService = inject(I18nService);
414
+ alertService = inject(AlertService);
415
+ async loadBaseTranslations() {
416
+ try {
417
+ const enUSBase = await import('./nettyapps-ntybase-en-USbase-Bl-neyoj.mjs');
418
+ const trTRBase = await import('./nettyapps-ntybase-tr-TRbase-CO4HBOmj.mjs');
419
+ this.i18nService.addTranslations('English', enUSBase.default);
420
+ this.i18nService.addTranslations('Türkçe', trTRBase.default);
421
+ }
422
+ catch (error) {
423
+ this.alertService.showError('Error loading base translations in component:', error);
424
+ throw error;
425
+ }
426
+ }
427
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyBaseApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
428
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: NettyBaseApp, isStandalone: true, selector: "ntybase-netty-base-app", ngImport: i0, template: "", styles: [""] });
429
+ }
430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyBaseApp, decorators: [{
431
+ type: Component,
432
+ args: [{ selector: 'ntybase-netty-base-app', imports: [], template: "" }]
433
+ }] });
434
+
435
+ class ParseLog {
436
+ rowIndex = 0; // Excel line no (1-based)
437
+ message = ""; // Error or info message (fallback)
438
+ level = "INFO";
439
+ messageKey; // i18n translation key
440
+ messageParams; // parameters for translation
441
+ init() {
442
+ this.rowIndex = 0;
443
+ this.message = "";
444
+ this.level = "INFO";
445
+ this.messageKey = undefined;
446
+ this.messageParams = undefined;
447
+ }
448
+ compare(other) { return this; }
449
+ getPK() { return this.rowIndex; }
450
+ setPK(pk) { this.rowIndex = pk; }
451
+ }
452
+
453
+ class ExcelParserError extends Error {
454
+ key;
455
+ params;
456
+ constructor(key, params) {
457
+ super(key);
458
+ this.key = key;
459
+ this.params = params;
460
+ this.name = 'ExcelParserError';
461
+ }
462
+ }
463
+ class ExcelParser {
464
+ mappings;
465
+ constructor(mappings) {
466
+ this.mappings = mappings;
467
+ }
468
+ async parse(file, options) {
469
+ // PERFORMANS: XLSX library only loads at parse time!
470
+ const XLSX = await import('xlsx');
471
+ const sheetIndex = options?.sheetIndex ?? 0;
472
+ const headerRowIndex = options?.headerRowIndex ?? 0; // 0-based
473
+ return new Promise((resolve, reject) => {
474
+ const reader = new FileReader();
475
+ reader.onload = (e) => {
476
+ try {
477
+ const data = new Uint8Array(e.target?.result);
478
+ const workbook = XLSX.read(data, { type: 'array' });
479
+ if (!workbook.SheetNames[sheetIndex]) {
480
+ throw new ExcelParserError('@EXCEL_PARSER.sheetNotFound', { index: sheetIndex });
481
+ }
482
+ const sheetName = workbook.SheetNames[sheetIndex];
483
+ const sheet = workbook.Sheets[sheetName];
484
+ const rows = XLSX.utils.sheet_to_json(sheet, { header: 1 });
485
+ const logs = [];
486
+ const result = [];
487
+ // Skip headerline
488
+ const dataRows = rows.slice(headerRowIndex + 1);
489
+ dataRows.forEach((row, i) => {
490
+ // Skip empty lines
491
+ if (!row || row.length === 0)
492
+ return;
493
+ const obj = {};
494
+ let hasError = false;
495
+ const actualRowIndex = headerRowIndex + i + 2; // Excel line no (1-based)
496
+ this.mappings.forEach(m => {
497
+ let rawValue = row[m.index];
498
+ if ((rawValue === undefined || rawValue === null || rawValue === '') && m.defaultValue !== undefined) {
499
+ rawValue = m.defaultValue;
500
+ logs.push(Object.assign(new ParseLog(), {
501
+ rowIndex: actualRowIndex,
502
+ message: `Boş alan için default değer atandı: ${String(m.prop)}`,
503
+ level: 'INFO',
504
+ messageKey: '@EXCEL_PARSER.defaultValueSet',
505
+ messageParams: { prop: String(m.prop) }
506
+ }));
507
+ }
508
+ if (m.required && (rawValue === undefined || rawValue === null || rawValue === '')) {
509
+ logs.push(Object.assign(new ParseLog(), {
510
+ rowIndex: actualRowIndex,
511
+ message: `Zorunlu alan boş: ${String(m.prop)}`,
512
+ level: 'ERROR',
513
+ messageKey: '@EXCEL_PARSER.requiredFieldMissing',
514
+ messageParams: { prop: String(m.prop) }
515
+ }));
516
+ hasError = true;
517
+ }
518
+ try {
519
+ obj[m.prop] = m.converter ? m.converter(rawValue) : rawValue;
520
+ }
521
+ catch (err) {
522
+ logs.push(Object.assign(new ParseLog(), {
523
+ rowIndex: actualRowIndex,
524
+ message: `Tip dönüşüm hatası: ${String(m.prop)} -> ${rawValue}`,
525
+ level: 'ERROR',
526
+ messageKey: '@EXCEL_PARSER.conversionError',
527
+ messageParams: { prop: String(m.prop), value: rawValue }
528
+ }));
529
+ hasError = true;
530
+ }
531
+ });
532
+ if (!hasError) {
533
+ result.push(obj);
534
+ }
535
+ else {
536
+ logs.push(Object.assign(new ParseLog(), {
537
+ rowIndex: actualRowIndex,
538
+ message: `Satır atlandı`,
539
+ level: 'WARN',
540
+ messageKey: '@EXCEL_PARSER.rowSkipped'
541
+ }));
542
+ }
543
+ });
544
+ resolve({ data: result, logs });
545
+ }
546
+ catch (error) {
547
+ reject(error);
548
+ }
549
+ };
550
+ reader.onerror = () => reject(reader.error);
551
+ reader.readAsArrayBuffer(file);
552
+ });
553
+ }
554
+ async generateSampleExcel(options) {
555
+ const sampleCount = options?.sampleCount ?? 5;
556
+ const fileName = (options?.fileName ?? 'sample-import.xlsx').endsWith('.xlsx')
557
+ ? (options?.fileName ?? 'sample-import.xlsx')
558
+ : `${options?.fileName}.xlsx`;
559
+ const sheetName = (options?.sheetName ?? 'Sample').substring(0, 15);
560
+ const XLSX = await import('xlsx');
561
+ // Header row: property names according to column order
562
+ const headers = this.mappings.map(m => m.headerName || String(m.prop));
563
+ const rows = [];
564
+ for (let i = 1; i <= sampleCount; i++) {
565
+ const row = this.mappings.map(m => {
566
+ if (m.sampleValue !== undefined) {
567
+ // Use sampleValue if it exists
568
+ return typeof m.sampleValue === 'function'
569
+ ? m.sampleValue(i) // if it's a function, generate value based on index
570
+ : m.sampleValue; // if it's a constant value, use it directly
571
+ }
572
+ });
573
+ rows.push(row);
574
+ }
575
+ const worksheet = XLSX.utils.aoa_to_sheet([headers, ...rows]);
576
+ const workbook = XLSX.utils.book_new();
577
+ XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
578
+ XLSX.writeFile(workbook, fileName);
579
+ }
580
+ }
581
+
582
+ class ButtonRenderer {
583
+ params = null;
584
+ label = '';
585
+ type = '';
586
+ toggleValue = null;
587
+ editValid = false;
588
+ historyValid = false;
589
+ lineValid = false;
590
+ popupSelectValid = false;
591
+ popupEditValid = false;
592
+ toggleValid = false;
593
+ toggle_icon = '';
594
+ none = false;
595
+ addValid = false;
596
+ deleteValid = false;
597
+ agInit(params) {
598
+ this.params = params;
599
+ this.type = this.params.type || null;
600
+ this.label = this.params.label || null;
601
+ this.toggleValue = this.params.value || null;
602
+ switch (this.toggleValue) {
603
+ case true:
604
+ this.toggle_icon = 'select_check_box';
605
+ break;
606
+ case false:
607
+ this.toggle_icon = 'check_box_outline_blank';
608
+ break;
609
+ default:
610
+ this.toggle_icon = '';
611
+ break;
612
+ }
613
+ this.resetValids();
614
+ switch (this.type.toLowerCase().trim()) {
615
+ case 'edit':
616
+ this.editValid = true;
617
+ break;
618
+ case 'log':
619
+ this.historyValid = true;
620
+ break;
621
+ case 'line':
622
+ this.lineValid = true;
623
+ break;
624
+ case 'popupselect':
625
+ this.popupSelectValid = true;
626
+ break;
627
+ case 'toggle':
628
+ this.toggleValid = true;
629
+ break;
630
+ case 'none':
631
+ this.none = true;
632
+ break;
633
+ case 'add':
634
+ this.addValid = true;
635
+ break;
636
+ case 'delete':
637
+ this.deleteValid = true;
638
+ break;
639
+ default:
640
+ this.popupEditValid = true;
641
+ break;
642
+ }
643
+ }
644
+ /** Refresh the display
645
+ *
646
+ * @param params
647
+ * @returns
648
+ */
649
+ refresh(params) {
650
+ return false;
651
+ }
652
+ resetValids() {
653
+ this.editValid = false;
654
+ this.historyValid = false;
655
+ this.lineValid = false;
656
+ this.popupSelectValid = false;
657
+ this.popupEditValid = false;
658
+ this.toggleValid = false;
659
+ }
660
+ onClick(event) {
661
+ if (this.params.onClick instanceof Function) {
662
+ // put anything into params u want pass into parents component
663
+ const params = {
664
+ event: event,
665
+ rowData: this.params.node.data,
666
+ type: this.type,
667
+ // ...something
668
+ };
669
+ this.params.onClick(params);
670
+ }
671
+ }
672
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ButtonRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
673
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: ButtonRenderer, isStandalone: true, selector: "ntybase-button-renderer", host: { attributes: { "ntybase-id": "ButtonRenderer" } }, ngImport: i0, template: "@if (editValid || popupEditValid) {\n<mat-icon\n class=\"cursor center edit\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"4000\"\n >edit</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center-log\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >log</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >history</mat-icon\n>\n} @if (lineValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (popupSelectValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >content_copy</mat-icon\n>\n} @if (toggleValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >{{toggleValue ? 'check_box' : 'check_box_outline_blank'}}</mat-icon\n>\n} @if (none) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (addValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >playlist_add</mat-icon\n>\n} @if (deleteValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >delete_outline</mat-icon\n>\n}\n", styles: [".cursor{cursor:pointer}.center{display:flex;justify-content:center;align-items:center;width:100%}.center-log{display:flex;justify-content:center;align-items:center;margin-bottom:-12px}.edit{margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }] });
674
+ }
675
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ButtonRenderer, decorators: [{
676
+ type: Component,
677
+ args: [{ selector: 'ntybase-button-renderer', imports: [MatIconModule, MatTooltipModule, MatMenuModule], host: { 'ntybase-id': 'ButtonRenderer' }, template: "@if (editValid || popupEditValid) {\n<mat-icon\n class=\"cursor center edit\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"4000\"\n >edit</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center-log\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >log</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >history</mat-icon\n>\n} @if (lineValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (popupSelectValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >content_copy</mat-icon\n>\n} @if (toggleValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >{{toggleValue ? 'check_box' : 'check_box_outline_blank'}}</mat-icon\n>\n} @if (none) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (addValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >playlist_add</mat-icon\n>\n} @if (deleteValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >delete_outline</mat-icon\n>\n}\n", styles: [".cursor{cursor:pointer}.center{display:flex;justify-content:center;align-items:center;width:100%}.center-log{display:flex;justify-content:center;align-items:center;margin-bottom:-12px}.edit{margin-top:8px}\n"] }]
678
+ }] });
679
+
680
+ class CheckboxRenderer {
681
+ params = null;
682
+ label = '';
683
+ type = '';
684
+ supportClick = false;
685
+ checked = null;
686
+ agInit(params) {
687
+ this.onProcess(params);
688
+ }
689
+ refresh(params) {
690
+ if (params != null) {
691
+ this.onProcess(params);
692
+ }
693
+ return true;
694
+ }
695
+ onProcess(params) {
696
+ this.params = params;
697
+ this.checked = this.params.value ?? false;
698
+ this.type = this.params.type || null;
699
+ this.label = this.params.label || null;
700
+ if (this.type != null) {
701
+ if (this.type.toLowerCase().trim() == 'click') {
702
+ this.supportClick = true;
703
+ }
704
+ }
705
+ }
706
+ onClick(event) {
707
+ this.checked = !this.checked;
708
+ if (this.params.onClick instanceof Function) {
709
+ // put anything into params u want pass into parents component
710
+ const params = {
711
+ event: event,
712
+ rowData: this.params.node.data,
713
+ type: this.type,
714
+ checked: this.checked,
715
+ // ...something
716
+ };
717
+ this.params.onClick(params);
718
+ }
719
+ }
720
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
721
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CheckboxRenderer, isStandalone: true, selector: "ntybase-checkbox-renderer", host: { attributes: { "ntybase-id": "CheckboxRenderer" } }, ngImport: i0, template: "@if (supportClick) {\n<input\n id=\"checkbox\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onClick($event)\"\n/>\n} @if (!supportClick) {\n<input id=\"checkbox\" type=\"checkbox\" [checked]=\"params.value\" disabled />\n}\n\n<label for=\"checkbox\">{{label}}</label>\n", styles: [""] });
722
+ }
723
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxRenderer, decorators: [{
724
+ type: Component,
725
+ args: [{ selector: 'ntybase-checkbox-renderer', imports: [], host: { 'ntybase-id': 'CheckboxRenderer' }, template: "@if (supportClick) {\n<input\n id=\"checkbox\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onClick($event)\"\n/>\n} @if (!supportClick) {\n<input id=\"checkbox\" type=\"checkbox\" [checked]=\"params.value\" disabled />\n}\n\n<label for=\"checkbox\">{{label}}</label>\n" }]
726
+ }] });
727
+
728
+ class NettyHelper {
729
+ /**
730
+ * Returns null if fields are equal otherwise return second field
731
+ * @param firstField
732
+ * @param secondField
733
+ * @returns
734
+ */
735
+ static difference(firstField, secondField) {
736
+ if (firstField != secondField) {
737
+ return secondField;
738
+ }
739
+ return null;
740
+ }
741
+ /**
742
+ * Returns null if fields are equal otherwise return second field
743
+ * @param firstField
744
+ * @param secondField
745
+ * @param format
746
+ * @returns
747
+ */
748
+ static dateDifference(firstField, secondField, format) {
749
+ let culture = localStorage.getItem('languageApiCode') ?? 'tr-TR';
750
+ let datePipe = new DatePipe(culture);
751
+ if (datePipe.transform(firstField, format) !=
752
+ datePipe.transform(secondField, format)) {
624
753
  return secondField;
625
754
  }
626
755
  return null;
@@ -1280,12 +1409,12 @@ class SysfunctionProxy {
1280
1409
  securityDto.formCode = formCode;
1281
1410
  securityDto.application = this.environmentProxy.getApplicationName();
1282
1411
  let call$ = this.http.post(sysFunctionsURL, securityDto);
1283
- return call$.pipe(map((result) => result), catchError$1((error) => {
1412
+ return call$.pipe(map((result) => result), catchError((error) => {
1284
1413
  let errorMessage = error.message; //.error.title;
1285
1414
  return throwError(() => new Error(errorMessage ?? ''));
1286
1415
  }));
1287
1416
  }
1288
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SysfunctionProxy, deps: [{ token: i1$3.HttpClient }, { token: i2$1.EnvironmentProxy }], target: i0.ɵɵFactoryTarget.Injectable });
1417
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SysfunctionProxy, deps: [{ token: i1$3.HttpClient }, { token: i2$2.EnvironmentProxy }], target: i0.ɵɵFactoryTarget.Injectable });
1289
1418
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SysfunctionProxy, providedIn: 'root' });
1290
1419
  }
1291
1420
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SysfunctionProxy, decorators: [{
@@ -1293,7 +1422,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
1293
1422
  args: [{
1294
1423
  providedIn: 'root',
1295
1424
  }]
1296
- }], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: i2$1.EnvironmentProxy }] });
1425
+ }], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: i2$2.EnvironmentProxy }] });
1297
1426
 
1298
1427
  class NettyAgGridBase extends NettyAppsBase {
1299
1428
  FILTER_MODE_KEY = 'nettyapps_filter_mode';
@@ -1681,81 +1810,327 @@ class NettyAgGridBase extends NettyAppsBase {
1681
1810
  });
1682
1811
  updateRowSelection({ mode: 'multiRow', checkboxes: true, headerCheckbox: true });
1683
1812
  }
1684
- if (this._isPopupValid() == true) {
1685
- this.columnDefs().pop();
1686
- this.columnDefs().shift();
1687
- if (this._isPopupFilterValid() == true) {
1688
- if (this.allowEdit()) {
1689
- this.columnDefs().unshift({
1690
- headerName: '', sortable: false, resizable: false, filter: false,
1691
- minWidth: 50, maxWidth: 50, suppressSizeToFit: true, cellRenderer: 'buttonRenderer',
1692
- cellRendererParams: {
1693
- onClick: this.onBtnClick?.bind(this),
1694
- label: this.translateService.instant('@Update'),
1695
- type: 'popupEdit',
1696
- },
1697
- });
1698
- updateRowSelection({ mode: 'multiRow', checkboxes: true });
1813
+ if (this._isPopupValid() == true) {
1814
+ this.columnDefs().pop();
1815
+ this.columnDefs().shift();
1816
+ if (this._isPopupFilterValid() == true) {
1817
+ if (this.allowEdit()) {
1818
+ this.columnDefs().unshift({
1819
+ headerName: '', sortable: false, resizable: false, filter: false,
1820
+ minWidth: 50, maxWidth: 50, suppressSizeToFit: true, cellRenderer: 'buttonRenderer',
1821
+ cellRendererParams: {
1822
+ onClick: this.onBtnClick?.bind(this),
1823
+ label: this.translateService.instant('@Update'),
1824
+ type: 'popupEdit',
1825
+ },
1826
+ });
1827
+ updateRowSelection({ mode: 'multiRow', checkboxes: true });
1828
+ }
1829
+ else {
1830
+ this.columnDefs().unshift({
1831
+ headerName: '', sortable: false, resizable: false, filter: false,
1832
+ minWidth: 50, maxWidth: 50, suppressSizeToFit: true, cellStyle: { 'padding-top': '5px' }
1833
+ });
1834
+ updateRowSelection({ mode: 'multiRow', checkboxes: true });
1835
+ }
1836
+ }
1837
+ else {
1838
+ if (this.allowEdit() == false) {
1839
+ this.columnDefs().unshift({
1840
+ headerName: '', sortable: false, resizable: false, filter: false, minWidth: 50,
1841
+ maxWidth: 50, suppressSizeToFit: true, cellRenderer: 'buttonRenderer',
1842
+ cellRendererParams: {
1843
+ onClick: this.onBtnClick?.bind(this),
1844
+ label: this.translateService.instant('@Update'),
1845
+ type: 'popupEdit',
1846
+ },
1847
+ });
1848
+ updateRowSelection({ mode: 'singleRow', checkboxes: true });
1849
+ }
1850
+ if (this.readOnly()) {
1851
+ this.columnDefs().unshift({
1852
+ headerName: this.translateService.instant('@select'), sortable: false, resizable: false,
1853
+ filter: false, minWidth: 80, maxWidth: 80, suppressSizeToFit: true,
1854
+ cellRenderer: 'buttonRenderer', cellStyle: { 'margin-top': '8px' },
1855
+ cellRendererParams: {
1856
+ onClick: this.onBtnClick?.bind(this),
1857
+ label: this.translateService.instant('@select'),
1858
+ type: 'popupSelect',
1859
+ },
1860
+ });
1861
+ updateRowSelection({ mode: 'singleRow', checkboxes: false });
1862
+ }
1863
+ }
1864
+ }
1865
+ }
1866
+ // ---------------------------------------------
1867
+ // --- Functions to Show / Hide Grid Columns ---
1868
+ // ---------------------------------------------
1869
+ onShowHideColumns() {
1870
+ this.gridColumnsVisible.update((a) => !a);
1871
+ this.initAgGrid();
1872
+ }
1873
+ isHidden(isEmbeddedHide, isVisibleHide) {
1874
+ const isEmbedded = this._isEmbedded();
1875
+ const isVisibleSwitchOn = this.gridColumnsVisible();
1876
+ if (isVisibleHide && !isVisibleSwitchOn)
1877
+ return true;
1878
+ if (isEmbeddedHide && isEmbedded)
1879
+ return true;
1880
+ return false;
1881
+ }
1882
+ // *****************************************
1883
+ // *** Logging Functions ***
1884
+ // *****************************************
1885
+ logInputs(message) {
1886
+ if (!message || message.length < 1) {
1887
+ message = 'agGridBase - Inputs log';
1888
+ }
1889
+ const inputs = {
1890
+ "popupFilterValid": this.popupFilterValid(),
1891
+ "_isPopupFilterValid": this._isPopupFilterValid(),
1892
+ "popupValid": this.popupValid(),
1893
+ "_isPopupValid": this._isPopupValid(),
1894
+ "componantParameterGUID": this.componantParameterGUID(),
1895
+ "componantParameterType": this.componantParameterType(),
1896
+ "embedded": this.embedded(),
1897
+ "_isEmbedded": this._isEmbedded(),
1898
+ };
1899
+ console.log(message, inputs);
1900
+ }
1901
+ logAuthentication(message) {
1902
+ if (!message || message.length < 1) {
1903
+ message = 'agGridBase - Authentication log';
1904
+ }
1905
+ const inputs = {
1906
+ "authenticationList": this.authenticationList,
1907
+ "accessRightsProcessed": this.accessRightsProcessed(),
1908
+ "readOnly": this.readOnly(),
1909
+ "allowAdd": this.allowAdd(),
1910
+ "allowEdit": this.allowEdit(),
1911
+ "allowDelete": this.allowDelete(),
1912
+ "allowLog": this.allowLog(),
1913
+ "allowRead": this.allowRead(),
1914
+ };
1915
+ console.log(message, inputs);
1916
+ }
1917
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
1918
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: NettyAgGridBase, isStandalone: true, selector: "ntybase-ag-grid-base", inputs: { popupFilterValid: { classPropertyName: "popupFilterValid", publicName: "popupFilterValid", isSignal: true, isRequired: false, transformFunction: null }, popupValid: { classPropertyName: "popupValid", publicName: "popupValid", isSignal: true, isRequired: false, transformFunction: null }, componantParameterGUID: { classPropertyName: "componantParameterGUID", publicName: "componantParameterGUID", isSignal: true, isRequired: false, transformFunction: null }, componantParameterType: { classPropertyName: "componantParameterType", publicName: "componantParameterType", isSignal: true, isRequired: false, transformFunction: null }, agGridSelectionMode: { classPropertyName: "agGridSelectionMode", publicName: "agGridSelectionMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onElementSelect: "onElementSelect", selectedElement: "selectedElement" }, host: { attributes: { "ntybase-id": "NettyAgGridBase" } }, usesInheritance: true, ngImport: i0, template: ``, isInline: true });
1919
+ }
1920
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridBase, decorators: [{
1921
+ type: Component,
1922
+ args: [{ selector: 'ntybase-ag-grid-base', imports: [], template: ``, host: { 'ntybase-id': 'NettyAgGridBase' } }]
1923
+ }], ctorParameters: () => [], propDecorators: { popupFilterValid: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupFilterValid", required: false }] }], popupValid: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupValid", required: false }] }], componantParameterGUID: [{ type: i0.Input, args: [{ isSignal: true, alias: "componantParameterGUID", required: false }] }], componantParameterType: [{ type: i0.Input, args: [{ isSignal: true, alias: "componantParameterType", required: false }] }], onElementSelect: [{ type: i0.Output, args: ["onElementSelect"] }], selectedElement: [{ type: i0.Output, args: ["selectedElement"] }], agGridSelectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "agGridSelectionMode", required: false }] }] } });
1924
+
1925
+ ModuleRegistry.registerModules([AllCommunityModule, StatusBarModule, ClientSideRowModelModule, ClipboardModule, ExcelExportModule, ColumnMenuModule,
1926
+ ContextMenuModule, CellSelectionModule, HighlightChangesModule, RowSelectionModule, SetFilterModule, MultiFilterModule, TextFilterModule, NumberFilterModule, DateFilterModule]);
1927
+ class NettyAgGridListBase extends NettyAgGridBase {
1928
+ // ********************************************
1929
+ // *** INPUTS ***
1930
+ // ********************************************
1931
+ // Services
1932
+ router = inject(Router);
1933
+ dialog = inject(MatDialog);
1934
+ openInPopup = signal(false, ...(ngDevMode ? [{ debugName: "openInPopup" }] : [])); // true: Open add / edit component in popup
1935
+ // ---------------------------------------------------
1936
+ // --- RECORD LIST ---
1937
+ // ---------------------------------------------------
1938
+ nettyAppsProxy = injectNettyStandardProxy(this.componentName());
1939
+ /**
1940
+ * Component initialization lifecycle hook
1941
+ */
1942
+ async ngOnInit() {
1943
+ this.nettyAppsProxy.setURLPath(this.componentName());
1944
+ await this.setAccessRights(false);
1945
+ const savedSearchValue = sessionStorage.getItem(this.searchValueName());
1946
+ if (savedSearchValue) {
1947
+ this.searchValue.set(savedSearchValue);
1948
+ }
1949
+ this.loadData();
1950
+ // Load user grid preferences
1951
+ await this.nettyAgGridService.copyGridUserPereferenceToLocal(this.preferenceType());
1952
+ await this.AfterOnInit();
1953
+ }
1954
+ gotoURL(routePrefix, rightSidenav = [], parameters, type, dialogComponent = null, isNewTab = false, isPopup = this._isEmbedded()) {
1955
+ const baseHref = this.environment.getBaseHref().endsWith('/')
1956
+ ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
1957
+ : this.environment.getBaseHref();
1958
+ const navigationExtras = {
1959
+ queryParams: {
1960
+ parameters: JSON.stringify(parameters),
1961
+ ...(type && { type }),
1962
+ isNewTab: isNewTab || undefined,
1963
+ },
1964
+ queryParamsHandling: 'merge',
1965
+ };
1966
+ if (isNewTab) {
1967
+ const fullUrl = this.router
1968
+ .createUrlTree([baseHref, ...routePrefix, ...rightSidenav], navigationExtras)
1969
+ .toString();
1970
+ window.open(fullUrl, '_blank');
1971
+ return;
1972
+ }
1973
+ if (isPopup && dialogComponent) {
1974
+ this.dialog
1975
+ .open(dialogComponent, {
1976
+ data: {
1977
+ parameters: parameters,
1978
+ mode: type || 'edit',
1979
+ embedded: true,
1980
+ },
1981
+ maxWidth: '100vw',
1982
+ disableClose: true,
1983
+ hasBackdrop: false,
1984
+ })
1985
+ .afterClosed()
1986
+ .subscribe((result) => {
1987
+ if (result === 'saved') {
1988
+ this.updateRowInGrid;
1989
+ }
1990
+ });
1991
+ return;
1992
+ }
1993
+ // Log control
1994
+ if (rightSidenav.length == 0 || rightSidenav[0] === 'log') {
1995
+ this.router.navigate([baseHref, ...routePrefix, ...rightSidenav], navigationExtras);
1996
+ return;
1997
+ }
1998
+ // In all other cases, open the side menu
1999
+ this.router
2000
+ .navigate([
2001
+ {
2002
+ outlets: {
2003
+ primary: routePrefix,
2004
+ rightSidenav: [...routePrefix, ...rightSidenav],
2005
+ },
2006
+ },
2007
+ ], navigationExtras)
2008
+ .then(() => {
2009
+ // Ensure sidenav is opened after navigation
2010
+ this.commonService.toggleRightSidenav(true);
2011
+ });
2012
+ }
2013
+ popupGotoURL(urlSegments) {
2014
+ const baseHref = this.environment.getBaseHref().endsWith('/')
2015
+ ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
2016
+ : this.environment.getBaseHref();
2017
+ this.router.navigate([
2018
+ {
2019
+ outlets: {
2020
+ primary: [baseHref, ...urlSegments],
2021
+ rightSidenav: null,
2022
+ },
2023
+ },
2024
+ ]);
2025
+ }
2026
+ toggleOpenMode() {
2027
+ this.openInPopup.update(a => !a);
2028
+ localStorage.setItem('openInPopup', JSON.stringify(this.openInPopup()));
2029
+ const message = this.openInPopup() ? '@openInPopup' : '@openInSidenav';
2030
+ this.alertService.showSuccess(message);
2031
+ }
2032
+ /**
2033
+ * Listens for update events from CommonService and refreshes the grid accordingly.
2034
+ * - For 'add' or 'update' actions: Updates the relevant row
2035
+ * - For 'delete' action: Removes the row
2036
+ * - Performs no action if:
2037
+ * - Grid API is not ready, or
2038
+ * - The update type doesn't match
2039
+ */
2040
+ constructor() {
2041
+ super();
2042
+ this.frameworkComponents = {
2043
+ buttonRenderer: ButtonRenderer,
2044
+ checkboxRenderer: CheckboxRenderer,
2045
+ };
2046
+ const savedMode = localStorage.getItem('openInPopup');
2047
+ if (savedMode !== null) {
2048
+ this.openInPopup.set(JSON.parse(savedMode) === true);
2049
+ }
2050
+ this.translateService.onLangChange.subscribe(() => {
2051
+ this.setAgGridTranslations();
2052
+ });
2053
+ effect(() => {
2054
+ const update = this.commonService.updates();
2055
+ if (!update || !this.gridApi)
2056
+ return;
2057
+ if (update.type === this.getEntityType?.()) {
2058
+ switch (update.action) {
2059
+ case 'add':
2060
+ case 'update':
2061
+ this.updateRowInGrid(update.data, this.pkFieldName());
2062
+ break;
1699
2063
  }
1700
- else {
1701
- this.columnDefs().unshift({
1702
- headerName: '', sortable: false, resizable: false, filter: false,
1703
- minWidth: 50, maxWidth: 50, suppressSizeToFit: true, cellStyle: { 'padding-top': '5px' }
1704
- });
1705
- updateRowSelection({ mode: 'multiRow', checkboxes: true });
2064
+ }
2065
+ });
2066
+ effect(() => { this.onElementSelect.emit(this.selectedRows()); });
2067
+ // Manage filter expanded state
2068
+ effect(() => {
2069
+ this._isEmbedded();
2070
+ this.initAgGrid();
2071
+ });
2072
+ effect(() => {
2073
+ const isEmbedded = this._isEmbedded();
2074
+ const currentPref = this.preferenceType();
2075
+ const currentSearch = this.searchValueName();
2076
+ if (isEmbedded) {
2077
+ if (currentPref && !currentPref.endsWith('_isEmbedded')) {
2078
+ this.preferenceType.set(`${currentPref}_isEmbedded`);
2079
+ }
2080
+ if (currentSearch && !currentSearch.endsWith('_isEmbedded')) {
2081
+ this.searchValueName.set(`${currentSearch}_isEmbedded`);
1706
2082
  }
1707
2083
  }
1708
2084
  else {
1709
- if (this.allowEdit() == false) {
1710
- this.columnDefs().unshift({
1711
- headerName: '', sortable: false, resizable: false, filter: false, minWidth: 50,
1712
- maxWidth: 50, suppressSizeToFit: true, cellRenderer: 'buttonRenderer',
1713
- cellRendererParams: {
1714
- onClick: this.onBtnClick?.bind(this),
1715
- label: this.translateService.instant('@Update'),
1716
- type: 'popupEdit',
1717
- },
1718
- });
1719
- updateRowSelection({ mode: 'singleRow', checkboxes: true });
2085
+ if (currentPref?.endsWith('_isEmbedded')) {
2086
+ this.preferenceType.set(currentPref.replace('_isEmbedded', ''));
1720
2087
  }
1721
- if (this.readOnly()) {
1722
- this.columnDefs().unshift({
1723
- headerName: this.translateService.instant('@select'), sortable: false, resizable: false,
1724
- filter: false, minWidth: 80, maxWidth: 80, suppressSizeToFit: true,
1725
- cellRenderer: 'buttonRenderer', cellStyle: { 'margin-top': '8px' },
1726
- cellRendererParams: {
1727
- onClick: this.onBtnClick?.bind(this),
1728
- label: this.translateService.instant('@select'),
1729
- type: 'popupSelect',
1730
- },
1731
- });
1732
- updateRowSelection({ mode: 'singleRow', checkboxes: false });
2088
+ if (currentSearch?.endsWith('_isEmbedded')) {
2089
+ this.searchValueName.set(currentSearch.replace('_isEmbedded', ''));
1733
2090
  }
1734
2091
  }
1735
- }
2092
+ });
1736
2093
  }
1737
- // ---------------------------------------------
1738
- // --- Functions to Show / Hide Grid Columns ---
1739
- // ---------------------------------------------
1740
- onShowHideColumns() {
1741
- this.gridColumnsVisible.update((a) => !a);
1742
- this.initAgGrid();
2094
+ // *********************************************************
2095
+ // *** Data Management Functions ***
2096
+ // *********************************************************
2097
+ loadData() {
2098
+ this.nettyAppsProxy.select(this.record).subscribe({
2099
+ next: (data) => {
2100
+ this.setData(data, false);
2101
+ },
2102
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
2103
+ });
1743
2104
  }
1744
- isHidden(isEmbeddedHide, isVisibleHide) {
1745
- const isEmbedded = this._isEmbedded();
1746
- const isVisibleSwitchOn = this.gridColumnsVisible();
1747
- if (isVisibleHide && !isVisibleSwitchOn)
1748
- return true;
1749
- if (isEmbeddedHide && isEmbedded)
1750
- return true;
1751
- return false;
2105
+ async deleteSelected() {
2106
+ if (!this.gridApi)
2107
+ return;
2108
+ const selectedNodes = this.gridApi.getSelectedNodes();
2109
+ if (selectedNodes.length === 0) {
2110
+ await this.alertService.showAlert('@pleaseSelectRowToDelete');
2111
+ return;
2112
+ }
2113
+ const confirmed = await this.alertService.showConfirm('@confirmDeleteSelectedRecords');
2114
+ if (confirmed) {
2115
+ const selectedRows = selectedNodes.map((node) => node.data);
2116
+ this.deleteRows(selectedRows);
2117
+ }
2118
+ }
2119
+ deleteRows(rows) {
2120
+ this.nettyAppsProxy.deleteList(rows).subscribe({
2121
+ next: () => {
2122
+ this.gridApi.applyTransaction({ remove: rows });
2123
+ this.alertService.showSuccess('@recordDeletedSuccessfully');
2124
+ },
2125
+ error: (err) => this.alertService.showError(err),
2126
+ });
1752
2127
  }
1753
2128
  // *****************************************
1754
2129
  // *** Logging Functions ***
1755
2130
  // *****************************************
1756
2131
  logInputs(message) {
1757
2132
  if (!message || message.length < 1) {
1758
- message = 'agGridBase - Inputs log';
2133
+ message = 'AgGridListBase - Inputs log';
1759
2134
  }
1760
2135
  const inputs = {
1761
2136
  "popupFilterValid": this.popupFilterValid(),
@@ -1769,405 +2144,340 @@ class NettyAgGridBase extends NettyAppsBase {
1769
2144
  };
1770
2145
  console.log(message, inputs);
1771
2146
  }
1772
- logAuthentication(message) {
1773
- if (!message || message.length < 1) {
1774
- message = 'agGridBase - Authentication log';
1775
- }
1776
- const inputs = {
1777
- "authenticationList": this.authenticationList,
1778
- "accessRightsProcessed": this.accessRightsProcessed(),
1779
- "readOnly": this.readOnly(),
1780
- "allowAdd": this.allowAdd(),
1781
- "allowEdit": this.allowEdit(),
1782
- "allowDelete": this.allowDelete(),
1783
- "allowLog": this.allowLog(),
1784
- "allowRead": this.allowRead(),
1785
- };
1786
- console.log(message, inputs);
1787
- }
1788
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
1789
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: NettyAgGridBase, isStandalone: true, selector: "ntybase-ag-grid-base", inputs: { popupFilterValid: { classPropertyName: "popupFilterValid", publicName: "popupFilterValid", isSignal: true, isRequired: false, transformFunction: null }, popupValid: { classPropertyName: "popupValid", publicName: "popupValid", isSignal: true, isRequired: false, transformFunction: null }, componantParameterGUID: { classPropertyName: "componantParameterGUID", publicName: "componantParameterGUID", isSignal: true, isRequired: false, transformFunction: null }, componantParameterType: { classPropertyName: "componantParameterType", publicName: "componantParameterType", isSignal: true, isRequired: false, transformFunction: null }, agGridSelectionMode: { classPropertyName: "agGridSelectionMode", publicName: "agGridSelectionMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onElementSelect: "onElementSelect", selectedElement: "selectedElement" }, host: { attributes: { "ntybase-id": "NettyAgGridBase" } }, usesInheritance: true, ngImport: i0, template: ``, isInline: true });
2147
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridListBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
2148
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: NettyAgGridListBase, isStandalone: true, selector: "ntybase-ag-grid-list-base", host: { attributes: { "ntybase-id": "NettyAgGridListBase" } }, usesInheritance: true, ngImport: i0, template: ``, isInline: true });
1790
2149
  }
1791
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridBase, decorators: [{
2150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridListBase, decorators: [{
1792
2151
  type: Component,
1793
- args: [{ selector: 'ntybase-ag-grid-base', imports: [], template: ``, host: { 'ntybase-id': 'NettyAgGridBase' } }]
1794
- }], ctorParameters: () => [], propDecorators: { popupFilterValid: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupFilterValid", required: false }] }], popupValid: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupValid", required: false }] }], componantParameterGUID: [{ type: i0.Input, args: [{ isSignal: true, alias: "componantParameterGUID", required: false }] }], componantParameterType: [{ type: i0.Input, args: [{ isSignal: true, alias: "componantParameterType", required: false }] }], onElementSelect: [{ type: i0.Output, args: ["onElementSelect"] }], selectedElement: [{ type: i0.Output, args: ["selectedElement"] }], agGridSelectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "agGridSelectionMode", required: false }] }] } });
2152
+ args: [{ selector: 'ntybase-ag-grid-list-base', imports: [], template: ``, host: { 'ntybase-id': 'NettyAgGridListBase' } }]
2153
+ }], ctorParameters: () => [] });
1795
2154
 
1796
- class ButtonRenderer {
1797
- params = null;
1798
- label = '';
1799
- type = '';
1800
- toggleValue = null;
1801
- editValid = false;
1802
- historyValid = false;
1803
- lineValid = false;
1804
- popupSelectValid = false;
1805
- popupEditValid = false;
1806
- toggleValid = false;
1807
- toggle_icon = '';
1808
- none = false;
1809
- addValid = false;
1810
- deleteValid = false;
1811
- agInit(params) {
1812
- this.params = params;
1813
- this.type = this.params.type || null;
1814
- this.label = this.params.label || null;
1815
- this.toggleValue = this.params.value || null;
1816
- switch (this.toggleValue) {
1817
- case true:
1818
- this.toggle_icon = 'select_check_box';
1819
- break;
1820
- case false:
1821
- this.toggle_icon = 'check_box_outline_blank';
1822
- break;
1823
- default:
1824
- this.toggle_icon = '';
1825
- break;
1826
- }
1827
- this.resetValids();
1828
- switch (this.type.toLowerCase().trim()) {
1829
- case 'edit':
1830
- this.editValid = true;
1831
- break;
1832
- case 'log':
1833
- this.historyValid = true;
1834
- break;
1835
- case 'line':
1836
- this.lineValid = true;
1837
- break;
1838
- case 'popupselect':
1839
- this.popupSelectValid = true;
1840
- break;
1841
- case 'toggle':
1842
- this.toggleValid = true;
1843
- break;
1844
- case 'none':
1845
- this.none = true;
1846
- break;
1847
- case 'add':
1848
- this.addValid = true;
1849
- break;
1850
- case 'delete':
1851
- this.deleteValid = true;
1852
- break;
1853
- default:
1854
- this.popupEditValid = true;
1855
- break;
1856
- }
1857
- }
1858
- /** Refresh the display
1859
- *
1860
- * @param params
1861
- * @returns
1862
- */
1863
- refresh(params) {
1864
- return false;
1865
- }
1866
- resetValids() {
1867
- this.editValid = false;
1868
- this.historyValid = false;
1869
- this.lineValid = false;
1870
- this.popupSelectValid = false;
1871
- this.popupEditValid = false;
1872
- this.toggleValid = false;
1873
- }
1874
- onClick(event) {
1875
- if (this.params.onClick instanceof Function) {
1876
- // put anything into params u want pass into parents component
1877
- const params = {
1878
- event: event,
1879
- rowData: this.params.node.data,
1880
- type: this.type,
1881
- // ...something
1882
- };
1883
- this.params.onClick(params);
2155
+ class ExcelImportBase extends NettyAgGridListBase {
2156
+ isFileSelectionHidden = signal(false, ...(ngDevMode ? [{ debugName: "isFileSelectionHidden" }] : []));
2157
+ isFileValid = signal(false, ...(ngDevMode ? [{ debugName: "isFileValid" }] : []));
2158
+ logs = signal([], ...(ngDevMode ? [{ debugName: "logs" }] : []));
2159
+ hasLogs = computed(() => this.logs().length > 0, ...(ngDevMode ? [{ debugName: "hasLogs" }] : []));
2160
+ logDialog = inject(MatDialog);
2161
+ parser = new ExcelParser([]);
2162
+ // override methods
2163
+ onBtnClick(e) { }
2164
+ loadData() { }
2165
+ // Methods
2166
+ onFilesSelected(evt) {
2167
+ const files = Array.isArray(evt) ? evt : evt.target.files;
2168
+ if (!files || files.length !== 1) {
2169
+ return;
2170
+ }
2171
+ const file = files[0];
2172
+ if (file) {
2173
+ this.recordList.set([]);
2174
+ this.logs.set([]);
2175
+ this.parser.parse(file).then(result => {
2176
+ this.recordList.set(result.data);
2177
+ this.logs.set(result.logs);
2178
+ this.isFileSelectionHidden.set(true);
2179
+ if (result.logs.length > 0)
2180
+ this.showLogs();
2181
+ });
1884
2182
  }
1885
2183
  }
1886
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ButtonRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
1887
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: ButtonRenderer, isStandalone: true, selector: "ntybase-button-renderer", host: { attributes: { "ntybase-id": "ButtonRenderer" } }, ngImport: i0, template: "@if (editValid || popupEditValid) {\n<mat-icon\n class=\"cursor center edit\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"4000\"\n >edit</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center-log\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >log</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >history</mat-icon\n>\n} @if (lineValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (popupSelectValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >content_copy</mat-icon\n>\n} @if (toggleValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >{{toggleValue ? 'check_box' : 'check_box_outline_blank'}}</mat-icon\n>\n} @if (none) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (addValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >playlist_add</mat-icon\n>\n} @if (deleteValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >delete_outline</mat-icon\n>\n}\n", styles: [".cursor{cursor:pointer}.center{display:flex;justify-content:center;align-items:center;width:100%}.center-log{display:flex;justify-content:center;align-items:center;margin-bottom:-12px}.edit{margin-top:8px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatMenuModule }] });
2184
+ downloadSampleExcel() {
2185
+ this.parser.generateSampleExcel();
2186
+ }
2187
+ showLogs() {
2188
+ const dialogRef = this.logDialog.open(ExcelLogViewer$1, {
2189
+ height: '70%',
2190
+ width: '90%',
2191
+ maxWidth: '100vw',
2192
+ maxHeight: '100vh'
2193
+ });
2194
+ dialogRef.componentInstance.setParseData(this.logs());
2195
+ dialogRef.componentInstance.selectedElement.subscribe((element) => {
2196
+ dialogRef.close();
2197
+ });
2198
+ }
2199
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelImportBase, deps: null, target: i0.ɵɵFactoryTarget.Component });
2200
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ExcelImportBase, isStandalone: true, selector: "ntybase-excel-import-base", usesInheritance: true, ngImport: i0, template: ``, isInline: true });
1888
2201
  }
1889
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ButtonRenderer, decorators: [{
2202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelImportBase, decorators: [{
1890
2203
  type: Component,
1891
- args: [{ selector: 'ntybase-button-renderer', imports: [MatIconModule, MatTooltipModule, MatMenuModule], host: { 'ntybase-id': 'ButtonRenderer' }, template: "@if (editValid || popupEditValid) {\n<mat-icon\n class=\"cursor center edit\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"4000\"\n >edit</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center-log\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >log</mat-icon\n>\n} @if (historyValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >history</mat-icon\n>\n} @if (lineValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (popupSelectValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >content_copy</mat-icon\n>\n} @if (toggleValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >{{toggleValue ? 'check_box' : 'check_box_outline_blank'}}</mat-icon\n>\n} @if (none) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n [matTooltipShowDelay]=\"3000\"\n >menu_open</mat-icon\n>\n} @if (addValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >playlist_add</mat-icon\n>\n} @if (deleteValid) {\n<mat-icon\n class=\"cursor center\"\n matTooltip=\"{{label}}\"\n (click)=\"onClick($event)\"\n [matTooltipShowDelay]=\"3000\"\n >delete_outline</mat-icon\n>\n}\n", styles: [".cursor{cursor:pointer}.center{display:flex;justify-content:center;align-items:center;width:100%}.center-log{display:flex;justify-content:center;align-items:center;margin-bottom:-12px}.edit{margin-top:8px}\n"] }]
2204
+ args: [{ selector: 'ntybase-excel-import-base', imports: [], template: `` }]
1892
2205
  }] });
1893
2206
 
1894
- class CheckboxRenderer {
1895
- params = null;
1896
- label = '';
1897
- type = '';
1898
- supportClick = false;
1899
- checked = null;
1900
- agInit(params) {
1901
- this.onProcess(params);
1902
- }
1903
- refresh(params) {
1904
- if (params != null) {
1905
- this.onProcess(params);
1906
- }
1907
- return true;
1908
- }
1909
- onProcess(params) {
1910
- this.params = params;
1911
- this.checked = this.params.value ?? false;
1912
- this.type = this.params.type || null;
1913
- this.label = this.params.label || null;
1914
- if (this.type != null) {
1915
- if (this.type.toLowerCase().trim() == 'click') {
1916
- this.supportClick = true;
1917
- }
1918
- }
1919
- }
1920
- onClick(event) {
1921
- this.checked = !this.checked;
1922
- if (this.params.onClick instanceof Function) {
1923
- // put anything into params u want pass into parents component
1924
- const params = {
1925
- event: event,
1926
- rowData: this.params.node.data,
1927
- type: this.type,
1928
- checked: this.checked,
1929
- // ...something
1930
- };
1931
- this.params.onClick(params);
1932
- }
1933
- }
1934
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
1935
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CheckboxRenderer, isStandalone: true, selector: "ntybase-checkbox-renderer", host: { attributes: { "ntybase-id": "CheckboxRenderer" } }, ngImport: i0, template: "@if (supportClick) {\n<input\n id=\"checkbox\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onClick($event)\"\n/>\n} @if (!supportClick) {\n<input id=\"checkbox\" type=\"checkbox\" [checked]=\"params.value\" disabled />\n}\n\n<label for=\"checkbox\">{{label}}</label>\n", styles: [""] });
2207
+ class Ntybase {
2208
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Ntybase, deps: [], target: i0.ɵɵFactoryTarget.Component });
2209
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: Ntybase, isStandalone: false, selector: "lib-ntybase", ngImport: i0, template: `
2210
+ <p>
2211
+ ntybase works!
2212
+ </p>
2213
+ `, isInline: true, styles: [""] });
1936
2214
  }
1937
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxRenderer, decorators: [{
2215
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Ntybase, decorators: [{
1938
2216
  type: Component,
1939
- args: [{ selector: 'ntybase-checkbox-renderer', imports: [], host: { 'ntybase-id': 'CheckboxRenderer' }, template: "@if (supportClick) {\n<input\n id=\"checkbox\"\n type=\"checkbox\"\n [checked]=\"checked\"\n (click)=\"onClick($event)\"\n/>\n} @if (!supportClick) {\n<input id=\"checkbox\" type=\"checkbox\" [checked]=\"params.value\" disabled />\n}\n\n<label for=\"checkbox\">{{label}}</label>\n" }]
2217
+ args: [{ selector: 'lib-ntybase', standalone: false, template: `
2218
+ <p>
2219
+ ntybase works!
2220
+ </p>
2221
+ ` }]
1940
2222
  }] });
1941
2223
 
1942
- ModuleRegistry.registerModules([AllCommunityModule, StatusBarModule, ClientSideRowModelModule, ClipboardModule, ExcelExportModule, ColumnMenuModule,
1943
- ContextMenuModule, CellSelectionModule, HighlightChangesModule, RowSelectionModule, SetFilterModule, MultiFilterModule, TextFilterModule, NumberFilterModule, DateFilterModule]);
1944
- class NettyAgGridListBase extends NettyAgGridBase {
1945
- // ********************************************
1946
- // *** INPUTS ***
1947
- // ********************************************
1948
- // Services
1949
- router = inject(Router);
1950
- dialog = inject(MatDialog);
1951
- openInPopup = signal(false, ...(ngDevMode ? [{ debugName: "openInPopup" }] : [])); // true: Open add / edit component in popup
1952
- // ---------------------------------------------------
1953
- // --- RECORD LIST ---
1954
- // ---------------------------------------------------
1955
- nettyAppsProxy = injectNettyStandardProxy(this.componentName());
2224
+ const credentialsKey = 'credentials';
2225
+ class CredentialsService {
2226
+ _credentials = null;
2227
+ constructor() {
2228
+ const savedCredentials = sessionStorage.getItem(credentialsKey) ||
2229
+ localStorage.getItem(credentialsKey);
2230
+ if (savedCredentials) {
2231
+ this._credentials = JSON.parse(savedCredentials);
2232
+ }
2233
+ }
1956
2234
  /**
1957
- * Component initialization lifecycle hook
2235
+ * Checks is the user is authenticated.
2236
+ * @return True if the user is authenticated.
1958
2237
  */
1959
- async ngOnInit() {
1960
- this.nettyAppsProxy.setURLPath(this.componentName());
1961
- await this.setAccessRights(false);
1962
- const savedSearchValue = sessionStorage.getItem(this.searchValueName());
1963
- if (savedSearchValue) {
1964
- this.searchValue.set(savedSearchValue);
2238
+ isAuthenticated() {
2239
+ return !!this.credentials;
2240
+ }
2241
+ /**
2242
+ * Gets the user credentials.
2243
+ * @return The user credentials or null if the user is not authenticated.
2244
+ */
2245
+ get credentials() {
2246
+ return this._credentials;
2247
+ }
2248
+ get token() {
2249
+ return this._credentials?.token ?? null;
2250
+ }
2251
+ /**
2252
+ * Sets the user credentials.
2253
+ * The credentials may be persisted across sessions by setting the `remember` parameter to true.
2254
+ * Otherwise, the credentials are only persisted for the current session.
2255
+ * @param credentials The user credentials.
2256
+ * @param remember True to remember credentials across sessions.
2257
+ */
2258
+ setCredentials(credentials, remember) {
2259
+ this._credentials = credentials || null;
2260
+ if (credentials) {
2261
+ const storage = remember ? localStorage : sessionStorage;
2262
+ storage.setItem(credentialsKey, JSON.stringify(credentials));
2263
+ }
2264
+ else {
2265
+ sessionStorage.removeItem(credentialsKey);
2266
+ localStorage.removeItem(credentialsKey);
1965
2267
  }
1966
- this.loadData();
1967
- // Load user grid preferences
1968
- await this.nettyAgGridService.copyGridUserPereferenceToLocal(this.preferenceType());
1969
- await this.AfterOnInit();
1970
2268
  }
1971
- gotoURL(routePrefix, rightSidenav = [], parameters, type, dialogComponent = null, isNewTab = false, isPopup = this._isEmbedded()) {
1972
- const baseHref = this.environment.getBaseHref().endsWith('/')
1973
- ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
1974
- : this.environment.getBaseHref();
1975
- const navigationExtras = {
1976
- queryParams: {
1977
- parameters: JSON.stringify(parameters),
1978
- ...(type && { type }),
1979
- isNewTab: isNewTab || undefined,
1980
- },
1981
- queryParamsHandling: 'merge',
1982
- };
1983
- if (isNewTab) {
1984
- const fullUrl = this.router
1985
- .createUrlTree([baseHref, ...routePrefix, ...rightSidenav], navigationExtras)
1986
- .toString();
1987
- window.open(fullUrl, '_blank');
1988
- return;
2269
+ /** Get Credentials
2270
+ *
2271
+ * @returns
2272
+ */
2273
+ getCredentials() {
2274
+ let _credentialsString = sessionStorage.getItem(credentialsKey);
2275
+ if (_credentialsString == null || _credentialsString == '') {
2276
+ _credentialsString = localStorage.getItem(credentialsKey);
1989
2277
  }
1990
- if (isPopup && dialogComponent) {
1991
- this.dialog
1992
- .open(dialogComponent, {
1993
- data: {
1994
- parameters: parameters,
1995
- mode: type || 'edit',
1996
- embedded: true,
1997
- },
1998
- maxWidth: '100vw',
1999
- disableClose: true,
2000
- hasBackdrop: false,
2001
- })
2002
- .afterClosed()
2003
- .subscribe((result) => {
2004
- if (result === 'saved') {
2005
- this.updateRowInGrid;
2006
- }
2007
- });
2008
- return;
2278
+ return JSON.parse(_credentialsString ?? '');
2279
+ }
2280
+ /** Get the token if available otherwise return empty string
2281
+ *
2282
+ * @returns
2283
+ */
2284
+ getToken() {
2285
+ try {
2286
+ let _credentials = this.getCredentials();
2287
+ return _credentials.token;
2009
2288
  }
2010
- // Log control
2011
- if (rightSidenav.length == 0 || rightSidenav[0] === 'log') {
2012
- this.router.navigate([baseHref, ...routePrefix, ...rightSidenav], navigationExtras);
2013
- return;
2289
+ catch (error) {
2290
+ return '';
2291
+ }
2292
+ }
2293
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2294
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, providedIn: 'root' });
2295
+ }
2296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, decorators: [{
2297
+ type: Injectable,
2298
+ args: [{
2299
+ providedIn: 'root',
2300
+ }]
2301
+ }], ctorParameters: () => [] });
2302
+
2303
+ class UrlHelperService {
2304
+ router = inject(Router);
2305
+ cleanUrl(url) {
2306
+ let result = url
2307
+ .replace('/mfalogin?redirect=', '')
2308
+ .replace('/mfalogin?redirect=', '')
2309
+ .replace('/mfalogin?redirect=', '')
2310
+ .replace('/login?redirect=', '')
2311
+ .replace('/login?redirect=', '')
2312
+ .replace('/login?redirect=', '')
2313
+ .replace(new RegExp('%25', 'g'), '%')
2314
+ .replace(new RegExp('%25', 'g'), '%')
2315
+ .replace(new RegExp('%25', 'g'), '%')
2316
+ .replace(new RegExp('%25', 'g'), '%')
2317
+ .replace(new RegExp('%25', 'g'), '%')
2318
+ .replace(new RegExp('%25', 'g'), '%')
2319
+ .replace(new RegExp('%22', 'g'), '"')
2320
+ .replace(new RegExp('%3F', 'g'), '?')
2321
+ .replace(new RegExp('%3D', 'g'), '=')
2322
+ .replace(new RegExp('%2F', 'g'), '/')
2323
+ .replace(new RegExp('%26', 'g'), '&')
2324
+ .replace(new RegExp('/mfalogin?redirect=', 'g'), '')
2325
+ .replace(new RegExp('/login?redirect=', 'g'), '');
2326
+ console.log('url:', url);
2327
+ console.log('result:', result);
2328
+ // return url;
2329
+ return result;
2330
+ }
2331
+ navigate(url) {
2332
+ let urlParts = url.split('?');
2333
+ if (urlParts.length == 1) {
2334
+ return this.router.navigate(urlParts, { replaceUrl: true });
2014
2335
  }
2015
- // In all other cases, open the side menu
2016
- this.router
2017
- .navigate([
2018
- {
2019
- outlets: {
2020
- primary: routePrefix,
2021
- rightSidenav: [...routePrefix, ...rightSidenav],
2022
- },
2336
+ let parameters = urlParts[1].split('&');
2337
+ return this.router.navigate([urlParts[0]], {
2338
+ queryParams: {
2339
+ parameters: parameters[0]?.replace('parameters=', '') ?? '',
2340
+ type: parameters[1]?.replace('type=', '') ?? '',
2023
2341
  },
2024
- ], navigationExtras)
2025
- .then(() => {
2026
- // Ensure sidenav is opened after navigation
2027
- this.commonService.toggleRightSidenav(true);
2342
+ replaceUrl: true,
2028
2343
  });
2029
2344
  }
2030
- popupGotoURL(urlSegments) {
2031
- const baseHref = this.environment.getBaseHref().endsWith('/')
2032
- ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
2033
- : this.environment.getBaseHref();
2034
- this.router.navigate([
2035
- {
2036
- outlets: {
2037
- primary: [baseHref, ...urlSegments],
2038
- rightSidenav: null,
2039
- },
2040
- },
2041
- ]);
2042
- }
2043
- toggleOpenMode() {
2044
- this.openInPopup.update(a => !a);
2045
- localStorage.setItem('openInPopup', JSON.stringify(this.openInPopup()));
2046
- const message = this.openInPopup() ? '@openInPopup' : '@openInSidenav';
2047
- this.alertService.showSuccess(message);
2048
- }
2049
- /**
2050
- * Listens for update events from CommonService and refreshes the grid accordingly.
2051
- * - For 'add' or 'update' actions: Updates the relevant row
2052
- * - For 'delete' action: Removes the row
2053
- * - Performs no action if:
2054
- * - Grid API is not ready, or
2055
- * - The update type doesn't match
2056
- */
2057
- constructor() {
2058
- super();
2059
- this.frameworkComponents = {
2060
- buttonRenderer: ButtonRenderer,
2061
- checkboxRenderer: CheckboxRenderer,
2062
- };
2063
- const savedMode = localStorage.getItem('openInPopup');
2064
- if (savedMode !== null) {
2065
- this.openInPopup.set(JSON.parse(savedMode) === true);
2066
- }
2067
- this.translateService.onLangChange.subscribe(() => {
2068
- this.setAgGridTranslations();
2069
- });
2070
- effect(() => {
2071
- const update = this.commonService.updates();
2072
- if (!update || !this.gridApi)
2073
- return;
2074
- if (update.type === this.getEntityType?.()) {
2075
- switch (update.action) {
2076
- case 'add':
2077
- case 'update':
2078
- this.updateRowInGrid(update.data, this.pkFieldName());
2079
- break;
2345
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2346
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, providedIn: 'root' });
2347
+ }
2348
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, decorators: [{
2349
+ type: Injectable,
2350
+ args: [{
2351
+ providedIn: 'root',
2352
+ }]
2353
+ }] });
2354
+
2355
+ class AuthenticationInterceptor {
2356
+ router = inject(Router);
2357
+ credentialsService = inject(CredentialsService);
2358
+ environmentProxy = inject(EnvironmentProxy);
2359
+ urlHelperService = inject(UrlHelperService);
2360
+ intercept(req, next) {
2361
+ if (req.headers.get('No-Auth') == 'True')
2362
+ return next.handle(req.clone());
2363
+ let token = this.credentialsService.token;
2364
+ if (token != null) {
2365
+ let appName = this.environmentProxy.getApplicationName();
2366
+ const clonedreq = req.clone({
2367
+ headers: req.headers.set('Authorization', 'Bearer ' + token),
2368
+ // .set("NettyAppName",appName)
2369
+ });
2370
+ return next.handle(clonedreq).pipe(catchError$1((error) => {
2371
+ if (error instanceof HttpErrorResponse && error.status === 401) {
2372
+ // Handle 401 error, e.g., navigate to the login page
2373
+ this.router.navigate(['/login'], {
2374
+ queryParams: {
2375
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2376
+ },
2377
+ replaceUrl: true,
2378
+ });
2379
+ // Return an observable with a successful response
2380
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2080
2381
  }
2081
- }
2082
- });
2083
- effect(() => { this.onElementSelect.emit(this.selectedRows()); });
2084
- // Manage filter expanded state
2085
- effect(() => {
2086
- this._isEmbedded();
2087
- this.initAgGrid();
2088
- });
2089
- effect(() => {
2090
- const isEmbedded = this._isEmbedded();
2091
- const currentPref = this.preferenceType();
2092
- const currentSearch = this.searchValueName();
2093
- if (isEmbedded) {
2094
- if (currentPref && !currentPref.endsWith('_isEmbedded')) {
2095
- this.preferenceType.set(`${currentPref}_isEmbedded`);
2382
+ if (error instanceof HttpErrorResponse && error.status === 403) {
2383
+ this.router.navigate(['/forbidden'], {
2384
+ state: { attemptedUrl: this.router.url }, // Orijinal URL'i state olarak geçme
2385
+ });
2386
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2096
2387
  }
2097
- if (currentSearch && !currentSearch.endsWith('_isEmbedded')) {
2098
- this.searchValueName.set(`${currentSearch}_isEmbedded`);
2388
+ if (error instanceof HttpErrorResponse && error.status === 428) {
2389
+ // Handle 428 error, e.g., navigate to the login page
2390
+ this.router.navigate(['/mfalogin'], {
2391
+ queryParams: {
2392
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2393
+ },
2394
+ replaceUrl: true,
2395
+ });
2396
+ // Return an observable with a successful response
2397
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2099
2398
  }
2100
- }
2101
- else {
2102
- if (currentPref?.endsWith('_isEmbedded')) {
2103
- this.preferenceType.set(currentPref.replace('_isEmbedded', ''));
2399
+ // For other errors, re-throw the error to propagate it further
2400
+ return throwError(() => error);
2401
+ }));
2402
+ }
2403
+ else {
2404
+ return next.handle(req.clone()).pipe(catchError$1((error) => {
2405
+ if (error instanceof HttpErrorResponse && error.status === 401) {
2406
+ // Handle 401 error, e.g., navigate to the login page
2407
+ this.router.navigate(['/login'], {
2408
+ queryParams: {
2409
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2410
+ },
2411
+ replaceUrl: true,
2412
+ });
2413
+ // Return an observable with a successful response
2414
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2104
2415
  }
2105
- if (currentSearch?.endsWith('_isEmbedded')) {
2106
- this.searchValueName.set(currentSearch.replace('_isEmbedded', ''));
2416
+ if (error instanceof HttpErrorResponse && error.status === 403) {
2417
+ this.router.navigate(['/forbidden'], {
2418
+ state: { attemptedUrl: this.router.url }, // Orijinal URL'i state olarak geçme
2419
+ });
2420
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2107
2421
  }
2108
- }
2109
- });
2110
- }
2111
- // *********************************************************
2112
- // *** Data Management Functions ***
2113
- // *********************************************************
2114
- loadData() {
2115
- this.nettyAppsProxy.select(this.record).subscribe({
2116
- next: (data) => {
2117
- this.setData(data, false);
2118
- },
2119
- error: (err) => this.alertService.showError('@dataLoadFailed', err),
2120
- });
2121
- }
2122
- async deleteSelected() {
2123
- if (!this.gridApi)
2124
- return;
2125
- const selectedNodes = this.gridApi.getSelectedNodes();
2126
- if (selectedNodes.length === 0) {
2127
- await this.alertService.showAlert('@pleaseSelectRowToDelete');
2128
- return;
2129
- }
2130
- const confirmed = await this.alertService.showConfirm('@confirmDeleteSelectedRecords');
2131
- if (confirmed) {
2132
- const selectedRows = selectedNodes.map((node) => node.data);
2133
- this.deleteRows(selectedRows);
2422
+ if (error instanceof HttpErrorResponse && error.status === 428) {
2423
+ // Handle 428 error, e.g., navigate to the login page
2424
+ this.router.navigate(['/mfalogin'], {
2425
+ queryParams: {
2426
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2427
+ },
2428
+ replaceUrl: true,
2429
+ });
2430
+ // Return an observable with a successful response
2431
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2432
+ }
2433
+ // For other errors, re-throw the error to propagate it further
2434
+ return throwError(() => error);
2435
+ }));
2134
2436
  }
2135
2437
  }
2136
- deleteRows(rows) {
2137
- this.nettyAppsProxy.deleteList(rows).subscribe({
2138
- next: () => {
2139
- this.gridApi.applyTransaction({ remove: rows });
2140
- this.alertService.showSuccess('@recordDeletedSuccessfully');
2141
- },
2142
- error: (err) => this.alertService.showError(err),
2143
- });
2144
- }
2145
- // *****************************************
2146
- // *** Logging Functions ***
2147
- // *****************************************
2148
- logInputs(message) {
2149
- if (!message || message.length < 1) {
2150
- message = 'AgGridListBase - Inputs log';
2151
- }
2152
- const inputs = {
2153
- "popupFilterValid": this.popupFilterValid(),
2154
- "_isPopupFilterValid": this._isPopupFilterValid(),
2155
- "popupValid": this.popupValid(),
2156
- "_isPopupValid": this._isPopupValid(),
2157
- "componantParameterGUID": this.componantParameterGUID(),
2158
- "componantParameterType": this.componantParameterType(),
2159
- "embedded": this.embedded(),
2160
- "_isEmbedded": this._isEmbedded(),
2161
- };
2162
- console.log(message, inputs);
2438
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2439
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor });
2440
+ }
2441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor, decorators: [{
2442
+ type: Injectable
2443
+ }] });
2444
+
2445
+ class CanDeactivateGuard {
2446
+ canDeactivate(component) {
2447
+ return component.canDeactivate ? component.canDeactivate() : true;
2163
2448
  }
2164
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridListBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
2165
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: NettyAgGridListBase, isStandalone: true, selector: "ntybase-ag-grid-list-base", host: { attributes: { "ntybase-id": "NettyAgGridListBase" } }, usesInheritance: true, ngImport: i0, template: ``, isInline: true });
2166
2449
  }
2167
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridListBase, decorators: [{
2168
- type: Component,
2169
- args: [{ selector: 'ntybase-ag-grid-list-base', imports: [], template: ``, host: { 'ntybase-id': 'NettyAgGridListBase' } }]
2170
- }], ctorParameters: () => [] });
2450
+
2451
+ class NtybaseModule {
2452
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2453
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, declarations: [Ntybase], exports: [Ntybase] });
2454
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, providers: [
2455
+ {
2456
+ provide: HTTP_INTERCEPTORS,
2457
+ useClass: AuthenticationInterceptor,
2458
+ multi: true,
2459
+ },
2460
+ [CanDeactivateGuard],
2461
+ DatePipe,
2462
+ ] });
2463
+ }
2464
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, decorators: [{
2465
+ type: NgModule,
2466
+ args: [{
2467
+ declarations: [Ntybase],
2468
+ imports: [],
2469
+ exports: [Ntybase],
2470
+ providers: [
2471
+ {
2472
+ provide: HTTP_INTERCEPTORS,
2473
+ useClass: AuthenticationInterceptor,
2474
+ multi: true,
2475
+ },
2476
+ [CanDeactivateGuard],
2477
+ DatePipe,
2478
+ ],
2479
+ }]
2480
+ }] });
2171
2481
 
2172
2482
  class Guid {
2173
2483
  value = this.empty;
@@ -2638,297 +2948,98 @@ class NettyAgGridSaveBase extends NettyAppsBase {
2638
2948
  if (this.viewMode() === 'sidenav') {
2639
2949
  this.commonService.toggleRightSidenav(true);
2640
2950
  }
2641
- },
2642
- error: (err) => {
2643
- this.alertService.showError('@dataLoadFailed');
2644
- this.commonService.toggleRightSidenav(false);
2645
- // Redirect to user list on error in fullscreen mode
2646
- if (this.viewMode() === 'fullscreen') {
2647
- const cleanPath = this.commonService.getCleanUrlPath();
2648
- this.router.navigate([cleanPath]);
2649
- }
2650
- },
2651
- });
2652
- }
2653
- // ***************************************************
2654
- // *** gotoURL Methods ***
2655
- // ***************************************************
2656
- gotoURL(routePrefix, rightSidenav = [], parameters, type, dialogComponent = null, isNewTab = false, isPopup = this._isEmbedded()) {
2657
- const baseHref = this.environment.getBaseHref().endsWith('/')
2658
- ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
2659
- : this.environment.getBaseHref();
2660
- const navigationExtras = {
2661
- queryParams: {
2662
- parameters: JSON.stringify(parameters),
2663
- ...(type && { type }),
2664
- isNewTab: isNewTab || undefined,
2665
- },
2666
- queryParamsHandling: 'merge',
2667
- };
2668
- if (isNewTab) {
2669
- const fullUrl = this.router
2670
- .createUrlTree([baseHref, ...routePrefix, ...rightSidenav], navigationExtras)
2671
- .toString();
2672
- window.open(fullUrl, '_blank');
2673
- return;
2674
- }
2675
- if (isPopup && dialogComponent) {
2676
- this.dialog
2677
- .open(dialogComponent, {
2678
- data: {
2679
- parameters: parameters,
2680
- mode: type || 'edit',
2681
- embedded: true,
2682
- },
2683
- maxWidth: '100vw',
2684
- disableClose: true,
2685
- hasBackdrop: false,
2686
- })
2687
- .afterClosed();
2688
- return;
2689
- }
2690
- // Log control
2691
- if (rightSidenav.length == 0 || rightSidenav[0] === 'log') {
2692
- this.router.navigate([baseHref, ...routePrefix, ...rightSidenav], navigationExtras);
2693
- return;
2694
- }
2695
- // In all other cases, open the side menu
2696
- this.router
2697
- .navigate([
2698
- {
2699
- outlets: {
2700
- primary: routePrefix,
2701
- rightSidenav: [...routePrefix, ...rightSidenav],
2702
- },
2703
- },
2704
- ], navigationExtras)
2705
- .then(() => {
2706
- // Ensure sidenav is opened after navigation
2707
- this.commonService.toggleRightSidenav(true);
2708
- });
2709
- }
2710
- popupGotoURL(urlSegments) {
2711
- const baseHref = this.environment.getBaseHref().endsWith('/')
2712
- ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
2713
- : this.environment.getBaseHref();
2714
- this.router.navigate([
2715
- {
2716
- outlets: {
2717
- primary: [baseHref, ...urlSegments],
2718
- rightSidenav: null,
2719
- },
2720
- },
2721
- ]);
2722
- }
2723
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridSaveBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
2724
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: NettyAgGridSaveBase, isStandalone: true, selector: "ntybase-ag-grid-save-base", inputs: { parameters: { classPropertyName: "parameters", publicName: "parameters", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "saveForm", first: true, predicate: ["saveForm"], descendants: true }], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
2725
- }
2726
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridSaveBase, decorators: [{
2727
- type: Component,
2728
- args: [{ selector: 'ntybase-ag-grid-save-base', imports: [], template: `` }]
2729
- }], ctorParameters: () => [], propDecorators: { parameters: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameters", required: false }] }], saveForm: [{
2730
- type: ViewChild,
2731
- args: ['saveForm']
2732
- }] } });
2733
-
2734
- class ParseLog {
2735
- rowIndex = 0; // Excel line no (1-based)
2736
- message = ""; // Error or info message (fallback)
2737
- level = "INFO";
2738
- messageKey; // i18n translation key
2739
- messageParams; // parameters for translation
2740
- init() {
2741
- this.rowIndex = 0;
2742
- this.message = "";
2743
- this.level = "INFO";
2744
- this.messageKey = undefined;
2745
- this.messageParams = undefined;
2746
- }
2747
- compare(other) { return this; }
2748
- getPK() { return this.rowIndex; }
2749
- setPK(pk) { this.rowIndex = pk; }
2750
- }
2751
-
2752
- class ExcelParserError extends Error {
2753
- key;
2754
- params;
2755
- constructor(key, params) {
2756
- super(key);
2757
- this.key = key;
2758
- this.params = params;
2759
- this.name = 'ExcelParserError';
2760
- }
2761
- }
2762
- class ExcelParser {
2763
- mappings;
2764
- constructor(mappings) {
2765
- this.mappings = mappings;
2766
- }
2767
- async parse(file, options) {
2768
- // PERFORMANS: XLSX library only loads at parse time!
2769
- const XLSX = await import('xlsx');
2770
- const sheetIndex = options?.sheetIndex ?? 0;
2771
- const headerRowIndex = options?.headerRowIndex ?? 0; // 0-based
2772
- return new Promise((resolve, reject) => {
2773
- const reader = new FileReader();
2774
- reader.onload = (e) => {
2775
- try {
2776
- const data = new Uint8Array(e.target?.result);
2777
- const workbook = XLSX.read(data, { type: 'array' });
2778
- if (!workbook.SheetNames[sheetIndex]) {
2779
- throw new ExcelParserError('@EXCEL_PARSER.sheetNotFound', { index: sheetIndex });
2780
- }
2781
- const sheetName = workbook.SheetNames[sheetIndex];
2782
- const sheet = workbook.Sheets[sheetName];
2783
- const rows = XLSX.utils.sheet_to_json(sheet, { header: 1 });
2784
- const logs = [];
2785
- const result = [];
2786
- // Skip headerline
2787
- const dataRows = rows.slice(headerRowIndex + 1);
2788
- dataRows.forEach((row, i) => {
2789
- // Skip empty lines
2790
- if (!row || row.length === 0)
2791
- return;
2792
- const obj = {};
2793
- let hasError = false;
2794
- const actualRowIndex = headerRowIndex + i + 2; // Excel line no (1-based)
2795
- this.mappings.forEach(m => {
2796
- let rawValue = row[m.index];
2797
- if ((rawValue === undefined || rawValue === null || rawValue === '') && m.defaultValue !== undefined) {
2798
- rawValue = m.defaultValue;
2799
- logs.push(Object.assign(new ParseLog(), {
2800
- rowIndex: actualRowIndex,
2801
- message: `Boş alan için default değer atandı: ${String(m.prop)}`,
2802
- level: 'INFO',
2803
- messageKey: '@EXCEL_PARSER.defaultValueSet',
2804
- messageParams: { prop: String(m.prop) }
2805
- }));
2806
- }
2807
- if (m.required && (rawValue === undefined || rawValue === null || rawValue === '')) {
2808
- logs.push(Object.assign(new ParseLog(), {
2809
- rowIndex: actualRowIndex,
2810
- message: `Zorunlu alan boş: ${String(m.prop)}`,
2811
- level: 'ERROR',
2812
- messageKey: '@EXCEL_PARSER.requiredFieldMissing',
2813
- messageParams: { prop: String(m.prop) }
2814
- }));
2815
- hasError = true;
2816
- }
2817
- try {
2818
- obj[m.prop] = m.converter ? m.converter(rawValue) : rawValue;
2819
- }
2820
- catch (err) {
2821
- logs.push(Object.assign(new ParseLog(), {
2822
- rowIndex: actualRowIndex,
2823
- message: `Tip dönüşüm hatası: ${String(m.prop)} -> ${rawValue}`,
2824
- level: 'ERROR',
2825
- messageKey: '@EXCEL_PARSER.conversionError',
2826
- messageParams: { prop: String(m.prop), value: rawValue }
2827
- }));
2828
- hasError = true;
2829
- }
2830
- });
2831
- if (!hasError) {
2832
- result.push(obj);
2833
- }
2834
- else {
2835
- logs.push(Object.assign(new ParseLog(), {
2836
- rowIndex: actualRowIndex,
2837
- message: `Satır atlandı`,
2838
- level: 'WARN',
2839
- messageKey: '@EXCEL_PARSER.rowSkipped'
2840
- }));
2841
- }
2842
- });
2843
- resolve({ data: result, logs });
2844
- }
2845
- catch (error) {
2846
- reject(error);
2847
- }
2848
- };
2849
- reader.onerror = () => reject(reader.error);
2850
- reader.readAsArrayBuffer(file);
2851
- });
2852
- }
2853
- async generateSampleExcel(options) {
2854
- const sampleCount = options?.sampleCount ?? 5;
2855
- const fileName = (options?.fileName ?? 'sample-import.xlsx').endsWith('.xlsx')
2856
- ? (options?.fileName ?? 'sample-import.xlsx')
2857
- : `${options?.fileName}.xlsx`;
2858
- const sheetName = (options?.sheetName ?? 'Sample').substring(0, 15);
2859
- const XLSX = await import('xlsx');
2860
- // Header row: property names according to column order
2861
- const headers = this.mappings.map(m => m.headerName || String(m.prop));
2862
- const rows = [];
2863
- for (let i = 1; i <= sampleCount; i++) {
2864
- const row = this.mappings.map(m => {
2865
- if (m.sampleValue !== undefined) {
2866
- // Use sampleValue if it exists
2867
- return typeof m.sampleValue === 'function'
2868
- ? m.sampleValue(i) // if it's a function, generate value based on index
2869
- : m.sampleValue; // if it's a constant value, use it directly
2951
+ },
2952
+ error: (err) => {
2953
+ this.alertService.showError('@dataLoadFailed');
2954
+ this.commonService.toggleRightSidenav(false);
2955
+ // Redirect to user list on error in fullscreen mode
2956
+ if (this.viewMode() === 'fullscreen') {
2957
+ const cleanPath = this.commonService.getCleanUrlPath();
2958
+ this.router.navigate([cleanPath]);
2870
2959
  }
2871
- });
2872
- rows.push(row);
2873
- }
2874
- const worksheet = XLSX.utils.aoa_to_sheet([headers, ...rows]);
2875
- const workbook = XLSX.utils.book_new();
2876
- XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
2877
- XLSX.writeFile(workbook, fileName);
2960
+ },
2961
+ });
2878
2962
  }
2879
- }
2880
-
2881
- class ExcelImportBase extends NettyAgGridListBase {
2882
- isFileSelectionHidden = signal(false, ...(ngDevMode ? [{ debugName: "isFileSelectionHidden" }] : []));
2883
- isFileValid = signal(false, ...(ngDevMode ? [{ debugName: "isFileValid" }] : []));
2884
- logs = signal([], ...(ngDevMode ? [{ debugName: "logs" }] : []));
2885
- hasLogs = computed(() => this.logs().length > 0, ...(ngDevMode ? [{ debugName: "hasLogs" }] : []));
2886
- logDialog = inject(MatDialog);
2887
- parser = new ExcelParser([]);
2888
- // override methods
2889
- onBtnClick(e) { }
2890
- loadData() { }
2891
- // Methods
2892
- onFilesSelected(evt) {
2893
- const files = Array.isArray(evt) ? evt : evt.target.files;
2894
- if (!files || files.length !== 1) {
2963
+ // ***************************************************
2964
+ // *** gotoURL Methods ***
2965
+ // ***************************************************
2966
+ gotoURL(routePrefix, rightSidenav = [], parameters, type, dialogComponent = null, isNewTab = false, isPopup = this._isEmbedded()) {
2967
+ const baseHref = this.environment.getBaseHref().endsWith('/')
2968
+ ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
2969
+ : this.environment.getBaseHref();
2970
+ const navigationExtras = {
2971
+ queryParams: {
2972
+ parameters: JSON.stringify(parameters),
2973
+ ...(type && { type }),
2974
+ isNewTab: isNewTab || undefined,
2975
+ },
2976
+ queryParamsHandling: 'merge',
2977
+ };
2978
+ if (isNewTab) {
2979
+ const fullUrl = this.router
2980
+ .createUrlTree([baseHref, ...routePrefix, ...rightSidenav], navigationExtras)
2981
+ .toString();
2982
+ window.open(fullUrl, '_blank');
2895
2983
  return;
2896
2984
  }
2897
- const file = files[0];
2898
- if (file) {
2899
- this.recordList.set([]);
2900
- this.logs.set([]);
2901
- this.parser.parse(file).then(result => {
2902
- this.recordList.set(result.data);
2903
- this.logs.set(result.logs);
2904
- this.isFileSelectionHidden.set(true);
2905
- if (result.logs.length > 0)
2906
- this.showLogs();
2907
- });
2985
+ if (isPopup && dialogComponent) {
2986
+ this.dialog
2987
+ .open(dialogComponent, {
2988
+ data: {
2989
+ parameters: parameters,
2990
+ mode: type || 'edit',
2991
+ embedded: true,
2992
+ },
2993
+ maxWidth: '100vw',
2994
+ disableClose: true,
2995
+ hasBackdrop: false,
2996
+ })
2997
+ .afterClosed();
2998
+ return;
2908
2999
  }
2909
- }
2910
- downloadSampleExcel() {
2911
- this.parser.generateSampleExcel();
2912
- }
2913
- showLogs() {
2914
- const dialogRef = this.logDialog.open(ExcelLogViewer, {
2915
- height: '70%',
2916
- width: '90%',
2917
- maxWidth: '100vw',
2918
- maxHeight: '100vh'
2919
- });
2920
- dialogRef.componentInstance.setParseData(this.logs());
2921
- dialogRef.componentInstance.selectedElement.subscribe((element) => {
2922
- dialogRef.close();
3000
+ // Log control
3001
+ if (rightSidenav.length == 0 || rightSidenav[0] === 'log') {
3002
+ this.router.navigate([baseHref, ...routePrefix, ...rightSidenav], navigationExtras);
3003
+ return;
3004
+ }
3005
+ // In all other cases, open the side menu
3006
+ this.router
3007
+ .navigate([
3008
+ {
3009
+ outlets: {
3010
+ primary: routePrefix,
3011
+ rightSidenav: [...routePrefix, ...rightSidenav],
3012
+ },
3013
+ },
3014
+ ], navigationExtras)
3015
+ .then(() => {
3016
+ // Ensure sidenav is opened after navigation
3017
+ this.commonService.toggleRightSidenav(true);
2923
3018
  });
2924
3019
  }
2925
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelImportBase, deps: null, target: i0.ɵɵFactoryTarget.Component });
2926
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ExcelImportBase, isStandalone: true, selector: "ntybase-excel-import-base", usesInheritance: true, ngImport: i0, template: ``, isInline: true });
3020
+ popupGotoURL(urlSegments) {
3021
+ const baseHref = this.environment.getBaseHref().endsWith('/')
3022
+ ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
3023
+ : this.environment.getBaseHref();
3024
+ this.router.navigate([
3025
+ {
3026
+ outlets: {
3027
+ primary: [baseHref, ...urlSegments],
3028
+ rightSidenav: null,
3029
+ },
3030
+ },
3031
+ ]);
3032
+ }
3033
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridSaveBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
3034
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: NettyAgGridSaveBase, isStandalone: true, selector: "ntybase-ag-grid-save-base", inputs: { parameters: { classPropertyName: "parameters", publicName: "parameters", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "saveForm", first: true, predicate: ["saveForm"], descendants: true }], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
2927
3035
  }
2928
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelImportBase, decorators: [{
3036
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridSaveBase, decorators: [{
2929
3037
  type: Component,
2930
- args: [{ selector: 'ntybase-excel-import-base', imports: [], template: `` }]
2931
- }] });
3038
+ args: [{ selector: 'ntybase-ag-grid-save-base', imports: [], template: `` }]
3039
+ }], ctorParameters: () => [], propDecorators: { parameters: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameters", required: false }] }], saveForm: [{
3040
+ type: ViewChild,
3041
+ args: ['saveForm']
3042
+ }] } });
2932
3043
 
2933
3044
  class RangeDateTimeFilter {
2934
3045
  params;
@@ -3728,7 +3839,7 @@ const ntyAuthenticationInterceptor = (req, next) => {
3728
3839
  headers: req.headers.set('Authorization', 'Bearer ' + token)
3729
3840
  // .set("NettyAppName",appName)
3730
3841
  });
3731
- return next(clonedreq).pipe(catchError((error) => {
3842
+ return next(clonedreq).pipe(catchError$1((error) => {
3732
3843
  if (error instanceof HttpErrorResponse && error.status === 401) {
3733
3844
  // Handle 401 error, e.g., navigate to the login page
3734
3845
  router.navigate(['/login'], {
@@ -3762,7 +3873,7 @@ const ntyAuthenticationInterceptor = (req, next) => {
3762
3873
  }));
3763
3874
  }
3764
3875
  else {
3765
- return next(req.clone()).pipe(catchError((error) => {
3876
+ return next(req.clone()).pipe(catchError$1((error) => {
3766
3877
  if (error instanceof HttpErrorResponse && error.status === 401) {
3767
3878
  // Handle 401 error, e.g., navigate to the login page
3768
3879
  router.navigate(['/login'], {
@@ -3855,7 +3966,7 @@ class AuthenticationService {
3855
3966
  // Parse JWT
3856
3967
  this.credentialsService.setCredentials(data, context.remember);
3857
3968
  return data;
3858
- }), take(1), catchError((error) => {
3969
+ }), take(1), catchError$1((error) => {
3859
3970
  let errorMessage = '';
3860
3971
  switch (error.status) {
3861
3972
  case '404':
@@ -3919,7 +4030,7 @@ class AuthenticationService {
3919
4030
  });
3920
4031
  return mfaCodeCall$.pipe(map$1((message) => {
3921
4032
  return message;
3922
- }), take(1), catchError((error) => {
4033
+ }), take(1), catchError$1((error) => {
3923
4034
  let errorMessage = '';
3924
4035
  errorMessage =
3925
4036
  error.status +
@@ -3943,7 +4054,7 @@ class AuthenticationService {
3943
4054
  console.log('mfaCodeUrl', mfaCodeUrl);
3944
4055
  return resendMFACodeCall$.pipe(map$1((message) => {
3945
4056
  return message;
3946
- }), take(1), catchError((error) => {
4057
+ }), take(1), catchError$1((error) => {
3947
4058
  let errorMessage = '';
3948
4059
  errorMessage =
3949
4060
  error.status +
@@ -3982,7 +4093,7 @@ class AuthenticationService {
3982
4093
  // and saves the credentials into localstorage
3983
4094
  return loginCall$.pipe(map$1((message) => {
3984
4095
  return message;
3985
- }), take(1), catchError((error) => {
4096
+ }), take(1), catchError$1((error) => {
3986
4097
  let errorMessage = '';
3987
4098
  errorMessage =
3988
4099
  error.status +
@@ -4339,7 +4450,7 @@ class PasswordProxy {
4339
4450
  });
4340
4451
  return resertPasswordCall$.pipe(map((message) => {
4341
4452
  return message;
4342
- }), take$1(1), catchError$1((error) => {
4453
+ }), take$1(1), catchError((error) => {
4343
4454
  let errorMessage = '';
4344
4455
  errorMessage =
4345
4456
  error.status +
@@ -4528,29 +4639,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
4528
4639
  }]
4529
4640
  }] });
4530
4641
 
4531
- class NettyBaseApp {
4532
- i18nService = inject(I18nService);
4533
- alertService = inject(AlertService);
4534
- async loadBaseTranslations() {
4535
- try {
4536
- const enUSBase = await import('./nettyapps-ntybase-en-USbase-Bl-neyoj.mjs');
4537
- const trTRBase = await import('./nettyapps-ntybase-tr-TRbase-CO4HBOmj.mjs');
4538
- this.i18nService.addTranslations('English', enUSBase.default);
4539
- this.i18nService.addTranslations('Türkçe', trTRBase.default);
4540
- }
4541
- catch (error) {
4542
- this.alertService.showError('Error loading base translations in component:', error);
4543
- throw error;
4544
- }
4545
- }
4546
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyBaseApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
4547
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: NettyBaseApp, isStandalone: true, selector: "ntybase-netty-base-app", ngImport: i0, template: "", styles: [""] });
4548
- }
4549
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyBaseApp, decorators: [{
4550
- type: Component,
4551
- args: [{ selector: 'ntybase-netty-base-app', imports: [], template: "" }]
4552
- }] });
4553
-
4554
4642
  class EnvironmentInfo {
4555
4643
  showNettyInfo = true;
4556
4644
  environmentProxy = inject(EnvironmentProxy);
@@ -4722,91 +4810,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
4722
4810
  }]
4723
4811
  }] });
4724
4812
 
4725
- class NettyAppsFilterBase extends NettyAppsBase {
4726
- // *********************************************************
4727
- // *** Input / Output ***
4728
- // *********************************************************
4729
- isFilterExpanded = model(true, ...(ngDevMode ? [{ debugName: "isFilterExpanded" }] : []));
4730
- filteredRecords = output();
4731
- filterSelectionChanged = output();
4732
- refresh = input(0, ...(ngDevMode ? [{ debugName: "refresh" }] : []));
4733
- fileName = input('nettyapps_', ...(ngDevMode ? [{ debugName: "fileName" }] : []));
4734
- // *********************************************************
4735
- // *** Service ***
4736
- // *********************************************************
4737
- filterProxy = injectNettyStandardFilterProxy(this.componentName());
4738
- // *********************************************************
4739
- // *** Signals ***
4740
- // *********************************************************
4741
- currentItem = signal(this.createNewFilter(), ...(ngDevMode ? [{ debugName: "currentItem" }] : []));
4742
- // *********************************************************
4743
- // *** Constructor ***
4744
- // *********************************************************
4745
- constructor() {
4746
- super();
4747
- effect(() => {
4748
- if (this.refresh() > 0) {
4749
- this.onApply();
4750
- }
4751
- });
4752
- }
4753
- // *********************************************************
4754
- // *** Functions ***
4755
- // *********************************************************
4756
- async ngOnInit() {
4757
- this.afterOnInit();
4758
- }
4759
- onApply() {
4760
- this.filterSelectionChanged.emit(this.currentItem());
4761
- this.filterProxy.selectFilter(this.currentItem()).subscribe({
4762
- next: (result) => {
4763
- this.filteredRecords.emit(result);
4764
- this.isFilterExpanded.set(false);
4765
- },
4766
- error: (err) => this.alertService.showError('@dataLoadFailed', err),
4767
- });
4768
- }
4769
- onReset() {
4770
- this.filterProxy.initFilter().subscribe({
4771
- next: (filter) => {
4772
- this.currentItem.set(filter);
4773
- this.filterSelectionChanged.emit(this.currentItem());
4774
- },
4775
- error: (err) => this.alertService.showError('@dataLoadFailed', err),
4776
- });
4777
- }
4778
- onExport() {
4779
- this.filterSelectionChanged.emit(this.currentItem());
4780
- this.filterProxy.downloadXLS(this.currentItem()).subscribe({
4781
- next: (response) => {
4782
- this.downloadBlobFile(response, 'application/zip', this.translateService.instant('@00000072') + '.zip');
4783
- },
4784
- error: (err) => this.alertService.showError('@dataLoadFailed', err),
4785
- });
4786
- }
4787
- async afterOnInit() { }
4788
- // *****************************************
4789
- // *** Logging Functions ***
4790
- // *****************************************
4791
- logInputs(message) {
4792
- if (!message || message.length < 1) {
4793
- message = 'NettyAppsFilterBase - Inputs log';
4794
- }
4795
- const inputs = {
4796
- "isFilterExpanded": this.isFilterExpanded(),
4797
- "refresh": this.refresh(),
4798
- "fileName": this.fileName(),
4799
- };
4800
- console.log(message, inputs);
4801
- }
4802
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAppsFilterBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
4803
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: NettyAppsFilterBase, isStandalone: true, selector: "ntybase-netty-apps-base", inputs: { isFilterExpanded: { classPropertyName: "isFilterExpanded", publicName: "isFilterExpanded", isSignal: true, isRequired: false, transformFunction: null }, refresh: { classPropertyName: "refresh", publicName: "refresh", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isFilterExpanded: "isFilterExpandedChange", filteredRecords: "filteredRecords", filterSelectionChanged: "filterSelectionChanged" }, usesInheritance: true, ngImport: i0, template: ``, isInline: true });
4804
- }
4805
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAppsFilterBase, decorators: [{
4806
- type: Component,
4807
- args: [{ selector: 'ntybase-netty-apps-base', imports: [], template: `` }]
4808
- }], ctorParameters: () => [], propDecorators: { isFilterExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "isFilterExpanded", required: false }] }, { type: i0.Output, args: ["isFilterExpandedChange"] }], filteredRecords: [{ type: i0.Output, args: ["filteredRecords"] }], filterSelectionChanged: [{ type: i0.Output, args: ["filterSelectionChanged"] }], refresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "refresh", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }] } });
4809
-
4810
4813
  // converters.ts
4811
4814
  // Sayı dönüştürücü (hem . hem , destekler)
4812
4815
  const toNumber = (v) => {
@@ -4843,6 +4846,50 @@ const toEnum = (v, enumObj) => {
4843
4846
  return enumObj[key] ?? null;
4844
4847
  };
4845
4848
 
4849
+ //-------------------------------
4850
+ //| Generated by NettyWizard V2 |
4851
+ //-------------------------------
4852
+ class ExcelLogViewer extends NettyAgGridListBase {
4853
+ /** Component Constructor */
4854
+ constructor() {
4855
+ super();
4856
+ }
4857
+ /** Get the rowId */
4858
+ getRowId = (params) => params.data.rowIndex.toString();
4859
+ /** Get the entity type for the component */
4860
+ getEntityType = () => 'ParseLog';
4861
+ pkFieldName() { return 'rowIndex'; }
4862
+ loadData() { }
4863
+ setParseData(data) {
4864
+ data.forEach((item) => {
4865
+ if (item.messageKey) {
4866
+ item.message = this.translateService.instant(item.messageKey, item.messageParams);
4867
+ }
4868
+ });
4869
+ super.setData(data);
4870
+ }
4871
+ /** Initialize Ag-Grid specific settings */
4872
+ initAgGrid() {
4873
+ this.excelStyles = this.nettyAgGridService.getExcelStyles();
4874
+ this.columnDefs.set([
4875
+ { headerName: this.translateService.instant('@EXCEL_PARSER_LOG.row'), field: 'rowIndex', cellClass: 'numberType', filter: this.customFilters() ? RangeNumberFilter : 'agNumberColumnFilter', type: "numericColumn", cellStyle: { textAlign: 'right' } },
4876
+ { headerName: this.translateService.instant('@EXCEL_PARSER_LOG.message'), field: 'message', cellClass: 'text-format', filter: this.customFilters() ? RangeStringFilter : 'agSetColumnFilter', },
4877
+ { headerName: this.translateService.instant('@EXCEL_PARSER_LOG.level'), field: 'level', cellClass: 'text-format', filter: this.customFilters() ? RangeStringFilter : 'agSetColumnFilter', },
4878
+ ]);
4879
+ this.initAgGrid_extension();
4880
+ }
4881
+ popupClose() {
4882
+ super.popupClose();
4883
+ }
4884
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelLogViewer, deps: [], target: i0.ɵɵFactoryTarget.Component });
4885
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ExcelLogViewer, isStandalone: true, selector: "app-excel-log-viewer", usesInheritance: true, ngImport: i0, template: "<div class='list-container'>\n <div class='list-menu-button-bar'>\n <ntyui-button type='menu' icon='settings_ethernet' [disableOnClick]='false' (clicked)='expandCollapse()' />\n <ntyui-button type='menu' icon='regular_expression'\n [toolTip]=\"(customFilters() ? '@customFilterActive' : '@defaultFilterActive') | translate\"\n [disableOnClick]='true' [disableDuration]='0'\n [ngClass]=\"{'custom-filter-mode': !customFilters(),'default-filter-mode': customFilters()}\"\n (clicked)='toggleFilterMode()' />\n <ntyui-filter-button icon='filter_alt' (isSearchOpen)=\"onFilterTextBoxVisibilityChange($event)\"\n [searchValue]='searchValue()' (onSearch)='quickSearch($event)' />\n <ntyui-button type='close' class='list-close-button' [toolTip]=\"'@close'|translate\" (clicked)='popupClose()' />\n </div>\n <div class='list-grid'>\n <ag-grid-angular #agGrid class='ag-theme-balham grid-form-grid-full' [rowData]='recordList()'\n [columnDefs]='columnDefs()' [gridOptions]='gridOptions' [rowSelection]='gridOptions.rowSelection'\n [components]='frameworkComponents' [suppressAggFuncInHeader]='true' [enableCellTextSelection]='true'\n (firstDataRendered)='onFirstDataRendered($event)' (columnMoved)='saveGrid($event)'\n (columnVisible)='saveGrid($event)' (columnResized)='saveGrid($event)' (gridReady)='onGridReady($event)'\n [statusBar]='statusBar'></ag-grid-angular>\n </div>\n</div>", styles: [""], dependencies: [{ kind: "component", type: AgGridAngular, selector: "ag-grid-angular", inputs: ["gridOptions", "modules", "statusBar", "sideBar", "suppressContextMenu", "preventDefaultOnContextMenu", "allowContextMenuWithControlKey", "columnMenu", "suppressMenuHide", "enableBrowserTooltips", "tooltipTrigger", "tooltipShowDelay", "tooltipSwitchShowDelay", "tooltipHideDelay", "tooltipMouseTrack", "tooltipShowMode", "tooltipInteraction", "popupParent", "copyHeadersToClipboard", "copyGroupHeadersToClipboard", "clipboardDelimiter", "suppressCopyRowsToClipboard", "suppressCopySingleCellRanges", "suppressLastEmptyLineOnPaste", "suppressClipboardPaste", "suppressClipboardApi", "suppressCutToClipboard", "columnDefs", "defaultColDef", "defaultColGroupDef", "columnTypes", "dataTypeDefinitions", "maintainColumnOrder", "enableStrictPivotColumnOrder", "suppressFieldDotNotation", "headerHeight", "groupHeaderHeight", "floatingFiltersHeight", "pivotHeaderHeight", "pivotGroupHeaderHeight", "hidePaddedHeaderRows", "allowDragFromColumnsToolPanel", "suppressMovableColumns", "suppressColumnMoveAnimation", "suppressMoveWhenColumnDragging", "suppressDragLeaveHidesColumns", "suppressGroupChangesColumnVisibility", "suppressMakeColumnVisibleAfterUnGroup", "suppressRowGroupHidesColumns", "colResizeDefault", "suppressAutoSize", "autoSizePadding", "skipHeaderOnAutoSize", "autoSizeStrategy", "animateColumnResizing", "components", "editType", "suppressStartEditOnTab", "getFullRowEditValidationErrors", "invalidEditValueMode", "singleClickEdit", "suppressClickEdit", "readOnlyEdit", "stopEditingWhenCellsLoseFocus", "enterNavigatesVertically", "enterNavigatesVerticallyAfterEdit", "enableCellEditingOnBackspace", "undoRedoCellEditing", "undoRedoCellEditingLimit", "defaultCsvExportParams", "suppressCsvExport", "defaultExcelExportParams", "suppressExcelExport", "excelStyles", "findSearchValue", "findOptions", "quickFilterText", "cacheQuickFilter", "includeHiddenColumnsInQuickFilter", "quickFilterParser", "quickFilterMatcher", "applyQuickFilterBeforePivotOrAgg", "excludeChildrenWhenTreeDataFiltering", "enableAdvancedFilter", "alwaysPassFilter", "includeHiddenColumnsInAdvancedFilter", "advancedFilterParent", "advancedFilterBuilderParams", "advancedFilterParams", "suppressAdvancedFilterEval", "suppressSetFilterByDefault", "enableFilterHandlers", "filterHandlers", "enableCharts", "chartThemes", "customChartThemes", "chartThemeOverrides", "chartToolPanelsDef", "chartMenuItems", "loadingCellRenderer", "loadingCellRendererParams", "loadingCellRendererSelector", "localeText", "masterDetail", "keepDetailRows", "keepDetailRowsCount", "detailCellRenderer", "detailCellRendererParams", "detailRowHeight", "detailRowAutoHeight", "context", "alignedGrids", "tabIndex", "rowBuffer", "valueCache", "valueCacheNeverExpires", "enableCellExpressions", "suppressTouch", "suppressFocusAfterRefresh", "suppressBrowserResizeObserver", "suppressPropertyNamesCheck", "suppressChangeDetection", "debug", "loading", "overlayLoadingTemplate", "loadingOverlayComponent", "loadingOverlayComponentParams", "suppressLoadingOverlay", "overlayNoRowsTemplate", "noRowsOverlayComponent", "noRowsOverlayComponentParams", "suppressNoRowsOverlay", "suppressOverlays", "overlayComponent", "overlayComponentParams", "overlayComponentSelector", "activeOverlay", "activeOverlayParams", "pagination", "paginationPageSize", "paginationPageSizeSelector", "paginationAutoPageSize", "paginateChildRows", "suppressPaginationPanel", "pivotMode", "pivotPanelShow", "pivotMaxGeneratedColumns", "pivotDefaultExpanded", "pivotColumnGroupTotals", "pivotRowTotals", "pivotSuppressAutoColumn", "suppressExpandablePivotGroups", "functionsReadOnly", "aggFuncs", "formulaDataSource", "formulaFuncs", "suppressAggFuncInHeader", "alwaysAggregateAtRootLevel", "aggregateOnlyChangedColumns", "suppressAggFilteredOnly", "removePivotHeaderRowWhenSingleValueColumn", "animateRows", "cellFlashDuration", "cellFadeDuration", "allowShowChangeAfterFilter", "domLayout", "ensureDomOrder", "enableCellSpan", "enableRtl", "suppressColumnVirtualisation", "suppressMaxRenderedRowRestriction", "suppressRowVirtualisation", "rowDragManaged", "refreshAfterGroupEdit", "rowDragInsertDelay", "suppressRowDrag", "suppressMoveWhenRowDragging", "rowDragEntireRow", "rowDragMultiRow", "rowDragText", "dragAndDropImageComponent", "dragAndDropImageComponentParams", "fullWidthCellRenderer", "fullWidthCellRendererParams", "embedFullWidthRows", "groupDisplayType", "groupDefaultExpanded", "autoGroupColumnDef", "groupMaintainOrder", "groupSelectsChildren", "groupLockGroupColumns", "groupAggFiltering", "groupTotalRow", "grandTotalRow", "suppressStickyTotalRow", "groupSuppressBlankHeader", "groupSelectsFiltered", "showOpenedGroup", "groupHideParentOfSingleChild", "groupRemoveSingleChildren", "groupRemoveLowestSingleChildren", "groupHideOpenParents", "groupAllowUnbalanced", "rowGroupPanelShow", "groupRowRenderer", "groupRowRendererParams", "treeData", "treeDataChildrenField", "treeDataParentIdField", "rowGroupPanelSuppressSort", "suppressGroupRowsSticky", "groupHierarchyConfig", "pinnedTopRowData", "pinnedBottomRowData", "enableRowPinning", "isRowPinnable", "isRowPinned", "rowModelType", "rowData", "asyncTransactionWaitMillis", "suppressModelUpdateAfterUpdateTransaction", "datasource", "cacheOverflowSize", "infiniteInitialRowCount", "serverSideInitialRowCount", "suppressServerSideFullWidthLoadingRow", "cacheBlockSize", "maxBlocksInCache", "maxConcurrentDatasourceRequests", "blockLoadDebounceMillis", "purgeClosedRowNodes", "serverSideDatasource", "serverSideSortAllLevels", "serverSideEnableClientSideSort", "serverSideOnlyRefreshFilteredGroups", "serverSidePivotResultFieldSeparator", "viewportDatasource", "viewportRowModelPageSize", "viewportRowModelBufferSize", "alwaysShowHorizontalScroll", "alwaysShowVerticalScroll", "debounceVerticalScrollbar", "suppressHorizontalScroll", "suppressScrollOnNewData", "suppressScrollWhenPopupsAreOpen", "suppressAnimationFrame", "suppressMiddleClickScrolls", "suppressPreventDefaultOnMouseWheel", "scrollbarWidth", "rowSelection", "cellSelection", "rowMultiSelectWithClick", "suppressRowDeselection", "suppressRowClickSelection", "suppressCellFocus", "suppressHeaderFocus", "selectionColumnDef", "rowNumbers", "suppressMultiRangeSelection", "enableCellTextSelection", "enableRangeSelection", "enableRangeHandle", "enableFillHandle", "fillHandleDirection", "suppressClearOnFillReduction", "sortingOrder", "accentedSort", "unSortIcon", "suppressMultiSort", "alwaysMultiSort", "multiSortKey", "suppressMaintainUnsortedOrder", "icons", "rowHeight", "rowStyle", "rowClass", "rowClassRules", "suppressRowHoverHighlight", "suppressRowTransform", "columnHoverHighlight", "gridId", "deltaSort", "treeDataDisplayType", "enableGroupEdit", "initialState", "theme", "loadThemeGoogleFonts", "themeCssLayer", "styleNonce", "themeStyleContainer", "getContextMenuItems", "getMainMenuItems", "postProcessPopup", "processUnpinnedColumns", "processCellForClipboard", "processHeaderForClipboard", "processGroupHeaderForClipboard", "processCellFromClipboard", "sendToClipboard", "processDataFromClipboard", "isExternalFilterPresent", "doesExternalFilterPass", "getChartToolbarItems", "createChartContainer", "focusGridInnerElement", "navigateToNextHeader", "tabToNextHeader", "navigateToNextCell", "tabToNextCell", "getLocaleText", "getDocument", "paginationNumberFormatter", "getGroupRowAgg", "isGroupOpenByDefault", "ssrmExpandAllAffectsAllRows", "initialGroupOrderComparator", "processPivotResultColDef", "processPivotResultColGroupDef", "getDataPath", "getChildCount", "getServerSideGroupLevelParams", "isServerSideGroupOpenByDefault", "isApplyServerSideTransaction", "isServerSideGroup", "getServerSideGroupKey", "getBusinessKeyForNode", "getRowId", "resetRowDataOnUpdate", "processRowPostCreate", "isRowSelectable", "isRowMaster", "fillOperation", "postSortRows", "getRowStyle", "getRowClass", "getRowHeight", "isFullWidthRow", "isRowValidDropPosition"], outputs: ["toolPanelVisibleChanged", "toolPanelSizeChanged", "columnMenuVisibleChanged", "contextMenuVisibleChanged", "cutStart", "cutEnd", "pasteStart", "pasteEnd", "columnVisible", "columnPinned", "columnResized", "columnMoved", "columnValueChanged", "columnPivotModeChanged", "columnPivotChanged", "columnGroupOpened", "newColumnsLoaded", "gridColumnsChanged", "displayedColumnsChanged", "virtualColumnsChanged", "columnEverythingChanged", "columnsReset", "columnHeaderMouseOver", "columnHeaderMouseLeave", "columnHeaderClicked", "columnHeaderContextMenu", "componentStateChanged", "cellValueChanged", "cellEditRequest", "rowValueChanged", "cellEditingStarted", "cellEditingStopped", "rowEditingStarted", "rowEditingStopped", "bulkEditingStarted", "bulkEditingStopped", "batchEditingStarted", "batchEditingStopped", "undoStarted", "undoEnded", "redoStarted", "redoEnded", "cellSelectionDeleteStart", "cellSelectionDeleteEnd", "rangeDeleteStart", "rangeDeleteEnd", "fillStart", "fillEnd", "filterOpened", "filterChanged", "filterModified", "filterUiChanged", "floatingFilterUiChanged", "advancedFilterBuilderVisibleChanged", "findChanged", "chartCreated", "chartRangeSelectionChanged", "chartOptionsChanged", "chartDestroyed", "cellKeyDown", "gridReady", "firstDataRendered", "gridSizeChanged", "modelUpdated", "virtualRowRemoved", "viewportChanged", "bodyScroll", "bodyScrollEnd", "dragStarted", "dragStopped", "dragCancelled", "stateUpdated", "paginationChanged", "rowDragEnter", "rowDragMove", "rowDragLeave", "rowDragEnd", "rowDragCancel", "rowResizeStarted", "rowResizeEnded", "columnRowGroupChanged", "rowGroupOpened", "expandOrCollapseAll", "pivotMaxColumnsExceeded", "pinnedRowDataChanged", "pinnedRowsChanged", "rowDataUpdated", "asyncTransactionsFlushed", "storeRefreshed", "headerFocused", "cellClicked", "cellDoubleClicked", "cellFocused", "cellMouseOver", "cellMouseOut", "cellMouseDown", "rowClicked", "rowDoubleClicked", "rowSelected", "selectionChanged", "cellContextMenu", "rangeSelectionChanged", "cellSelectionChanged", "tooltipShow", "tooltipHide", "sortChanged"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: NettyUIButton, selector: "ntyui-button", inputs: ["icon", "isFilled", "menuReference", "disableOnClick", "disableDuration", "waitingText", "type", "toolTip"], outputs: ["clicked"] }, { kind: "component", type: NettyUIFilterButton, selector: "ntyui-filter-button", inputs: ["icon", "waitingText", "searchValue"], outputs: ["clicked", "onSearch", "isSearchOpen"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
4886
+ }
4887
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelLogViewer, decorators: [{
4888
+ type: Component,
4889
+ args: [{ selector: 'app-excel-log-viewer', imports: [AgGridAngular, CommonModule, FormsModule, NettyUIButton, NettyUIFilterButton,
4890
+ FormsModule, TranslateModule], template: "<div class='list-container'>\n <div class='list-menu-button-bar'>\n <ntyui-button type='menu' icon='settings_ethernet' [disableOnClick]='false' (clicked)='expandCollapse()' />\n <ntyui-button type='menu' icon='regular_expression'\n [toolTip]=\"(customFilters() ? '@customFilterActive' : '@defaultFilterActive') | translate\"\n [disableOnClick]='true' [disableDuration]='0'\n [ngClass]=\"{'custom-filter-mode': !customFilters(),'default-filter-mode': customFilters()}\"\n (clicked)='toggleFilterMode()' />\n <ntyui-filter-button icon='filter_alt' (isSearchOpen)=\"onFilterTextBoxVisibilityChange($event)\"\n [searchValue]='searchValue()' (onSearch)='quickSearch($event)' />\n <ntyui-button type='close' class='list-close-button' [toolTip]=\"'@close'|translate\" (clicked)='popupClose()' />\n </div>\n <div class='list-grid'>\n <ag-grid-angular #agGrid class='ag-theme-balham grid-form-grid-full' [rowData]='recordList()'\n [columnDefs]='columnDefs()' [gridOptions]='gridOptions' [rowSelection]='gridOptions.rowSelection'\n [components]='frameworkComponents' [suppressAggFuncInHeader]='true' [enableCellTextSelection]='true'\n (firstDataRendered)='onFirstDataRendered($event)' (columnMoved)='saveGrid($event)'\n (columnVisible)='saveGrid($event)' (columnResized)='saveGrid($event)' (gridReady)='onGridReady($event)'\n [statusBar]='statusBar'></ag-grid-angular>\n </div>\n</div>" }]
4891
+ }], ctorParameters: () => [] });
4892
+
4846
4893
  /*
4847
4894
  * Public API Surface of ntybase
4848
4895
  */
@@ -4851,5 +4898,5 @@ const toEnum = (v, enumObj) => {
4851
4898
  * Generated bundle index. Do not edit.
4852
4899
  */
4853
4900
 
4854
- export { AlertService, AuthenticationGuard, AuthenticationInterceptor, AuthenticationService, ButtonRenderer, CanDeactivateGuard, CheckboxRenderer, CommonService, ConfirmDialog, CredentialsService, CurrentUserPreference, ENVIRONMENT_CONFIG, EnvironmentInfo, EnvironmentInfoService, ErrorAlert, ExcelImportBase, ExcelParser, ExcelParserError, ForgotPassword, Guid, Login, LoginDto, MFACodeDto, MfaLogin, NettyAgGridBase, NettyAgGridListBase, NettyAgGridListFilterBase, NettyAgGridLogBase, NettyAgGridSaveBase, NettyAgGridService, NettyAppsBase, NettyAppsFilterBase, NettyBaseApp, NettyHelper, NettyImageService, NettyMenuService, NtyLoadingComponent, NtyLoadingInterceptor, NtyLoadingService, Ntybase, NtybaseModule, PageTitle, ParseLog, RangeDateTimeFilter, RangeNumberFilter, RangeStringFilter, UrlHelperService, ntyAuthenticationInterceptor, toBoolean, toDate, toEnum, toNumber, toUpperString };
4901
+ export { AlertService, AuthenticationGuard, AuthenticationInterceptor, AuthenticationService, ButtonRenderer, CanDeactivateGuard, CheckboxRenderer, CommonService, ConfirmDialog, CredentialsService, CurrentUserPreference, ENVIRONMENT_CONFIG, EnvironmentInfo, EnvironmentInfoService, ErrorAlert, ExcelImportBase, ExcelLogViewer, ExcelParser, ExcelParserError, ForgotPassword, Guid, Login, LoginDto, MFACodeDto, MfaLogin, NettyAgGridBase, NettyAgGridListBase, NettyAgGridListFilterBase, NettyAgGridLogBase, NettyAgGridSaveBase, NettyAgGridService, NettyAppsBase, NettyAppsFilterBase, NettyBaseApp, NettyHelper, NettyImageService, NettyMenuService, NtyLoadingComponent, NtyLoadingInterceptor, NtyLoadingService, Ntybase, NtybaseModule, PageTitle, ParseLog, RangeDateTimeFilter, RangeNumberFilter, RangeStringFilter, UrlHelperService, ntyAuthenticationInterceptor, toBoolean, toDate, toEnum, toNumber, toUpperString };
4855
4902
  //# sourceMappingURL=nettyapps-ntybase.mjs.map