@nettyapps/ntybase 21.0.2 → 21.0.4
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.
- package/fesm2022/nettyapps-ntybase.mjs +51 -1072
- package/fesm2022/nettyapps-ntybase.mjs.map +1 -1
- package/package.json +1 -1
- package/types/nettyapps-ntybase.d.ts +133 -353
- package/styles/public-nettyapp-base.scss +0 -343
- package/themes/blueorangetheme.css +0 -313
- package/themes/deep-bluetheme.css +0 -312
- package/themes/graytheme.css +0 -297
- package/themes/greentheme.css +0 -313
- package/themes/orangetheme.css +0 -312
- package/themes/purpletheme.css +0 -312
- package/themes/redtheme.css +0 -312
- package/themes/themes.css +0 -7
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, Injectable, inject, NgModule, Inject, signal, input, output, computed, effect, model, ViewChild,
|
|
3
|
-
import * as i1$
|
|
2
|
+
import { Component, Injectable, inject, NgModule, Inject, signal, input, output, computed, effect, model, ViewChild, InjectionToken, Optional, Input } from '@angular/core';
|
|
3
|
+
import * as i1$3 from '@angular/common/http';
|
|
4
4
|
import { HttpErrorResponse, HttpResponse, HTTP_INTERCEPTORS, HttpClient, HttpHeaders } from '@angular/common/http';
|
|
5
5
|
import { of, throwError, lastValueFrom, map, catchError as catchError$1, Subject, finalize, take as take$1, takeUntil } from 'rxjs';
|
|
6
6
|
import { catchError, map as map$1, take } from 'rxjs/operators';
|
|
7
|
-
import
|
|
8
|
-
import { Router, ActivatedRoute, RouterLink, RouterModule } from '@angular/router';
|
|
7
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
9
8
|
import * as i2$1 from '@nettyapps/ntycontract';
|
|
10
9
|
import { EnvironmentProxy } from '@nettyapps/ntycontract';
|
|
11
|
-
import
|
|
12
|
-
import { DatePipe, Location, DecimalPipe, CommonModule, TitleCasePipe } from '@angular/common';
|
|
10
|
+
import { DatePipe, Location, DecimalPipe } from '@angular/common';
|
|
13
11
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
14
|
-
import * as
|
|
12
|
+
import * as i1$1 from '@ngx-translate/core';
|
|
15
13
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
16
14
|
import { Buffer } from 'buffer';
|
|
17
15
|
import * as i1 from '@angular/material/dialog';
|
|
18
|
-
import { MAT_DIALOG_DATA, MatDialogModule, MatDialog, MatDialogRef
|
|
16
|
+
import { MAT_DIALOG_DATA, MatDialogModule, MatDialog, MatDialogRef } from '@angular/material/dialog';
|
|
19
17
|
import * as i3 from '@angular/material/divider';
|
|
20
18
|
import { MatDividerModule } from '@angular/material/divider';
|
|
21
19
|
import * as i2 from '@angular/material/icon';
|
|
22
20
|
import { MatIconModule } from '@angular/material/icon';
|
|
23
|
-
import * as i1$
|
|
21
|
+
import * as i1$2 from '@angular/material/snack-bar';
|
|
24
22
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
25
23
|
import { Mutex } from 'async-mutex';
|
|
26
24
|
import { ModuleRegistry, AllCommunityModule, ClientSideRowModelModule, HighlightChangesModule, themeQuartz } from 'ag-grid-community';
|
|
@@ -28,23 +26,14 @@ import { StatusBarModule, ClipboardModule, ExcelExportModule, ColumnMenuModule,
|
|
|
28
26
|
import * as i2$2 from '@angular/material/tooltip';
|
|
29
27
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
30
28
|
import * as i2$3 from '@angular/material/menu';
|
|
31
|
-
import { MatMenuModule
|
|
29
|
+
import { MatMenuModule } from '@angular/material/menu';
|
|
32
30
|
import * as XLSX from 'xlsx';
|
|
33
31
|
import { I18nService } from '@nettyapps/ntyi18n';
|
|
34
|
-
import * as i1$
|
|
35
|
-
import { FormBuilder, Validators, FormsModule, ReactiveFormsModule
|
|
36
|
-
import * as
|
|
32
|
+
import * as i1$4 from '@angular/forms';
|
|
33
|
+
import { FormBuilder, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
34
|
+
import * as i3$1 from '@angular/material/input';
|
|
37
35
|
import { MatInputModule } from '@angular/material/input';
|
|
38
36
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
39
|
-
import * as i3$2 from '@angular/material/list';
|
|
40
|
-
import { MatListModule } from '@angular/material/list';
|
|
41
|
-
import { NettyUISearchInput, UiBase } from '@nettyapps/ntyui';
|
|
42
|
-
import * as i3$3 from '@angular/material/toolbar';
|
|
43
|
-
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
44
|
-
import * as i2$4 from '@angular/material/autocomplete';
|
|
45
|
-
import { MatAutocompleteModule, MatAutocompleteTrigger } from '@angular/material/autocomplete';
|
|
46
|
-
import { ErrorStateMatcher } from '@angular/material/core';
|
|
47
|
-
import { Clipboard } from '@angular/cdk/clipboard';
|
|
48
37
|
|
|
49
38
|
class Ntybase {
|
|
50
39
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Ntybase, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -402,7 +391,7 @@ class ConfirmDialog {
|
|
|
402
391
|
this.data = data;
|
|
403
392
|
}
|
|
404
393
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ConfirmDialog, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
405
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", 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}}</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}}</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:
|
|
394
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", 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}}</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}}</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" }] });
|
|
406
395
|
}
|
|
407
396
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ConfirmDialog, decorators: [{
|
|
408
397
|
type: Component,
|
|
@@ -484,7 +473,7 @@ class AlertService {
|
|
|
484
473
|
verticalPosition: 'bottom',
|
|
485
474
|
});
|
|
486
475
|
}
|
|
487
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AlertService, deps: [{ token: i1$
|
|
476
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AlertService, deps: [{ token: i1$2.MatSnackBar }, { token: i1.MatDialog }, { token: i1$1.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
488
477
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AlertService, providedIn: 'root' });
|
|
489
478
|
}
|
|
490
479
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AlertService, decorators: [{
|
|
@@ -492,7 +481,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
492
481
|
args: [{
|
|
493
482
|
providedIn: 'root',
|
|
494
483
|
}]
|
|
495
|
-
}], ctorParameters: () => [{ type: i1$
|
|
484
|
+
}], ctorParameters: () => [{ type: i1$2.MatSnackBar }, { type: i1.MatDialog }, { type: i1$1.TranslateService }] });
|
|
496
485
|
|
|
497
486
|
class CommonService {
|
|
498
487
|
// Services
|
|
@@ -1016,7 +1005,7 @@ class SysfunctionProxy {
|
|
|
1016
1005
|
return throwError(() => new Error(errorMessage ?? ''));
|
|
1017
1006
|
}));
|
|
1018
1007
|
}
|
|
1019
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SysfunctionProxy, deps: [{ token: i1$
|
|
1008
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SysfunctionProxy, deps: [{ token: i1$3.HttpClient }, { token: i2$1.EnvironmentProxy }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1020
1009
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SysfunctionProxy, providedIn: 'root' });
|
|
1021
1010
|
}
|
|
1022
1011
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SysfunctionProxy, decorators: [{
|
|
@@ -1024,7 +1013,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
1024
1013
|
args: [{
|
|
1025
1014
|
providedIn: 'root',
|
|
1026
1015
|
}]
|
|
1027
|
-
}], ctorParameters: () => [{ type: i1$
|
|
1016
|
+
}], ctorParameters: () => [{ type: i1$3.HttpClient }, { type: i2$1.EnvironmentProxy }] });
|
|
1028
1017
|
|
|
1029
1018
|
class ButtonRenderer {
|
|
1030
1019
|
params = null;
|
|
@@ -2337,7 +2326,7 @@ class RangeDateTimeFilter {
|
|
|
2337
2326
|
}
|
|
2338
2327
|
}
|
|
2339
2328
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: RangeDateTimeFilter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2340
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: RangeDateTimeFilter, isStandalone: true, selector: "ntybase-range-date-time-filter", ngImport: i0, template: "<div class=\"custom-filter\">\n <div class=\"custom-filter__header\">\n <label class=\"custom-filter__title\">\n {{ '@dateTimeFilter' | translate }}\n </label>\n <input\n type=\"text\"\n class=\"custom-filter__input\"\n [placeholder]=\"'@dateTimeFilterPlaceholder' | translate\"\n [value]=\"filterText\"\n (input)=\"onFilterTextChanged($event)\"\n />\n </div>\n\n <div class=\"custom-filter__help\">\n <strong class=\"custom-filter__help-title\">\n {{ '@formats' | translate }}:\n </strong>\n\n <div class=\"custom-filter__format\">\n {{ '@range' | translate }}:\n <code>start..end</code>\n <span class=\"custom-filter__example\">(today..yesterday)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@singleDate' | translate }}:\n <code>YYYY-MM-DD</code>\n <span class=\"custom-filter__example\">(2024-05-15)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@dateTime' | translate }}:\n <code>YYYY-MM-DD HH:MM</code>\n <span class=\"custom-filter__example\">(2024-05-15 14:30)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@multiple' | translate }}:\n <code>date1,date2,start..end</code>\n </div>\n\n <strong class=\"custom-filter__subtitle\">\n {{ '@specialKeywords' | translate }}:\n </strong>\n\n <div class=\"custom-filter__format\">\n {{ '@turkish' | translate }}:\n <span class=\"custom-filter__keywords\">\n <code class=\"custom-filter__keyword\">bug\u00FCn</code>\n <code class=\"custom-filter__keyword\">d\u00FCn</code>\n <code class=\"custom-filter__keyword\">bu hafta</code>\n <code class=\"custom-filter__keyword\">bu ay</code>\n </span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@english' | translate }}:\n <span class=\"custom-filter__keywords\">\n <code class=\"custom-filter__keyword\">today</code>\n <code class=\"custom-filter__keyword\">yesterday</code>\n <code class=\"custom-filter__keyword\">thisWeek</code>\n <code class=\"custom-filter__keyword\">thisMonth</code>\n </span>\n </div>\n\n <div class=\"custom-filter__note\">{{ '@filterExample' | translate }}</div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type:
|
|
2329
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: RangeDateTimeFilter, isStandalone: true, selector: "ntybase-range-date-time-filter", ngImport: i0, template: "<div class=\"custom-filter\">\n <div class=\"custom-filter__header\">\n <label class=\"custom-filter__title\">\n {{ '@dateTimeFilter' | translate }}\n </label>\n <input\n type=\"text\"\n class=\"custom-filter__input\"\n [placeholder]=\"'@dateTimeFilterPlaceholder' | translate\"\n [value]=\"filterText\"\n (input)=\"onFilterTextChanged($event)\"\n />\n </div>\n\n <div class=\"custom-filter__help\">\n <strong class=\"custom-filter__help-title\">\n {{ '@formats' | translate }}:\n </strong>\n\n <div class=\"custom-filter__format\">\n {{ '@range' | translate }}:\n <code>start..end</code>\n <span class=\"custom-filter__example\">(today..yesterday)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@singleDate' | translate }}:\n <code>YYYY-MM-DD</code>\n <span class=\"custom-filter__example\">(2024-05-15)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@dateTime' | translate }}:\n <code>YYYY-MM-DD HH:MM</code>\n <span class=\"custom-filter__example\">(2024-05-15 14:30)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@multiple' | translate }}:\n <code>date1,date2,start..end</code>\n </div>\n\n <strong class=\"custom-filter__subtitle\">\n {{ '@specialKeywords' | translate }}:\n </strong>\n\n <div class=\"custom-filter__format\">\n {{ '@turkish' | translate }}:\n <span class=\"custom-filter__keywords\">\n <code class=\"custom-filter__keyword\">bug\u00FCn</code>\n <code class=\"custom-filter__keyword\">d\u00FCn</code>\n <code class=\"custom-filter__keyword\">bu hafta</code>\n <code class=\"custom-filter__keyword\">bu ay</code>\n </span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@english' | translate }}:\n <span class=\"custom-filter__keywords\">\n <code class=\"custom-filter__keyword\">today</code>\n <code class=\"custom-filter__keyword\">yesterday</code>\n <code class=\"custom-filter__keyword\">thisWeek</code>\n <code class=\"custom-filter__keyword\">thisMonth</code>\n </span>\n </div>\n\n <div class=\"custom-filter__note\">{{ '@filterExample' | translate }}</div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
2341
2330
|
}
|
|
2342
2331
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: RangeDateTimeFilter, decorators: [{
|
|
2343
2332
|
type: Component,
|
|
@@ -2536,7 +2525,7 @@ class RangeNumberFilter {
|
|
|
2536
2525
|
}
|
|
2537
2526
|
}
|
|
2538
2527
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: RangeNumberFilter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2539
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: RangeNumberFilter, isStandalone: true, selector: "ntybase-range-number-filter", ngImport: i0, template: "<div class=\"custom-filter\">\n <div class=\"custom-filter__header\">\n <label class=\"custom-filter__title\">\n {{ '@numberFilter' | translate }}\n </label>\n <input\n type=\"text\"\n class=\"custom-filter__input\"\n [placeholder]=\"'@numberFilterPlaceholder' | translate\"\n [value]=\"filterText\"\n (input)=\"onFilterTextChanged($event)\"\n />\n </div>\n\n <div class=\"custom-filter__help\">\n <strong class=\"custom-filter__help-title\"\n >{{ '@formats' | translate }}:</strong\n >\n\n <div class=\"custom-filter__format\">\n {{ '@closedRange' | translate }}:\n <code>min..max</code>\n <span class=\"custom-filter__example\">(0..5)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@equalOrGreater' | translate }}:\n <code>min..</code>\n <span class=\"custom-filter__example\">(5..)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@equalOrLess' | translate }}:\n <code>..max</code>\n <span class=\"custom-filter__example\">(..10)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@singleValue' | translate }}:\n <code>number</code>\n <span class=\"custom-filter__example\">(10)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@exclusion' | translate }}:\n <code>!number</code>\n <span class=\"custom-filter__example\">(!5)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@rangeExclusion' | translate }}:\n <code>!min..max</code>\n <span class=\"custom-filter__example\">(!5..10)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@multiple' | translate }}:\n <code>value1,value2,range</code>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type:
|
|
2528
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: RangeNumberFilter, isStandalone: true, selector: "ntybase-range-number-filter", ngImport: i0, template: "<div class=\"custom-filter\">\n <div class=\"custom-filter__header\">\n <label class=\"custom-filter__title\">\n {{ '@numberFilter' | translate }}\n </label>\n <input\n type=\"text\"\n class=\"custom-filter__input\"\n [placeholder]=\"'@numberFilterPlaceholder' | translate\"\n [value]=\"filterText\"\n (input)=\"onFilterTextChanged($event)\"\n />\n </div>\n\n <div class=\"custom-filter__help\">\n <strong class=\"custom-filter__help-title\"\n >{{ '@formats' | translate }}:</strong\n >\n\n <div class=\"custom-filter__format\">\n {{ '@closedRange' | translate }}:\n <code>min..max</code>\n <span class=\"custom-filter__example\">(0..5)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@equalOrGreater' | translate }}:\n <code>min..</code>\n <span class=\"custom-filter__example\">(5..)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@equalOrLess' | translate }}:\n <code>..max</code>\n <span class=\"custom-filter__example\">(..10)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@singleValue' | translate }}:\n <code>number</code>\n <span class=\"custom-filter__example\">(10)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@exclusion' | translate }}:\n <code>!number</code>\n <span class=\"custom-filter__example\">(!5)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@rangeExclusion' | translate }}:\n <code>!min..max</code>\n <span class=\"custom-filter__example\">(!5..10)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@multiple' | translate }}:\n <code>value1,value2,range</code>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
2540
2529
|
}
|
|
2541
2530
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: RangeNumberFilter, decorators: [{
|
|
2542
2531
|
type: Component,
|
|
@@ -2789,7 +2778,7 @@ class RangeStringFilter {
|
|
|
2789
2778
|
}
|
|
2790
2779
|
}
|
|
2791
2780
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: RangeStringFilter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2792
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: RangeStringFilter, isStandalone: true, selector: "ntybase-range-string-filter", ngImport: i0, template: "<div class=\"custom-filter\">\n <div class=\"custom-filter__header\">\n <label class=\"custom-filter__title\">\n {{ '@stringFilter' | translate }}\n </label>\n <input\n type=\"text\"\n class=\"custom-filter__input\"\n [placeholder]=\"'@stringFilterPlaceholder' | translate\"\n [value]=\"filterText\"\n (input)=\"onFilterTextChanged($event)\"\n />\n </div>\n\n <div class=\"custom-filter__help\">\n <strong class=\"custom-filter__help-title\">\n {{ '@formats' | translate }}:\n </strong>\n\n <div class=\"custom-filter__format\">\n {{ '@exactMatch' | translate }}:\n <code>text</code>\n <span class=\"custom-filter__example\">(ahmet)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@startsWith' | translate }}:\n <code>text*</code>\n <span class=\"custom-filter__example\">(ahmet*)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@endsWith' | translate }}:\n <code>*text</code>\n <span class=\"custom-filter__example\">(*metin)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@contains' | translate }}:\n <code>*text*</code>\n <span class=\"custom-filter__example\">(*ahmet*)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@range' | translate }}:\n <code>start..end</code>\n <span class=\"custom-filter__example\">(ali..veli)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n <span class=\"custom-filter__description\">\n {{ '@singleCharacter' | translate }}:\n </span>\n <code>?em</code>\n <span class=\"custom-filter__example\">\n (?em = 3 characters, 2nd and 3rd letters \"em\")\n </span>\n </div>\n\n <div class=\"custom-filter__format\">\n <span class=\"custom-filter__description\">\n {{ '@multipleCharacters' | translate }}:\n </span>\n <code>???in</code>\n <span class=\"custom-filter__example\">\n (5 characters, last 2 letters \"in\")\n </span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@not' | translate }}:\n <code>!condition</code>\n <span class=\"custom-filter__example\">(!*ahmet*, !?hmet)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@regex' | translate }}:\n <code>$$pattern</code>\n <span class=\"custom-filter__example\">($$^[A-Z].*, $$a.*b)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@multiple' | translate }}:\n <code>value1,value2,*end,$$pattern</code>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type:
|
|
2781
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: RangeStringFilter, isStandalone: true, selector: "ntybase-range-string-filter", ngImport: i0, template: "<div class=\"custom-filter\">\n <div class=\"custom-filter__header\">\n <label class=\"custom-filter__title\">\n {{ '@stringFilter' | translate }}\n </label>\n <input\n type=\"text\"\n class=\"custom-filter__input\"\n [placeholder]=\"'@stringFilterPlaceholder' | translate\"\n [value]=\"filterText\"\n (input)=\"onFilterTextChanged($event)\"\n />\n </div>\n\n <div class=\"custom-filter__help\">\n <strong class=\"custom-filter__help-title\">\n {{ '@formats' | translate }}:\n </strong>\n\n <div class=\"custom-filter__format\">\n {{ '@exactMatch' | translate }}:\n <code>text</code>\n <span class=\"custom-filter__example\">(ahmet)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@startsWith' | translate }}:\n <code>text*</code>\n <span class=\"custom-filter__example\">(ahmet*)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@endsWith' | translate }}:\n <code>*text</code>\n <span class=\"custom-filter__example\">(*metin)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@contains' | translate }}:\n <code>*text*</code>\n <span class=\"custom-filter__example\">(*ahmet*)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@range' | translate }}:\n <code>start..end</code>\n <span class=\"custom-filter__example\">(ali..veli)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n <span class=\"custom-filter__description\">\n {{ '@singleCharacter' | translate }}:\n </span>\n <code>?em</code>\n <span class=\"custom-filter__example\">\n (?em = 3 characters, 2nd and 3rd letters \"em\")\n </span>\n </div>\n\n <div class=\"custom-filter__format\">\n <span class=\"custom-filter__description\">\n {{ '@multipleCharacters' | translate }}:\n </span>\n <code>???in</code>\n <span class=\"custom-filter__example\">\n (5 characters, last 2 letters \"in\")\n </span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@not' | translate }}:\n <code>!condition</code>\n <span class=\"custom-filter__example\">(!*ahmet*, !?hmet)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@regex' | translate }}:\n <code>$$pattern</code>\n <span class=\"custom-filter__example\">($$^[A-Z].*, $$a.*b)</span>\n </div>\n\n <div class=\"custom-filter__format\">\n {{ '@multiple' | translate }}:\n <code>value1,value2,*end,$$pattern</code>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
2793
2782
|
}
|
|
2794
2783
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: RangeStringFilter, decorators: [{
|
|
2795
2784
|
type: Component,
|
|
@@ -3216,7 +3205,7 @@ class Login extends AuthBase {
|
|
|
3216
3205
|
});
|
|
3217
3206
|
}
|
|
3218
3207
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Login, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3219
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: Login, isStandalone: true, selector: "ntybase-login", usesInheritance: true, ngImport: i0, template: "<div class=\"login-page-container\">\n <div class=\"login-image-container\"></div>\n\n <div class=\"login-container glass-effect\">\n <!-- Language Button -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <h2>{{'app_name' | translate }}</h2>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n\n @if (!isLoading()) {\n <form (ngSubmit)=\"login()\" [formGroup]=\"loginForm\" novalidate>\n @if (error()) {\n <div class=\"error-message\">\n <span class=\"error-icon\">!</span>\n {{ error() }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"username\">{{'@username' | translate}}</label>\n <input\n type=\"text\"\n id=\"username\"\n formControlName=\"username\"\n [placeholder]=\"'@username' | translate\"\n required\n />\n @if (loginForm.controls['username'].invalid &&\n loginForm.controls['username'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'username is required' | translate }}\n </mat-error>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"password\">{{'@password' | translate}}</label>\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n [placeholder]=\"'@password' | translate\"\n required\n />\n @if (loginForm.controls['password'].invalid &&\n loginForm.controls['password'].touched) {\n <div class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </div>\n }\n </div>\n\n <div class=\"form-group remember\">\n <input type=\"checkbox\" id=\"remember\" formControlName=\"remember\" />\n <label for=\"remember\">{{ '@rememberMe' | translate }}</label>\n <a class=\"forgot-password\" (click)=\"onForgotPassword()\"\n >{{ '@forgotPassword' | translate }}</a\n >\n </div>\n\n <button\n type=\"submit\"\n class=\"login-button\"\n [disabled]=\"loginForm.invalid || isLoading()\"\n >\n {{ '@login' | translate }}\n </button>\n </form>\n } @else {\n <div class=\"loading-spinner\">\n <span>{{ '@loggingIn' | translate }}</span>\n </div>\n }\n\n <div class=\"footer\">\n @if(version() && version() !== '?.?'){\n <div class=\"version\">{{ version() }}</div>\n }\n </div>\n </div>\n</div>\n", styles: [".login-page-container{position:relative;display:flex;height:100vh;background-image:var(--login-bg-image, url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;justify-content:flex-end;padding-right:5%}.login-image-container{display:none}.login-container{width:100%;max-width:400px;padding:2.5rem;display:flex;flex-direction:column;justify-content:center;background:#ffffff1a;border-radius:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.2);margin:20px;height:fit-content;align-self:center}.login-container h2{color:#fff;text-align:center;margin-bottom:2rem;font-size:1.8rem;font-weight:600;text-shadow:0 2px 4px rgba(0,0,0,.3)}.form-group{margin-bottom:1.5rem}.form-group label{display:block;font-weight:500;color:#fff;font-size:.9rem;text-shadow:0 1px 2px rgba(0,0,0,.3)}.form-group input[type=text],.form-group input[type=password]{width:100%;padding:.85rem 1rem;margin-top:.5rem;border:1px solid rgba(255,255,255,.3);border-radius:8px;font-size:.95rem;background-color:#ffffff26;color:#fff}.form-group input::placeholder{color:#ffffffb3}.form-group input[type=text]:focus,.form-group input[type=password]:focus{outline:none;border-color:#ffffff80;background-color:#ffffff40;box-shadow:0 0 0 3px #ffffff1a}.remember{display:flex;align-items:center;margin-bottom:1.5rem}.remember input{width:18px;height:18px;margin-right:.75rem;cursor:pointer}.remember label{color:#fff;font-size:.9rem;cursor:pointer;-webkit-user-select:none;user-select:none;text-shadow:0 1px 2px rgba(0,0,0,.3)}.forgot-password{margin-left:auto;color:#ffffffe6;font-size:.85rem;text-decoration:none}.forgot-password:hover{text-decoration:underline}.login-button{width:100%;padding:1rem;background-color:#fff3;color:#fff;border:1px solid rgba(255,255,255,.4);border-radius:8px;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s}.login-button:hover{background-color:#ffffff4d}.loading-spinner{text-align:center;padding:2rem}.loading-spinner p{margin-top:1rem;color:#fff}.footer{margin-top:2rem;text-align:center}.version{color:#ffffffb3;font-size:.8rem;display:block;text-shadow:0 1px 2px rgba(0,0,0,.3)}@media(max-width:768px){.login-page-container{justify-content:center;padding-right:0;align-items:center}.login-container{max-width:90%;margin:20px auto}}.language-toggle{position:absolute;top:20px;right:20px;z-index:10}.language-toggle button{background:#fff3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.3);cursor:pointer}.language-toggle button:hover{background:#ffffff4d}.language-toggle button mat-icon{color:#fff}.login-container h2{margin-top:.5rem}.flag-icon{width:24px;height:16px;margin-right:8px;border:1px solid #ddd}.error-message{background-color:#f8d7da;color:#721c24;padding:12px 15px;border-radius:4px;margin-bottom:20px;display:flex;align-items:center;border:1px solid #f5c6cb;font-size:14px;animation:fadeIn .3s ease-in-out}.error-message .error-icon{display:inline-block;width:20px;height:20px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:20px;margin-right:10px;font-weight:700;font-size:12px}.validation-error{color:#dc3545;font-size:12px;margin-top:5px;display:flex;align-items:center;animation:fadeIn .3s ease-in-out}.validation-error .error-icon{display:inline-block;width:16px;height:16px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:16px;margin-right:6px;font-weight:700;font-size:10px}input.ng-invalid.ng-touched{border:1px solid #dc3545!important}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$
|
|
3208
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: Login, isStandalone: true, selector: "ntybase-login", usesInheritance: true, ngImport: i0, template: "<div class=\"login-page-container\">\n <div class=\"login-image-container\"></div>\n\n <div class=\"login-container glass-effect\">\n <!-- Language Button -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <h2>{{'app_name' | translate }}</h2>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n\n @if (!isLoading()) {\n <form (ngSubmit)=\"login()\" [formGroup]=\"loginForm\" novalidate>\n @if (error()) {\n <div class=\"error-message\">\n <span class=\"error-icon\">!</span>\n {{ error() }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"username\">{{'@username' | translate}}</label>\n <input\n type=\"text\"\n id=\"username\"\n formControlName=\"username\"\n [placeholder]=\"'@username' | translate\"\n required\n />\n @if (loginForm.controls['username'].invalid &&\n loginForm.controls['username'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'username is required' | translate }}\n </mat-error>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"password\">{{'@password' | translate}}</label>\n <input\n type=\"password\"\n id=\"password\"\n formControlName=\"password\"\n [placeholder]=\"'@password' | translate\"\n required\n />\n @if (loginForm.controls['password'].invalid &&\n loginForm.controls['password'].touched) {\n <div class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </div>\n }\n </div>\n\n <div class=\"form-group remember\">\n <input type=\"checkbox\" id=\"remember\" formControlName=\"remember\" />\n <label for=\"remember\">{{ '@rememberMe' | translate }}</label>\n <a class=\"forgot-password\" (click)=\"onForgotPassword()\"\n >{{ '@forgotPassword' | translate }}</a\n >\n </div>\n\n <button\n type=\"submit\"\n class=\"login-button\"\n [disabled]=\"loginForm.invalid || isLoading()\"\n >\n {{ '@login' | translate }}\n </button>\n </form>\n } @else {\n <div class=\"loading-spinner\">\n <span>{{ '@loggingIn' | translate }}</span>\n </div>\n }\n\n <div class=\"footer\">\n @if(version() && version() !== '?.?'){\n <div class=\"version\">{{ version() }}</div>\n }\n </div>\n </div>\n</div>\n", styles: [".login-page-container{position:relative;display:flex;height:100vh;background-image:var(--login-bg-image, url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;justify-content:flex-end;padding-right:5%}.login-image-container{display:none}.login-container{width:100%;max-width:400px;padding:2.5rem;display:flex;flex-direction:column;justify-content:center;background:#ffffff1a;border-radius:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.2);margin:20px;height:fit-content;align-self:center}.login-container h2{color:#fff;text-align:center;margin-bottom:2rem;font-size:1.8rem;font-weight:600;text-shadow:0 2px 4px rgba(0,0,0,.3)}.form-group{margin-bottom:1.5rem}.form-group label{display:block;font-weight:500;color:#fff;font-size:.9rem;text-shadow:0 1px 2px rgba(0,0,0,.3)}.form-group input[type=text],.form-group input[type=password]{width:100%;padding:.85rem 1rem;margin-top:.5rem;border:1px solid rgba(255,255,255,.3);border-radius:8px;font-size:.95rem;background-color:#ffffff26;color:#fff}.form-group input::placeholder{color:#ffffffb3}.form-group input[type=text]:focus,.form-group input[type=password]:focus{outline:none;border-color:#ffffff80;background-color:#ffffff40;box-shadow:0 0 0 3px #ffffff1a}.remember{display:flex;align-items:center;margin-bottom:1.5rem}.remember input{width:18px;height:18px;margin-right:.75rem;cursor:pointer}.remember label{color:#fff;font-size:.9rem;cursor:pointer;-webkit-user-select:none;user-select:none;text-shadow:0 1px 2px rgba(0,0,0,.3)}.forgot-password{margin-left:auto;color:#ffffffe6;font-size:.85rem;text-decoration:none}.forgot-password:hover{text-decoration:underline}.login-button{width:100%;padding:1rem;background-color:#fff3;color:#fff;border:1px solid rgba(255,255,255,.4);border-radius:8px;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s}.login-button:hover{background-color:#ffffff4d}.loading-spinner{text-align:center;padding:2rem}.loading-spinner p{margin-top:1rem;color:#fff}.footer{margin-top:2rem;text-align:center}.version{color:#ffffffb3;font-size:.8rem;display:block;text-shadow:0 1px 2px rgba(0,0,0,.3)}@media(max-width:768px){.login-page-container{justify-content:center;padding-right:0;align-items:center}.login-container{max-width:90%;margin:20px auto}}.language-toggle{position:absolute;top:20px;right:20px;z-index:10}.language-toggle button{background:#fff3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.3);cursor:pointer}.language-toggle button:hover{background:#ffffff4d}.language-toggle button mat-icon{color:#fff}.login-container h2{margin-top:.5rem}.flag-icon{width:24px;height:16px;margin-right:8px;border:1px solid #ddd}.error-message{background-color:#f8d7da;color:#721c24;padding:12px 15px;border-radius:4px;margin-bottom:20px;display:flex;align-items:center;border:1px solid #f5c6cb;font-size:14px;animation:fadeIn .3s ease-in-out}.error-message .error-icon{display:inline-block;width:20px;height:20px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:20px;margin-right:10px;font-weight:700;font-size:12px}.validation-error{color:#dc3545;font-size:12px;margin-top:5px;display:flex;align-items:center;animation:fadeIn .3s ease-in-out}.validation-error .error-icon{display:inline-block;width:16px;height:16px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:16px;margin-right:6px;font-weight:700;font-size:10px}input.ng-invalid.ng-touched{border:1px solid #dc3545!important}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2$3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
3220
3209
|
}
|
|
3221
3210
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Login, decorators: [{
|
|
3222
3211
|
type: Component,
|
|
@@ -3328,7 +3317,7 @@ class MfaLogin extends AuthBase {
|
|
|
3328
3317
|
clearInterval(this.countdownInterval);
|
|
3329
3318
|
}
|
|
3330
3319
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MfaLogin, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3331
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: MfaLogin, isStandalone: true, selector: "ntybase-mfa-login", usesInheritance: true, ngImport: i0, template: "<div class=\"login-page-container\">\n <div class=\"login-image-container\"></div>\n\n <div class=\"login-container glass-effect\">\n <!-- Language Button -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <h2>{{'app_name' | translate }}</h2>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n\n @if (!isLoading()) {\n <form (ngSubmit)=\"login()\" [formGroup]=\"loginForm\" novalidate>\n @if (error()) {\n <div class=\"error-message\">\n <span class=\"error-icon\">!</span>\n {{ error() }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"mfaCode\">{{'mfaCode' | translate}}</label>\n <input\n type=\"text\"\n id=\"mfaCode\"\n formControlName=\"mfaCode\"\n [placeholder]=\"'mfaCode' | translate\"\n required\n />\n @if (loginForm.controls['mfaCode'].invalid &&\n loginForm.controls['mfaCode'].touched) {\n <div class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'mfaCode is required' | translate }}\n </div>\n }\n\n <!-- Time -->\n @if (!resendable()) {\n <div class=\"time-remaining\">\n {{ '@tokenCount' | translate }}: {{ getFormattedTime() }}\n </div>\n }\n </div>\n\n <button\n type=\"submit\"\n class=\"login-button\"\n [disabled]=\"loginForm.invalid || isLoading() || !resendable()\"\n >\n {{ '@login' | translate }}\n </button>\n\n @if (resendable()) {\n <div class=\"resend-container\">\n <span (click)=\"onResendMFACode()\" class=\"resend-link\">\n {{ 'resend MFACode' | translate }}\n </span>\n </div>\n }\n </form>\n } @else {\n <div class=\"loading-spinner\">\n <span>{{ '@loggingIn' | translate }}</span>\n </div>\n }\n\n <div class=\"footer\">\n <span class=\"version\">v{{version}}</span>\n </div>\n </div>\n</div>\n", styles: [".login-page-container{position:relative;display:flex;height:100vh;background-image:var(--mfa-login-bg-image, url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;justify-content:flex-end;padding-right:5%}.login-image-container{display:none}.login-container{width:100%;max-width:400px;padding:2.5rem;display:flex;flex-direction:column;justify-content:center;background:#ffffff1a;border-radius:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.2);margin:20px;height:fit-content;align-self:center}.login-container h2{color:#fff;text-align:center;margin-bottom:2rem;font-size:1.8rem;font-weight:600;text-shadow:0 2px 4px rgba(0,0,0,.3)}.form-group{margin-bottom:1.5rem}.form-group label{display:block;font-weight:500;color:#fff;font-size:.9rem;text-shadow:0 1px 2px rgba(0,0,0,.3)}.form-group input[type=text],.form-group input[type=password]{width:100%;padding:.85rem 1rem;margin-top:.5rem;border:1px solid rgba(255,255,255,.3);border-radius:8px;font-size:.95rem;background-color:#ffffff26;color:#fff}.form-group input::placeholder{color:#ffffffb3}.form-group input[type=text]:focus,.form-group input[type=password]:focus{outline:none;border-color:#ffffff80;background-color:#ffffff40;box-shadow:0 0 0 3px #ffffff1a}.login-button{width:100%;padding:1rem;background-color:#fff3;color:#fff;border:1px solid rgba(255,255,255,.4);border-radius:8px;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s}.login-button:hover{background-color:#ffffff4d}.loading-spinner{text-align:center;padding:2rem}.loading-spinner p{margin-top:1rem;color:#fff}.footer{margin-top:2rem;text-align:center}.version{color:#ffffffb3;font-size:.8rem;display:block;text-shadow:0 1px 2px rgba(0,0,0,.3)}.language-toggle{position:absolute;top:20px;right:20px;z-index:10}.language-toggle button{background:#fff3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.3);cursor:pointer}.language-toggle button:hover{background:#ffffff4d}.language-toggle button mat-icon{color:#fff}.login-container h2{margin-top:.5rem}.flag-icon{width:24px;height:16px;margin-right:8px;border:1px solid #ddd}.error-message{background-color:#f8d7da;color:#721c24;padding:12px 15px;border-radius:4px;margin-bottom:20px;display:flex;align-items:center;border:1px solid #f5c6cb;font-size:14px;animation:fadeIn .3s ease-in-out}.error-message .error-icon{display:inline-block;width:20px;height:20px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:20px;margin-right:10px;font-weight:700;font-size:12px}.validation-error{color:#dc3545;font-size:12px;margin-top:5px;display:flex;align-items:center;animation:fadeIn .3s ease-in-out}.validation-error .error-icon{display:inline-block;width:16px;height:16px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:16px;margin-right:6px;font-weight:700;font-size:10px}.invalid-input{border:1px solid #dc3545!important}.invalid-input:focus{box-shadow:0 0 0 .2rem #dc354540}.resend-container{margin-top:15px;text-align:center}.resend-container .resend-link{color:#007bff;cursor:pointer;text-decoration:underline;font-size:13px}.resend-container .resend-link:hover{color:#0056b3}.time-remaining{margin-top:16px;font-size:1rem;color:#f5f5f5}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}@media(max-width:768px){.login-page-container{justify-content:center;padding-right:0;align-items:center}.login-container{max-width:90%;margin:20px auto}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$
|
|
3320
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: MfaLogin, isStandalone: true, selector: "ntybase-mfa-login", usesInheritance: true, ngImport: i0, template: "<div class=\"login-page-container\">\n <div class=\"login-image-container\"></div>\n\n <div class=\"login-container glass-effect\">\n <!-- Language Button -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <h2>{{'app_name' | translate }}</h2>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n\n @if (!isLoading()) {\n <form (ngSubmit)=\"login()\" [formGroup]=\"loginForm\" novalidate>\n @if (error()) {\n <div class=\"error-message\">\n <span class=\"error-icon\">!</span>\n {{ error() }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"mfaCode\">{{'mfaCode' | translate}}</label>\n <input\n type=\"text\"\n id=\"mfaCode\"\n formControlName=\"mfaCode\"\n [placeholder]=\"'mfaCode' | translate\"\n required\n />\n @if (loginForm.controls['mfaCode'].invalid &&\n loginForm.controls['mfaCode'].touched) {\n <div class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'mfaCode is required' | translate }}\n </div>\n }\n\n <!-- Time -->\n @if (!resendable()) {\n <div class=\"time-remaining\">\n {{ '@tokenCount' | translate }}: {{ getFormattedTime() }}\n </div>\n }\n </div>\n\n <button\n type=\"submit\"\n class=\"login-button\"\n [disabled]=\"loginForm.invalid || isLoading() || !resendable()\"\n >\n {{ '@login' | translate }}\n </button>\n\n @if (resendable()) {\n <div class=\"resend-container\">\n <span (click)=\"onResendMFACode()\" class=\"resend-link\">\n {{ 'resend MFACode' | translate }}\n </span>\n </div>\n }\n </form>\n } @else {\n <div class=\"loading-spinner\">\n <span>{{ '@loggingIn' | translate }}</span>\n </div>\n }\n\n <div class=\"footer\">\n <span class=\"version\">v{{version}}</span>\n </div>\n </div>\n</div>\n", styles: [".login-page-container{position:relative;display:flex;height:100vh;background-image:var(--mfa-login-bg-image, url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;justify-content:flex-end;padding-right:5%}.login-image-container{display:none}.login-container{width:100%;max-width:400px;padding:2.5rem;display:flex;flex-direction:column;justify-content:center;background:#ffffff1a;border-radius:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.2);margin:20px;height:fit-content;align-self:center}.login-container h2{color:#fff;text-align:center;margin-bottom:2rem;font-size:1.8rem;font-weight:600;text-shadow:0 2px 4px rgba(0,0,0,.3)}.form-group{margin-bottom:1.5rem}.form-group label{display:block;font-weight:500;color:#fff;font-size:.9rem;text-shadow:0 1px 2px rgba(0,0,0,.3)}.form-group input[type=text],.form-group input[type=password]{width:100%;padding:.85rem 1rem;margin-top:.5rem;border:1px solid rgba(255,255,255,.3);border-radius:8px;font-size:.95rem;background-color:#ffffff26;color:#fff}.form-group input::placeholder{color:#ffffffb3}.form-group input[type=text]:focus,.form-group input[type=password]:focus{outline:none;border-color:#ffffff80;background-color:#ffffff40;box-shadow:0 0 0 3px #ffffff1a}.login-button{width:100%;padding:1rem;background-color:#fff3;color:#fff;border:1px solid rgba(255,255,255,.4);border-radius:8px;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s}.login-button:hover{background-color:#ffffff4d}.loading-spinner{text-align:center;padding:2rem}.loading-spinner p{margin-top:1rem;color:#fff}.footer{margin-top:2rem;text-align:center}.version{color:#ffffffb3;font-size:.8rem;display:block;text-shadow:0 1px 2px rgba(0,0,0,.3)}.language-toggle{position:absolute;top:20px;right:20px;z-index:10}.language-toggle button{background:#fff3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.3);cursor:pointer}.language-toggle button:hover{background:#ffffff4d}.language-toggle button mat-icon{color:#fff}.login-container h2{margin-top:.5rem}.flag-icon{width:24px;height:16px;margin-right:8px;border:1px solid #ddd}.error-message{background-color:#f8d7da;color:#721c24;padding:12px 15px;border-radius:4px;margin-bottom:20px;display:flex;align-items:center;border:1px solid #f5c6cb;font-size:14px;animation:fadeIn .3s ease-in-out}.error-message .error-icon{display:inline-block;width:20px;height:20px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:20px;margin-right:10px;font-weight:700;font-size:12px}.validation-error{color:#dc3545;font-size:12px;margin-top:5px;display:flex;align-items:center;animation:fadeIn .3s ease-in-out}.validation-error .error-icon{display:inline-block;width:16px;height:16px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:16px;margin-right:6px;font-weight:700;font-size:10px}.invalid-input{border:1px solid #dc3545!important}.invalid-input:focus{box-shadow:0 0 0 .2rem #dc354540}.resend-container{margin-top:15px;text-align:center}.resend-container .resend-link{color:#007bff;cursor:pointer;text-decoration:underline;font-size:13px}.resend-container .resend-link:hover{color:#0056b3}.time-remaining{margin-top:16px;font-size:1rem;color:#f5f5f5}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}@media(max-width:768px){.login-page-container{justify-content:center;padding-right:0;align-items:center}.login-container{max-width:90%;margin:20px auto}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2$3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
3332
3321
|
}
|
|
3333
3322
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MfaLogin, decorators: [{
|
|
3334
3323
|
type: Component,
|
|
@@ -3502,7 +3491,7 @@ class ForgotPassword extends AuthBase {
|
|
|
3502
3491
|
});
|
|
3503
3492
|
}
|
|
3504
3493
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ForgotPassword, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3505
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ForgotPassword, isStandalone: true, selector: "ntybase-forgot-password", usesInheritance: true, ngImport: i0, template: "<div class=\"login-page-container\">\n <div class=\"login-image-container\"></div>\n\n <div class=\"login-container glass-effect\">\n <!-- Language Button -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <h2>{{'app_name' | translate }}</h2>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n\n @if (!isLoading()) {\n <form\n (ngSubmit)=\"updatePassword()\"\n [formGroup]=\"updatePasswordForm\"\n novalidate\n >\n @if (error()) {\n <div class=\"error-message\">\n <span class=\"error-icon\">!</span>\n {{ error() }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"username\">{{'@username' | translate}}</label>\n <input\n type=\"text\"\n id=\"username\"\n [placeholder]=\"'@username' | translate\"\n formControlName=\"username\"\n required\n />\n </div>\n\n <div class=\"form-group\">\n <label for=\"newPassword\">{{'@password' | translate}}</label>\n <input\n type=\"password\"\n id=\"newPassword\"\n [placeholder]=\"'@password' | translate\"\n formControlName=\"newPassword\"\n required\n />\n @if (updatePasswordForm.controls['newPassword'].invalid &&\n updatePasswordForm.controls['newPassword'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </mat-error>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"newPasswordCheck\">{{'@passwordCheck' | translate}}</label>\n <input\n type=\"password\"\n id=\"newPasswordCheck\"\n [placeholder]=\"'@passwordCheck' | translate\"\n formControlName=\"newPasswordCheck\"\n required\n />\n @if (updatePasswordForm.controls['newPasswordCheck'].invalid &&\n updatePasswordForm.controls['newPasswordCheck'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </mat-error>\n }\n </div>\n\n <button\n type=\"submit\"\n class=\"login-button\"\n [disabled]=\"updatePasswordForm.invalid\"\n >\n {{ '@setPassword' | translate }}\n </button>\n </form>\n } @else {\n <!-- Burada eski #loading template'inin i\u00E7eri\u011Fi direkt olarak kullan\u0131l\u0131yor -->\n <div class=\"loading-spinner\">\n <span>{{ '@updatingPassword' | translate }}</span>\n </div>\n }\n\n <div class=\"footer\">\n <span class=\"version\">v{{version}}</span>\n </div>\n </div>\n</div>\n", styles: [".login-page-container{position:relative;display:flex;height:100vh;background-image:var(--forgot-password-bg-image, url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;justify-content:flex-end;padding-right:5%}.login-image-container{display:none}.login-container{width:100%;max-width:400px;padding:2.5rem;display:flex;flex-direction:column;justify-content:center;background:#ffffff1a;border-radius:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.2);margin:20px;height:fit-content;align-self:center}.login-container h2{color:#fff;text-align:center;margin-bottom:2rem;font-size:1.8rem;font-weight:600;text-shadow:0 2px 4px rgba(0,0,0,.3)}.form-group{margin-bottom:1.5rem}.form-group label{display:block;font-weight:500;color:#fff;font-size:.9rem;text-shadow:0 1px 2px rgba(0,0,0,.3)}.form-group input[type=text],.form-group input[type=password]{width:100%;padding:.85rem 1rem;margin-top:.5rem;border:1px solid rgba(255,255,255,.3);border-radius:8px;font-size:.95rem;background-color:#ffffff26;color:#fff}.form-group input::placeholder{color:#ffffffb3}.form-group input[type=text]:focus,.form-group input[type=password]:focus{outline:none;border-color:#ffffff80;background-color:#ffffff40;box-shadow:0 0 0 3px #ffffff1a}.remember{display:flex;align-items:center;margin-bottom:1.5rem}.remember input{width:18px;height:18px;margin-right:.75rem;cursor:pointer}.remember label{color:#fff;font-size:.9rem;cursor:pointer;-webkit-user-select:none;user-select:none;text-shadow:0 1px 2px rgba(0,0,0,.3)}.forgot-password{margin-left:auto;color:#ffffffe6;font-size:.85rem;text-decoration:none}.forgot-password:hover{text-decoration:underline}.login-button{width:100%;padding:1rem;background-color:#fff3;color:#fff;border:1px solid rgba(255,255,255,.4);border-radius:8px;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s}.login-button:hover{background-color:#ffffff4d}.loading-spinner{text-align:center;padding:2rem}.loading-spinner p{margin-top:1rem;color:#fff}.footer{margin-top:2rem;text-align:center}.version{color:#ffffffb3;font-size:.8rem;display:block;text-shadow:0 1px 2px rgba(0,0,0,.3)}@media(max-width:768px){.login-page-container{justify-content:center;padding-right:0;align-items:center}.login-container{max-width:90%;margin:20px auto}}.language-toggle{position:absolute;top:20px;right:20px;z-index:10}.language-toggle button{background:#fff3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.3);cursor:pointer}.language-toggle button:hover{background:#ffffff4d}.language-toggle button mat-icon{color:#fff}.login-container h2{margin-top:.5rem}.flag-icon{width:24px;height:16px;margin-right:8px;border:1px solid #ddd}.error-message{background-color:#f8d7da;color:#721c24;padding:12px 15px;border-radius:4px;margin-bottom:20px;display:flex;align-items:center;border:1px solid #f5c6cb;font-size:14px;animation:fadeIn .3s ease-in-out}.error-message .error-icon{display:inline-block;width:20px;height:20px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:20px;margin-right:10px;font-weight:700;font-size:12px}.validation-error{color:#dc3545;font-size:12px;margin-top:5px;display:flex;align-items:center;animation:fadeIn .3s ease-in-out}.validation-error .error-icon{display:inline-block;width:16px;height:16px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:16px;margin-right:6px;font-weight:700;font-size:10px}input.ng-invalid.ng-touched{border:1px solid #dc3545!important}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$
|
|
3494
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ForgotPassword, isStandalone: true, selector: "ntybase-forgot-password", usesInheritance: true, ngImport: i0, template: "<div class=\"login-page-container\">\n <div class=\"login-image-container\"></div>\n\n <div class=\"login-container glass-effect\">\n <!-- Language Button -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <h2>{{'app_name' | translate }}</h2>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n\n @if (!isLoading()) {\n <form\n (ngSubmit)=\"updatePassword()\"\n [formGroup]=\"updatePasswordForm\"\n novalidate\n >\n @if (error()) {\n <div class=\"error-message\">\n <span class=\"error-icon\">!</span>\n {{ error() }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"username\">{{'@username' | translate}}</label>\n <input\n type=\"text\"\n id=\"username\"\n [placeholder]=\"'@username' | translate\"\n formControlName=\"username\"\n required\n />\n </div>\n\n <div class=\"form-group\">\n <label for=\"newPassword\">{{'@password' | translate}}</label>\n <input\n type=\"password\"\n id=\"newPassword\"\n [placeholder]=\"'@password' | translate\"\n formControlName=\"newPassword\"\n required\n />\n @if (updatePasswordForm.controls['newPassword'].invalid &&\n updatePasswordForm.controls['newPassword'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </mat-error>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"newPasswordCheck\">{{'@passwordCheck' | translate}}</label>\n <input\n type=\"password\"\n id=\"newPasswordCheck\"\n [placeholder]=\"'@passwordCheck' | translate\"\n formControlName=\"newPasswordCheck\"\n required\n />\n @if (updatePasswordForm.controls['newPasswordCheck'].invalid &&\n updatePasswordForm.controls['newPasswordCheck'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </mat-error>\n }\n </div>\n\n <button\n type=\"submit\"\n class=\"login-button\"\n [disabled]=\"updatePasswordForm.invalid\"\n >\n {{ '@setPassword' | translate }}\n </button>\n </form>\n } @else {\n <!-- Burada eski #loading template'inin i\u00E7eri\u011Fi direkt olarak kullan\u0131l\u0131yor -->\n <div class=\"loading-spinner\">\n <span>{{ '@updatingPassword' | translate }}</span>\n </div>\n }\n\n <div class=\"footer\">\n <span class=\"version\">v{{version}}</span>\n </div>\n </div>\n</div>\n", styles: [".login-page-container{position:relative;display:flex;height:100vh;background-image:var(--forgot-password-bg-image, url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;justify-content:flex-end;padding-right:5%}.login-image-container{display:none}.login-container{width:100%;max-width:400px;padding:2.5rem;display:flex;flex-direction:column;justify-content:center;background:#ffffff1a;border-radius:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.2);margin:20px;height:fit-content;align-self:center}.login-container h2{color:#fff;text-align:center;margin-bottom:2rem;font-size:1.8rem;font-weight:600;text-shadow:0 2px 4px rgba(0,0,0,.3)}.form-group{margin-bottom:1.5rem}.form-group label{display:block;font-weight:500;color:#fff;font-size:.9rem;text-shadow:0 1px 2px rgba(0,0,0,.3)}.form-group input[type=text],.form-group input[type=password]{width:100%;padding:.85rem 1rem;margin-top:.5rem;border:1px solid rgba(255,255,255,.3);border-radius:8px;font-size:.95rem;background-color:#ffffff26;color:#fff}.form-group input::placeholder{color:#ffffffb3}.form-group input[type=text]:focus,.form-group input[type=password]:focus{outline:none;border-color:#ffffff80;background-color:#ffffff40;box-shadow:0 0 0 3px #ffffff1a}.remember{display:flex;align-items:center;margin-bottom:1.5rem}.remember input{width:18px;height:18px;margin-right:.75rem;cursor:pointer}.remember label{color:#fff;font-size:.9rem;cursor:pointer;-webkit-user-select:none;user-select:none;text-shadow:0 1px 2px rgba(0,0,0,.3)}.forgot-password{margin-left:auto;color:#ffffffe6;font-size:.85rem;text-decoration:none}.forgot-password:hover{text-decoration:underline}.login-button{width:100%;padding:1rem;background-color:#fff3;color:#fff;border:1px solid rgba(255,255,255,.4);border-radius:8px;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s}.login-button:hover{background-color:#ffffff4d}.loading-spinner{text-align:center;padding:2rem}.loading-spinner p{margin-top:1rem;color:#fff}.footer{margin-top:2rem;text-align:center}.version{color:#ffffffb3;font-size:.8rem;display:block;text-shadow:0 1px 2px rgba(0,0,0,.3)}@media(max-width:768px){.login-page-container{justify-content:center;padding-right:0;align-items:center}.login-container{max-width:90%;margin:20px auto}}.language-toggle{position:absolute;top:20px;right:20px;z-index:10}.language-toggle button{background:#fff3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.3);cursor:pointer}.language-toggle button:hover{background:#ffffff4d}.language-toggle button mat-icon{color:#fff}.login-container h2{margin-top:.5rem}.flag-icon{width:24px;height:16px;margin-right:8px;border:1px solid #ddd}.error-message{background-color:#f8d7da;color:#721c24;padding:12px 15px;border-radius:4px;margin-bottom:20px;display:flex;align-items:center;border:1px solid #f5c6cb;font-size:14px;animation:fadeIn .3s ease-in-out}.error-message .error-icon{display:inline-block;width:20px;height:20px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:20px;margin-right:10px;font-weight:700;font-size:12px}.validation-error{color:#dc3545;font-size:12px;margin-top:5px;display:flex;align-items:center;animation:fadeIn .3s ease-in-out}.validation-error .error-icon{display:inline-block;width:16px;height:16px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:16px;margin-right:6px;font-weight:700;font-size:10px}input.ng-invalid.ng-touched{border:1px solid #dc3545!important}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2$3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
3506
3495
|
}
|
|
3507
3496
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ForgotPassword, decorators: [{
|
|
3508
3497
|
type: Component,
|
|
@@ -3517,188 +3506,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
3517
3506
|
], template: "<div class=\"login-page-container\">\n <div class=\"login-image-container\"></div>\n\n <div class=\"login-container glass-effect\">\n <!-- Language Button -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <h2>{{'app_name' | translate }}</h2>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n\n @if (!isLoading()) {\n <form\n (ngSubmit)=\"updatePassword()\"\n [formGroup]=\"updatePasswordForm\"\n novalidate\n >\n @if (error()) {\n <div class=\"error-message\">\n <span class=\"error-icon\">!</span>\n {{ error() }}\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"username\">{{'@username' | translate}}</label>\n <input\n type=\"text\"\n id=\"username\"\n [placeholder]=\"'@username' | translate\"\n formControlName=\"username\"\n required\n />\n </div>\n\n <div class=\"form-group\">\n <label for=\"newPassword\">{{'@password' | translate}}</label>\n <input\n type=\"password\"\n id=\"newPassword\"\n [placeholder]=\"'@password' | translate\"\n formControlName=\"newPassword\"\n required\n />\n @if (updatePasswordForm.controls['newPassword'].invalid &&\n updatePasswordForm.controls['newPassword'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </mat-error>\n }\n </div>\n\n <div class=\"form-group\">\n <label for=\"newPasswordCheck\">{{'@passwordCheck' | translate}}</label>\n <input\n type=\"password\"\n id=\"newPasswordCheck\"\n [placeholder]=\"'@passwordCheck' | translate\"\n formControlName=\"newPasswordCheck\"\n required\n />\n @if (updatePasswordForm.controls['newPasswordCheck'].invalid &&\n updatePasswordForm.controls['newPasswordCheck'].touched) {\n <mat-error class=\"validation-error\">\n <span class=\"error-icon\">!</span>\n {{ 'password is required' | translate }}\n </mat-error>\n }\n </div>\n\n <button\n type=\"submit\"\n class=\"login-button\"\n [disabled]=\"updatePasswordForm.invalid\"\n >\n {{ '@setPassword' | translate }}\n </button>\n </form>\n } @else {\n <!-- Burada eski #loading template'inin i\u00E7eri\u011Fi direkt olarak kullan\u0131l\u0131yor -->\n <div class=\"loading-spinner\">\n <span>{{ '@updatingPassword' | translate }}</span>\n </div>\n }\n\n <div class=\"footer\">\n <span class=\"version\">v{{version}}</span>\n </div>\n </div>\n</div>\n", styles: [".login-page-container{position:relative;display:flex;height:100vh;background-image:var(--forgot-password-bg-image, url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-position:center;background-repeat:no-repeat;background-size:cover;background-attachment:fixed;justify-content:flex-end;padding-right:5%}.login-image-container{display:none}.login-container{width:100%;max-width:400px;padding:2.5rem;display:flex;flex-direction:column;justify-content:center;background:#ffffff1a;border-radius:16px;box-shadow:0 8px 32px #0003;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.2);margin:20px;height:fit-content;align-self:center}.login-container h2{color:#fff;text-align:center;margin-bottom:2rem;font-size:1.8rem;font-weight:600;text-shadow:0 2px 4px rgba(0,0,0,.3)}.form-group{margin-bottom:1.5rem}.form-group label{display:block;font-weight:500;color:#fff;font-size:.9rem;text-shadow:0 1px 2px rgba(0,0,0,.3)}.form-group input[type=text],.form-group input[type=password]{width:100%;padding:.85rem 1rem;margin-top:.5rem;border:1px solid rgba(255,255,255,.3);border-radius:8px;font-size:.95rem;background-color:#ffffff26;color:#fff}.form-group input::placeholder{color:#ffffffb3}.form-group input[type=text]:focus,.form-group input[type=password]:focus{outline:none;border-color:#ffffff80;background-color:#ffffff40;box-shadow:0 0 0 3px #ffffff1a}.remember{display:flex;align-items:center;margin-bottom:1.5rem}.remember input{width:18px;height:18px;margin-right:.75rem;cursor:pointer}.remember label{color:#fff;font-size:.9rem;cursor:pointer;-webkit-user-select:none;user-select:none;text-shadow:0 1px 2px rgba(0,0,0,.3)}.forgot-password{margin-left:auto;color:#ffffffe6;font-size:.85rem;text-decoration:none}.forgot-password:hover{text-decoration:underline}.login-button{width:100%;padding:1rem;background-color:#fff3;color:#fff;border:1px solid rgba(255,255,255,.4);border-radius:8px;font-size:1rem;font-weight:500;cursor:pointer;transition:all .2s}.login-button:hover{background-color:#ffffff4d}.loading-spinner{text-align:center;padding:2rem}.loading-spinner p{margin-top:1rem;color:#fff}.footer{margin-top:2rem;text-align:center}.version{color:#ffffffb3;font-size:.8rem;display:block;text-shadow:0 1px 2px rgba(0,0,0,.3)}@media(max-width:768px){.login-page-container{justify-content:center;padding-right:0;align-items:center}.login-container{max-width:90%;margin:20px auto}}.language-toggle{position:absolute;top:20px;right:20px;z-index:10}.language-toggle button{background:#fff3;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.3);cursor:pointer}.language-toggle button:hover{background:#ffffff4d}.language-toggle button mat-icon{color:#fff}.login-container h2{margin-top:.5rem}.flag-icon{width:24px;height:16px;margin-right:8px;border:1px solid #ddd}.error-message{background-color:#f8d7da;color:#721c24;padding:12px 15px;border-radius:4px;margin-bottom:20px;display:flex;align-items:center;border:1px solid #f5c6cb;font-size:14px;animation:fadeIn .3s ease-in-out}.error-message .error-icon{display:inline-block;width:20px;height:20px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:20px;margin-right:10px;font-weight:700;font-size:12px}.validation-error{color:#dc3545;font-size:12px;margin-top:5px;display:flex;align-items:center;animation:fadeIn .3s ease-in-out}.validation-error .error-icon{display:inline-block;width:16px;height:16px;background-color:#dc3545;color:#fff;border-radius:50%;text-align:center;line-height:16px;margin-right:6px;font-weight:700;font-size:10px}input.ng-invalid.ng-touched{border:1px solid #dc3545!important}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
3518
3507
|
}], ctorParameters: () => [] });
|
|
3519
3508
|
|
|
3520
|
-
class HttpError403 {
|
|
3521
|
-
attemptedUrl = '';
|
|
3522
|
-
routeSubscription;
|
|
3523
|
-
router = inject(Router);
|
|
3524
|
-
route = inject(ActivatedRoute);
|
|
3525
|
-
location = inject(Location);
|
|
3526
|
-
commonService = inject(CommonService);
|
|
3527
|
-
constructor() {
|
|
3528
|
-
// Router'dan state'i al
|
|
3529
|
-
const navigation = this.router.currentNavigation();
|
|
3530
|
-
this.attemptedUrl = navigation?.extras.state?.['attemptedUrl'] || '';
|
|
3531
|
-
// Eğer state'ten gelmediyse, mevcut URL'i temizleyerek kullan
|
|
3532
|
-
if (!this.attemptedUrl) {
|
|
3533
|
-
this.attemptedUrl = this.getCleanUrlPath();
|
|
3534
|
-
}
|
|
3535
|
-
this.routeSubscription = this.router.events.subscribe(() => {
|
|
3536
|
-
this.updateAttemptedUrl();
|
|
3537
|
-
});
|
|
3538
|
-
}
|
|
3539
|
-
ngOnInit() {
|
|
3540
|
-
// 1. URL'deki secondary outlet'leri temizle (örneğin: "(rightSidenav:...)")
|
|
3541
|
-
this.cleanUrlFromFragments();
|
|
3542
|
-
// 2. Hata mesajı için attemptedUrl'i güncelle
|
|
3543
|
-
this.updateAttemptedUrl();
|
|
3544
|
-
// 3. Right sidenav'ı kapat
|
|
3545
|
-
this.commonService.toggleRightSidenav(false);
|
|
3546
|
-
}
|
|
3547
|
-
ngOnDestroy() {
|
|
3548
|
-
if (this.routeSubscription) {
|
|
3549
|
-
this.routeSubscription.unsubscribe();
|
|
3550
|
-
}
|
|
3551
|
-
}
|
|
3552
|
-
/**
|
|
3553
|
-
* URL'deki fragment ve outlet'leri temizler.
|
|
3554
|
-
* Örnek: "/sys/NettyUserGroup(rightSidenav:...)" → "/sys/NettyUserGroup"
|
|
3555
|
-
*/
|
|
3556
|
-
cleanUrlFromFragments() {
|
|
3557
|
-
const currentUrl = this.router.url;
|
|
3558
|
-
const cleanUrl = currentUrl.split('(')[0]; // "(" sonrasını sil
|
|
3559
|
-
if (currentUrl !== cleanUrl) {
|
|
3560
|
-
// URL'yi temizlenmiş haliyle değiştir (tarayıcı geçmişine eklemeden)
|
|
3561
|
-
this.router.navigateByUrl(cleanUrl, {
|
|
3562
|
-
replaceUrl: true,
|
|
3563
|
-
skipLocationChange: false,
|
|
3564
|
-
});
|
|
3565
|
-
}
|
|
3566
|
-
}
|
|
3567
|
-
/**
|
|
3568
|
-
* attemptedUrl'i güncel router URL'ine göre günceller
|
|
3569
|
-
*/
|
|
3570
|
-
updateAttemptedUrl() {
|
|
3571
|
-
this.attemptedUrl = this.getCleanUrlPath();
|
|
3572
|
-
}
|
|
3573
|
-
/**
|
|
3574
|
-
* Temizlenmiş URL yolunu döndürür (queryParams ve fragment olmadan).
|
|
3575
|
-
*/
|
|
3576
|
-
getCleanUrlPath() {
|
|
3577
|
-
return this.router.url.split('?')[0].split('(')[0];
|
|
3578
|
-
}
|
|
3579
|
-
goHome() {
|
|
3580
|
-
this.router.navigate(['/'], { replaceUrl: true });
|
|
3581
|
-
this.commonService.toggleRightSidenav(false);
|
|
3582
|
-
}
|
|
3583
|
-
goBack() {
|
|
3584
|
-
this.location.back();
|
|
3585
|
-
}
|
|
3586
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: HttpError403, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3587
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: HttpError403, isStandalone: true, selector: "ntybase-http-error403", ngImport: i0, template: "<div class=\"error-container\">\n <div class=\"error-page\">\n <h1>403 - Eri\u015Fim Engellendi</h1>\n\n <p>\n <strong>\u00DCzg\u00FCn\u00FCz, {{ attemptedUrl }}</strong> sayfas\u0131na eri\u015Fim izniniz\n bulunmamaktad\u0131r.\n </p>\n\n <p class=\"error-detail\">\n Bu sayfay\u0131 g\u00F6r\u00FCnt\u00FClemek i\u00E7in gerekli yetkilere sahip de\u011Filsiniz. E\u011Fer bu\n bir hata oldu\u011Funu d\u00FC\u015F\u00FCn\u00FCyorsan\u0131z, l\u00FCtfen sistem y\u00F6neticinizle ileti\u015Fime\n ge\u00E7in.\n </p>\n <button mat-raised-button (click)=\"goHome()\" color=\"primary\" routerLink=\"/\">\n Ana Sayfaya D\u00F6n\n </button>\n <button mat-raised-button (click)=\"goBack()\" color=\"primary\" routerLink=\"/\">\n Geri D\u00F6n\n </button>\n </div>\n</div>\n", styles: [".error-container{background-image:var(--httperror403-bg-image, linear-gradient(rgba(0, 0, 0, .6), rgba(0, 0, 0, .6)), url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-blend-mode:overlay;height:100vh;width:100%;background-position:center;background-repeat:no-repeat;background-size:cover;display:flex;justify-content:center;align-items:center;color:#fff;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.error-page{text-align:center;padding:3rem;max-width:650px;margin:0 auto;background-color:#000000b3;border-radius:16px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 8px 32px #0000004d;animation:fadeIn .8s ease-in-out}.error-page h1{font-size:6rem;margin:0;color:var(--mat-sys-primary-container);text-shadow:0 4px 8px rgba(0,0,0,.3);font-weight:700}.error-page h3{font-size:1.8rem;margin-top:0;margin-bottom:1.5rem;color:#f8f9fa}.error-page p{margin:1.5rem 0;font-size:1.1rem;line-height:1.6;color:#e9ecef}.error-page strong{word-break:break-all;color:#ff6b6b;font-weight:500}button{margin:.5rem;padding:.8rem 2rem;font-size:1rem;font-weight:500;border-radius:50px;transition:all .3s ease;background-color:var(--mat-sys-primary);color:var(--mat-sys-on-primary)}button:hover{transform:translateY(-2px);box-shadow:0 6px 12px #00000026}button:active{transform:translateY(0)}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@media(max-width:600px){.error-page{padding:2rem;width:90%}.error-page h1{font-size:4rem}.error-page h3{font-size:1.5rem}button{display:block;width:100%;margin:.5rem 0}}\n"] });
|
|
3588
|
-
}
|
|
3589
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: HttpError403, decorators: [{
|
|
3590
|
-
type: Component,
|
|
3591
|
-
args: [{ selector: 'ntybase-http-error403', imports: [], template: "<div class=\"error-container\">\n <div class=\"error-page\">\n <h1>403 - Eri\u015Fim Engellendi</h1>\n\n <p>\n <strong>\u00DCzg\u00FCn\u00FCz, {{ attemptedUrl }}</strong> sayfas\u0131na eri\u015Fim izniniz\n bulunmamaktad\u0131r.\n </p>\n\n <p class=\"error-detail\">\n Bu sayfay\u0131 g\u00F6r\u00FCnt\u00FClemek i\u00E7in gerekli yetkilere sahip de\u011Filsiniz. E\u011Fer bu\n bir hata oldu\u011Funu d\u00FC\u015F\u00FCn\u00FCyorsan\u0131z, l\u00FCtfen sistem y\u00F6neticinizle ileti\u015Fime\n ge\u00E7in.\n </p>\n <button mat-raised-button (click)=\"goHome()\" color=\"primary\" routerLink=\"/\">\n Ana Sayfaya D\u00F6n\n </button>\n <button mat-raised-button (click)=\"goBack()\" color=\"primary\" routerLink=\"/\">\n Geri D\u00F6n\n </button>\n </div>\n</div>\n", styles: [".error-container{background-image:var(--httperror403-bg-image, linear-gradient(rgba(0, 0, 0, .6), rgba(0, 0, 0, .6)), url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-blend-mode:overlay;height:100vh;width:100%;background-position:center;background-repeat:no-repeat;background-size:cover;display:flex;justify-content:center;align-items:center;color:#fff;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.error-page{text-align:center;padding:3rem;max-width:650px;margin:0 auto;background-color:#000000b3;border-radius:16px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 8px 32px #0000004d;animation:fadeIn .8s ease-in-out}.error-page h1{font-size:6rem;margin:0;color:var(--mat-sys-primary-container);text-shadow:0 4px 8px rgba(0,0,0,.3);font-weight:700}.error-page h3{font-size:1.8rem;margin-top:0;margin-bottom:1.5rem;color:#f8f9fa}.error-page p{margin:1.5rem 0;font-size:1.1rem;line-height:1.6;color:#e9ecef}.error-page strong{word-break:break-all;color:#ff6b6b;font-weight:500}button{margin:.5rem;padding:.8rem 2rem;font-size:1rem;font-weight:500;border-radius:50px;transition:all .3s ease;background-color:var(--mat-sys-primary);color:var(--mat-sys-on-primary)}button:hover{transform:translateY(-2px);box-shadow:0 6px 12px #00000026}button:active{transform:translateY(0)}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@media(max-width:600px){.error-page{padding:2rem;width:90%}.error-page h1{font-size:4rem}.error-page h3{font-size:1.5rem}button{display:block;width:100%;margin:.5rem 0}}\n"] }]
|
|
3592
|
-
}], ctorParameters: () => [] });
|
|
3593
|
-
|
|
3594
|
-
class HttpError404 {
|
|
3595
|
-
attemptedUrl = '';
|
|
3596
|
-
routeSubscription;
|
|
3597
|
-
router = inject(Router);
|
|
3598
|
-
route = inject(ActivatedRoute);
|
|
3599
|
-
location = inject(Location);
|
|
3600
|
-
commonService = inject(CommonService);
|
|
3601
|
-
constructor() {
|
|
3602
|
-
this.routeSubscription = this.router.events.subscribe(() => {
|
|
3603
|
-
this.updateAttemptedUrl();
|
|
3604
|
-
});
|
|
3605
|
-
}
|
|
3606
|
-
ngOnInit() {
|
|
3607
|
-
// 1. URL'deki secondary outlet'leri temizle (örneğin: "(rightSidenav:...)")
|
|
3608
|
-
this.cleanUrlFromFragments();
|
|
3609
|
-
// 2. Hata mesajı için attemptedUrl'i güncelle
|
|
3610
|
-
this.updateAttemptedUrl();
|
|
3611
|
-
// 3. Right sidenav'ı kapat
|
|
3612
|
-
this.commonService.toggleRightSidenav(false);
|
|
3613
|
-
}
|
|
3614
|
-
ngOnDestroy() {
|
|
3615
|
-
if (this.routeSubscription) {
|
|
3616
|
-
this.routeSubscription.unsubscribe();
|
|
3617
|
-
}
|
|
3618
|
-
}
|
|
3619
|
-
/**
|
|
3620
|
-
* URL'deki fragment ve outlet'leri temizler.
|
|
3621
|
-
* Örnek: "/sys/NettyUserGroup(rightSidenav:...)" → "/sys/NettyUserGroup"
|
|
3622
|
-
*/
|
|
3623
|
-
cleanUrlFromFragments() {
|
|
3624
|
-
const currentUrl = this.router.url;
|
|
3625
|
-
const cleanUrl = currentUrl.split('(')[0]; // "(" sonrasını sil
|
|
3626
|
-
if (currentUrl !== cleanUrl) {
|
|
3627
|
-
// URL'yi temizlenmiş haliyle değiştir (tarayıcı geçmişine eklemeden)
|
|
3628
|
-
this.router.navigateByUrl(cleanUrl, {
|
|
3629
|
-
replaceUrl: true,
|
|
3630
|
-
skipLocationChange: false,
|
|
3631
|
-
});
|
|
3632
|
-
}
|
|
3633
|
-
}
|
|
3634
|
-
/**
|
|
3635
|
-
* Temizlenmiş URL yolunu döndürür (queryParams ve fragment olmadan).
|
|
3636
|
-
*/
|
|
3637
|
-
getCleanUrlPath() {
|
|
3638
|
-
return this.router.url.split('?')[0].split('(')[0];
|
|
3639
|
-
}
|
|
3640
|
-
/**
|
|
3641
|
-
* attemptedUrl'i güncel router URL'ine göre günceller
|
|
3642
|
-
*/
|
|
3643
|
-
updateAttemptedUrl() {
|
|
3644
|
-
this.attemptedUrl = this.getCleanUrlPath();
|
|
3645
|
-
}
|
|
3646
|
-
goHome() {
|
|
3647
|
-
this.router.navigate(['/'], { replaceUrl: true });
|
|
3648
|
-
this.commonService.toggleRightSidenav(false);
|
|
3649
|
-
}
|
|
3650
|
-
goBack() {
|
|
3651
|
-
this.location.back();
|
|
3652
|
-
}
|
|
3653
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: HttpError404, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3654
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: HttpError404, isStandalone: true, selector: "ntybase-http-error404", ngImport: i0, template: "<div class=\"error-container\">\n <div class=\"error-page\">\n <h1>404</h1>\n <h3>Sayfa Bulunamad\u0131</h3>\n <p><strong>{{ attemptedUrl }}</strong> adresi bulunamad\u0131.</p>\n <p>Bu i\u00E7erik ta\u015F\u0131nm\u0131\u015F veya silinmi\u015F olabilir.</p>\n <button mat-raised-button (click)=\"goHome()\" color=\"primary\" routerLink=\"/\">\n Ana Sayfaya D\u00F6n\n </button>\n <button mat-raised-button (click)=\"goBack()\" color=\"primary\" routerLink=\"/\">\n Geri D\u00F6n\n </button>\n </div>\n</div>\n", styles: [".error-container{background-image:var(--httperror404-bg-image, linear-gradient(rgba(0, 0, 0, .6), rgba(0, 0, 0, .6)), url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-blend-mode:overlay;height:100vh;width:100%;background-position:center;background-repeat:no-repeat;background-size:cover;display:flex;justify-content:center;align-items:center;color:#fff;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.error-page{text-align:center;padding:3rem;max-width:650px;margin:0 auto;background-color:#000000b3;border-radius:16px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 8px 32px #0000004d;animation:fadeIn .8s ease-in-out}.error-page h1{font-size:6rem;margin:0;color:var(--mat-sys-primary-container);text-shadow:0 4px 8px rgba(0,0,0,.3);font-weight:700}.error-page h3{font-size:1.8rem;margin-top:0;margin-bottom:1.5rem;color:#f8f9fa}.error-page p{margin:1.5rem 0;font-size:1.1rem;line-height:1.6;color:#e9ecef}.error-page strong{word-break:break-all;color:#ff6b6b;font-weight:500}button{margin:.5rem;padding:.8rem 2rem;font-size:1rem;font-weight:500;border-radius:50px;transition:all .3s ease;background-color:var(--mat-sys-primary);color:var(--mat-sys-on-primary)}button:hover{transform:translateY(-2px);box-shadow:0 6px 12px #00000026}button:active{transform:translateY(0)}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@media(max-width:600px){.error-page{padding:2rem;width:90%}.error-page h1{font-size:4rem}.error-page h3{font-size:1.5rem}button{display:block;width:100%;margin:.5rem 0}}\n"] });
|
|
3655
|
-
}
|
|
3656
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: HttpError404, decorators: [{
|
|
3657
|
-
type: Component,
|
|
3658
|
-
args: [{ selector: 'ntybase-http-error404', imports: [], template: "<div class=\"error-container\">\n <div class=\"error-page\">\n <h1>404</h1>\n <h3>Sayfa Bulunamad\u0131</h3>\n <p><strong>{{ attemptedUrl }}</strong> adresi bulunamad\u0131.</p>\n <p>Bu i\u00E7erik ta\u015F\u0131nm\u0131\u015F veya silinmi\u015F olabilir.</p>\n <button mat-raised-button (click)=\"goHome()\" color=\"primary\" routerLink=\"/\">\n Ana Sayfaya D\u00F6n\n </button>\n <button mat-raised-button (click)=\"goBack()\" color=\"primary\" routerLink=\"/\">\n Geri D\u00F6n\n </button>\n </div>\n</div>\n", styles: [".error-container{background-image:var(--httperror404-bg-image, linear-gradient(rgba(0, 0, 0, .6), rgba(0, 0, 0, .6)), url(https://images.unsplash.com/photo-1519681393784-d120267933ba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1124&q=100));background-blend-mode:overlay;height:100vh;width:100%;background-position:center;background-repeat:no-repeat;background-size:cover;display:flex;justify-content:center;align-items:center;color:#fff;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif}.error-page{text-align:center;padding:3rem;max-width:650px;margin:0 auto;background-color:#000000b3;border-radius:16px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 8px 32px #0000004d;animation:fadeIn .8s ease-in-out}.error-page h1{font-size:6rem;margin:0;color:var(--mat-sys-primary-container);text-shadow:0 4px 8px rgba(0,0,0,.3);font-weight:700}.error-page h3{font-size:1.8rem;margin-top:0;margin-bottom:1.5rem;color:#f8f9fa}.error-page p{margin:1.5rem 0;font-size:1.1rem;line-height:1.6;color:#e9ecef}.error-page strong{word-break:break-all;color:#ff6b6b;font-weight:500}button{margin:.5rem;padding:.8rem 2rem;font-size:1rem;font-weight:500;border-radius:50px;transition:all .3s ease;background-color:var(--mat-sys-primary);color:var(--mat-sys-on-primary)}button:hover{transform:translateY(-2px);box-shadow:0 6px 12px #00000026}button:active{transform:translateY(0)}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@media(max-width:600px){.error-page{padding:2rem;width:90%}.error-page h1{font-size:4rem}.error-page h3{font-size:1.5rem}button{display:block;width:100%;margin:.5rem 0}}\n"] }]
|
|
3659
|
-
}], ctorParameters: () => [] });
|
|
3660
|
-
|
|
3661
|
-
class NettyMenuService {
|
|
3662
|
-
http = inject(HttpClient);
|
|
3663
|
-
environmentProxy = inject(EnvironmentProxy);
|
|
3664
|
-
i18nService = inject(I18nService);
|
|
3665
|
-
menuName = signal('', ...(ngDevMode ? [{ debugName: "menuName" }] : []));
|
|
3666
|
-
menu = signal(null, ...(ngDevMode ? [{ debugName: "menu" }] : []));
|
|
3667
|
-
constructor() {
|
|
3668
|
-
effect(() => {
|
|
3669
|
-
const currentMenuName = this.menuName();
|
|
3670
|
-
const currentLang = this.i18nService.currentLang();
|
|
3671
|
-
if (!currentMenuName.trim()) {
|
|
3672
|
-
return;
|
|
3673
|
-
}
|
|
3674
|
-
let functionUrl = this.environmentProxy.getAdminLink('/GetMenu');
|
|
3675
|
-
if (currentMenuName.trim().length > 0) {
|
|
3676
|
-
functionUrl += '/' + currentMenuName.trim();
|
|
3677
|
-
}
|
|
3678
|
-
this.http.get(functionUrl).subscribe({
|
|
3679
|
-
next: (data) => this.menu.set(data),
|
|
3680
|
-
error: (err) => {
|
|
3681
|
-
console.error('Failed to fetch menu:', err);
|
|
3682
|
-
this.menu.set(null);
|
|
3683
|
-
},
|
|
3684
|
-
});
|
|
3685
|
-
});
|
|
3686
|
-
}
|
|
3687
|
-
setMenuName(name) {
|
|
3688
|
-
if (name && name.trim()) {
|
|
3689
|
-
this.menuName.set(name.trim());
|
|
3690
|
-
}
|
|
3691
|
-
}
|
|
3692
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: NettyMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3693
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: NettyMenuService, providedIn: 'root' });
|
|
3694
|
-
}
|
|
3695
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: NettyMenuService, decorators: [{
|
|
3696
|
-
type: Injectable,
|
|
3697
|
-
args: [{
|
|
3698
|
-
providedIn: 'root',
|
|
3699
|
-
}]
|
|
3700
|
-
}], ctorParameters: () => [] });
|
|
3701
|
-
|
|
3702
3509
|
// text-image.service.ts
|
|
3703
3510
|
/**
|
|
3704
3511
|
* Manage Image operations
|
|
@@ -3753,335 +3560,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
3753
3560
|
}]
|
|
3754
3561
|
}] });
|
|
3755
3562
|
|
|
3756
|
-
class LeftSidenav {
|
|
3757
|
-
authService = inject(AuthenticationService);
|
|
3758
|
-
router = inject(Router);
|
|
3759
|
-
menuService = inject(NettyMenuService);
|
|
3760
|
-
commonService = inject(CommonService);
|
|
3761
|
-
environmentProxy = inject(EnvironmentProxy);
|
|
3762
|
-
credentialsService = inject(CredentialsService);
|
|
3763
|
-
imageService = inject(NettyImageService);
|
|
3764
|
-
elementRef = inject(ElementRef);
|
|
3765
|
-
username = signal('', ...(ngDevMode ? [{ debugName: "username" }] : []));
|
|
3766
|
-
profileImage = signal('', ...(ngDevMode ? [{ debugName: "profileImage" }] : []));
|
|
3767
|
-
version = this.environmentProxy.version();
|
|
3768
|
-
isMinimized = input(false, ...(ngDevMode ? [{ debugName: "isMinimized" }] : []));
|
|
3769
|
-
toggleMinimize = output();
|
|
3770
|
-
onToggleMinimize() {
|
|
3771
|
-
this.toggleMinimize.emit();
|
|
3772
|
-
}
|
|
3773
|
-
logout() {
|
|
3774
|
-
this.authService.logout().subscribe({
|
|
3775
|
-
next: (success) => {
|
|
3776
|
-
if (success) {
|
|
3777
|
-
const cleanUrl = this.commonService.getCleanUrlPath();
|
|
3778
|
-
this.router.navigateByUrl(cleanUrl, { replaceUrl: true }).then(() => {
|
|
3779
|
-
this.router.navigate(['/login']);
|
|
3780
|
-
});
|
|
3781
|
-
}
|
|
3782
|
-
},
|
|
3783
|
-
error: (err) => {
|
|
3784
|
-
console.error('Logout failed:', err);
|
|
3785
|
-
},
|
|
3786
|
-
});
|
|
3787
|
-
}
|
|
3788
|
-
// Menu Search
|
|
3789
|
-
menuItems = signal([], ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
|
|
3790
|
-
searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
3791
|
-
originalMenuItems = signal([], ...(ngDevMode ? [{ debugName: "originalMenuItems" }] : []));
|
|
3792
|
-
constructor() {
|
|
3793
|
-
effect(() => {
|
|
3794
|
-
const fetchedMenu = this.menuService.menu();
|
|
3795
|
-
if (fetchedMenu) {
|
|
3796
|
-
const processedItems = this.processMenuItems(fetchedMenu);
|
|
3797
|
-
this.originalMenuItems.set(processedItems);
|
|
3798
|
-
}
|
|
3799
|
-
else {
|
|
3800
|
-
this.originalMenuItems.set([]);
|
|
3801
|
-
}
|
|
3802
|
-
});
|
|
3803
|
-
this.loadUserInfo();
|
|
3804
|
-
}
|
|
3805
|
-
ngOnInit() {
|
|
3806
|
-
// Application name gelene kadar 3 kez dene
|
|
3807
|
-
this.trySetMenuName(0);
|
|
3808
|
-
}
|
|
3809
|
-
trySetMenuName(attempt) {
|
|
3810
|
-
const appName = this.environmentProxy.getApplicationName();
|
|
3811
|
-
if (appName && appName.trim()) {
|
|
3812
|
-
// Application name geldi, menüyü yükle
|
|
3813
|
-
this.menuService.setMenuName(appName);
|
|
3814
|
-
}
|
|
3815
|
-
else if (attempt < 3) {
|
|
3816
|
-
// Henüz gelmedi, 300ms sonra tekrar dene
|
|
3817
|
-
setTimeout(() => {
|
|
3818
|
-
this.trySetMenuName(attempt + 1);
|
|
3819
|
-
}, 300);
|
|
3820
|
-
}
|
|
3821
|
-
else {
|
|
3822
|
-
// 3 denemeden sonra hala gelmedi, boş string ile dene
|
|
3823
|
-
console.warn('Application name not found, using empty string');
|
|
3824
|
-
this.menuService.setMenuName('');
|
|
3825
|
-
}
|
|
3826
|
-
}
|
|
3827
|
-
ngAfterViewInit() {
|
|
3828
|
-
setTimeout(() => {
|
|
3829
|
-
this.loadUserInfo();
|
|
3830
|
-
}, 0);
|
|
3831
|
-
}
|
|
3832
|
-
loadUserInfo() {
|
|
3833
|
-
const credentials = this.credentialsService.getCredentials();
|
|
3834
|
-
if (credentials && credentials.username) {
|
|
3835
|
-
this.username.set(credentials.username);
|
|
3836
|
-
this.generateProfileImage(credentials.username);
|
|
3837
|
-
}
|
|
3838
|
-
}
|
|
3839
|
-
generateProfileImage(username) {
|
|
3840
|
-
const initials = this.getInitials(username);
|
|
3841
|
-
const primaryColor = this.getCssVariableValue('--mat-sys-primary');
|
|
3842
|
-
const imageUrl = this.imageService.generateTextImage(initials, 40, 40, primaryColor || '#4ECDC4', '#FFFFFF', 'rgba(0, 0, 0, 0.2)');
|
|
3843
|
-
this.profileImage.set(imageUrl);
|
|
3844
|
-
}
|
|
3845
|
-
getCssVariableValue(variableName) {
|
|
3846
|
-
if (typeof window === 'undefined')
|
|
3847
|
-
return null;
|
|
3848
|
-
const element = this.elementRef.nativeElement;
|
|
3849
|
-
return (getComputedStyle(element).getPropertyValue(variableName).trim() || null);
|
|
3850
|
-
}
|
|
3851
|
-
getInitials(username) {
|
|
3852
|
-
if (!username)
|
|
3853
|
-
return 'U';
|
|
3854
|
-
const names = username.trim().split(' ');
|
|
3855
|
-
if (names.length === 1) {
|
|
3856
|
-
return names[0].charAt(0).toUpperCase();
|
|
3857
|
-
}
|
|
3858
|
-
else {
|
|
3859
|
-
return (names[0].charAt(0) + names[names.length - 1].charAt(0)).toUpperCase();
|
|
3860
|
-
}
|
|
3861
|
-
}
|
|
3862
|
-
processMenuItems(apiResponse) {
|
|
3863
|
-
if (!apiResponse || !Array.isArray(apiResponse)) {
|
|
3864
|
-
return [];
|
|
3865
|
-
}
|
|
3866
|
-
return apiResponse.map((item) => ({
|
|
3867
|
-
name: item.label || item.name,
|
|
3868
|
-
icon: item.icon || '',
|
|
3869
|
-
link: item.route || item.link || '#',
|
|
3870
|
-
expanded: false,
|
|
3871
|
-
children: item.children ? this.processMenuItems(item.children) : [],
|
|
3872
|
-
}));
|
|
3873
|
-
}
|
|
3874
|
-
filteredMenuItems = computed(() => {
|
|
3875
|
-
const term = this.searchTerm().toLowerCase();
|
|
3876
|
-
if (!term)
|
|
3877
|
-
return this.originalMenuItems();
|
|
3878
|
-
return this.filterMenuItems(this.originalMenuItems(), term);
|
|
3879
|
-
}, ...(ngDevMode ? [{ debugName: "filteredMenuItems" }] : []));
|
|
3880
|
-
filterMenuItems(items, term) {
|
|
3881
|
-
const normalizedTerm = this.commonService.normalizeTurkish(term);
|
|
3882
|
-
return items
|
|
3883
|
-
.map((item) => {
|
|
3884
|
-
const filteredChildren = item.children
|
|
3885
|
-
? this.filterMenuItems(item.children, term)
|
|
3886
|
-
: [];
|
|
3887
|
-
const normalizedName = this.commonService.normalizeTurkish(item.name);
|
|
3888
|
-
const matches = normalizedName.includes(normalizedTerm) ||
|
|
3889
|
-
filteredChildren.length > 0;
|
|
3890
|
-
return matches
|
|
3891
|
-
? {
|
|
3892
|
-
...item,
|
|
3893
|
-
children: filteredChildren,
|
|
3894
|
-
expanded: matches || filteredChildren.length > 0,
|
|
3895
|
-
}
|
|
3896
|
-
: null;
|
|
3897
|
-
})
|
|
3898
|
-
.filter((item) => item !== null);
|
|
3899
|
-
}
|
|
3900
|
-
toggleSubMenu(item) {
|
|
3901
|
-
item.expanded = !item.expanded;
|
|
3902
|
-
}
|
|
3903
|
-
onSearch(term) {
|
|
3904
|
-
this.searchTerm.set(term);
|
|
3905
|
-
}
|
|
3906
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LeftSidenav, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3907
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: LeftSidenav, isStandalone: true, selector: "ntybase-left-sidenav", inputs: { isMinimized: { classPropertyName: "isMinimized", publicName: "isMinimized", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleMinimize: "toggleMinimize" }, ngImport: i0, template: "<div class=\"sidenav-content-wrapper\">\n <!-- Minimize Icon -->\n <button mat-icon-button (click)=\"onToggleMinimize()\" class=\"minimize-button\">\n <mat-icon class=\"minimize-icon\">\n {{ isMinimized() ? \"chevron_right\" : \"chevron_left\" }}\n </mat-icon>\n </button>\n\n <!-- Profile -->\n <div class=\"profile-section\">\n <button mat-button [matMenuTriggerFor]=\"profileMenu\" class=\"profile-button\">\n <img [src]=\"profileImage()\" [alt]=\"username()\" class=\"profile-image\" />\n @if(!isMinimized()){\n <div class=\"profile-info\">\n <p class=\"profile-name\">{{ username() }}</p>\n </div>\n }\n </button>\n\n <mat-menu #profileMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item disabled>\n <mat-icon>account_circle</mat-icon>\n <span>{{ '@profile' | translate }}</span>\n </button>\n <button mat-menu-item mat-button disabled>\n <mat-icon>swap_horiz</mat-icon>\n <span>{{ '@changeCompany' | translate }}</span>\n </button>\n <button mat-menu-item mat-button (click)=\"logout()\">\n <mat-icon>logout</mat-icon>\n <span>{{ '@logout' | translate }}</span>\n </button>\n </mat-menu>\n </div>\n\n <!-- Search Input -->\n @if (!isMinimized()){\n <ntyui-search-input\n class=\"search-input\"\n [label]=\"'@search' | translate\"\n [placeholder]=\"'@placeholderSearch' | translate\"\n [appearance]=\"'outline'\"\n (search)=\"onSearch($event)\"\n >\n </ntyui-search-input>\n }\n\n <!-- Menu -->\n @if (!isMinimized()) {\n <mat-nav-list>\n <div class=\"sidebar\">\n <ul>\n <!-- Recursive menu render -->\n @let items = filteredMenuItems(); @let level = 0;\n <ng-container\n [ngTemplateOutlet]=\"menuItemsTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: items, level: level }\"\n ></ng-container>\n </ul>\n </div>\n </mat-nav-list>\n }\n\n <!-- Footer -->\n <div class=\"sidenav-footer\">\n <button mat-button [matMenuTriggerFor]=\"footerMenu\" class=\"footer-button\">\n @if (!isMinimized()) {\n <div class=\"footer-text\">\n <div class=\"company-name\">\n <p>© 2025 AXIS</p>\n </div>\n </div>\n }\n </button>\n <div class=\"version\">\n <span class=\"version\">v{{version}}</span>\n </div>\n </div>\n\n <mat-menu #footerMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item disabled>\n <mat-icon>swap_horiz</mat-icon>\n {{ '@changeCompany' | translate }}\n </button>\n <button mat-menu-item mat-button (click)=\"logout()\">\n <mat-icon>logout</mat-icon>\n <span>{{ '@logout' | translate }}</span>\n </button>\n </mat-menu>\n</div>\n\n<!-- Recursive Menu Template -->\n<ng-template #menuItemsTemplate let-items let-level=\"level\">\n @for (item of items; track item.name) {\n <li [class]=\"'menu-level-' + level\">\n <!-- Leaf node (no children) -->\n @if (!item.children || item.children.length === 0) {\n <a\n [routerLink]=\"item.link\"\n routerLinkActive=\"active\"\n [class]=\"'menu-link level-' + level\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n <span>{{ item.name }}</span>\n </a>\n }\n\n <!-- Parent node with children -->\n @if (item.children && item.children.length > 0) {\n <a\n (click)=\"toggleSubMenu(item)\"\n [class.expanded]=\"item.expanded\"\n [class]=\"'menu-link has-children level-' + level\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n <span>{{ item.name }}</span>\n <mat-icon [class.rotated]=\"item.expanded\" class=\"expand-icon\">\n {{ item.expanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </a>\n }\n\n <!-- Recursive submenu -->\n @if (item.children && item.children.length > 0 && item.expanded) {\n <ul [class]=\"'submenu level-' + (level + 1)\">\n <ng-container\n *ngTemplateOutlet=\"menuItemsTemplate; context: { $implicit: item.children, level: level + 1 }\"\n ></ng-container>\n </ul>\n }\n </li>\n }\n</ng-template>\n", styles: [".profile-section{text-align:center;cursor:pointer;transition:all .3s ease;display:flex;align-items:center;flex-direction:column;position:relative}.profile-section:hover{transform:scale(.98)}.profile-section .profile-button{display:flex;flex-direction:column;align-items:center;background:none;border:none;padding:0;cursor:pointer;width:100%}.profile-image{width:60px;height:60px;border-radius:50%;object-fit:cover;margin:0 auto 8px;display:block;border:2px solid white;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.profile-name{font-weight:500;font-size:1rem;color:inherit;transition:opacity .3s ease;margin-top:8px}:host-context(.minimized) .profile-section{padding:10px 0}:host-context(.minimized) .profile-image{width:40px;height:40px;margin:0 auto}.sidenav-footer{position:static;bottom:0;left:0;right:0;padding:16px;color:inherit;font-size:12px;border-top:1px solid rgba(0,0,0,.1);transition:all .3s ease;display:flex;align-items:center;justify-content:space-between;margin-top:auto}.sidenav-footer .version{font-size:10px;margin-top:4px}.footer-button{border:none;background:none;cursor:pointer}:host-context(.minimized) .version{margin-right:7px}:host-context(.minimized) .sidenav-content-wrapper{overflow:hidden}.sidenav-content-wrapper{position:relative;height:100%;display:flex;flex-direction:column;overflow-x:hidden}.sidebar{flex:1;overflow:auto}.sidebar ul{list-style:none;padding:0;margin:0}.sidebar li{margin-bottom:4px;position:relative}.sidebar li a{display:flex;align-items:center;padding:12px 0 0;border-radius:6px;color:var(--mat-sys-primary);text-decoration:none;transition:all .2s ease;position:relative;overflow:hidden}.sidebar li a:hover{background-color:var(--mat-nty-save-record-header-bar);color:var(--mat-nty-save-record-identifier)}.sidebar li a.active{background-color:var(--mat-nty-save-record-header-bar);color:var(--mat-nty-save-record-identifier);font-weight:500}.sidebar li a.active:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:3px;background-color:var(--mat-nty-save-record-header-bar);border-radius:3px 0 0 3px}.sidebar mat-icon{font-size:20px;width:20px;height:20px;color:inherit}.sidebar span{font-size:.875rem;white-space:nowrap}.menu-link.level-2{margin-left:20px;font-size:.82rem}.menu-link.level-3{margin-left:20px;font-size:.8rem}.menu-link.level-4{margin-left:20px;font-size:.78rem}.submenu{padding-left:12px;margin-top:4px}.submenu li a{padding:10px 16px 0 20px}.submenu mat-icon{font-size:18px}.sidebar li a mat-icon:last-child{margin-left:auto;margin-right:0;font-size:18px;color:#5f6368}:host-context(.minimized) .sidebar li a{justify-content:center;padding:12px 0}:host-context(.minimized) .sidenav-content-wrapper button[mat-icon-button]{position:absolute;right:-8px;top:50%;z-index:999}:host-context(.minimized) .sidebar mat-icon{margin-right:0}:host-context(.minimized) .sidebar span,:host-context(.minimized) .sidebar li a mat-icon:last-child{display:none}:host-context(.minimized) .submenu{display:none}.sidenav-content-wrapper button[mat-icon-button]{position:absolute;right:-8px;top:1px;z-index:999}.search-input{margin-top:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i3$2.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2$3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i5.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: NettyUISearchInput, selector: "ntyui-search-input", outputs: ["search"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }] });
|
|
3908
|
-
}
|
|
3909
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LeftSidenav, decorators: [{
|
|
3910
|
-
type: Component,
|
|
3911
|
-
args: [{ selector: 'ntybase-left-sidenav', imports: [
|
|
3912
|
-
CommonModule,
|
|
3913
|
-
MatIconModule,
|
|
3914
|
-
MatListModule,
|
|
3915
|
-
MatMenuModule,
|
|
3916
|
-
MatMenuTrigger,
|
|
3917
|
-
RouterLink,
|
|
3918
|
-
RouterModule,
|
|
3919
|
-
NettyUISearchInput,
|
|
3920
|
-
TranslateModule,
|
|
3921
|
-
], template: "<div class=\"sidenav-content-wrapper\">\n <!-- Minimize Icon -->\n <button mat-icon-button (click)=\"onToggleMinimize()\" class=\"minimize-button\">\n <mat-icon class=\"minimize-icon\">\n {{ isMinimized() ? \"chevron_right\" : \"chevron_left\" }}\n </mat-icon>\n </button>\n\n <!-- Profile -->\n <div class=\"profile-section\">\n <button mat-button [matMenuTriggerFor]=\"profileMenu\" class=\"profile-button\">\n <img [src]=\"profileImage()\" [alt]=\"username()\" class=\"profile-image\" />\n @if(!isMinimized()){\n <div class=\"profile-info\">\n <p class=\"profile-name\">{{ username() }}</p>\n </div>\n }\n </button>\n\n <mat-menu #profileMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item disabled>\n <mat-icon>account_circle</mat-icon>\n <span>{{ '@profile' | translate }}</span>\n </button>\n <button mat-menu-item mat-button disabled>\n <mat-icon>swap_horiz</mat-icon>\n <span>{{ '@changeCompany' | translate }}</span>\n </button>\n <button mat-menu-item mat-button (click)=\"logout()\">\n <mat-icon>logout</mat-icon>\n <span>{{ '@logout' | translate }}</span>\n </button>\n </mat-menu>\n </div>\n\n <!-- Search Input -->\n @if (!isMinimized()){\n <ntyui-search-input\n class=\"search-input\"\n [label]=\"'@search' | translate\"\n [placeholder]=\"'@placeholderSearch' | translate\"\n [appearance]=\"'outline'\"\n (search)=\"onSearch($event)\"\n >\n </ntyui-search-input>\n }\n\n <!-- Menu -->\n @if (!isMinimized()) {\n <mat-nav-list>\n <div class=\"sidebar\">\n <ul>\n <!-- Recursive menu render -->\n @let items = filteredMenuItems(); @let level = 0;\n <ng-container\n [ngTemplateOutlet]=\"menuItemsTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: items, level: level }\"\n ></ng-container>\n </ul>\n </div>\n </mat-nav-list>\n }\n\n <!-- Footer -->\n <div class=\"sidenav-footer\">\n <button mat-button [matMenuTriggerFor]=\"footerMenu\" class=\"footer-button\">\n @if (!isMinimized()) {\n <div class=\"footer-text\">\n <div class=\"company-name\">\n <p>© 2025 AXIS</p>\n </div>\n </div>\n }\n </button>\n <div class=\"version\">\n <span class=\"version\">v{{version}}</span>\n </div>\n </div>\n\n <mat-menu #footerMenu=\"matMenu\" xPosition=\"before\">\n <button mat-menu-item disabled>\n <mat-icon>swap_horiz</mat-icon>\n {{ '@changeCompany' | translate }}\n </button>\n <button mat-menu-item mat-button (click)=\"logout()\">\n <mat-icon>logout</mat-icon>\n <span>{{ '@logout' | translate }}</span>\n </button>\n </mat-menu>\n</div>\n\n<!-- Recursive Menu Template -->\n<ng-template #menuItemsTemplate let-items let-level=\"level\">\n @for (item of items; track item.name) {\n <li [class]=\"'menu-level-' + level\">\n <!-- Leaf node (no children) -->\n @if (!item.children || item.children.length === 0) {\n <a\n [routerLink]=\"item.link\"\n routerLinkActive=\"active\"\n [class]=\"'menu-link level-' + level\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n <span>{{ item.name }}</span>\n </a>\n }\n\n <!-- Parent node with children -->\n @if (item.children && item.children.length > 0) {\n <a\n (click)=\"toggleSubMenu(item)\"\n [class.expanded]=\"item.expanded\"\n [class]=\"'menu-link has-children level-' + level\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n <span>{{ item.name }}</span>\n <mat-icon [class.rotated]=\"item.expanded\" class=\"expand-icon\">\n {{ item.expanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </a>\n }\n\n <!-- Recursive submenu -->\n @if (item.children && item.children.length > 0 && item.expanded) {\n <ul [class]=\"'submenu level-' + (level + 1)\">\n <ng-container\n *ngTemplateOutlet=\"menuItemsTemplate; context: { $implicit: item.children, level: level + 1 }\"\n ></ng-container>\n </ul>\n }\n </li>\n }\n</ng-template>\n", styles: [".profile-section{text-align:center;cursor:pointer;transition:all .3s ease;display:flex;align-items:center;flex-direction:column;position:relative}.profile-section:hover{transform:scale(.98)}.profile-section .profile-button{display:flex;flex-direction:column;align-items:center;background:none;border:none;padding:0;cursor:pointer;width:100%}.profile-image{width:60px;height:60px;border-radius:50%;object-fit:cover;margin:0 auto 8px;display:block;border:2px solid white;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.profile-name{font-weight:500;font-size:1rem;color:inherit;transition:opacity .3s ease;margin-top:8px}:host-context(.minimized) .profile-section{padding:10px 0}:host-context(.minimized) .profile-image{width:40px;height:40px;margin:0 auto}.sidenav-footer{position:static;bottom:0;left:0;right:0;padding:16px;color:inherit;font-size:12px;border-top:1px solid rgba(0,0,0,.1);transition:all .3s ease;display:flex;align-items:center;justify-content:space-between;margin-top:auto}.sidenav-footer .version{font-size:10px;margin-top:4px}.footer-button{border:none;background:none;cursor:pointer}:host-context(.minimized) .version{margin-right:7px}:host-context(.minimized) .sidenav-content-wrapper{overflow:hidden}.sidenav-content-wrapper{position:relative;height:100%;display:flex;flex-direction:column;overflow-x:hidden}.sidebar{flex:1;overflow:auto}.sidebar ul{list-style:none;padding:0;margin:0}.sidebar li{margin-bottom:4px;position:relative}.sidebar li a{display:flex;align-items:center;padding:12px 0 0;border-radius:6px;color:var(--mat-sys-primary);text-decoration:none;transition:all .2s ease;position:relative;overflow:hidden}.sidebar li a:hover{background-color:var(--mat-nty-save-record-header-bar);color:var(--mat-nty-save-record-identifier)}.sidebar li a.active{background-color:var(--mat-nty-save-record-header-bar);color:var(--mat-nty-save-record-identifier);font-weight:500}.sidebar li a.active:before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:3px;background-color:var(--mat-nty-save-record-header-bar);border-radius:3px 0 0 3px}.sidebar mat-icon{font-size:20px;width:20px;height:20px;color:inherit}.sidebar span{font-size:.875rem;white-space:nowrap}.menu-link.level-2{margin-left:20px;font-size:.82rem}.menu-link.level-3{margin-left:20px;font-size:.8rem}.menu-link.level-4{margin-left:20px;font-size:.78rem}.submenu{padding-left:12px;margin-top:4px}.submenu li a{padding:10px 16px 0 20px}.submenu mat-icon{font-size:18px}.sidebar li a mat-icon:last-child{margin-left:auto;margin-right:0;font-size:18px;color:#5f6368}:host-context(.minimized) .sidebar li a{justify-content:center;padding:12px 0}:host-context(.minimized) .sidenav-content-wrapper button[mat-icon-button]{position:absolute;right:-8px;top:50%;z-index:999}:host-context(.minimized) .sidebar mat-icon{margin-right:0}:host-context(.minimized) .sidebar span,:host-context(.minimized) .sidebar li a mat-icon:last-child{display:none}:host-context(.minimized) .submenu{display:none}.sidenav-content-wrapper button[mat-icon-button]{position:absolute;right:-8px;top:1px;z-index:999}.search-input{margin-top:10px}\n"] }]
|
|
3922
|
-
}], ctorParameters: () => [], propDecorators: { isMinimized: [{ type: i0.Input, args: [{ isSignal: true, alias: "isMinimized", required: false }] }], toggleMinimize: [{ type: i0.Output, args: ["toggleMinimize"] }] } });
|
|
3923
|
-
|
|
3924
|
-
class Theme {
|
|
3925
|
-
THEME_STORAGE_KEY = 'app-theme';
|
|
3926
|
-
appTheme = signal('light', ...(ngDevMode ? [{ debugName: "appTheme" }] : []));
|
|
3927
|
-
themes = [
|
|
3928
|
-
{ name: 'light', icon: 'light_mode' },
|
|
3929
|
-
{ name: 'dark', icon: 'dark_mode' },
|
|
3930
|
-
];
|
|
3931
|
-
selectedTheme = computed(() => this.themes.find((theme) => theme.name === this.appTheme()), ...(ngDevMode ? [{ debugName: "selectedTheme" }] : []));
|
|
3932
|
-
constructor() {
|
|
3933
|
-
const savedTheme = this.getSavedTheme();
|
|
3934
|
-
if (savedTheme) {
|
|
3935
|
-
this.appTheme.set(savedTheme);
|
|
3936
|
-
}
|
|
3937
|
-
effect(() => {
|
|
3938
|
-
const appTheme = this.appTheme();
|
|
3939
|
-
document.body.style.setProperty('color-scheme', appTheme);
|
|
3940
|
-
document.body.setAttribute('data-ag-theme-mode', appTheme);
|
|
3941
|
-
});
|
|
3942
|
-
}
|
|
3943
|
-
getThemes() {
|
|
3944
|
-
return this.themes;
|
|
3945
|
-
}
|
|
3946
|
-
setTheme(theme) {
|
|
3947
|
-
this.appTheme.set(theme);
|
|
3948
|
-
this.saveTheme(theme);
|
|
3949
|
-
}
|
|
3950
|
-
getSavedTheme() {
|
|
3951
|
-
if (typeof window !== 'undefined' && window.localStorage) {
|
|
3952
|
-
const saved = localStorage.getItem(this.THEME_STORAGE_KEY);
|
|
3953
|
-
return saved === 'light' || saved === 'dark' ? saved : null;
|
|
3954
|
-
}
|
|
3955
|
-
return null;
|
|
3956
|
-
}
|
|
3957
|
-
saveTheme(theme) {
|
|
3958
|
-
if (typeof window !== 'undefined' && window.localStorage) {
|
|
3959
|
-
localStorage.setItem(this.THEME_STORAGE_KEY, theme);
|
|
3960
|
-
}
|
|
3961
|
-
}
|
|
3962
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Theme, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3963
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Theme, providedIn: 'root' });
|
|
3964
|
-
}
|
|
3965
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Theme, decorators: [{
|
|
3966
|
-
type: Injectable,
|
|
3967
|
-
args: [{
|
|
3968
|
-
providedIn: 'root',
|
|
3969
|
-
}]
|
|
3970
|
-
}], ctorParameters: () => [] });
|
|
3971
|
-
|
|
3972
|
-
class ColorPalette {
|
|
3973
|
-
THEME_STORAGE_KEY = 'selected-theme';
|
|
3974
|
-
themes = [];
|
|
3975
|
-
currentTheme = signal(null, ...(ngDevMode ? [{ debugName: "currentTheme" }] : []));
|
|
3976
|
-
setThemes(customThemes) {
|
|
3977
|
-
this.themes = customThemes;
|
|
3978
|
-
const savedThemeId = this.getSavedTheme();
|
|
3979
|
-
const themeToSet = savedThemeId
|
|
3980
|
-
? this.themes.find((t) => t.id === savedThemeId)
|
|
3981
|
-
: this.themes[0];
|
|
3982
|
-
if (themeToSet) {
|
|
3983
|
-
this.currentTheme.set(themeToSet);
|
|
3984
|
-
}
|
|
3985
|
-
else if (this.themes.length > 0) {
|
|
3986
|
-
this.currentTheme.set(this.themes[0]);
|
|
3987
|
-
}
|
|
3988
|
-
}
|
|
3989
|
-
getThemes() {
|
|
3990
|
-
return this.themes;
|
|
3991
|
-
}
|
|
3992
|
-
setTheme(themeId) {
|
|
3993
|
-
const theme = this.themes.find((t) => t.id === themeId);
|
|
3994
|
-
if (theme) {
|
|
3995
|
-
this.currentTheme.set(theme);
|
|
3996
|
-
this.saveTheme(themeId);
|
|
3997
|
-
}
|
|
3998
|
-
}
|
|
3999
|
-
getSavedTheme() {
|
|
4000
|
-
if (typeof window !== 'undefined' && window.localStorage) {
|
|
4001
|
-
return localStorage.getItem(this.THEME_STORAGE_KEY);
|
|
4002
|
-
}
|
|
4003
|
-
return null;
|
|
4004
|
-
}
|
|
4005
|
-
saveTheme(themeId) {
|
|
4006
|
-
if (typeof window !== 'undefined' && window.localStorage) {
|
|
4007
|
-
localStorage.setItem(this.THEME_STORAGE_KEY, themeId);
|
|
4008
|
-
}
|
|
4009
|
-
}
|
|
4010
|
-
updateThemeClass = effect(() => {
|
|
4011
|
-
const theme = this.currentTheme();
|
|
4012
|
-
if (theme) {
|
|
4013
|
-
document.body.classList.remove(...this.themes.map((t) => `${t.id}-theme`));
|
|
4014
|
-
document.body.classList.add(`${theme.id}-theme`);
|
|
4015
|
-
}
|
|
4016
|
-
}, ...(ngDevMode ? [{ debugName: "updateThemeClass" }] : []));
|
|
4017
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ColorPalette, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4018
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ColorPalette, providedIn: 'root' });
|
|
4019
|
-
}
|
|
4020
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ColorPalette, decorators: [{
|
|
4021
|
-
type: Injectable,
|
|
4022
|
-
args: [{
|
|
4023
|
-
providedIn: 'root',
|
|
4024
|
-
}]
|
|
4025
|
-
}] });
|
|
4026
|
-
|
|
4027
|
-
class Toolbar {
|
|
4028
|
-
themeService = inject(Theme);
|
|
4029
|
-
colorPaletteService = inject(ColorPalette);
|
|
4030
|
-
i18nService = inject(I18nService);
|
|
4031
|
-
router = inject(Router);
|
|
4032
|
-
toggleSidenav = output();
|
|
4033
|
-
onToggleSidenav() {
|
|
4034
|
-
this.toggleSidenav.emit();
|
|
4035
|
-
}
|
|
4036
|
-
// Language
|
|
4037
|
-
icon = model(false, ...(ngDevMode ? [{ debugName: "icon" }] : []));
|
|
4038
|
-
get currentLanguage() {
|
|
4039
|
-
return this.i18nService.language;
|
|
4040
|
-
}
|
|
4041
|
-
get languages() {
|
|
4042
|
-
return this.i18nService.supportedLanguages;
|
|
4043
|
-
}
|
|
4044
|
-
setLanguage(language) {
|
|
4045
|
-
this.i18nService.language = language;
|
|
4046
|
-
setTimeout(() => {
|
|
4047
|
-
window.location.reload();
|
|
4048
|
-
}, 100);
|
|
4049
|
-
}
|
|
4050
|
-
getCurrentLanguageIcon() {
|
|
4051
|
-
switch (this.i18nService.language) {
|
|
4052
|
-
case 'Türkçe':
|
|
4053
|
-
return 'fi fi-tr';
|
|
4054
|
-
case 'English':
|
|
4055
|
-
return 'fi fi-us';
|
|
4056
|
-
default:
|
|
4057
|
-
return 'fi fi-tr';
|
|
4058
|
-
}
|
|
4059
|
-
}
|
|
4060
|
-
getLanguageIcon(language) {
|
|
4061
|
-
switch (language) {
|
|
4062
|
-
case 'Türkçe':
|
|
4063
|
-
return 'fi fi-tr';
|
|
4064
|
-
case 'English':
|
|
4065
|
-
return 'fi fi-us';
|
|
4066
|
-
default:
|
|
4067
|
-
return 'fi fi-tr';
|
|
4068
|
-
}
|
|
4069
|
-
}
|
|
4070
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Toolbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4071
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: Toolbar, isStandalone: true, selector: "ntybase-toolbar", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleSidenav: "toggleSidenav", icon: "iconChange" }, ngImport: i0, template: "<mat-toolbar class=\"sidenav-header\">\n <div class=\"left-section\">\n <button mat-icon-button (click)=\"onToggleSidenav()\" class=\"menu-button\">\n <mat-icon>menu</mat-icon>\n </button>\n <span>{{'app_name' | translate }}</span>\n\n <!-- Language Selection -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n </div>\n\n <div class=\"spacer\"></div>\n\n <div class=\"flex-stretch\"></div>\n <button\n mat-icon-button\n [mat-menu-trigger-for]=\"themeMenu\"\n class=\"theme-button\"\n >\n <mat-icon>{{ themeService.selectedTheme()?.icon }}</mat-icon>\n </button>\n <mat-menu #themeMenu=\"matMenu\">\n @for (theme of themeService.getThemes(); track theme.name) {\n <button\n [class.selected-theme]=\"themeService.selectedTheme()?.name === theme.name\"\n mat-menu-item\n (click)=\"themeService.setTheme(theme.name)\"\n >\n <mat-icon>{{ theme.icon }}</mat-icon>\n <span>{{ theme.name | titlecase }}</span>\n </button>\n }\n </mat-menu>\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"customThemeMenu\"\n class=\"custom-theme-button\"\n >\n <mat-icon>format_color_fill</mat-icon>\n </button>\n <mat-menu #customThemeMenu=\"matMenu\">\n @for (customTheme of colorPaletteService.getThemes(); track customTheme.id)\n {\n <button\n mat-menu-item\n (click)=\"colorPaletteService.setTheme(customTheme.id)\"\n >\n <div class=\"theme-menu-item\">\n <div\n class=\"color-preview\"\n [style.background-color]=\"customTheme.primary\"\n ></div>\n <span>{{ customTheme.displayName }}</span>\n </div>\n </button>\n }\n </mat-menu>\n</mat-toolbar>\n", styles: ["mat-toolbar{position:fixed;top:0;left:0;right:0;z-index:3;box-shadow:0 1px 5px #0000001a;display:flex;align-items:center}.sidenav-header{display:flex;justify-content:space-between;align-items:center;padding:16px;margin:0;font-weight:500}.sidenav-header .left-section{display:flex;align-items:center;gap:16px}.sidenav-header .spacer{flex:1 1 auto}.flex-stretch{flex:1 0 auto}.theme-menu-item{display:flex;align-items:center;gap:12px}.color-preview{width:24px;height:24px;border-radius:50%}::ng-deep .theme-button{border:none;background:none;margin-right:15px;cursor:pointer}::ng-deep .custom-theme-button{border:none;background:none;cursor:pointer}::ng-deep .menu-button{border:none;background:none;cursor:pointer}.language-button{margin:0 auto}::ng-deep button{border:none;background:none;cursor:pointer}\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: MatMenuModule }, { kind: "component", type: i2$3.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i3$3.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$5.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }] });
|
|
4072
|
-
}
|
|
4073
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: Toolbar, decorators: [{
|
|
4074
|
-
type: Component,
|
|
4075
|
-
args: [{ selector: 'ntybase-toolbar', imports: [
|
|
4076
|
-
MatIconModule,
|
|
4077
|
-
MatMenuModule,
|
|
4078
|
-
MatToolbarModule,
|
|
4079
|
-
CommonModule,
|
|
4080
|
-
TitleCasePipe,
|
|
4081
|
-
TranslateModule,
|
|
4082
|
-
], template: "<mat-toolbar class=\"sidenav-header\">\n <div class=\"left-section\">\n <button mat-icon-button (click)=\"onToggleSidenav()\" class=\"menu-button\">\n <mat-icon>menu</mat-icon>\n </button>\n <span>{{'app_name' | translate }}</span>\n\n <!-- Language Selection -->\n <div class=\"language-toggle\">\n @if (icon()) {\n <button mat-icon-button [matMenuTriggerFor]=\"languageMenu\">\n <span class=\"{{ getCurrentLanguageIcon() }}\"></span>\n </button>\n } @else {\n <button\n mat-raised-button\n color=\"primary\"\n [matMenuTriggerFor]=\"languageMenu\"\n >\n {{ currentLanguage }}\n </button>\n }\n </div>\n\n <!-- Language Menu -->\n <mat-menu #languageMenu=\"matMenu\">\n @for (language of languages; track language) {\n <button mat-menu-item (click)=\"setLanguage(language)\">\n <span class=\"{{ getLanguageIcon(language) }}\"></span>\n {{ language }}\n </button>\n }\n </mat-menu>\n </div>\n\n <div class=\"spacer\"></div>\n\n <div class=\"flex-stretch\"></div>\n <button\n mat-icon-button\n [mat-menu-trigger-for]=\"themeMenu\"\n class=\"theme-button\"\n >\n <mat-icon>{{ themeService.selectedTheme()?.icon }}</mat-icon>\n </button>\n <mat-menu #themeMenu=\"matMenu\">\n @for (theme of themeService.getThemes(); track theme.name) {\n <button\n [class.selected-theme]=\"themeService.selectedTheme()?.name === theme.name\"\n mat-menu-item\n (click)=\"themeService.setTheme(theme.name)\"\n >\n <mat-icon>{{ theme.icon }}</mat-icon>\n <span>{{ theme.name | titlecase }}</span>\n </button>\n }\n </mat-menu>\n <button\n mat-icon-button\n [matMenuTriggerFor]=\"customThemeMenu\"\n class=\"custom-theme-button\"\n >\n <mat-icon>format_color_fill</mat-icon>\n </button>\n <mat-menu #customThemeMenu=\"matMenu\">\n @for (customTheme of colorPaletteService.getThemes(); track customTheme.id)\n {\n <button\n mat-menu-item\n (click)=\"colorPaletteService.setTheme(customTheme.id)\"\n >\n <div class=\"theme-menu-item\">\n <div\n class=\"color-preview\"\n [style.background-color]=\"customTheme.primary\"\n ></div>\n <span>{{ customTheme.displayName }}</span>\n </div>\n </button>\n }\n </mat-menu>\n</mat-toolbar>\n", styles: ["mat-toolbar{position:fixed;top:0;left:0;right:0;z-index:3;box-shadow:0 1px 5px #0000001a;display:flex;align-items:center}.sidenav-header{display:flex;justify-content:space-between;align-items:center;padding:16px;margin:0;font-weight:500}.sidenav-header .left-section{display:flex;align-items:center;gap:16px}.sidenav-header .spacer{flex:1 1 auto}.flex-stretch{flex:1 0 auto}.theme-menu-item{display:flex;align-items:center;gap:12px}.color-preview{width:24px;height:24px;border-radius:50%}::ng-deep .theme-button{border:none;background:none;margin-right:15px;cursor:pointer}::ng-deep .custom-theme-button{border:none;background:none;cursor:pointer}::ng-deep .menu-button{border:none;background:none;cursor:pointer}.language-button{margin:0 auto}::ng-deep button{border:none;background:none;cursor:pointer}\n"] }]
|
|
4083
|
-
}], propDecorators: { toggleSidenav: [{ type: i0.Output, args: ["toggleSidenav"] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }, { type: i0.Output, args: ["iconChange"] }] } });
|
|
4084
|
-
|
|
4085
3563
|
class NettyBaseApp {
|
|
4086
3564
|
i18nService = inject(I18nService);
|
|
4087
3565
|
async loadBaseTranslations() {
|
|
@@ -4196,545 +3674,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
4196
3674
|
type: Input
|
|
4197
3675
|
}] } });
|
|
4198
3676
|
|
|
4199
|
-
class
|
|
4200
|
-
value = this.empty;
|
|
4201
|
-
constructor(value) {
|
|
4202
|
-
if (value) {
|
|
4203
|
-
if (Guid.isValid(value)) {
|
|
4204
|
-
this.value = value;
|
|
4205
|
-
}
|
|
4206
|
-
}
|
|
4207
|
-
}
|
|
4208
|
-
static newGuid() {
|
|
4209
|
-
return new Guid('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
4210
|
-
const r = (Math.random() * 16) | 0;
|
|
4211
|
-
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
4212
|
-
return v.toString(16);
|
|
4213
|
-
}));
|
|
4214
|
-
}
|
|
4215
|
-
/**
|
|
4216
|
-
* return all zeros '00000000-0000-0000-0000-000000000000'
|
|
4217
|
-
*/
|
|
4218
|
-
static get empty() {
|
|
4219
|
-
return '00000000-0000-0000-0000-000000000000';
|
|
4220
|
-
}
|
|
4221
|
-
get empty() {
|
|
4222
|
-
return Guid.empty;
|
|
4223
|
-
}
|
|
4224
|
-
static isValid(str) {
|
|
4225
|
-
const validRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4226
|
-
return validRegex.test(str);
|
|
4227
|
-
}
|
|
4228
|
-
toString() {
|
|
4229
|
-
return this.value;
|
|
4230
|
-
}
|
|
4231
|
-
toJSON() {
|
|
4232
|
-
return this.value;
|
|
4233
|
-
}
|
|
4234
|
-
/**
|
|
4235
|
-
* True is guid is empty or not valid
|
|
4236
|
-
* @param str
|
|
4237
|
-
* @returns
|
|
4238
|
-
*/
|
|
4239
|
-
static isNullOrEmpty(str) {
|
|
4240
|
-
if (str == null || str == undefined) {
|
|
4241
|
-
return true;
|
|
4242
|
-
}
|
|
4243
|
-
if (!Guid.isValid(str)) {
|
|
4244
|
-
return true;
|
|
4245
|
-
}
|
|
4246
|
-
if (str == Guid.empty) {
|
|
4247
|
-
return true;
|
|
4248
|
-
}
|
|
4249
|
-
return false;
|
|
4250
|
-
}
|
|
4251
|
-
/**
|
|
4252
|
-
* True if the guid is valid and not all zeros (empty)
|
|
4253
|
-
* @param str
|
|
4254
|
-
* @returns
|
|
4255
|
-
*/
|
|
4256
|
-
static isValidAndNotEmpty(str) {
|
|
4257
|
-
return !Guid.isNullOrEmpty(str);
|
|
4258
|
-
}
|
|
4259
|
-
/**
|
|
4260
|
-
* Return empty guid if the given guid is not valid
|
|
4261
|
-
* @param guid
|
|
4262
|
-
* @returns
|
|
4263
|
-
*/
|
|
4264
|
-
static emptyWhenNull(guid) {
|
|
4265
|
-
if (Guid.isValidAndNotEmpty(guid)) {
|
|
4266
|
-
return guid;
|
|
4267
|
-
}
|
|
4268
|
-
return Guid.empty;
|
|
4269
|
-
}
|
|
4270
|
-
}
|
|
4271
|
-
|
|
4272
|
-
class AutoCompleteProxy {
|
|
3677
|
+
class NettyMenuService {
|
|
4273
3678
|
http = inject(HttpClient);
|
|
4274
3679
|
environmentProxy = inject(EnvironmentProxy);
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
}
|
|
4279
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoCompleteProxy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4280
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoCompleteProxy, providedIn: 'root' });
|
|
4281
|
-
}
|
|
4282
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoCompleteProxy, decorators: [{
|
|
4283
|
-
type: Injectable,
|
|
4284
|
-
args: [{
|
|
4285
|
-
providedIn: 'root',
|
|
4286
|
-
}]
|
|
4287
|
-
}] });
|
|
4288
|
-
|
|
4289
|
-
class NtyAutoCompleteFilter {
|
|
4290
|
-
coid = null;
|
|
4291
|
-
searchString = null;
|
|
4292
|
-
fields = null;
|
|
4293
|
-
}
|
|
4294
|
-
|
|
4295
|
-
/**
|
|
4296
|
-
* This component can load and display any container which is provided dynamically during run time
|
|
4297
|
-
* The only requirement is the component that will be displayed should extend AgGridBaseComponent
|
|
4298
|
-
*/
|
|
4299
|
-
class AutoCompleteLookup {
|
|
4300
|
-
data = inject(MAT_DIALOG_DATA);
|
|
4301
|
-
container;
|
|
4302
|
-
component = input(...(ngDevMode ? [undefined, { debugName: "component" }] : []));
|
|
4303
|
-
filterField = input(null, ...(ngDevMode ? [{ debugName: "filterField" }] : []));
|
|
4304
|
-
filterFieldValue = input(null, ...(ngDevMode ? [{ debugName: "filterFieldValue" }] : []));
|
|
4305
|
-
filterFieldNumeric = input(false, ...(ngDevMode ? [{ debugName: "filterFieldNumeric" }] : []));
|
|
4306
|
-
filterFieldEquality = input('=', ...(ngDevMode ? [{ debugName: "filterFieldEquality" }] : []));
|
|
4307
|
-
// Output
|
|
4308
|
-
selectedElement = output();
|
|
4309
|
-
ngOnInit() {
|
|
4310
|
-
this.initializeComponent();
|
|
4311
|
-
}
|
|
4312
|
-
ngOnChanges(changes) {
|
|
4313
|
-
if (this.isComponentConfigChanged(changes)) {
|
|
4314
|
-
this.initializeComponent();
|
|
4315
|
-
}
|
|
4316
|
-
}
|
|
4317
|
-
isComponentConfigChanged(changes) {
|
|
4318
|
-
return (!!changes['component'] ||
|
|
4319
|
-
!!changes['filterField'] ||
|
|
4320
|
-
!!changes['filterFieldValue'] ||
|
|
4321
|
-
!!changes['filterFieldNumeric'] ||
|
|
4322
|
-
!!changes['filterFieldEquality']);
|
|
4323
|
-
}
|
|
4324
|
-
initializeComponent() {
|
|
4325
|
-
const config = this.data || this.getInputConfig();
|
|
4326
|
-
this.loadComponent(config);
|
|
4327
|
-
}
|
|
4328
|
-
getInputConfig() {
|
|
4329
|
-
return {
|
|
4330
|
-
component: this.component(),
|
|
4331
|
-
filterField: this.filterField(),
|
|
4332
|
-
filterFieldValue: this.filterFieldValue(),
|
|
4333
|
-
filterFieldNumeric: this.filterFieldNumeric(),
|
|
4334
|
-
filterFieldEquality: this.filterFieldEquality(),
|
|
4335
|
-
};
|
|
4336
|
-
}
|
|
4337
|
-
loadComponent(config) {
|
|
4338
|
-
if (!config?.component)
|
|
4339
|
-
return;
|
|
4340
|
-
this.container.clear();
|
|
4341
|
-
const componentRef = this.container.createComponent(config.component);
|
|
4342
|
-
componentRef.setInput('popupValid', true);
|
|
4343
|
-
if (config.filterField !== undefined) {
|
|
4344
|
-
componentRef.setInput('filterField', config.filterField);
|
|
4345
|
-
}
|
|
4346
|
-
if (config.filterFieldValue !== undefined) {
|
|
4347
|
-
componentRef.setInput('filterFieldValue', config.filterFieldValue);
|
|
4348
|
-
}
|
|
4349
|
-
if (config.filterFieldEquality !== undefined) {
|
|
4350
|
-
componentRef.setInput('filterFieldEquality', config.filterFieldEquality);
|
|
4351
|
-
}
|
|
4352
|
-
if (config.filterFieldNumeric !== undefined) {
|
|
4353
|
-
componentRef.setInput('filterFieldNumeric', config.filterFieldNumeric);
|
|
4354
|
-
}
|
|
4355
|
-
const sub = componentRef.instance.selectedElement.subscribe((data) => {
|
|
4356
|
-
this.selectedElement.emit(data);
|
|
4357
|
-
});
|
|
4358
|
-
componentRef.onDestroy(() => sub.unsubscribe());
|
|
4359
|
-
}
|
|
4360
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoCompleteLookup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4361
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: AutoCompleteLookup, isStandalone: true, selector: "ntybase-auto-complete-lookup", inputs: { component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: false, transformFunction: null }, filterField: { classPropertyName: "filterField", publicName: "filterField", isSignal: true, isRequired: false, transformFunction: null }, filterFieldValue: { classPropertyName: "filterFieldValue", publicName: "filterFieldValue", isSignal: true, isRequired: false, transformFunction: null }, filterFieldNumeric: { classPropertyName: "filterFieldNumeric", publicName: "filterFieldNumeric", isSignal: true, isRequired: false, transformFunction: null }, filterFieldEquality: { classPropertyName: "filterFieldEquality", publicName: "filterFieldEquality", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedElement: "selectedElement" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: ` <ng-template #container></ng-template> `, isInline: true });
|
|
4362
|
-
}
|
|
4363
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoCompleteLookup, decorators: [{
|
|
4364
|
-
type: Component,
|
|
4365
|
-
args: [{
|
|
4366
|
-
selector: 'ntybase-auto-complete-lookup',
|
|
4367
|
-
imports: [],
|
|
4368
|
-
template: ` <ng-template #container></ng-template> `,
|
|
4369
|
-
}]
|
|
4370
|
-
}], propDecorators: { container: [{
|
|
4371
|
-
type: ViewChild,
|
|
4372
|
-
args: ['container', { read: ViewContainerRef, static: true }]
|
|
4373
|
-
}], component: [{ type: i0.Input, args: [{ isSignal: true, alias: "component", required: false }] }], filterField: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterField", required: false }] }], filterFieldValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFieldValue", required: false }] }], filterFieldNumeric: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFieldNumeric", required: false }] }], filterFieldEquality: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFieldEquality", required: false }] }], selectedElement: [{ type: i0.Output, args: ["selectedElement"] }] } });
|
|
4374
|
-
|
|
4375
|
-
class AutoCompletePopupMenu {
|
|
4376
|
-
field = '';
|
|
4377
|
-
recordGuid;
|
|
4378
|
-
fieldDisabled = false;
|
|
4379
|
-
componentPath = '';
|
|
4380
|
-
inputValue = '';
|
|
4381
|
-
Result = output();
|
|
4382
|
-
clipboard = inject(Clipboard);
|
|
4383
|
-
alertService = inject(AlertService);
|
|
4384
|
-
ngOnInit() { }
|
|
4385
|
-
gotoNew() {
|
|
4386
|
-
if (!this.componentPath)
|
|
4387
|
-
return;
|
|
4388
|
-
// Split the component path into segments
|
|
4389
|
-
const pathSegments = this.componentPath.split('/').filter((p) => p);
|
|
4390
|
-
this.gotoNewTab(pathSegments, '', 'new');
|
|
4391
|
-
this.Result.emit('New');
|
|
4392
|
-
}
|
|
4393
|
-
gotoMain() {
|
|
4394
|
-
if (!this.componentPath || !this.recordGuid)
|
|
4395
|
-
return;
|
|
4396
|
-
// Split the component path into segments
|
|
4397
|
-
const pathSegments = this.componentPath.split('/').filter((p) => p);
|
|
4398
|
-
this.gotoNewTab(pathSegments, this.recordGuid, 'edit');
|
|
4399
|
-
this.Result.emit('Main');
|
|
4400
|
-
}
|
|
4401
|
-
gotoLookup() {
|
|
4402
|
-
if (!this.fieldDisabled) {
|
|
4403
|
-
this.Result.emit('Lookup');
|
|
4404
|
-
}
|
|
4405
|
-
}
|
|
4406
|
-
gotoNewTab(target, params, type) {
|
|
4407
|
-
if (!target || target.length === 0)
|
|
4408
|
-
return;
|
|
4409
|
-
// Construct the URL directly in the format you want
|
|
4410
|
-
let url = `/${target.join('/')}`;
|
|
4411
|
-
// Add query parameters
|
|
4412
|
-
const queryParams = [];
|
|
4413
|
-
if (params) {
|
|
4414
|
-
queryParams.push(`parameters=${encodeURIComponent(JSON.stringify(params))}`);
|
|
4415
|
-
}
|
|
4416
|
-
if (type) {
|
|
4417
|
-
queryParams.push(`type=${type}`);
|
|
4418
|
-
}
|
|
4419
|
-
queryParams.push('isNewTab=true');
|
|
4420
|
-
if (queryParams.length > 0) {
|
|
4421
|
-
url += `?${queryParams.join('&')}`;
|
|
4422
|
-
}
|
|
4423
|
-
// Open in new tab
|
|
4424
|
-
window.open(url, '_blank');
|
|
4425
|
-
}
|
|
4426
|
-
copyToClipboard() {
|
|
4427
|
-
if (this.inputValue) {
|
|
4428
|
-
this.clipboard.copy(this.inputValue);
|
|
4429
|
-
this.alertService.showAlert('@copiedToClipboard');
|
|
4430
|
-
this.Result.emit('Copy');
|
|
4431
|
-
}
|
|
4432
|
-
}
|
|
4433
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoCompletePopupMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4434
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: AutoCompletePopupMenu, isStandalone: true, selector: "ntybase-auto-complete-popup-menu", inputs: { field: "field", recordGuid: "recordGuid", fieldDisabled: "fieldDisabled", componentPath: "componentPath", inputValue: "inputValue" }, outputs: { Result: "Result" }, ngImport: i0, template: "<div class=\"dialogbase\">\n <div class=\"menu\">\n <ul class=\"list-group\">\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center menu-item\"\n >\n <span (click)=\"copyToClipboard()\" class=\"align-line\"\n ><mat-icon>content_copy</mat-icon>{{'@copy'| translate}}</span\n >\n </li>\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center menu-item\"\n >\n <span (click)=\"gotoMain()\" class=\"align-line\"\n ><mat-icon>edit</mat-icon>{{'@popupGotoRecordDefinition'|\n translate}}</span\n >\n </li>\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center menu-item\"\n >\n <span (click)=\"gotoNew()\" class=\"align-line\"\n ><mat-icon>add</mat-icon>{{'@popupNewRecord'| translate}}</span\n >\n </li>\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center\"\n [ngClass]=\"{'menu-item':!fieldDisabled , 'menu-item-disabled':fieldDisabled }\"\n >\n <span (click)=\"gotoLookup()\" class=\"align-line\"\n ><mat-icon>search</mat-icon>{{'@popupSelectFromList'|translate}}</span\n >\n </li>\n </ul>\n </div>\n</div>\n", styles: [".dialogbase{background:#0000001a;padding:0;border-radius:12px;overflow:hidden;box-shadow:0 4px 20px #00000026}.menu{background:var(--mat-sys-primary-container);padding:0;display:flex;border-radius:inherit}.align-line{display:flex;vertical-align:middle;align-items:center;gap:12px;padding:0 8px}.menu-item{padding:12px 16px;display:flex;vertical-align:middle;cursor:pointer;transition:all .2s ease-out;border-radius:8px;margin:4px;color:var(--mat-sys-on-primary-container)}.menu-item:hover{background:var(--mat-sys-on-primary-fixed);color:var(--mat-sys-on-primary);transform:translateY(-2px);box-shadow:0 2px 8px #0000001a}.menu-item:hover .mat-icon{color:var(--mat-sys-on-primary);transform:scale(1.05)}.menu-item-disabled,.menu-item-disabled:hover{background:var(--mat-sys-on-primary-fixed);color:var(--mat-sys-on-primary);font-style:italic;opacity:.7;cursor:not-allowed}.menu-item-disabled .mat-icon,.menu-item-disabled:hover .mat-icon{color:var(--mat-sys-on-primary)}.mat-icon{transition:all .2s ease-out;font-size:20px;width:20px;height:20px}.list-group{list-style:none;padding:8px;margin:0;width:100%}.list-group-item{background-position:bottom;background-size:100% 1px;background-repeat:no-repeat;padding-bottom:12px;margin-bottom:4px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3$1.TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
|
|
4435
|
-
}
|
|
4436
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoCompletePopupMenu, decorators: [{
|
|
4437
|
-
type: Component,
|
|
4438
|
-
args: [{ selector: 'ntybase-auto-complete-popup-menu', imports: [CommonModule, ReactiveFormsModule, MatIconModule, TranslateModule], encapsulation: ViewEncapsulation.None, template: "<div class=\"dialogbase\">\n <div class=\"menu\">\n <ul class=\"list-group\">\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center menu-item\"\n >\n <span (click)=\"copyToClipboard()\" class=\"align-line\"\n ><mat-icon>content_copy</mat-icon>{{'@copy'| translate}}</span\n >\n </li>\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center menu-item\"\n >\n <span (click)=\"gotoMain()\" class=\"align-line\"\n ><mat-icon>edit</mat-icon>{{'@popupGotoRecordDefinition'|\n translate}}</span\n >\n </li>\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center menu-item\"\n >\n <span (click)=\"gotoNew()\" class=\"align-line\"\n ><mat-icon>add</mat-icon>{{'@popupNewRecord'| translate}}</span\n >\n </li>\n <li\n class=\"list-group-item list-group-item-action d-flex justify-content-between align-items-center\"\n [ngClass]=\"{'menu-item':!fieldDisabled , 'menu-item-disabled':fieldDisabled }\"\n >\n <span (click)=\"gotoLookup()\" class=\"align-line\"\n ><mat-icon>search</mat-icon>{{'@popupSelectFromList'|translate}}</span\n >\n </li>\n </ul>\n </div>\n</div>\n", styles: [".dialogbase{background:#0000001a;padding:0;border-radius:12px;overflow:hidden;box-shadow:0 4px 20px #00000026}.menu{background:var(--mat-sys-primary-container);padding:0;display:flex;border-radius:inherit}.align-line{display:flex;vertical-align:middle;align-items:center;gap:12px;padding:0 8px}.menu-item{padding:12px 16px;display:flex;vertical-align:middle;cursor:pointer;transition:all .2s ease-out;border-radius:8px;margin:4px;color:var(--mat-sys-on-primary-container)}.menu-item:hover{background:var(--mat-sys-on-primary-fixed);color:var(--mat-sys-on-primary);transform:translateY(-2px);box-shadow:0 2px 8px #0000001a}.menu-item:hover .mat-icon{color:var(--mat-sys-on-primary);transform:scale(1.05)}.menu-item-disabled,.menu-item-disabled:hover{background:var(--mat-sys-on-primary-fixed);color:var(--mat-sys-on-primary);font-style:italic;opacity:.7;cursor:not-allowed}.menu-item-disabled .mat-icon,.menu-item-disabled:hover .mat-icon{color:var(--mat-sys-on-primary)}.mat-icon{transition:all .2s ease-out;font-size:20px;width:20px;height:20px}.list-group{list-style:none;padding:8px;margin:0;width:100%}.list-group-item{background-position:bottom;background-size:100% 1px;background-repeat:no-repeat;padding-bottom:12px;margin-bottom:4px}\n"] }]
|
|
4439
|
-
}], propDecorators: { field: [{
|
|
4440
|
-
type: Input
|
|
4441
|
-
}], recordGuid: [{
|
|
4442
|
-
type: Input
|
|
4443
|
-
}], fieldDisabled: [{
|
|
4444
|
-
type: Input
|
|
4445
|
-
}], componentPath: [{
|
|
4446
|
-
type: Input
|
|
4447
|
-
}], inputValue: [{
|
|
4448
|
-
type: Input
|
|
4449
|
-
}], Result: [{ type: i0.Output, args: ["Result"] }] } });
|
|
4450
|
-
|
|
4451
|
-
class SelectionItem {
|
|
4452
|
-
name = null;
|
|
4453
|
-
value = null;
|
|
4454
|
-
constructor(_value = null, _name = null) {
|
|
4455
|
-
this.name = _name;
|
|
4456
|
-
this.value = _value;
|
|
4457
|
-
}
|
|
4458
|
-
}
|
|
4459
|
-
class AutoComplete extends UiBase {
|
|
4460
|
-
// Input parameters
|
|
4461
|
-
tableName = input('', ...(ngDevMode ? [{ debugName: "tableName" }] : []));
|
|
4462
|
-
searchAfter = input(3, ...(ngDevMode ? [{ debugName: "searchAfter" }] : []));
|
|
4463
|
-
fieldCode = input(null, ...(ngDevMode ? [{ debugName: "fieldCode" }] : []));
|
|
4464
|
-
fieldName = input(null, ...(ngDevMode ? [{ debugName: "fieldName" }] : []));
|
|
4465
|
-
lookupComponent = input(null, ...(ngDevMode ? [{ debugName: "lookupComponent" }] : []));
|
|
4466
|
-
lookupComponentPath = input(null, ...(ngDevMode ? [{ debugName: "lookupComponentPath" }] : []));
|
|
4467
|
-
filterField = input(null, ...(ngDevMode ? [{ debugName: "filterField" }] : []));
|
|
4468
|
-
filterFieldValue = input(null, ...(ngDevMode ? [{ debugName: "filterFieldValue" }] : []));
|
|
4469
|
-
filterFieldNumeric = input(false, ...(ngDevMode ? [{ debugName: "filterFieldNumeric" }] : []));
|
|
4470
|
-
filterFieldEquality = input('=', ...(ngDevMode ? [{ debugName: "filterFieldEquality" }] : []));
|
|
4471
|
-
debounceTime = input(500, ...(ngDevMode ? [{ debugName: "debounceTime" }] : []));
|
|
4472
|
-
// Inject dependencies
|
|
4473
|
-
alertService = inject(AlertService);
|
|
4474
|
-
autoCompleteService = inject(AutoCompleteProxy);
|
|
4475
|
-
dialog = inject(MatDialog);
|
|
4476
|
-
autoCompleteTrigger;
|
|
4477
|
-
inputField;
|
|
4478
|
-
control = new FormControl();
|
|
4479
|
-
matcher = new ErrorStateMatcher();
|
|
4480
|
-
// Signal parameters
|
|
4481
|
-
searchText = signal('', ...(ngDevMode ? [{ debugName: "searchText" }] : []));
|
|
4482
|
-
selectedOption = signal(null, ...(ngDevMode ? [{ debugName: "selectedOption" }] : []));
|
|
4483
|
-
loadedOptions = signal([], ...(ngDevMode ? [{ debugName: "loadedOptions" }] : []));
|
|
4484
|
-
searchSignal = signal('', ...(ngDevMode ? [{ debugName: "searchSignal" }] : []));
|
|
4485
|
-
debounceTimeout;
|
|
3680
|
+
i18nService = inject(I18nService);
|
|
3681
|
+
menuName = signal('', ...(ngDevMode ? [{ debugName: "menuName" }] : []));
|
|
3682
|
+
menu = signal(null, ...(ngDevMode ? [{ debugName: "menu" }] : []));
|
|
4486
3683
|
constructor() {
|
|
4487
|
-
super();
|
|
4488
|
-
// Sync form control with selected option
|
|
4489
3684
|
effect(() => {
|
|
4490
|
-
const
|
|
4491
|
-
|
|
4492
|
-
|
|
3685
|
+
const currentMenuName = this.menuName();
|
|
3686
|
+
const currentLang = this.i18nService.currentLang();
|
|
3687
|
+
if (!currentMenuName.trim()) {
|
|
3688
|
+
return;
|
|
4493
3689
|
}
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
this.selectedOption.set(found);
|
|
4498
|
-
this.searchText.set(found.name || '');
|
|
4499
|
-
}
|
|
3690
|
+
let functionUrl = this.environmentProxy.getAdminLink('/GetMenu');
|
|
3691
|
+
if (currentMenuName.trim().length > 0) {
|
|
3692
|
+
functionUrl += '/' + currentMenuName.trim();
|
|
4500
3693
|
}
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
if (this.shouldTriggerSearch(searchValue)) {
|
|
4508
|
-
this.loadAutoCompleteData(searchValue);
|
|
4509
|
-
}
|
|
4510
|
-
else {
|
|
4511
|
-
this.loadedOptions.set([]);
|
|
4512
|
-
}
|
|
4513
|
-
}, this.debounceTime());
|
|
4514
|
-
onCleanup(() => {
|
|
4515
|
-
clearTimeout(this.debounceTimeout);
|
|
3694
|
+
this.http.get(functionUrl).subscribe({
|
|
3695
|
+
next: (data) => this.menu.set(data),
|
|
3696
|
+
error: (err) => {
|
|
3697
|
+
console.error('Failed to fetch menu:', err);
|
|
3698
|
+
this.menu.set(null);
|
|
3699
|
+
},
|
|
4516
3700
|
});
|
|
4517
3701
|
});
|
|
4518
|
-
effect(() => {
|
|
4519
|
-
this.onChange(this.value());
|
|
4520
|
-
});
|
|
4521
|
-
effect(() => {
|
|
4522
|
-
this.updateValidators();
|
|
4523
|
-
});
|
|
4524
|
-
}
|
|
4525
|
-
shouldTriggerSearch(searchValue) {
|
|
4526
|
-
return searchValue.length >= this.searchAfter();
|
|
4527
|
-
}
|
|
4528
|
-
filteredData = computed(() => {
|
|
4529
|
-
return this.loadedOptions();
|
|
4530
|
-
}, ...(ngDevMode ? [{ debugName: "filteredData" }] : []));
|
|
4531
|
-
onInputChanged(event) {
|
|
4532
|
-
const value = event.target.value;
|
|
4533
|
-
this.searchText.set(value);
|
|
4534
|
-
this.onTouched();
|
|
4535
|
-
// Clear selection if text doesn't match
|
|
4536
|
-
if (this.selectedOption() && this.selectedOption()?.name !== value) {
|
|
4537
|
-
this.selectedOption.set(null);
|
|
4538
|
-
}
|
|
4539
|
-
if (value.length === 0) {
|
|
4540
|
-
this.clearInput();
|
|
4541
|
-
return;
|
|
4542
|
-
}
|
|
4543
|
-
this.searchSignal.set(value);
|
|
4544
|
-
this.autoCompleteTrigger.closePanel();
|
|
4545
|
-
}
|
|
4546
|
-
loadAutoCompleteData(searchValue) {
|
|
4547
|
-
this.loadedOptions.set([]);
|
|
4548
|
-
const filter = new NtyAutoCompleteFilter();
|
|
4549
|
-
filter.searchString =
|
|
4550
|
-
searchValue.trim() === '' && searchValue.length >= this.searchAfter()
|
|
4551
|
-
? ''
|
|
4552
|
-
: searchValue;
|
|
4553
|
-
filter.fields = [];
|
|
4554
|
-
if (this.filterField() && this.filterField().trim().length > 0) {
|
|
4555
|
-
const fields = {
|
|
4556
|
-
equalitySign: this.filterFieldEquality(),
|
|
4557
|
-
fieldName: this.filterField(),
|
|
4558
|
-
fieldValue: this.filterFieldValue(),
|
|
4559
|
-
numeric: this.filterFieldNumeric(),
|
|
4560
|
-
};
|
|
4561
|
-
filter.fields?.push(fields);
|
|
4562
|
-
}
|
|
4563
|
-
this.autoCompleteService
|
|
4564
|
-
.getAutocompleteDataFilter(this.tableName(), filter)
|
|
4565
|
-
.subscribe({
|
|
4566
|
-
next: (data) => {
|
|
4567
|
-
if (data && Array.isArray(data)) {
|
|
4568
|
-
const options = data.map((item) => ({
|
|
4569
|
-
name: item.text,
|
|
4570
|
-
value: item.guidValue,
|
|
4571
|
-
}));
|
|
4572
|
-
this.loadedOptions.set(options);
|
|
4573
|
-
if (options.length === 1) {
|
|
4574
|
-
this.selectedOption.set(options[0]);
|
|
4575
|
-
this.control.setValue(options[0].value);
|
|
4576
|
-
this.searchText.set(options[0].name || '');
|
|
4577
|
-
}
|
|
4578
|
-
else if (options.length > 1) {
|
|
4579
|
-
this.autoCompleteTrigger.openPanel();
|
|
4580
|
-
}
|
|
4581
|
-
}
|
|
4582
|
-
},
|
|
4583
|
-
error: (err) => {
|
|
4584
|
-
this.alertService.showAlert(err.message);
|
|
4585
|
-
},
|
|
4586
|
-
});
|
|
4587
|
-
}
|
|
4588
|
-
clearInput() {
|
|
4589
|
-
this.selectedOption.set(new SelectionItem(Guid.empty, ''));
|
|
4590
|
-
this.control.reset();
|
|
4591
|
-
this.searchText.set('');
|
|
4592
|
-
this.loadedOptions.set([]);
|
|
4593
|
-
this.inputField.nativeElement.value = '';
|
|
4594
|
-
}
|
|
4595
|
-
onPaste(event) {
|
|
4596
|
-
const clipboardData = event.clipboardData;
|
|
4597
|
-
if (!clipboardData)
|
|
4598
|
-
return;
|
|
4599
|
-
const pastedText = clipboardData.getData('text');
|
|
4600
|
-
this.searchText.set(pastedText);
|
|
4601
|
-
this.searchSignal.set(pastedText);
|
|
4602
|
-
}
|
|
4603
|
-
displayFn(item) {
|
|
4604
|
-
return this.searchText();
|
|
4605
|
-
}
|
|
4606
|
-
optionSelected(event) {
|
|
4607
|
-
const selectedValue = event.option.value;
|
|
4608
|
-
const selected = this.loadedOptions().find((opt) => opt.value === selectedValue);
|
|
4609
|
-
if (selected) {
|
|
4610
|
-
this.selectedOption.set(selected);
|
|
4611
|
-
this.control.setValue(selected.value);
|
|
4612
|
-
this.searchText.set(selected.name || '');
|
|
4613
|
-
}
|
|
4614
|
-
}
|
|
4615
|
-
writeValue(value) {
|
|
4616
|
-
this.value.set(value);
|
|
4617
|
-
if (!value)
|
|
4618
|
-
return;
|
|
4619
|
-
if (this.fieldCode()) {
|
|
4620
|
-
this.selectedOption.set({ value, name: this.fieldCode() });
|
|
4621
|
-
}
|
|
4622
|
-
}
|
|
4623
|
-
onLookup() {
|
|
4624
|
-
if (!this.lookupComponent())
|
|
4625
|
-
return;
|
|
4626
|
-
const dialogRef = this.dialog.open(AutoCompleteLookup, {
|
|
4627
|
-
height: 'auto',
|
|
4628
|
-
width: '100%',
|
|
4629
|
-
maxWidth: '100%',
|
|
4630
|
-
maxHeight: 'auto',
|
|
4631
|
-
data: {
|
|
4632
|
-
component: this.lookupComponent(),
|
|
4633
|
-
...(this.filterField() && {
|
|
4634
|
-
filterField: this.filterField(),
|
|
4635
|
-
filterFieldValue: this.filterFieldValue(),
|
|
4636
|
-
filterFieldEquality: this.filterFieldEquality(),
|
|
4637
|
-
filterFieldNumeric: this.filterFieldNumeric(),
|
|
4638
|
-
}),
|
|
4639
|
-
},
|
|
4640
|
-
});
|
|
4641
|
-
dialogRef.componentInstance.selectedElement.subscribe((data) => {
|
|
4642
|
-
if (data) {
|
|
4643
|
-
const selection = new SelectionItem(data.value, data.text);
|
|
4644
|
-
this.selectedOption.set(selection);
|
|
4645
|
-
this.control.setValue(selection.value);
|
|
4646
|
-
this.searchText.set(selection.name || '');
|
|
4647
|
-
}
|
|
4648
|
-
dialogRef.close();
|
|
4649
|
-
});
|
|
4650
3702
|
}
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
* @returns
|
|
4655
|
-
*/
|
|
4656
|
-
rightClick(event) {
|
|
4657
|
-
event.stopPropagation();
|
|
4658
|
-
const dialogConfig = new MatDialogConfig();
|
|
4659
|
-
dialogConfig.position = {
|
|
4660
|
-
top: event.clientY + 'px',
|
|
4661
|
-
left: event.clientX + 'px',
|
|
4662
|
-
};
|
|
4663
|
-
dialogConfig.height = 'auto';
|
|
4664
|
-
dialogConfig.width = 'auto';
|
|
4665
|
-
dialogConfig.panelClass = 'foo';
|
|
4666
|
-
const dialogRef = this.dialog.open(AutoCompletePopupMenu, dialogConfig);
|
|
4667
|
-
dialogRef.componentInstance.field = this.tableName();
|
|
4668
|
-
dialogRef.componentInstance.recordGuid = this.value();
|
|
4669
|
-
dialogRef.componentInstance.fieldDisabled = this.disabled();
|
|
4670
|
-
dialogRef.componentInstance.componentPath = this.lookupComponentPath();
|
|
4671
|
-
dialogRef.componentInstance.inputValue = this.searchText();
|
|
4672
|
-
dialogRef.componentInstance.Result.subscribe((result) => {
|
|
4673
|
-
switch (result) {
|
|
4674
|
-
case 'Lookup':
|
|
4675
|
-
dialogRef.close();
|
|
4676
|
-
this.onLookup();
|
|
4677
|
-
break;
|
|
4678
|
-
default:
|
|
4679
|
-
dialogRef.close();
|
|
4680
|
-
break;
|
|
4681
|
-
}
|
|
4682
|
-
});
|
|
4683
|
-
return false;
|
|
4684
|
-
}
|
|
4685
|
-
// Validation
|
|
4686
|
-
getErrorMessage() {
|
|
4687
|
-
if (this.control.hasError('required') && this.errorMessages()['required']) {
|
|
4688
|
-
return this.errorMessages()['required'];
|
|
4689
|
-
}
|
|
4690
|
-
return '';
|
|
4691
|
-
}
|
|
4692
|
-
updateValidators() {
|
|
4693
|
-
const validators = [];
|
|
4694
|
-
if (this.required()) {
|
|
4695
|
-
validators.push(Validators.required);
|
|
3703
|
+
setMenuName(name) {
|
|
3704
|
+
if (name && name.trim()) {
|
|
3705
|
+
this.menuName.set(name.trim());
|
|
4696
3706
|
}
|
|
4697
|
-
this.control.setValidators(validators);
|
|
4698
|
-
this.control.updateValueAndValidity();
|
|
4699
3707
|
}
|
|
4700
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type:
|
|
4701
|
-
static
|
|
4702
|
-
{
|
|
4703
|
-
provide: NG_VALUE_ACCESSOR,
|
|
4704
|
-
useExisting: forwardRef(() => AutoComplete),
|
|
4705
|
-
multi: true,
|
|
4706
|
-
}
|
|
4707
|
-
], viewQueries: [{ propertyName: "autoCompleteTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }, { propertyName: "inputField", first: true, predicate: ["autoCompleteInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field\n class=\"ui-full-width\"\n [appearance]=\"appearance()\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && value()\"\n>\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n type=\"text\"\n #autoCompleteInput\n matInput\n [(ngModel)]=\"value\"\n [matAutocomplete]=\"auto\"\n (input)=\"onInputChanged($event)\"\n (paste)=\"onPaste($event)\"\n [errorStateMatcher]=\"matcher\"\n [formControl]=\"control\"\n (contextmenu)=\"rightClick($event)\"\n />\n\n @if (value() && !disabled()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn number-clear-btn\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n }\n\n <button\n mat-icon-button\n matSuffix\n aria-label=\"Search\"\n (click)=\"onLookup()\"\n class=\"search-btn\"\n >\n <mat-icon>search</mat-icon>\n </button>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [displayWith]=\"displayFn.bind(this)\"\n (optionSelected)=\"optionSelected($event)\"\n >\n @for (option of filteredData(); track option.value) {\n <mat-option [value]=\"option.value\"> {{ option.name }} </mat-option>\n }\n </mat-autocomplete>\n\n <mat-error>{{ getErrorMessage() }}</mat-error>\n</mat-form-field>\n", styles: ["::ng-deep .ui-full-width{width:100%;max-width:500px}::ng-deep .mat-mdc-form-field-subscript-wrapper{width:auto;height:0}::ng-deep .clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}::ng-deep .search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}::ng-deep .search-icon:hover,::ng-deep .clear-btn:hover{color:#f97a00}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1$4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i2$4.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i2$4.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1$4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatDialogModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4708
|
-
}
|
|
4709
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AutoComplete, decorators: [{
|
|
4710
|
-
type: Component,
|
|
4711
|
-
args: [{ selector: 'ntybase-auto-complete', imports: [
|
|
4712
|
-
MatFormFieldModule,
|
|
4713
|
-
MatAutocompleteModule,
|
|
4714
|
-
FormsModule,
|
|
4715
|
-
MatInputModule,
|
|
4716
|
-
MatIconModule,
|
|
4717
|
-
ReactiveFormsModule,
|
|
4718
|
-
MatDialogModule
|
|
4719
|
-
], providers: [
|
|
4720
|
-
{
|
|
4721
|
-
provide: NG_VALUE_ACCESSOR,
|
|
4722
|
-
useExisting: forwardRef(() => AutoComplete),
|
|
4723
|
-
multi: true,
|
|
4724
|
-
}
|
|
4725
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-form-field\n class=\"ui-full-width\"\n [appearance]=\"appearance()\"\n [class.required-field]=\"required()\"\n [class.required-with-value]=\"required() && value()\"\n>\n @if (label()) {\n <mat-label>{{ label() }}</mat-label>\n }\n\n <input\n type=\"text\"\n #autoCompleteInput\n matInput\n [(ngModel)]=\"value\"\n [matAutocomplete]=\"auto\"\n (input)=\"onInputChanged($event)\"\n (paste)=\"onPaste($event)\"\n [errorStateMatcher]=\"matcher\"\n [formControl]=\"control\"\n (contextmenu)=\"rightClick($event)\"\n />\n\n @if (value() && !disabled()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"clearInput()\"\n aria-label=\"Clear\"\n class=\"clear-btn number-clear-btn\"\n >\n <mat-icon>cancel</mat-icon>\n </button>\n }\n\n <button\n mat-icon-button\n matSuffix\n aria-label=\"Search\"\n (click)=\"onLookup()\"\n class=\"search-btn\"\n >\n <mat-icon>search</mat-icon>\n </button>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [displayWith]=\"displayFn.bind(this)\"\n (optionSelected)=\"optionSelected($event)\"\n >\n @for (option of filteredData(); track option.value) {\n <mat-option [value]=\"option.value\"> {{ option.name }} </mat-option>\n }\n </mat-autocomplete>\n\n <mat-error>{{ getErrorMessage() }}</mat-error>\n</mat-form-field>\n", styles: ["::ng-deep .ui-full-width{width:100%;max-width:500px}::ng-deep .mat-mdc-form-field-subscript-wrapper{width:auto;height:0}::ng-deep .clear-btn{background:none;border:none;box-shadow:none;cursor:pointer}::ng-deep .search-icon{background:none;border:none;box-shadow:none;opacity:1;cursor:pointer}::ng-deep .search-icon:hover,::ng-deep .clear-btn:hover{color:#f97a00}\n"] }]
|
|
4726
|
-
}], ctorParameters: () => [], propDecorators: { tableName: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableName", required: false }] }], searchAfter: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchAfter", required: false }] }], fieldCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldCode", required: false }] }], fieldName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldName", required: false }] }], lookupComponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookupComponent", required: false }] }], lookupComponentPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "lookupComponentPath", required: false }] }], filterField: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterField", required: false }] }], filterFieldValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFieldValue", required: false }] }], filterFieldNumeric: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFieldNumeric", required: false }] }], filterFieldEquality: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFieldEquality", required: false }] }], debounceTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceTime", required: false }] }], autoCompleteTrigger: [{
|
|
4727
|
-
type: ViewChild,
|
|
4728
|
-
args: [MatAutocompleteTrigger]
|
|
4729
|
-
}], inputField: [{
|
|
4730
|
-
type: ViewChild,
|
|
4731
|
-
args: ['autoCompleteInput']
|
|
4732
|
-
}] } });
|
|
4733
|
-
|
|
4734
|
-
class NettyFilter {
|
|
4735
|
-
value;
|
|
4736
|
-
text;
|
|
3708
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: NettyMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3709
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: NettyMenuService, providedIn: 'root' });
|
|
4737
3710
|
}
|
|
3711
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: NettyMenuService, decorators: [{
|
|
3712
|
+
type: Injectable,
|
|
3713
|
+
args: [{
|
|
3714
|
+
providedIn: 'root',
|
|
3715
|
+
}]
|
|
3716
|
+
}], ctorParameters: () => [] });
|
|
4738
3717
|
|
|
4739
3718
|
/*
|
|
4740
3719
|
* Public API Surface of ntybase
|
|
@@ -4744,5 +3723,5 @@ class NettyFilter {
|
|
|
4744
3723
|
* Generated bundle index. Do not edit.
|
|
4745
3724
|
*/
|
|
4746
3725
|
|
|
4747
|
-
export { AlertService, AuthenticationGuard, AuthenticationInterceptor, AuthenticationService,
|
|
3726
|
+
export { AlertService, AuthenticationGuard, AuthenticationInterceptor, AuthenticationService, ButtonRenderer, CanDeactivateGuard, CheckboxRenderer, CommonService, ConfirmDialog, CredentialsService, CurrentUserPreference, ENVIRONMENT_CONFIG, EnvironmentInfo, EnvironmentInfoService, ExcelImportBase, ForgotPassword, Login, LoginDto, MFACodeDto, MfaLogin, NettyAgGridBase, NettyAgGridSaveBase, NettyAgGridService, NettyBaseApp, NettyHelper, NettyImageService, NettyMenuService, Ntybase, NtybaseModule, RangeDateTimeFilter, RangeNumberFilter, RangeStringFilter, UrlHelperService };
|
|
4748
3727
|
//# sourceMappingURL=nettyapps-ntybase.mjs.map
|