@nettyapps/ntybase 21.1.38 → 21.1.39

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,152 @@ 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 { CommonModule, DatePipe, Location, DecimalPipe } from '@angular/common';
22
16
  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';
17
+ import * as i2$2 from '@nettyapps/ntycontract';
18
+ import { injectNettyStandardFilterProxy, EnvironmentProxy, injectNettyStandardProxy, injectNettyStandardLogProxy } from '@nettyapps/ntycontract';
19
+ import { I18nService } from '@nettyapps/ntyi18n';
20
+ import { ExcelLogViewer } from '@nettyapps/ntyux';
21
+ import { Router, ActivatedRoute } from '@angular/router';
26
22
  import { ModuleRegistry, AllCommunityModule, ClientSideRowModelModule, HighlightChangesModule, TextFilterModule, NumberFilterModule, DateFilterModule } from 'ag-grid-community';
27
- import * as i2$2 from '@angular/material/tooltip';
23
+ import { themeQuartz, StatusBarModule, ClipboardModule, ExcelExportModule, ColumnMenuModule, ContextMenuModule, CellSelectionModule, RowSelectionModule, SetFilterModule, MultiFilterModule } from 'ag-grid-enterprise';
24
+ import * as i2$1 from '@angular/material/tooltip';
28
25
  import { MatTooltipModule } from '@angular/material/tooltip';
29
26
  import * as i2$3 from '@angular/material/menu';
30
27
  import { MatMenuModule } from '@angular/material/menu';
31
- import { ExcelLogViewer } from '@nettyapps/ntyux';
32
- import { I18nService } from '@nettyapps/ntyi18n';
28
+ import * as i1$3 from '@angular/common/http';
29
+ import { HttpClient, HttpErrorResponse, HttpResponse, HTTP_INTERCEPTORS, HttpHeaders } from '@angular/common/http';
30
+ import { Mutex } from 'async-mutex';
31
+ import { toSignal } from '@angular/core/rxjs-interop';
32
+ import { catchError as catchError$1, map as map$1, take, finalize as finalize$1 } from 'rxjs/operators';
33
33
  import * as i1$4 from '@angular/forms';
34
34
  import { FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
35
35
  import * as i3$1 from '@angular/material/input';
36
36
  import { MatInputModule } from '@angular/material/input';
37
37
  import { MatFormFieldModule } from '@angular/material/form-field';
38
38
 
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: [""] });
39
+ class ConfirmDialog {
40
+ dialogRef = inject((MatDialogRef));
41
+ data = inject(MAT_DIALOG_DATA);
42
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ConfirmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
43
+ 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
44
  }
47
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Ntybase, decorators: [{
45
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ConfirmDialog, decorators: [{
48
46
  type: Component,
49
- args: [{ selector: 'lib-ntybase', standalone: false, template: `
50
- <p>
51
- ntybase works!
52
- </p>
53
- ` }]
47
+ 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
48
  }] });
55
49
 
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
- }
50
+ class ErrorAlert {
51
+ dialogRef = inject((MatDialogRef));
52
+ data = inject(MAT_DIALOG_DATA);
53
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ErrorAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
54
+ 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" }] });
55
+ }
56
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ErrorAlert, decorators: [{
57
+ type: Component,
58
+ 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"] }]
59
+ }] });
60
+
61
+ // alert.service.ts
62
+ class AlertService {
63
+ snackBar;
64
+ dialog;
65
+ translate;
66
+ constructor(snackBar, dialog, translate) {
67
+ this.snackBar = snackBar;
68
+ this.dialog = dialog;
69
+ this.translate = translate;
65
70
  }
66
- /**
67
- * Checks is the user is authenticated.
68
- * @return True if the user is authenticated.
69
- */
70
- isAuthenticated() {
71
- return !!this.credentials;
71
+ // For simple notifications
72
+ showAlert(message, action, duration = 3000) {
73
+ const actionText = action ? action : '@btnOK';
74
+ this.snackBar.open(this.translate.instant(message), this.translate.instant(actionText), { duration });
72
75
  }
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;
76
+ showWarning(message, action, duration = 3000) {
77
+ const actionText = action ? action : '@btnOK';
78
+ this.snackBar.open(this.translate.instant(message), this.translate.instant(actionText), { duration });
79
79
  }
80
- get token() {
81
- return this._credentials?.token ?? null;
80
+ // For confirmation dialogs
81
+ showConfirm(message) {
82
+ return new Promise((resolve) => {
83
+ const dialogRef = this.dialog.open(ConfirmDialog, {
84
+ width: 'auto',
85
+ height: 'auto',
86
+ data: {
87
+ message: message,
88
+ title: '@confirmation',
89
+ },
90
+ });
91
+ dialogRef.afterClosed().subscribe((result) => {
92
+ resolve(!!result);
93
+ });
94
+ });
82
95
  }
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
- }
96
+ // For success notifications
97
+ showSuccess(message, duration = 3000) {
98
+ this.snackBar.open(this.translate.instant(message), this.translate.instant('@btnOK'), {
99
+ duration,
100
+ panelClass: ['success-snackbar'],
101
+ horizontalPosition: 'right',
102
+ verticalPosition: 'bottom',
103
+ });
100
104
  }
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 ?? '');
105
+ /**
106
+ * Displays an error dialog with flexible parameters.
107
+ * Intelligently extracts meaningful C# error messages or falls back to a translation key.
108
+ * * Supported usages:
109
+ * - showError('@fallbackKey', err)
110
+ * - showError(err)
111
+ * - showError(err, '@fallbackKey')
112
+ * - showError('@fallbackKey')
113
+ */
114
+ showError(arg1, arg2, customComponent = ErrorAlert, width = 'auto', height = 'auto') {
115
+ const isArg1Str = typeof arg1 === 'string';
116
+ const fallbackKey = isArg1Str ? arg1 : (typeof arg2 === 'string' ? arg2 : '');
117
+ const errorObj = isArg1Str ? arg2 : arg1;
118
+ // Open the Dialog
119
+ return new Promise((resolve) => {
120
+ this.dialog.open(customComponent, {
121
+ width, height, maxWidth: '95vw',
122
+ data: {
123
+ message: this.getErrorMessage(errorObj, fallbackKey),
124
+ title: this.translate.instant('@errorOccurred'),
125
+ },
126
+ }).afterClosed().subscribe(() => resolve());
127
+ });
111
128
  }
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;
129
+ getErrorMessage(errorObj, fallbackKey) {
130
+ if (!errorObj) {
131
+ return fallbackKey ? this.translate.instant(fallbackKey) : this.translate.instant('@errorOccurred');
120
132
  }
121
- catch (error) {
122
- return '';
133
+ const data = errorObj.error ?? errorObj;
134
+ const isStr = typeof data === 'string';
135
+ const backendMessage = isStr ? data : (data?.message || data?.details || JSON.stringify(data));
136
+ const isMeaningful = isStr ? !data.startsWith('<') : !!(data?.message || data?.details);
137
+ if (fallbackKey) {
138
+ return isMeaningful ? backendMessage : this.translate.instant(fallbackKey);
123
139
  }
140
+ return backendMessage;
124
141
  }
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' });
142
+ 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 });
143
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, providedIn: 'root' });
127
144
  }
128
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, decorators: [{
145
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AlertService, decorators: [{
129
146
  type: Injectable,
130
147
  args: [{
131
148
  providedIn: 'root',
132
149
  }]
133
- }], ctorParameters: () => [] });
150
+ }], ctorParameters: () => [{ type: i1$2.MatSnackBar }, { type: i1.MatDialog }, { type: i1$1.TranslateService }] });
134
151
 
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
- });
152
+ class PageTitle {
153
+ title = signal('', ...(ngDevMode ? [{ debugName: "title" }] : []));
154
+ setTitle(newTitle) {
155
+ this.title.set(newTitle);
176
156
  }
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' });
157
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
158
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, providedIn: 'root' });
179
159
  }
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: [{
160
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PageTitle, decorators: [{
436
161
  type: Injectable,
437
162
  args: [{
438
163
  providedIn: 'root',
@@ -596,174 +321,575 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
596
321
  args: [{ selector: 'ntybase-netty-apps-base', imports: [], template: `` }]
597
322
  }], ctorParameters: () => [], propDecorators: { embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }] } });
598
323
 
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)) {
624
- return secondField;
625
- }
626
- return null;
324
+ class NettyAppsFilterBase extends NettyAppsBase {
325
+ // *********************************************************
326
+ // *** Input / Output ***
327
+ // *********************************************************
328
+ isFilterExpanded = model(true, ...(ngDevMode ? [{ debugName: "isFilterExpanded" }] : []));
329
+ filteredRecords = output();
330
+ filterSelectionChanged = output();
331
+ refresh = input(0, ...(ngDevMode ? [{ debugName: "refresh" }] : []));
332
+ fileName = input('nettyapps_', ...(ngDevMode ? [{ debugName: "fileName" }] : []));
333
+ // *********************************************************
334
+ // *** Service ***
335
+ // *********************************************************
336
+ filterProxy = injectNettyStandardFilterProxy(this.componentName());
337
+ // *********************************************************
338
+ // *** Signals ***
339
+ // *********************************************************
340
+ currentItem = signal(this.createNewFilter(), ...(ngDevMode ? [{ debugName: "currentItem" }] : []));
341
+ // *********************************************************
342
+ // *** Constructor ***
343
+ // *********************************************************
344
+ constructor() {
345
+ super();
346
+ effect(() => {
347
+ if (this.refresh() > 0) {
348
+ this.onApply();
349
+ }
350
+ });
627
351
  }
628
- }
629
-
630
- class CurrentUserPreference {
631
- coid = null;
632
- nettyUserPreferenceGUID = null;
633
- nettyUserGUID = null;
634
- nettyUserName = null;
635
- nettyUserFullName = null;
636
- nettyPreferenceType = null;
637
- nettyPreferenceData = null;
638
- init() {
639
- this.coid = null;
640
- this.nettyUserPreferenceGUID = null;
641
- this.nettyUserGUID = null;
642
- this.nettyUserName = '';
643
- this.nettyUserFullName = '';
644
- this.nettyPreferenceType = '';
645
- this.nettyPreferenceData = '';
352
+ // *********************************************************
353
+ // *** Functions ***
354
+ // *********************************************************
355
+ async ngOnInit() {
356
+ this.afterOnInit();
646
357
  }
647
- initParameter(parameters) {
648
- if (parameters == null || parameters == undefined) {
649
- this.init();
650
- return;
651
- }
652
- this.coid = parameters.coid;
653
- this.nettyUserPreferenceGUID = parameters.nettyUserPreferenceGUID;
654
- this.nettyUserGUID = parameters.nettyUserGUID;
655
- this.nettyUserName = parameters.nettyUserName;
656
- this.nettyUserFullName = parameters.nettyUserFullName;
657
- this.nettyPreferenceType = parameters.nettyPreferenceType;
658
- this.nettyPreferenceData = parameters.nettyPreferenceData;
358
+ onApply() {
359
+ this.filterSelectionChanged.emit(this.currentItem());
360
+ this.filterProxy.selectFilter(this.currentItem()).subscribe({
361
+ next: (result) => {
362
+ this.filteredRecords.emit(result);
363
+ this.isFilterExpanded.set(false);
364
+ },
365
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
366
+ });
659
367
  }
660
- compare(record) {
661
- let newRecord = new CurrentUserPreference();
662
- newRecord.init();
663
- newRecord.coid = record.coid;
664
- newRecord.nettyUserPreferenceGUID = record.nettyUserPreferenceGUID;
665
- newRecord.nettyUserGUID = NettyHelper.difference(this.nettyUserGUID, record.nettyUserGUID);
666
- newRecord.nettyPreferenceType = NettyHelper.difference(this.nettyPreferenceType, record.nettyPreferenceType);
667
- newRecord.nettyPreferenceData = NettyHelper.difference(this.nettyPreferenceData, record.nettyPreferenceData);
668
- return newRecord;
368
+ onReset() {
369
+ this.filterProxy.initFilter().subscribe({
370
+ next: (filter) => {
371
+ this.currentItem.set(filter);
372
+ this.filterSelectionChanged.emit(this.currentItem());
373
+ },
374
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
375
+ });
376
+ }
377
+ onExport() {
378
+ this.filterSelectionChanged.emit(this.currentItem());
379
+ this.filterProxy.downloadXLS(this.currentItem()).subscribe({
380
+ next: (response) => {
381
+ this.downloadBlobFile(response, 'application/zip', this.translateService.instant('@00000072') + '.zip');
382
+ },
383
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
384
+ });
385
+ }
386
+ async afterOnInit() { }
387
+ // *****************************************
388
+ // *** Logging Functions ***
389
+ // *****************************************
390
+ logInputs(message) {
391
+ if (!message || message.length < 1) {
392
+ message = 'NettyAppsFilterBase - Inputs log';
393
+ }
394
+ const inputs = {
395
+ "isFilterExpanded": this.isFilterExpanded(),
396
+ "refresh": this.refresh(),
397
+ "fileName": this.fileName(),
398
+ };
399
+ console.log(message, inputs);
669
400
  }
401
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAppsFilterBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
402
+ 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 });
670
403
  }
404
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAppsFilterBase, decorators: [{
405
+ type: Component,
406
+ args: [{ selector: 'ntybase-netty-apps-base', imports: [], template: `` }]
407
+ }], 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 }] }] } });
671
408
 
672
- class CommonService {
673
- // Services
674
- router = inject(Router);
675
- location = inject(Location);
676
- datePipe = inject(DatePipe);
677
- decimalPipe = inject(DecimalPipe);
409
+ class NettyBaseApp {
410
+ i18nService = inject(I18nService);
678
411
  alertService = inject(AlertService);
679
- translate = inject(TranslateService);
680
- dialog = inject(MatDialog);
681
- // Right sidenav
682
- rightSidenavOpen = signal(false, ...(ngDevMode ? [{ debugName: "rightSidenavOpen" }] : []));
683
- toggleRightSidenav(open) {
684
- this.rightSidenavOpen.set(open);
685
- }
686
- /**
687
- * Normalizes Turkish text for search and comparison operations by converting
688
- * Turkish special characters to their English equivalents and lowercasing.
689
- *
690
- */
691
- normalizeTurkish(text) {
692
- return text
693
- .replace(/I/g, 'i')
694
- .replace(/[ıİ]/g, 'i')
695
- .replace(/[ğĞ]/g, 'g')
696
- .replace(/[üÜ]/g, 'u')
697
- .replace(/[şŞ]/g, 's')
698
- .replace(/[öÖ]/g, 'o')
699
- .replace(/[çÇ]/g, 'c')
700
- .toLocaleLowerCase('tr-TR');
701
- }
702
- /**
703
- * Gets the clean URL path without fragments or query params
704
- */
705
- getCleanUrlPath() {
706
- const tree = this.router.parseUrl(this.router.url);
707
- const segments = tree.root.children['primary']?.segments || [];
708
- if (segments.length >= 2) {
709
- return segments
710
- .slice(0, 2)
711
- .map((s) => s.path)
712
- .join('/');
412
+ async loadBaseTranslations() {
413
+ try {
414
+ const enUSBase = await import('./nettyapps-ntybase-en-USbase-Bl-neyoj.mjs');
415
+ const trTRBase = await import('./nettyapps-ntybase-tr-TRbase-CO4HBOmj.mjs');
416
+ this.i18nService.addTranslations('English', enUSBase.default);
417
+ this.i18nService.addTranslations('Türkçe', trTRBase.default);
713
418
  }
714
- return '/';
715
- }
716
- /**
717
- * Clears the right sidenav outlet and resets the UI state.
718
- * Removes the right sidenav route while keeping the main content and query parameters.
719
- * Also collapses the sidenav and closes any open dialogs.
720
- */
721
- clearOutlet() {
722
- const currentUrl = this.router.parseUrl(this.router.url);
723
- const primaryOutlet = currentUrl.root.children['primary'];
724
- const rightSidenavOutlet = currentUrl.root.children['rightSidenav'];
725
- if (rightSidenavOutlet ||
726
- currentUrl.queryParams['parameters'] ||
727
- currentUrl.queryParams['type']) {
728
- this.router.navigate([
729
- {
730
- outlets: {
731
- rightSidenav: null,
732
- primary: primaryOutlet ? primaryOutlet.toString() : null,
733
- },
734
- },
735
- ], {
736
- queryParams: {},
737
- queryParamsHandling: '',
738
- replaceUrl: true,
739
- });
419
+ catch (error) {
420
+ this.alertService.showError('Error loading base translations in component:', error);
421
+ throw error;
740
422
  }
741
- this.toggleRightSidenav(false);
742
- this.dialog.closeAll();
743
423
  }
744
- ngOnDestroy() {
745
- this.clearOutlet();
424
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyBaseApp, deps: [], target: i0.ɵɵFactoryTarget.Component });
425
+ 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: [""] });
426
+ }
427
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyBaseApp, decorators: [{
428
+ type: Component,
429
+ args: [{ selector: 'ntybase-netty-base-app', imports: [], template: "" }]
430
+ }] });
431
+
432
+ class ParseLog {
433
+ rowIndex = 0; // Excel line no (1-based)
434
+ message = ""; // Error or info message (fallback)
435
+ level = "INFO";
436
+ messageKey; // i18n translation key
437
+ messageParams; // parameters for translation
438
+ init() {
439
+ this.rowIndex = 0;
440
+ this.message = "";
441
+ this.level = "INFO";
442
+ this.messageKey = undefined;
443
+ this.messageParams = undefined;
746
444
  }
747
- /** Merge columns with the given seperator
748
- *
749
- * @param columns string array to merge
750
- * @param seperator seperator for the array. space if null
751
- * @returns merged string
752
- */
753
- mergeColumns(columns, seperator = ' ') {
754
- let result = '';
755
- columns.forEach((column) => {
756
- if (!(column == undefined || column == null)) {
757
- if (result.length > 0) {
758
- result += seperator;
759
- }
760
- result += column.trim();
761
- }
762
- });
763
- return result.trim();
445
+ compare(other) { return this; }
446
+ getPK() { return this.rowIndex; }
447
+ setPK(pk) { this.rowIndex = pk; }
448
+ }
449
+
450
+ class ExcelParserError extends Error {
451
+ key;
452
+ params;
453
+ constructor(key, params) {
454
+ super(key);
455
+ this.key = key;
456
+ this.params = params;
457
+ this.name = 'ExcelParserError';
764
458
  }
765
- /** Go back to the last page or close the tab
766
- *
459
+ }
460
+ class ExcelParser {
461
+ mappings;
462
+ constructor(mappings) {
463
+ this.mappings = mappings;
464
+ }
465
+ async parse(file, options) {
466
+ // PERFORMANS: XLSX library only loads at parse time!
467
+ const XLSX = await import('xlsx');
468
+ const sheetIndex = options?.sheetIndex ?? 0;
469
+ const headerRowIndex = options?.headerRowIndex ?? 0; // 0-based
470
+ return new Promise((resolve, reject) => {
471
+ const reader = new FileReader();
472
+ reader.onload = (e) => {
473
+ try {
474
+ const data = new Uint8Array(e.target?.result);
475
+ const workbook = XLSX.read(data, { type: 'array' });
476
+ if (!workbook.SheetNames[sheetIndex]) {
477
+ throw new ExcelParserError('@EXCEL_PARSER.sheetNotFound', { index: sheetIndex });
478
+ }
479
+ const sheetName = workbook.SheetNames[sheetIndex];
480
+ const sheet = workbook.Sheets[sheetName];
481
+ const rows = XLSX.utils.sheet_to_json(sheet, { header: 1 });
482
+ const logs = [];
483
+ const result = [];
484
+ // Skip headerline
485
+ const dataRows = rows.slice(headerRowIndex + 1);
486
+ dataRows.forEach((row, i) => {
487
+ // Skip empty lines
488
+ if (!row || row.length === 0)
489
+ return;
490
+ const obj = {};
491
+ let hasError = false;
492
+ const actualRowIndex = headerRowIndex + i + 2; // Excel line no (1-based)
493
+ this.mappings.forEach(m => {
494
+ let rawValue = row[m.index];
495
+ if ((rawValue === undefined || rawValue === null || rawValue === '') && m.defaultValue !== undefined) {
496
+ rawValue = m.defaultValue;
497
+ logs.push(Object.assign(new ParseLog(), {
498
+ rowIndex: actualRowIndex,
499
+ message: `Boş alan için default değer atandı: ${String(m.prop)}`,
500
+ level: 'INFO',
501
+ messageKey: '@EXCEL_PARSER.defaultValueSet',
502
+ messageParams: { prop: String(m.prop) }
503
+ }));
504
+ }
505
+ if (m.required && (rawValue === undefined || rawValue === null || rawValue === '')) {
506
+ logs.push(Object.assign(new ParseLog(), {
507
+ rowIndex: actualRowIndex,
508
+ message: `Zorunlu alan boş: ${String(m.prop)}`,
509
+ level: 'ERROR',
510
+ messageKey: '@EXCEL_PARSER.requiredFieldMissing',
511
+ messageParams: { prop: String(m.prop) }
512
+ }));
513
+ hasError = true;
514
+ }
515
+ try {
516
+ obj[m.prop] = m.converter ? m.converter(rawValue) : rawValue;
517
+ }
518
+ catch (err) {
519
+ logs.push(Object.assign(new ParseLog(), {
520
+ rowIndex: actualRowIndex,
521
+ message: `Tip dönüşüm hatası: ${String(m.prop)} -> ${rawValue}`,
522
+ level: 'ERROR',
523
+ messageKey: '@EXCEL_PARSER.conversionError',
524
+ messageParams: { prop: String(m.prop), value: rawValue }
525
+ }));
526
+ hasError = true;
527
+ }
528
+ });
529
+ if (!hasError) {
530
+ result.push(obj);
531
+ }
532
+ else {
533
+ logs.push(Object.assign(new ParseLog(), {
534
+ rowIndex: actualRowIndex,
535
+ message: `Satır atlandı`,
536
+ level: 'WARN',
537
+ messageKey: '@EXCEL_PARSER.rowSkipped'
538
+ }));
539
+ }
540
+ });
541
+ resolve({ data: result, logs });
542
+ }
543
+ catch (error) {
544
+ reject(error);
545
+ }
546
+ };
547
+ reader.onerror = () => reject(reader.error);
548
+ reader.readAsArrayBuffer(file);
549
+ });
550
+ }
551
+ async generateSampleExcel(options) {
552
+ const sampleCount = options?.sampleCount ?? 5;
553
+ const fileName = (options?.fileName ?? 'sample-import.xlsx').endsWith('.xlsx')
554
+ ? (options?.fileName ?? 'sample-import.xlsx')
555
+ : `${options?.fileName}.xlsx`;
556
+ const sheetName = (options?.sheetName ?? 'Sample').substring(0, 15);
557
+ const XLSX = await import('xlsx');
558
+ // Header row: property names according to column order
559
+ const headers = this.mappings.map(m => m.headerName || String(m.prop));
560
+ const rows = [];
561
+ for (let i = 1; i <= sampleCount; i++) {
562
+ const row = this.mappings.map(m => {
563
+ if (m.sampleValue !== undefined) {
564
+ // Use sampleValue if it exists
565
+ return typeof m.sampleValue === 'function'
566
+ ? m.sampleValue(i) // if it's a function, generate value based on index
567
+ : m.sampleValue; // if it's a constant value, use it directly
568
+ }
569
+ });
570
+ rows.push(row);
571
+ }
572
+ const worksheet = XLSX.utils.aoa_to_sheet([headers, ...rows]);
573
+ const workbook = XLSX.utils.book_new();
574
+ XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
575
+ XLSX.writeFile(workbook, fileName);
576
+ }
577
+ }
578
+
579
+ class ButtonRenderer {
580
+ params = null;
581
+ label = '';
582
+ type = '';
583
+ toggleValue = null;
584
+ editValid = false;
585
+ historyValid = false;
586
+ lineValid = false;
587
+ popupSelectValid = false;
588
+ popupEditValid = false;
589
+ toggleValid = false;
590
+ toggle_icon = '';
591
+ none = false;
592
+ addValid = false;
593
+ deleteValid = false;
594
+ agInit(params) {
595
+ this.params = params;
596
+ this.type = this.params.type || null;
597
+ this.label = this.params.label || null;
598
+ this.toggleValue = this.params.value || null;
599
+ switch (this.toggleValue) {
600
+ case true:
601
+ this.toggle_icon = 'select_check_box';
602
+ break;
603
+ case false:
604
+ this.toggle_icon = 'check_box_outline_blank';
605
+ break;
606
+ default:
607
+ this.toggle_icon = '';
608
+ break;
609
+ }
610
+ this.resetValids();
611
+ switch (this.type.toLowerCase().trim()) {
612
+ case 'edit':
613
+ this.editValid = true;
614
+ break;
615
+ case 'log':
616
+ this.historyValid = true;
617
+ break;
618
+ case 'line':
619
+ this.lineValid = true;
620
+ break;
621
+ case 'popupselect':
622
+ this.popupSelectValid = true;
623
+ break;
624
+ case 'toggle':
625
+ this.toggleValid = true;
626
+ break;
627
+ case 'none':
628
+ this.none = true;
629
+ break;
630
+ case 'add':
631
+ this.addValid = true;
632
+ break;
633
+ case 'delete':
634
+ this.deleteValid = true;
635
+ break;
636
+ default:
637
+ this.popupEditValid = true;
638
+ break;
639
+ }
640
+ }
641
+ /** Refresh the display
642
+ *
643
+ * @param params
644
+ * @returns
645
+ */
646
+ refresh(params) {
647
+ return false;
648
+ }
649
+ resetValids() {
650
+ this.editValid = false;
651
+ this.historyValid = false;
652
+ this.lineValid = false;
653
+ this.popupSelectValid = false;
654
+ this.popupEditValid = false;
655
+ this.toggleValid = false;
656
+ }
657
+ onClick(event) {
658
+ if (this.params.onClick instanceof Function) {
659
+ // put anything into params u want pass into parents component
660
+ const params = {
661
+ event: event,
662
+ rowData: this.params.node.data,
663
+ type: this.type,
664
+ // ...something
665
+ };
666
+ this.params.onClick(params);
667
+ }
668
+ }
669
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ButtonRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
670
+ 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 }] });
671
+ }
672
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ButtonRenderer, decorators: [{
673
+ type: Component,
674
+ 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"] }]
675
+ }] });
676
+
677
+ class CheckboxRenderer {
678
+ params = null;
679
+ label = '';
680
+ type = '';
681
+ supportClick = false;
682
+ checked = null;
683
+ agInit(params) {
684
+ this.onProcess(params);
685
+ }
686
+ refresh(params) {
687
+ if (params != null) {
688
+ this.onProcess(params);
689
+ }
690
+ return true;
691
+ }
692
+ onProcess(params) {
693
+ this.params = params;
694
+ this.checked = this.params.value ?? false;
695
+ this.type = this.params.type || null;
696
+ this.label = this.params.label || null;
697
+ if (this.type != null) {
698
+ if (this.type.toLowerCase().trim() == 'click') {
699
+ this.supportClick = true;
700
+ }
701
+ }
702
+ }
703
+ onClick(event) {
704
+ this.checked = !this.checked;
705
+ if (this.params.onClick instanceof Function) {
706
+ // put anything into params u want pass into parents component
707
+ const params = {
708
+ event: event,
709
+ rowData: this.params.node.data,
710
+ type: this.type,
711
+ checked: this.checked,
712
+ // ...something
713
+ };
714
+ this.params.onClick(params);
715
+ }
716
+ }
717
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
718
+ 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: [""] });
719
+ }
720
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxRenderer, decorators: [{
721
+ type: Component,
722
+ 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" }]
723
+ }] });
724
+
725
+ class NettyHelper {
726
+ /**
727
+ * Returns null if fields are equal otherwise return second field
728
+ * @param firstField
729
+ * @param secondField
730
+ * @returns
731
+ */
732
+ static difference(firstField, secondField) {
733
+ if (firstField != secondField) {
734
+ return secondField;
735
+ }
736
+ return null;
737
+ }
738
+ /**
739
+ * Returns null if fields are equal otherwise return second field
740
+ * @param firstField
741
+ * @param secondField
742
+ * @param format
743
+ * @returns
744
+ */
745
+ static dateDifference(firstField, secondField, format) {
746
+ let culture = localStorage.getItem('languageApiCode') ?? 'tr-TR';
747
+ let datePipe = new DatePipe(culture);
748
+ if (datePipe.transform(firstField, format) !=
749
+ datePipe.transform(secondField, format)) {
750
+ return secondField;
751
+ }
752
+ return null;
753
+ }
754
+ }
755
+
756
+ class CurrentUserPreference {
757
+ coid = null;
758
+ nettyUserPreferenceGUID = null;
759
+ nettyUserGUID = null;
760
+ nettyUserName = null;
761
+ nettyUserFullName = null;
762
+ nettyPreferenceType = null;
763
+ nettyPreferenceData = null;
764
+ init() {
765
+ this.coid = null;
766
+ this.nettyUserPreferenceGUID = null;
767
+ this.nettyUserGUID = null;
768
+ this.nettyUserName = '';
769
+ this.nettyUserFullName = '';
770
+ this.nettyPreferenceType = '';
771
+ this.nettyPreferenceData = '';
772
+ }
773
+ initParameter(parameters) {
774
+ if (parameters == null || parameters == undefined) {
775
+ this.init();
776
+ return;
777
+ }
778
+ this.coid = parameters.coid;
779
+ this.nettyUserPreferenceGUID = parameters.nettyUserPreferenceGUID;
780
+ this.nettyUserGUID = parameters.nettyUserGUID;
781
+ this.nettyUserName = parameters.nettyUserName;
782
+ this.nettyUserFullName = parameters.nettyUserFullName;
783
+ this.nettyPreferenceType = parameters.nettyPreferenceType;
784
+ this.nettyPreferenceData = parameters.nettyPreferenceData;
785
+ }
786
+ compare(record) {
787
+ let newRecord = new CurrentUserPreference();
788
+ newRecord.init();
789
+ newRecord.coid = record.coid;
790
+ newRecord.nettyUserPreferenceGUID = record.nettyUserPreferenceGUID;
791
+ newRecord.nettyUserGUID = NettyHelper.difference(this.nettyUserGUID, record.nettyUserGUID);
792
+ newRecord.nettyPreferenceType = NettyHelper.difference(this.nettyPreferenceType, record.nettyPreferenceType);
793
+ newRecord.nettyPreferenceData = NettyHelper.difference(this.nettyPreferenceData, record.nettyPreferenceData);
794
+ return newRecord;
795
+ }
796
+ }
797
+
798
+ class CommonService {
799
+ // Services
800
+ router = inject(Router);
801
+ location = inject(Location);
802
+ datePipe = inject(DatePipe);
803
+ decimalPipe = inject(DecimalPipe);
804
+ alertService = inject(AlertService);
805
+ translate = inject(TranslateService);
806
+ dialog = inject(MatDialog);
807
+ // Right sidenav
808
+ rightSidenavOpen = signal(false, ...(ngDevMode ? [{ debugName: "rightSidenavOpen" }] : []));
809
+ toggleRightSidenav(open) {
810
+ this.rightSidenavOpen.set(open);
811
+ }
812
+ /**
813
+ * Normalizes Turkish text for search and comparison operations by converting
814
+ * Turkish special characters to their English equivalents and lowercasing.
815
+ *
816
+ */
817
+ normalizeTurkish(text) {
818
+ return text
819
+ .replace(/I/g, 'i')
820
+ .replace(/[ıİ]/g, 'i')
821
+ .replace(/[ğĞ]/g, 'g')
822
+ .replace(/[üÜ]/g, 'u')
823
+ .replace(/[şŞ]/g, 's')
824
+ .replace(/[öÖ]/g, 'o')
825
+ .replace(/[çÇ]/g, 'c')
826
+ .toLocaleLowerCase('tr-TR');
827
+ }
828
+ /**
829
+ * Gets the clean URL path without fragments or query params
830
+ */
831
+ getCleanUrlPath() {
832
+ const tree = this.router.parseUrl(this.router.url);
833
+ const segments = tree.root.children['primary']?.segments || [];
834
+ if (segments.length >= 2) {
835
+ return segments
836
+ .slice(0, 2)
837
+ .map((s) => s.path)
838
+ .join('/');
839
+ }
840
+ return '/';
841
+ }
842
+ /**
843
+ * Clears the right sidenav outlet and resets the UI state.
844
+ * Removes the right sidenav route while keeping the main content and query parameters.
845
+ * Also collapses the sidenav and closes any open dialogs.
846
+ */
847
+ clearOutlet() {
848
+ const currentUrl = this.router.parseUrl(this.router.url);
849
+ const primaryOutlet = currentUrl.root.children['primary'];
850
+ const rightSidenavOutlet = currentUrl.root.children['rightSidenav'];
851
+ if (rightSidenavOutlet ||
852
+ currentUrl.queryParams['parameters'] ||
853
+ currentUrl.queryParams['type']) {
854
+ this.router.navigate([
855
+ {
856
+ outlets: {
857
+ rightSidenav: null,
858
+ primary: primaryOutlet ? primaryOutlet.toString() : null,
859
+ },
860
+ },
861
+ ], {
862
+ queryParams: {},
863
+ queryParamsHandling: '',
864
+ replaceUrl: true,
865
+ });
866
+ }
867
+ this.toggleRightSidenav(false);
868
+ this.dialog.closeAll();
869
+ }
870
+ ngOnDestroy() {
871
+ this.clearOutlet();
872
+ }
873
+ /** Merge columns with the given seperator
874
+ *
875
+ * @param columns string array to merge
876
+ * @param seperator seperator for the array. space if null
877
+ * @returns merged string
878
+ */
879
+ mergeColumns(columns, seperator = ' ') {
880
+ let result = '';
881
+ columns.forEach((column) => {
882
+ if (!(column == undefined || column == null)) {
883
+ if (result.length > 0) {
884
+ result += seperator;
885
+ }
886
+ result += column.trim();
887
+ }
888
+ });
889
+ return result.trim();
890
+ }
891
+ /** Go back to the last page or close the tab
892
+ *
767
893
  */
768
894
  goBack() {
769
895
  if (!document.referrer) {
@@ -1280,12 +1406,12 @@ class SysfunctionProxy {
1280
1406
  securityDto.formCode = formCode;
1281
1407
  securityDto.application = this.environmentProxy.getApplicationName();
1282
1408
  let call$ = this.http.post(sysFunctionsURL, securityDto);
1283
- return call$.pipe(map((result) => result), catchError$1((error) => {
1409
+ return call$.pipe(map((result) => result), catchError((error) => {
1284
1410
  let errorMessage = error.message; //.error.title;
1285
1411
  return throwError(() => new Error(errorMessage ?? ''));
1286
1412
  }));
1287
1413
  }
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 });
1414
+ 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
1415
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SysfunctionProxy, providedIn: 'root' });
1290
1416
  }
1291
1417
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SysfunctionProxy, decorators: [{
@@ -1293,7 +1419,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
1293
1419
  args: [{
1294
1420
  providedIn: 'root',
1295
1421
  }]
1296
- }], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: i2$1.EnvironmentProxy }] });
1422
+ }], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: i2$2.EnvironmentProxy }] });
1297
1423
 
1298
1424
  class NettyAgGridBase extends NettyAppsBase {
1299
1425
  FILTER_MODE_KEY = 'nettyapps_filter_mode';
@@ -1764,180 +1890,34 @@ class NettyAgGridBase extends NettyAppsBase {
1764
1890
  "_isPopupValid": this._isPopupValid(),
1765
1891
  "componantParameterGUID": this.componantParameterGUID(),
1766
1892
  "componantParameterType": this.componantParameterType(),
1767
- "embedded": this.embedded(),
1768
- "_isEmbedded": this._isEmbedded(),
1769
- };
1770
- console.log(message, inputs);
1771
- }
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 });
1790
- }
1791
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridBase, decorators: [{
1792
- 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 }] }] } });
1795
-
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);
1884
- }
1885
- }
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 }] });
1888
- }
1889
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ButtonRenderer, decorators: [{
1890
- 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"] }]
1892
- }] });
1893
-
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
- }
1893
+ "embedded": this.embedded(),
1894
+ "_isEmbedded": this._isEmbedded(),
1895
+ };
1896
+ console.log(message, inputs);
1919
1897
  }
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);
1898
+ logAuthentication(message) {
1899
+ if (!message || message.length < 1) {
1900
+ message = 'agGridBase - Authentication log';
1932
1901
  }
1902
+ const inputs = {
1903
+ "authenticationList": this.authenticationList,
1904
+ "accessRightsProcessed": this.accessRightsProcessed(),
1905
+ "readOnly": this.readOnly(),
1906
+ "allowAdd": this.allowAdd(),
1907
+ "allowEdit": this.allowEdit(),
1908
+ "allowDelete": this.allowDelete(),
1909
+ "allowLog": this.allowLog(),
1910
+ "allowRead": this.allowRead(),
1911
+ };
1912
+ console.log(message, inputs);
1933
1913
  }
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: [""] });
1914
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
1915
+ 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 });
1936
1916
  }
1937
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxRenderer, decorators: [{
1917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridBase, decorators: [{
1938
1918
  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" }]
1940
- }] });
1919
+ args: [{ selector: 'ntybase-ag-grid-base', imports: [], template: ``, host: { 'ntybase-id': 'NettyAgGridBase' } }]
1920
+ }], 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 }] }] } });
1941
1921
 
1942
1922
  ModuleRegistry.registerModules([AllCommunityModule, StatusBarModule, ClientSideRowModelModule, ClipboardModule, ExcelExportModule, ColumnMenuModule,
1943
1923
  ContextMenuModule, CellSelectionModule, HighlightChangesModule, RowSelectionModule, SetFilterModule, MultiFilterModule, TextFilterModule, NumberFilterModule, DateFilterModule]);
@@ -2054,120 +2034,447 @@ class NettyAgGridListBase extends NettyAgGridBase {
2054
2034
  * - Grid API is not ready, or
2055
2035
  * - The update type doesn't match
2056
2036
  */
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);
2037
+ constructor() {
2038
+ super();
2039
+ this.frameworkComponents = {
2040
+ buttonRenderer: ButtonRenderer,
2041
+ checkboxRenderer: CheckboxRenderer,
2042
+ };
2043
+ const savedMode = localStorage.getItem('openInPopup');
2044
+ if (savedMode !== null) {
2045
+ this.openInPopup.set(JSON.parse(savedMode) === true);
2046
+ }
2047
+ this.translateService.onLangChange.subscribe(() => {
2048
+ this.setAgGridTranslations();
2049
+ });
2050
+ effect(() => {
2051
+ const update = this.commonService.updates();
2052
+ if (!update || !this.gridApi)
2053
+ return;
2054
+ if (update.type === this.getEntityType?.()) {
2055
+ switch (update.action) {
2056
+ case 'add':
2057
+ case 'update':
2058
+ this.updateRowInGrid(update.data, this.pkFieldName());
2059
+ break;
2060
+ }
2061
+ }
2062
+ });
2063
+ effect(() => { this.onElementSelect.emit(this.selectedRows()); });
2064
+ // Manage filter expanded state
2065
+ effect(() => {
2066
+ this._isEmbedded();
2067
+ this.initAgGrid();
2068
+ });
2069
+ effect(() => {
2070
+ const isEmbedded = this._isEmbedded();
2071
+ const currentPref = this.preferenceType();
2072
+ const currentSearch = this.searchValueName();
2073
+ if (isEmbedded) {
2074
+ if (currentPref && !currentPref.endsWith('_isEmbedded')) {
2075
+ this.preferenceType.set(`${currentPref}_isEmbedded`);
2076
+ }
2077
+ if (currentSearch && !currentSearch.endsWith('_isEmbedded')) {
2078
+ this.searchValueName.set(`${currentSearch}_isEmbedded`);
2079
+ }
2080
+ }
2081
+ else {
2082
+ if (currentPref?.endsWith('_isEmbedded')) {
2083
+ this.preferenceType.set(currentPref.replace('_isEmbedded', ''));
2084
+ }
2085
+ if (currentSearch?.endsWith('_isEmbedded')) {
2086
+ this.searchValueName.set(currentSearch.replace('_isEmbedded', ''));
2087
+ }
2088
+ }
2089
+ });
2090
+ }
2091
+ // *********************************************************
2092
+ // *** Data Management Functions ***
2093
+ // *********************************************************
2094
+ loadData() {
2095
+ this.nettyAppsProxy.select(this.record).subscribe({
2096
+ next: (data) => {
2097
+ this.setData(data, false);
2098
+ },
2099
+ error: (err) => this.alertService.showError('@dataLoadFailed', err),
2100
+ });
2101
+ }
2102
+ async deleteSelected() {
2103
+ if (!this.gridApi)
2104
+ return;
2105
+ const selectedNodes = this.gridApi.getSelectedNodes();
2106
+ if (selectedNodes.length === 0) {
2107
+ await this.alertService.showAlert('@pleaseSelectRowToDelete');
2108
+ return;
2109
+ }
2110
+ const confirmed = await this.alertService.showConfirm('@confirmDeleteSelectedRecords');
2111
+ if (confirmed) {
2112
+ const selectedRows = selectedNodes.map((node) => node.data);
2113
+ this.deleteRows(selectedRows);
2114
+ }
2115
+ }
2116
+ deleteRows(rows) {
2117
+ this.nettyAppsProxy.deleteList(rows).subscribe({
2118
+ next: () => {
2119
+ this.gridApi.applyTransaction({ remove: rows });
2120
+ this.alertService.showSuccess('@recordDeletedSuccessfully');
2121
+ },
2122
+ error: (err) => this.alertService.showError(err),
2123
+ });
2124
+ }
2125
+ // *****************************************
2126
+ // *** Logging Functions ***
2127
+ // *****************************************
2128
+ logInputs(message) {
2129
+ if (!message || message.length < 1) {
2130
+ message = 'AgGridListBase - Inputs log';
2131
+ }
2132
+ const inputs = {
2133
+ "popupFilterValid": this.popupFilterValid(),
2134
+ "_isPopupFilterValid": this._isPopupFilterValid(),
2135
+ "popupValid": this.popupValid(),
2136
+ "_isPopupValid": this._isPopupValid(),
2137
+ "componantParameterGUID": this.componantParameterGUID(),
2138
+ "componantParameterType": this.componantParameterType(),
2139
+ "embedded": this.embedded(),
2140
+ "_isEmbedded": this._isEmbedded(),
2141
+ };
2142
+ console.log(message, inputs);
2143
+ }
2144
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridListBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
2145
+ 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 });
2146
+ }
2147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridListBase, decorators: [{
2148
+ type: Component,
2149
+ args: [{ selector: 'ntybase-ag-grid-list-base', imports: [], template: ``, host: { 'ntybase-id': 'NettyAgGridListBase' } }]
2150
+ }], ctorParameters: () => [] });
2151
+
2152
+ class ExcelImportBase extends NettyAgGridListBase {
2153
+ isFileSelectionHidden = signal(false, ...(ngDevMode ? [{ debugName: "isFileSelectionHidden" }] : []));
2154
+ isFileValid = signal(false, ...(ngDevMode ? [{ debugName: "isFileValid" }] : []));
2155
+ logs = signal([], ...(ngDevMode ? [{ debugName: "logs" }] : []));
2156
+ hasLogs = computed(() => this.logs().length > 0, ...(ngDevMode ? [{ debugName: "hasLogs" }] : []));
2157
+ logDialog = inject(MatDialog);
2158
+ parser = new ExcelParser([]);
2159
+ // override methods
2160
+ onBtnClick(e) { }
2161
+ loadData() { }
2162
+ // Methods
2163
+ onFilesSelected(evt) {
2164
+ const files = Array.isArray(evt) ? evt : evt.target.files;
2165
+ if (!files || files.length !== 1) {
2166
+ return;
2167
+ }
2168
+ const file = files[0];
2169
+ if (file) {
2170
+ this.recordList.set([]);
2171
+ this.logs.set([]);
2172
+ this.parser.parse(file).then(result => {
2173
+ this.recordList.set(result.data);
2174
+ this.logs.set(result.logs);
2175
+ this.isFileSelectionHidden.set(true);
2176
+ if (result.logs.length > 0)
2177
+ this.showLogs();
2178
+ });
2179
+ }
2180
+ }
2181
+ downloadSampleExcel() {
2182
+ this.parser.generateSampleExcel();
2183
+ }
2184
+ showLogs() {
2185
+ const dialogRef = this.logDialog.open(ExcelLogViewer, {
2186
+ height: '70%',
2187
+ width: '90%',
2188
+ maxWidth: '100vw',
2189
+ maxHeight: '100vh'
2190
+ });
2191
+ dialogRef.componentInstance.setParseData(this.logs());
2192
+ dialogRef.componentInstance.selectedElement.subscribe((element) => {
2193
+ dialogRef.close();
2194
+ });
2195
+ }
2196
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelImportBase, deps: null, target: i0.ɵɵFactoryTarget.Component });
2197
+ 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 });
2198
+ }
2199
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelImportBase, decorators: [{
2200
+ type: Component,
2201
+ args: [{ selector: 'ntybase-excel-import-base', imports: [], template: `` }]
2202
+ }] });
2203
+
2204
+ class Ntybase {
2205
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Ntybase, deps: [], target: i0.ɵɵFactoryTarget.Component });
2206
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: Ntybase, isStandalone: false, selector: "lib-ntybase", ngImport: i0, template: `
2207
+ <p>
2208
+ ntybase works!
2209
+ </p>
2210
+ `, isInline: true, styles: [""] });
2211
+ }
2212
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: Ntybase, decorators: [{
2213
+ type: Component,
2214
+ args: [{ selector: 'lib-ntybase', standalone: false, template: `
2215
+ <p>
2216
+ ntybase works!
2217
+ </p>
2218
+ ` }]
2219
+ }] });
2220
+
2221
+ const credentialsKey = 'credentials';
2222
+ class CredentialsService {
2223
+ _credentials = null;
2224
+ constructor() {
2225
+ const savedCredentials = sessionStorage.getItem(credentialsKey) ||
2226
+ localStorage.getItem(credentialsKey);
2227
+ if (savedCredentials) {
2228
+ this._credentials = JSON.parse(savedCredentials);
2229
+ }
2230
+ }
2231
+ /**
2232
+ * Checks is the user is authenticated.
2233
+ * @return True if the user is authenticated.
2234
+ */
2235
+ isAuthenticated() {
2236
+ return !!this.credentials;
2237
+ }
2238
+ /**
2239
+ * Gets the user credentials.
2240
+ * @return The user credentials or null if the user is not authenticated.
2241
+ */
2242
+ get credentials() {
2243
+ return this._credentials;
2244
+ }
2245
+ get token() {
2246
+ return this._credentials?.token ?? null;
2247
+ }
2248
+ /**
2249
+ * Sets the user credentials.
2250
+ * The credentials may be persisted across sessions by setting the `remember` parameter to true.
2251
+ * Otherwise, the credentials are only persisted for the current session.
2252
+ * @param credentials The user credentials.
2253
+ * @param remember True to remember credentials across sessions.
2254
+ */
2255
+ setCredentials(credentials, remember) {
2256
+ this._credentials = credentials || null;
2257
+ if (credentials) {
2258
+ const storage = remember ? localStorage : sessionStorage;
2259
+ storage.setItem(credentialsKey, JSON.stringify(credentials));
2260
+ }
2261
+ else {
2262
+ sessionStorage.removeItem(credentialsKey);
2263
+ localStorage.removeItem(credentialsKey);
2066
2264
  }
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;
2080
- }
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`);
2096
- }
2097
- if (currentSearch && !currentSearch.endsWith('_isEmbedded')) {
2098
- this.searchValueName.set(`${currentSearch}_isEmbedded`);
2099
- }
2100
- }
2101
- else {
2102
- if (currentPref?.endsWith('_isEmbedded')) {
2103
- this.preferenceType.set(currentPref.replace('_isEmbedded', ''));
2104
- }
2105
- if (currentSearch?.endsWith('_isEmbedded')) {
2106
- this.searchValueName.set(currentSearch.replace('_isEmbedded', ''));
2107
- }
2108
- }
2109
- });
2110
2265
  }
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
- });
2266
+ /** Get Credentials
2267
+ *
2268
+ * @returns
2269
+ */
2270
+ getCredentials() {
2271
+ let _credentialsString = sessionStorage.getItem(credentialsKey);
2272
+ if (_credentialsString == null || _credentialsString == '') {
2273
+ _credentialsString = localStorage.getItem(credentialsKey);
2274
+ }
2275
+ return JSON.parse(_credentialsString ?? '');
2121
2276
  }
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;
2277
+ /** Get the token if available otherwise return empty string
2278
+ *
2279
+ * @returns
2280
+ */
2281
+ getToken() {
2282
+ try {
2283
+ let _credentials = this.getCredentials();
2284
+ return _credentials.token;
2129
2285
  }
2130
- const confirmed = await this.alertService.showConfirm('@confirmDeleteSelectedRecords');
2131
- if (confirmed) {
2132
- const selectedRows = selectedNodes.map((node) => node.data);
2133
- this.deleteRows(selectedRows);
2286
+ catch (error) {
2287
+ return '';
2134
2288
  }
2135
2289
  }
2136
- deleteRows(rows) {
2137
- this.nettyAppsProxy.deleteList(rows).subscribe({
2138
- next: () => {
2139
- this.gridApi.applyTransaction({ remove: rows });
2140
- this.alertService.showSuccess('@recordDeletedSuccessfully');
2290
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2291
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, providedIn: 'root' });
2292
+ }
2293
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CredentialsService, decorators: [{
2294
+ type: Injectable,
2295
+ args: [{
2296
+ providedIn: 'root',
2297
+ }]
2298
+ }], ctorParameters: () => [] });
2299
+
2300
+ class UrlHelperService {
2301
+ router = inject(Router);
2302
+ cleanUrl(url) {
2303
+ let result = url
2304
+ .replace('/mfalogin?redirect=', '')
2305
+ .replace('/mfalogin?redirect=', '')
2306
+ .replace('/mfalogin?redirect=', '')
2307
+ .replace('/login?redirect=', '')
2308
+ .replace('/login?redirect=', '')
2309
+ .replace('/login?redirect=', '')
2310
+ .replace(new RegExp('%25', 'g'), '%')
2311
+ .replace(new RegExp('%25', 'g'), '%')
2312
+ .replace(new RegExp('%25', 'g'), '%')
2313
+ .replace(new RegExp('%25', 'g'), '%')
2314
+ .replace(new RegExp('%25', 'g'), '%')
2315
+ .replace(new RegExp('%25', 'g'), '%')
2316
+ .replace(new RegExp('%22', 'g'), '"')
2317
+ .replace(new RegExp('%3F', 'g'), '?')
2318
+ .replace(new RegExp('%3D', 'g'), '=')
2319
+ .replace(new RegExp('%2F', 'g'), '/')
2320
+ .replace(new RegExp('%26', 'g'), '&')
2321
+ .replace(new RegExp('/mfalogin?redirect=', 'g'), '')
2322
+ .replace(new RegExp('/login?redirect=', 'g'), '');
2323
+ console.log('url:', url);
2324
+ console.log('result:', result);
2325
+ // return url;
2326
+ return result;
2327
+ }
2328
+ navigate(url) {
2329
+ let urlParts = url.split('?');
2330
+ if (urlParts.length == 1) {
2331
+ return this.router.navigate(urlParts, { replaceUrl: true });
2332
+ }
2333
+ let parameters = urlParts[1].split('&');
2334
+ return this.router.navigate([urlParts[0]], {
2335
+ queryParams: {
2336
+ parameters: parameters[0]?.replace('parameters=', '') ?? '',
2337
+ type: parameters[1]?.replace('type=', '') ?? '',
2141
2338
  },
2142
- error: (err) => this.alertService.showError(err),
2339
+ replaceUrl: true,
2143
2340
  });
2144
2341
  }
2145
- // *****************************************
2146
- // *** Logging Functions ***
2147
- // *****************************************
2148
- logInputs(message) {
2149
- if (!message || message.length < 1) {
2150
- message = 'AgGridListBase - Inputs log';
2342
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2343
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, providedIn: 'root' });
2344
+ }
2345
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UrlHelperService, decorators: [{
2346
+ type: Injectable,
2347
+ args: [{
2348
+ providedIn: 'root',
2349
+ }]
2350
+ }] });
2351
+
2352
+ class AuthenticationInterceptor {
2353
+ router = inject(Router);
2354
+ credentialsService = inject(CredentialsService);
2355
+ environmentProxy = inject(EnvironmentProxy);
2356
+ urlHelperService = inject(UrlHelperService);
2357
+ intercept(req, next) {
2358
+ if (req.headers.get('No-Auth') == 'True')
2359
+ return next.handle(req.clone());
2360
+ let token = this.credentialsService.token;
2361
+ if (token != null) {
2362
+ let appName = this.environmentProxy.getApplicationName();
2363
+ const clonedreq = req.clone({
2364
+ headers: req.headers.set('Authorization', 'Bearer ' + token),
2365
+ // .set("NettyAppName",appName)
2366
+ });
2367
+ return next.handle(clonedreq).pipe(catchError$1((error) => {
2368
+ if (error instanceof HttpErrorResponse && error.status === 401) {
2369
+ // Handle 401 error, e.g., navigate to the login page
2370
+ this.router.navigate(['/login'], {
2371
+ queryParams: {
2372
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2373
+ },
2374
+ replaceUrl: true,
2375
+ });
2376
+ // Return an observable with a successful response
2377
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2378
+ }
2379
+ if (error instanceof HttpErrorResponse && error.status === 403) {
2380
+ this.router.navigate(['/forbidden'], {
2381
+ state: { attemptedUrl: this.router.url }, // Orijinal URL'i state olarak geçme
2382
+ });
2383
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2384
+ }
2385
+ if (error instanceof HttpErrorResponse && error.status === 428) {
2386
+ // Handle 428 error, e.g., navigate to the login page
2387
+ this.router.navigate(['/mfalogin'], {
2388
+ queryParams: {
2389
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2390
+ },
2391
+ replaceUrl: true,
2392
+ });
2393
+ // Return an observable with a successful response
2394
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2395
+ }
2396
+ // For other errors, re-throw the error to propagate it further
2397
+ return throwError(() => error);
2398
+ }));
2399
+ }
2400
+ else {
2401
+ return next.handle(req.clone()).pipe(catchError$1((error) => {
2402
+ if (error instanceof HttpErrorResponse && error.status === 401) {
2403
+ // Handle 401 error, e.g., navigate to the login page
2404
+ this.router.navigate(['/login'], {
2405
+ queryParams: {
2406
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2407
+ },
2408
+ replaceUrl: true,
2409
+ });
2410
+ // Return an observable with a successful response
2411
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2412
+ }
2413
+ if (error instanceof HttpErrorResponse && error.status === 403) {
2414
+ this.router.navigate(['/forbidden'], {
2415
+ state: { attemptedUrl: this.router.url }, // Orijinal URL'i state olarak geçme
2416
+ });
2417
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2418
+ }
2419
+ if (error instanceof HttpErrorResponse && error.status === 428) {
2420
+ // Handle 428 error, e.g., navigate to the login page
2421
+ this.router.navigate(['/mfalogin'], {
2422
+ queryParams: {
2423
+ redirect: this.urlHelperService.cleanUrl(this.router.url),
2424
+ },
2425
+ replaceUrl: true,
2426
+ });
2427
+ // Return an observable with a successful response
2428
+ return of(new HttpResponse({ status: 200, body: { message: 'Success' } }));
2429
+ }
2430
+ // For other errors, re-throw the error to propagate it further
2431
+ return throwError(() => error);
2432
+ }));
2151
2433
  }
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);
2163
2434
  }
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 });
2435
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2436
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor });
2166
2437
  }
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: () => [] });
2438
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AuthenticationInterceptor, decorators: [{
2439
+ type: Injectable
2440
+ }] });
2441
+
2442
+ class CanDeactivateGuard {
2443
+ canDeactivate(component) {
2444
+ return component.canDeactivate ? component.canDeactivate() : true;
2445
+ }
2446
+ }
2447
+
2448
+ class NtybaseModule {
2449
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2450
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, declarations: [Ntybase], exports: [Ntybase] });
2451
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, providers: [
2452
+ {
2453
+ provide: HTTP_INTERCEPTORS,
2454
+ useClass: AuthenticationInterceptor,
2455
+ multi: true,
2456
+ },
2457
+ [CanDeactivateGuard],
2458
+ DatePipe,
2459
+ ] });
2460
+ }
2461
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NtybaseModule, decorators: [{
2462
+ type: NgModule,
2463
+ args: [{
2464
+ declarations: [Ntybase],
2465
+ imports: [],
2466
+ exports: [Ntybase],
2467
+ providers: [
2468
+ {
2469
+ provide: HTTP_INTERCEPTORS,
2470
+ useClass: AuthenticationInterceptor,
2471
+ multi: true,
2472
+ },
2473
+ [CanDeactivateGuard],
2474
+ DatePipe,
2475
+ ],
2476
+ }]
2477
+ }] });
2171
2478
 
2172
2479
  class Guid {
2173
2480
  value = this.empty;
@@ -2645,290 +2952,91 @@ class NettyAgGridSaveBase extends NettyAppsBase {
2645
2952
  // Redirect to user list on error in fullscreen mode
2646
2953
  if (this.viewMode() === 'fullscreen') {
2647
2954
  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);
2955
+ this.router.navigate([cleanPath]);
2847
2956
  }
2848
- };
2849
- reader.onerror = () => reject(reader.error);
2850
- reader.readAsArrayBuffer(file);
2957
+ },
2851
2958
  });
2852
2959
  }
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
2870
- }
2871
- });
2872
- rows.push(row);
2960
+ // ***************************************************
2961
+ // *** gotoURL Methods ***
2962
+ // ***************************************************
2963
+ gotoURL(routePrefix, rightSidenav = [], parameters, type, dialogComponent = null, isNewTab = false, isPopup = this._isEmbedded()) {
2964
+ const baseHref = this.environment.getBaseHref().endsWith('/')
2965
+ ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
2966
+ : this.environment.getBaseHref();
2967
+ const navigationExtras = {
2968
+ queryParams: {
2969
+ parameters: JSON.stringify(parameters),
2970
+ ...(type && { type }),
2971
+ isNewTab: isNewTab || undefined,
2972
+ },
2973
+ queryParamsHandling: 'merge',
2974
+ };
2975
+ if (isNewTab) {
2976
+ const fullUrl = this.router
2977
+ .createUrlTree([baseHref, ...routePrefix, ...rightSidenav], navigationExtras)
2978
+ .toString();
2979
+ window.open(fullUrl, '_blank');
2980
+ return;
2873
2981
  }
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);
2878
- }
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) {
2982
+ if (isPopup && dialogComponent) {
2983
+ this.dialog
2984
+ .open(dialogComponent, {
2985
+ data: {
2986
+ parameters: parameters,
2987
+ mode: type || 'edit',
2988
+ embedded: true,
2989
+ },
2990
+ maxWidth: '100vw',
2991
+ disableClose: true,
2992
+ hasBackdrop: false,
2993
+ })
2994
+ .afterClosed();
2895
2995
  return;
2896
2996
  }
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
- });
2997
+ // Log control
2998
+ if (rightSidenav.length == 0 || rightSidenav[0] === 'log') {
2999
+ this.router.navigate([baseHref, ...routePrefix, ...rightSidenav], navigationExtras);
3000
+ return;
2908
3001
  }
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();
3002
+ // In all other cases, open the side menu
3003
+ this.router
3004
+ .navigate([
3005
+ {
3006
+ outlets: {
3007
+ primary: routePrefix,
3008
+ rightSidenav: [...routePrefix, ...rightSidenav],
3009
+ },
3010
+ },
3011
+ ], navigationExtras)
3012
+ .then(() => {
3013
+ // Ensure sidenav is opened after navigation
3014
+ this.commonService.toggleRightSidenav(true);
2923
3015
  });
2924
3016
  }
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 });
3017
+ popupGotoURL(urlSegments) {
3018
+ const baseHref = this.environment.getBaseHref().endsWith('/')
3019
+ ? this.environment.getBaseHref().slice(0, -1) // Sondaki / işaretini kaldır
3020
+ : this.environment.getBaseHref();
3021
+ this.router.navigate([
3022
+ {
3023
+ outlets: {
3024
+ primary: [baseHref, ...urlSegments],
3025
+ rightSidenav: null,
3026
+ },
3027
+ },
3028
+ ]);
3029
+ }
3030
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridSaveBase, deps: [], target: i0.ɵɵFactoryTarget.Component });
3031
+ 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
3032
  }
2928
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ExcelImportBase, decorators: [{
3033
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NettyAgGridSaveBase, decorators: [{
2929
3034
  type: Component,
2930
- args: [{ selector: 'ntybase-excel-import-base', imports: [], template: `` }]
2931
- }] });
3035
+ args: [{ selector: 'ntybase-ag-grid-save-base', imports: [], template: `` }]
3036
+ }], ctorParameters: () => [], propDecorators: { parameters: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameters", required: false }] }], saveForm: [{
3037
+ type: ViewChild,
3038
+ args: ['saveForm']
3039
+ }] } });
2932
3040
 
2933
3041
  class RangeDateTimeFilter {
2934
3042
  params;
@@ -3728,7 +3836,7 @@ const ntyAuthenticationInterceptor = (req, next) => {
3728
3836
  headers: req.headers.set('Authorization', 'Bearer ' + token)
3729
3837
  // .set("NettyAppName",appName)
3730
3838
  });
3731
- return next(clonedreq).pipe(catchError((error) => {
3839
+ return next(clonedreq).pipe(catchError$1((error) => {
3732
3840
  if (error instanceof HttpErrorResponse && error.status === 401) {
3733
3841
  // Handle 401 error, e.g., navigate to the login page
3734
3842
  router.navigate(['/login'], {
@@ -3762,7 +3870,7 @@ const ntyAuthenticationInterceptor = (req, next) => {
3762
3870
  }));
3763
3871
  }
3764
3872
  else {
3765
- return next(req.clone()).pipe(catchError((error) => {
3873
+ return next(req.clone()).pipe(catchError$1((error) => {
3766
3874
  if (error instanceof HttpErrorResponse && error.status === 401) {
3767
3875
  // Handle 401 error, e.g., navigate to the login page
3768
3876
  router.navigate(['/login'], {
@@ -3855,7 +3963,7 @@ class AuthenticationService {
3855
3963
  // Parse JWT
3856
3964
  this.credentialsService.setCredentials(data, context.remember);
3857
3965
  return data;
3858
- }), take(1), catchError((error) => {
3966
+ }), take(1), catchError$1((error) => {
3859
3967
  let errorMessage = '';
3860
3968
  switch (error.status) {
3861
3969
  case '404':
@@ -3919,7 +4027,7 @@ class AuthenticationService {
3919
4027
  });
3920
4028
  return mfaCodeCall$.pipe(map$1((message) => {
3921
4029
  return message;
3922
- }), take(1), catchError((error) => {
4030
+ }), take(1), catchError$1((error) => {
3923
4031
  let errorMessage = '';
3924
4032
  errorMessage =
3925
4033
  error.status +
@@ -3943,7 +4051,7 @@ class AuthenticationService {
3943
4051
  console.log('mfaCodeUrl', mfaCodeUrl);
3944
4052
  return resendMFACodeCall$.pipe(map$1((message) => {
3945
4053
  return message;
3946
- }), take(1), catchError((error) => {
4054
+ }), take(1), catchError$1((error) => {
3947
4055
  let errorMessage = '';
3948
4056
  errorMessage =
3949
4057
  error.status +
@@ -3982,7 +4090,7 @@ class AuthenticationService {
3982
4090
  // and saves the credentials into localstorage
3983
4091
  return loginCall$.pipe(map$1((message) => {
3984
4092
  return message;
3985
- }), take(1), catchError((error) => {
4093
+ }), take(1), catchError$1((error) => {
3986
4094
  let errorMessage = '';
3987
4095
  errorMessage =
3988
4096
  error.status +
@@ -4339,7 +4447,7 @@ class PasswordProxy {
4339
4447
  });
4340
4448
  return resertPasswordCall$.pipe(map((message) => {
4341
4449
  return message;
4342
- }), take$1(1), catchError$1((error) => {
4450
+ }), take$1(1), catchError((error) => {
4343
4451
  let errorMessage = '';
4344
4452
  errorMessage =
4345
4453
  error.status +
@@ -4528,29 +4636,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
4528
4636
  }]
4529
4637
  }] });
4530
4638
 
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
4639
  class EnvironmentInfo {
4555
4640
  showNettyInfo = true;
4556
4641
  environmentProxy = inject(EnvironmentProxy);
@@ -4722,91 +4807,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
4722
4807
  }]
4723
4808
  }] });
4724
4809
 
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
4810
  // converters.ts
4811
4811
  // Sayı dönüştürücü (hem . hem , destekler)
4812
4812
  const toNumber = (v) => {