@flusys/ng-shared 5.1.3 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, PLATFORM_ID, Injectable, DOCUMENT, REQUEST, signal, computed, ElementRef, input, effect, Directive, TemplateRef, ViewContainerRef, output, Pipe, Injector, isDevMode, NgModule, resource, model, runInInjectionContext, untracked, forwardRef,
|
|
3
|
-
import { isPlatformServer, isPlatformBrowser, CommonModule, NgOptimizedImage, NgComponentOutlet, DatePipe
|
|
2
|
+
import { inject, PLATFORM_ID, Injectable, DOCUMENT, REQUEST, signal, computed, ElementRef, input, effect, Directive, TemplateRef, ViewContainerRef, output, Pipe, Injector, isDevMode, NgModule, resource, model, runInInjectionContext, untracked, forwardRef, ViewEncapsulation, Component, InjectionToken, DestroyRef, ApplicationRef, viewChild, afterNextRender } from '@angular/core';
|
|
3
|
+
import { isPlatformServer, DOCUMENT as DOCUMENT$1, isPlatformBrowser, CommonModule, NgOptimizedImage, NgComponentOutlet, DatePipe } from '@angular/common';
|
|
4
4
|
import { HttpClient, HttpContextToken, HttpHeaders, HttpParams } from '@angular/common/http';
|
|
5
5
|
import { APP_CONFIG, getServiceUrl, LOCALIZATION_STATE_SERVICE, FALLBACK_MESSAGES_REGISTRY, LOCALIZATION_API_SERVICE } from '@flusys/ng-core';
|
|
6
|
-
import { of, catchError as catchError$1, throwError, firstValueFrom, map as map$1
|
|
6
|
+
import { of, catchError as catchError$1, throwError, firstValueFrom, map as map$1 } from 'rxjs';
|
|
7
7
|
import { map, tap, catchError } from 'rxjs/operators';
|
|
8
8
|
import * as i1$1 from '@angular/forms';
|
|
9
9
|
import { NgControl, FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
10
10
|
import * as i3 from 'primeng/api';
|
|
11
|
-
import { MessageService
|
|
12
|
-
import { RouterOutlet, RouterLink, RouterLinkActive, Router
|
|
11
|
+
import { MessageService } from 'primeng/api';
|
|
12
|
+
import { RouterOutlet, RouterLink, RouterLinkActive, Router } from '@angular/router';
|
|
13
13
|
import { AutoCompleteModule } from 'primeng/autocomplete';
|
|
14
14
|
import { AvatarModule } from 'primeng/avatar';
|
|
15
15
|
import * as i1 from 'primeng/button';
|
|
@@ -58,7 +58,7 @@ import { TooltipModule } from 'primeng/tooltip';
|
|
|
58
58
|
import { TreeTableModule } from 'primeng/treetable';
|
|
59
59
|
import { ProgressSpinnerModule } from 'primeng/progressspinner';
|
|
60
60
|
import { ColorPickerModule } from 'primeng/colorpicker';
|
|
61
|
-
import {
|
|
61
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
62
62
|
|
|
63
63
|
const SHARED_MESSAGES = {
|
|
64
64
|
// Backend shared auth key (used by exception filters)
|
|
@@ -97,15 +97,19 @@ const SHARED_MESSAGES = {
|
|
|
97
97
|
'system.sdk.not.installed': 'Required SDK "{{sdk}}" not installed. Run: npm install {{sdk}}',
|
|
98
98
|
'system.path.traversal.detected': 'Path traversal detected',
|
|
99
99
|
'system.invalid.file.key': 'Invalid file key',
|
|
100
|
-
//
|
|
100
|
+
// shared feedback & confirmation keys (used across all list/form components)
|
|
101
101
|
'shared.success': 'Success',
|
|
102
102
|
'shared.error': 'Error',
|
|
103
103
|
'shared.info': 'Info',
|
|
104
104
|
'shared.warning': 'Warning',
|
|
105
105
|
'shared.confirm.delete.header': 'Confirm Delete',
|
|
106
|
-
// utils/base-form-page.ts
|
|
107
106
|
'shared.validation.error': 'Validation Error',
|
|
108
107
|
'shared.fill.required.fields': 'Please fill in all required fields',
|
|
108
|
+
// components/base-list/base-list.component.ts
|
|
109
|
+
'shared.no.data': 'No data found',
|
|
110
|
+
'shared.pagination.report': 'Showing {first} to {last} of {totalRecords} records',
|
|
111
|
+
// components/base-form/base-form.component.ts
|
|
112
|
+
'shared.required': 'is required',
|
|
109
113
|
// components/file-selector-dialog/file-selector-dialog.component.ts
|
|
110
114
|
'shared.file.selector.provider.not.configured': 'File selection not configured.',
|
|
111
115
|
'shared.file.selector.add.provider': 'Add',
|
|
@@ -755,6 +759,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
|
|
|
755
759
|
args: [{ providedIn: 'root' }]
|
|
756
760
|
}] });
|
|
757
761
|
|
|
762
|
+
class FaviconService {
|
|
763
|
+
http = inject(HttpClient);
|
|
764
|
+
platformService = inject(PlatformService);
|
|
765
|
+
document = inject(DOCUMENT$1);
|
|
766
|
+
svgTemplate = null;
|
|
767
|
+
apply() {
|
|
768
|
+
if (this.platformService.isServer)
|
|
769
|
+
return;
|
|
770
|
+
if (this.svgTemplate) {
|
|
771
|
+
this.render(this.svgTemplate);
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
this.http
|
|
775
|
+
.get('/favicon.svg', { responseType: 'text' })
|
|
776
|
+
.subscribe((text) => {
|
|
777
|
+
this.svgTemplate = text;
|
|
778
|
+
this.render(text);
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
render(svgText) {
|
|
782
|
+
const style = getComputedStyle(this.document.documentElement);
|
|
783
|
+
const resolved = svgText.replace(/var\(\s*(--[^,)]+?)\s*(?:,\s*([^)]+?))?\s*\)/g, (_, varName, fallback = '') => {
|
|
784
|
+
const value = style.getPropertyValue(varName).trim();
|
|
785
|
+
return value || fallback;
|
|
786
|
+
});
|
|
787
|
+
const link = this.document.querySelector('link[rel="icon"]');
|
|
788
|
+
if (link) {
|
|
789
|
+
link.href = `data:image/svg+xml,${encodeURIComponent(resolved)}`;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FaviconService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
793
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FaviconService, providedIn: 'root' });
|
|
794
|
+
}
|
|
795
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: FaviconService, decorators: [{
|
|
796
|
+
type: Injectable,
|
|
797
|
+
args: [{ providedIn: 'root' }]
|
|
798
|
+
}] });
|
|
799
|
+
|
|
758
800
|
class EditModeElementChangerDirective {
|
|
759
801
|
el = inject(ElementRef);
|
|
760
802
|
ngControl = inject(NgControl, { optional: true });
|
|
@@ -1681,6 +1723,28 @@ function provideValueAccessor(component) {
|
|
|
1681
1723
|
};
|
|
1682
1724
|
}
|
|
1683
1725
|
|
|
1726
|
+
class InlineSvgComponent {
|
|
1727
|
+
src = input.required(...(ngDevMode ? [{ debugName: "src" }] : []));
|
|
1728
|
+
http = inject(HttpClient);
|
|
1729
|
+
sanitizer = inject(DomSanitizer);
|
|
1730
|
+
svg = resource({ ...(ngDevMode ? { debugName: "svg" } : {}), params: this.src,
|
|
1731
|
+
loader: ({ params: url }) => firstValueFrom(this.http.get(url, { responseType: 'text' })).then((text) => this.sanitizer.bypassSecurityTrustHtml(text)) });
|
|
1732
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: InlineSvgComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1733
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: InlineSvgComponent, isStandalone: true, selector: "inline-svg", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
1734
|
+
@if (svg.hasValue()) {
|
|
1735
|
+
<span [innerHTML]="svg.value()"></span>
|
|
1736
|
+
}
|
|
1737
|
+
`, isInline: true, styles: ["inline-svg{display:inline-flex;align-items:center}inline-svg span{display:inline-flex;align-items:center;height:100%;width:100%}inline-svg svg{height:100%;width:auto}\n"], encapsulation: i0.ViewEncapsulation.None });
|
|
1738
|
+
}
|
|
1739
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: InlineSvgComponent, decorators: [{
|
|
1740
|
+
type: Component,
|
|
1741
|
+
args: [{ selector: 'inline-svg', encapsulation: ViewEncapsulation.None, template: `
|
|
1742
|
+
@if (svg.hasValue()) {
|
|
1743
|
+
<span [innerHTML]="svg.value()"></span>
|
|
1744
|
+
}
|
|
1745
|
+
`, styles: ["inline-svg{display:inline-flex;align-items:center}inline-svg span{display:inline-flex;align-items:center;height:100%;width:100%}inline-svg svg{height:100%;width:auto}\n"] }]
|
|
1746
|
+
}], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: true }] }] } });
|
|
1747
|
+
|
|
1684
1748
|
/**
|
|
1685
1749
|
* Injection Tokens for Provider Interfaces
|
|
1686
1750
|
*
|
|
@@ -3883,390 +3947,6 @@ function allPermissionsGuard(permissions, redirectTo = '/') {
|
|
|
3883
3947
|
return createGuard('allPermissionsGuard', redirectTo, (perms) => hasAllPermissions(permissions, perms), () => `Access denied - missing all of: ${permissions.join(', ')}`);
|
|
3884
3948
|
}
|
|
3885
3949
|
|
|
3886
|
-
/**
|
|
3887
|
-
* Base class for form page components that handle create/edit operations.
|
|
3888
|
-
* Provides common functionality for loading existing items, form submission,
|
|
3889
|
-
* navigation, and toast notifications.
|
|
3890
|
-
*
|
|
3891
|
-
* ## Features
|
|
3892
|
-
* - Automatic route parameter handling (loads item when ID is present)
|
|
3893
|
-
* - Edit mode detection based on existing item
|
|
3894
|
-
* - Unified submit handler for create/update operations
|
|
3895
|
-
* - Cancel navigation
|
|
3896
|
-
* - Toast messages for success/validation errors
|
|
3897
|
-
*
|
|
3898
|
-
* ## Usage
|
|
3899
|
-
*
|
|
3900
|
-
* ```typescript
|
|
3901
|
-
* interface IProductFormModel {
|
|
3902
|
-
* name: string;
|
|
3903
|
-
* price: number;
|
|
3904
|
-
* }
|
|
3905
|
-
*
|
|
3906
|
-
* @Component({
|
|
3907
|
-
* selector: 'app-product-form',
|
|
3908
|
-
* standalone: true,
|
|
3909
|
-
* * template: `...`
|
|
3910
|
-
* })
|
|
3911
|
-
* export class ProductFormComponent extends BaseFormPage<IProduct, IProductFormModel> {
|
|
3912
|
-
* private readonly productService = inject(ProductApiService);
|
|
3913
|
-
*
|
|
3914
|
-
* // Form model signal (private writable, public readonly)
|
|
3915
|
-
* private readonly _formModel = signal<IProductFormModel>({ name: '', price: 0 });
|
|
3916
|
-
* readonly formModel = this._formModel.asReadonly();
|
|
3917
|
-
*
|
|
3918
|
-
* // Required abstract implementations
|
|
3919
|
-
* getFormModel(): Signal<IProductFormModel> {
|
|
3920
|
-
* return this.formModel;
|
|
3921
|
-
* }
|
|
3922
|
-
*
|
|
3923
|
-
* getResourceRoute(): string {
|
|
3924
|
-
* return '/products';
|
|
3925
|
-
* }
|
|
3926
|
-
*
|
|
3927
|
-
* getResourceName(): string {
|
|
3928
|
-
* return 'Product';
|
|
3929
|
-
* }
|
|
3930
|
-
*
|
|
3931
|
-
* isFormValid(): boolean {
|
|
3932
|
-
* const model = this.formModel();
|
|
3933
|
-
* return model.name.trim().length > 0 && model.price > 0;
|
|
3934
|
-
* }
|
|
3935
|
-
*
|
|
3936
|
-
* loadItem(id: string): void {
|
|
3937
|
-
* this.isLoading.set(true);
|
|
3938
|
-
* this.productService.findById(id)
|
|
3939
|
-
* .pipe(takeUntilDestroyed(this.destroyRef))
|
|
3940
|
-
* .subscribe({
|
|
3941
|
-
* next: (response) => {
|
|
3942
|
-
* if (response.success && response.data) {
|
|
3943
|
-
* this.existingItem.set(response.data);
|
|
3944
|
-
* this._formModel.set({
|
|
3945
|
-
* name: response.data.name,
|
|
3946
|
-
* price: response.data.price,
|
|
3947
|
-
* });
|
|
3948
|
-
* }
|
|
3949
|
-
* this.isLoading.set(false);
|
|
3950
|
-
* },
|
|
3951
|
-
* error: () => {
|
|
3952
|
-
* this.router.navigate([this.getResourceRoute()]);
|
|
3953
|
-
* this.isLoading.set(false);
|
|
3954
|
-
* },
|
|
3955
|
-
* });
|
|
3956
|
-
* }
|
|
3957
|
-
*
|
|
3958
|
-
* createItem(model: IProductFormModel): Observable<ISingleResponse<IProduct>> {
|
|
3959
|
-
* return this.productService.insert(model);
|
|
3960
|
-
* }
|
|
3961
|
-
*
|
|
3962
|
-
* updateItem(model: IProductFormModel): Observable<ISingleResponse<IProduct>> {
|
|
3963
|
-
* return this.productService.update({ id: this.existingItem()!.id, ...model });
|
|
3964
|
-
* }
|
|
3965
|
-
* }
|
|
3966
|
-
* ```
|
|
3967
|
-
*
|
|
3968
|
-
* @template T The entity/interface type being edited
|
|
3969
|
-
* @template TFormModel The form model interface
|
|
3970
|
-
*/
|
|
3971
|
-
class BaseFormPage {
|
|
3972
|
-
router = inject(Router);
|
|
3973
|
-
route = inject(ActivatedRoute);
|
|
3974
|
-
messageService = inject(MessageService);
|
|
3975
|
-
destroyRef = inject(DestroyRef);
|
|
3976
|
-
translateAdapter = inject(TranslateService, {
|
|
3977
|
-
optional: true,
|
|
3978
|
-
});
|
|
3979
|
-
routeParams = toSignal(this.route.paramMap);
|
|
3980
|
-
initialized = false;
|
|
3981
|
-
/** Loading state for async operations */
|
|
3982
|
-
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
3983
|
-
/** The existing item when in edit mode, null when creating */
|
|
3984
|
-
existingItem = signal(null, ...(ngDevMode ? [{ debugName: "existingItem" }] : []));
|
|
3985
|
-
/** Whether the form is in edit mode (has existing item) */
|
|
3986
|
-
isEditMode = computed(() => !!this.existingItem(), ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
|
|
3987
|
-
constructor() {
|
|
3988
|
-
effect(() => {
|
|
3989
|
-
const params = this.routeParams();
|
|
3990
|
-
if (!params || this.initialized)
|
|
3991
|
-
return;
|
|
3992
|
-
this.initialized = true;
|
|
3993
|
-
const id = params.get('id');
|
|
3994
|
-
if (id && id !== 'new') {
|
|
3995
|
-
this.loadItem(id);
|
|
3996
|
-
}
|
|
3997
|
-
});
|
|
3998
|
-
}
|
|
3999
|
-
/**
|
|
4000
|
-
* Handle form submission.
|
|
4001
|
-
* Validates the form, then calls createItem or updateItem based on mode.
|
|
4002
|
-
* Shows appropriate toast messages and navigates back on success.
|
|
4003
|
-
*/
|
|
4004
|
-
onSubmit() {
|
|
4005
|
-
if (!this.isFormValid()) {
|
|
4006
|
-
this.showValidationError();
|
|
4007
|
-
return;
|
|
4008
|
-
}
|
|
4009
|
-
this.isLoading.set(true);
|
|
4010
|
-
const model = this.getFormModel()();
|
|
4011
|
-
const operation$ = this.isEditMode()
|
|
4012
|
-
? this.updateItem(model)
|
|
4013
|
-
: this.createItem(model);
|
|
4014
|
-
operation$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
4015
|
-
next: (res) => {
|
|
4016
|
-
const r = res;
|
|
4017
|
-
this.showSuccess(r?.messageKey
|
|
4018
|
-
? this.t(r.messageKey, r.messageVariables)
|
|
4019
|
-
: (r?.message ?? ''));
|
|
4020
|
-
this.router.navigate([this.getResourceRoute()]);
|
|
4021
|
-
},
|
|
4022
|
-
error: () => {
|
|
4023
|
-
this.isLoading.set(false);
|
|
4024
|
-
},
|
|
4025
|
-
complete: () => {
|
|
4026
|
-
this.isLoading.set(false);
|
|
4027
|
-
},
|
|
4028
|
-
});
|
|
4029
|
-
}
|
|
4030
|
-
/**
|
|
4031
|
-
* Handle cancel action.
|
|
4032
|
-
* Navigates back to the resource list.
|
|
4033
|
-
*/
|
|
4034
|
-
onCancel() {
|
|
4035
|
-
this.router.navigate([this.getResourceRoute()]);
|
|
4036
|
-
}
|
|
4037
|
-
/**
|
|
4038
|
-
* Show validation error toast.
|
|
4039
|
-
* Override to customize the validation error message.
|
|
4040
|
-
*/
|
|
4041
|
-
showValidationError() {
|
|
4042
|
-
this.messageService.add({
|
|
4043
|
-
severity: 'error',
|
|
4044
|
-
summary: this.t('shared.validation.error'),
|
|
4045
|
-
detail: this.t('shared.fill.required.fields'),
|
|
4046
|
-
});
|
|
4047
|
-
}
|
|
4048
|
-
/**
|
|
4049
|
-
* Show success toast.
|
|
4050
|
-
* @param detail The success message to display
|
|
4051
|
-
*/
|
|
4052
|
-
showSuccess(detail) {
|
|
4053
|
-
this.messageService.add({
|
|
4054
|
-
severity: 'success',
|
|
4055
|
-
summary: this.t('shared.success'),
|
|
4056
|
-
detail,
|
|
4057
|
-
});
|
|
4058
|
-
}
|
|
4059
|
-
/**
|
|
4060
|
-
* Show error toast.
|
|
4061
|
-
* @param detail The error message to display
|
|
4062
|
-
*/
|
|
4063
|
-
showError(detail) {
|
|
4064
|
-
this.messageService.add({
|
|
4065
|
-
severity: 'error',
|
|
4066
|
-
summary: this.t('shared.error'),
|
|
4067
|
-
detail,
|
|
4068
|
-
});
|
|
4069
|
-
}
|
|
4070
|
-
/**
|
|
4071
|
-
* Translate a key using the adapter, fallback to key if not available.
|
|
4072
|
-
*/
|
|
4073
|
-
t(key, variables) {
|
|
4074
|
-
return this.translateAdapter?.translate(key, variables) ?? key;
|
|
4075
|
-
}
|
|
4076
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormPage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4077
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.5", type: BaseFormPage, isStandalone: true, ngImport: i0 });
|
|
4078
|
-
}
|
|
4079
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseFormPage, decorators: [{
|
|
4080
|
-
type: Directive
|
|
4081
|
-
}], ctorParameters: () => [] });
|
|
4082
|
-
|
|
4083
|
-
/**
|
|
4084
|
-
* Base List Page
|
|
4085
|
-
* Abstract directive providing common signals, computed values, and utilities
|
|
4086
|
-
* for list page components across all feature packages.
|
|
4087
|
-
*
|
|
4088
|
-
* Features:
|
|
4089
|
-
* - Pagination state management (pageSize, currentPage, total)
|
|
4090
|
-
* - Loading state
|
|
4091
|
-
* - CRUD navigation helpers
|
|
4092
|
-
* - Message display utilities
|
|
4093
|
-
* - Delete confirmation with API integration
|
|
4094
|
-
* - Company feature flag support
|
|
4095
|
-
*
|
|
4096
|
-
* Usage:
|
|
4097
|
-
* ```typescript
|
|
4098
|
-
* @Component({ ... })
|
|
4099
|
-
* export class UserListComponent extends BaseListPage<IUser> {
|
|
4100
|
-
* getResourceRoute(): string { return '/users'; }
|
|
4101
|
-
* getDeleteConfirmMessage(user: IUser): string { return `Delete "${user.name}"?`; }
|
|
4102
|
-
* async loadData(): Promise<void> { ... }
|
|
4103
|
-
* }
|
|
4104
|
-
* ```
|
|
4105
|
-
*/
|
|
4106
|
-
class BaseListPage {
|
|
4107
|
-
router = inject(Router);
|
|
4108
|
-
messageService = inject(MessageService);
|
|
4109
|
-
appConfig = inject(APP_CONFIG);
|
|
4110
|
-
confirmationService = inject(ConfirmationService);
|
|
4111
|
-
destroyRef = inject(DestroyRef);
|
|
4112
|
-
translateAdapter = inject(TranslateService, {
|
|
4113
|
-
optional: true,
|
|
4114
|
-
});
|
|
4115
|
-
/** Items list */
|
|
4116
|
-
items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
4117
|
-
/** Loading state */
|
|
4118
|
-
isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
4119
|
-
/** Total records for pagination */
|
|
4120
|
-
total = signal(0, ...(ngDevMode ? [{ debugName: "total" }] : []));
|
|
4121
|
-
/** Page size */
|
|
4122
|
-
pageSize = signal(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
|
|
4123
|
-
/** First record index (for p-table lazy load) */
|
|
4124
|
-
first = signal(0, ...(ngDevMode ? [{ debugName: "first" }] : []));
|
|
4125
|
-
/** Current page (0-based for API, derived from first/pageSize) */
|
|
4126
|
-
currentPage = computed(() => Math.floor(this.first() / this.pageSize()), ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
|
|
4127
|
-
/** Show company info if company feature enabled */
|
|
4128
|
-
showCompanyInfo = computed(() => this.appConfig.enableCompanyFeature, ...(ngDevMode ? [{ debugName: "showCompanyInfo" }] : []));
|
|
4129
|
-
/**
|
|
4130
|
-
* Navigate to create page
|
|
4131
|
-
*/
|
|
4132
|
-
onCreate() {
|
|
4133
|
-
this.router.navigate([this.getResourceRoute(), 'new']);
|
|
4134
|
-
}
|
|
4135
|
-
/**
|
|
4136
|
-
* Navigate to edit page
|
|
4137
|
-
* @param id The ID of the item to edit
|
|
4138
|
-
*/
|
|
4139
|
-
onEdit(id) {
|
|
4140
|
-
this.router.navigate([this.getResourceRoute(), id]);
|
|
4141
|
-
}
|
|
4142
|
-
/**
|
|
4143
|
-
* Handle page change from p-table lazy load
|
|
4144
|
-
*/
|
|
4145
|
-
onPageChange(event) {
|
|
4146
|
-
this.first.set(event.first ?? 0);
|
|
4147
|
-
this.pageSize.set(event.rows ?? 10);
|
|
4148
|
-
this.loadData();
|
|
4149
|
-
}
|
|
4150
|
-
/**
|
|
4151
|
-
* Get pagination params for API call
|
|
4152
|
-
* Returns 0-based page for backend API
|
|
4153
|
-
*/
|
|
4154
|
-
getPaginationParams() {
|
|
4155
|
-
return {
|
|
4156
|
-
currentPage: this.currentPage(),
|
|
4157
|
-
pageSize: this.pageSize(),
|
|
4158
|
-
};
|
|
4159
|
-
}
|
|
4160
|
-
/**
|
|
4161
|
-
* Show success toast message
|
|
4162
|
-
*/
|
|
4163
|
-
showSuccess(detail, summary) {
|
|
4164
|
-
this.messageService.add({
|
|
4165
|
-
severity: 'success',
|
|
4166
|
-
summary: summary ?? this.t('shared.success'),
|
|
4167
|
-
detail,
|
|
4168
|
-
});
|
|
4169
|
-
}
|
|
4170
|
-
/**
|
|
4171
|
-
* Show error toast message
|
|
4172
|
-
*/
|
|
4173
|
-
showError(detail, summary) {
|
|
4174
|
-
this.messageService.add({
|
|
4175
|
-
severity: 'error',
|
|
4176
|
-
summary: summary ?? this.t('shared.error'),
|
|
4177
|
-
detail,
|
|
4178
|
-
});
|
|
4179
|
-
}
|
|
4180
|
-
/**
|
|
4181
|
-
* Show info toast message
|
|
4182
|
-
*/
|
|
4183
|
-
showInfo(detail, summary) {
|
|
4184
|
-
this.messageService.add({
|
|
4185
|
-
severity: 'info',
|
|
4186
|
-
summary: summary ?? this.t('shared.info'),
|
|
4187
|
-
detail,
|
|
4188
|
-
});
|
|
4189
|
-
}
|
|
4190
|
-
/**
|
|
4191
|
-
* Show warning toast message
|
|
4192
|
-
*/
|
|
4193
|
-
showWarn(detail, summary) {
|
|
4194
|
-
this.messageService.add({
|
|
4195
|
-
severity: 'warn',
|
|
4196
|
-
summary: summary ?? this.t('shared.warning'),
|
|
4197
|
-
detail,
|
|
4198
|
-
});
|
|
4199
|
-
}
|
|
4200
|
-
/**
|
|
4201
|
-
* Translate a key using the adapter, fallback to key if not available.
|
|
4202
|
-
*/
|
|
4203
|
-
t(key, variables) {
|
|
4204
|
-
return this.translateAdapter?.translate(key, variables) ?? key;
|
|
4205
|
-
}
|
|
4206
|
-
/**
|
|
4207
|
-
* Delete an item with confirmation dialog
|
|
4208
|
-
* @param item The item to delete
|
|
4209
|
-
* @param idGetter Function to extract ID from item
|
|
4210
|
-
* @param deleteApiCall Function that returns Observable for delete API call
|
|
4211
|
-
* @param options Optional configuration
|
|
4212
|
-
*/
|
|
4213
|
-
onDelete(item, idGetter, deleteApiCall, options) {
|
|
4214
|
-
this.confirmationService.confirm({
|
|
4215
|
-
message: this.getDeleteConfirmMessage(item),
|
|
4216
|
-
header: options?.header ?? this.t('shared.confirm.delete.header'),
|
|
4217
|
-
icon: 'pi pi-exclamation-triangle',
|
|
4218
|
-
acceptButtonStyleClass: 'p-button-danger',
|
|
4219
|
-
accept: () => {
|
|
4220
|
-
from(deleteApiCall(idGetter(item)))
|
|
4221
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
4222
|
-
.subscribe({
|
|
4223
|
-
next: (res) => {
|
|
4224
|
-
const r = res;
|
|
4225
|
-
this.showSuccess(r?.messageKey
|
|
4226
|
-
? this.t(r.messageKey, r.messageVariables)
|
|
4227
|
-
: (r?.message ?? ''));
|
|
4228
|
-
this.loadData();
|
|
4229
|
-
},
|
|
4230
|
-
});
|
|
4231
|
-
},
|
|
4232
|
-
});
|
|
4233
|
-
}
|
|
4234
|
-
/**
|
|
4235
|
-
* Delete an item with confirmation dialog using async/await
|
|
4236
|
-
* @param item The item to delete
|
|
4237
|
-
* @param idGetter Function to extract ID from item
|
|
4238
|
-
* @param deleteApiCall Async function for delete API call
|
|
4239
|
-
* @param options Optional configuration
|
|
4240
|
-
*/
|
|
4241
|
-
async onDeleteAsync(item, idGetter, deleteApiCall, options) {
|
|
4242
|
-
this.confirmationService.confirm({
|
|
4243
|
-
message: this.getDeleteConfirmMessage(item),
|
|
4244
|
-
header: options?.header ?? this.t('shared.confirm.delete.header'),
|
|
4245
|
-
icon: 'pi pi-exclamation-triangle',
|
|
4246
|
-
acceptButtonStyleClass: 'p-button-danger',
|
|
4247
|
-
accept: async () => {
|
|
4248
|
-
const res = await deleteApiCall(idGetter(item));
|
|
4249
|
-
const r = res;
|
|
4250
|
-
this.showSuccess(r?.messageKey
|
|
4251
|
-
? this.t(r.messageKey, r.messageVariables)
|
|
4252
|
-
: (r?.message ?? ''));
|
|
4253
|
-
await this.loadData();
|
|
4254
|
-
},
|
|
4255
|
-
});
|
|
4256
|
-
}
|
|
4257
|
-
/**
|
|
4258
|
-
* Navigate to a route
|
|
4259
|
-
*/
|
|
4260
|
-
navigateTo(path) {
|
|
4261
|
-
this.router.navigate(path);
|
|
4262
|
-
}
|
|
4263
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListPage, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4264
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.5", type: BaseListPage, isStandalone: true, ngImport: i0 });
|
|
4265
|
-
}
|
|
4266
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BaseListPage, decorators: [{
|
|
4267
|
-
type: Directive
|
|
4268
|
-
}] });
|
|
4269
|
-
|
|
4270
3950
|
function getOffsetMinutes(utcDate, timezone) {
|
|
4271
3951
|
const extract = (tz) => {
|
|
4272
3952
|
const parts = new Intl.DateTimeFormat('en-US', {
|
|
@@ -4334,5 +4014,5 @@ function getUserTimezone() {
|
|
|
4334
4014
|
* Generated bundle index. Do not edit.
|
|
4335
4015
|
*/
|
|
4336
4016
|
|
|
4337
|
-
export { ACTION_PERMISSIONS, AUTH_STATE_PROVIDER, AngularModule, ApiResourceService, ApiResourceService as ApiService, BRANCH_PERMISSIONS, BaseFormControl,
|
|
4017
|
+
export { ACTION_PERMISSIONS, AUTH_STATE_PROVIDER, AngularModule, ApiResourceService, ApiResourceService as ApiService, BRANCH_PERMISSIONS, BaseFormControl, BaseUserSelectComponent, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, COMPANY_PERMISSIONS, CookieService, EMAIL_CONFIG_PERMISSIONS, EMAIL_TEMPLATE_PERMISSIONS, EVENT_PERMISSIONS, EditModeElementChangerDirective, FILE_PERMISSIONS, FILE_PROVIDER, FILE_TYPE_FILTERS, FOLDER_PERMISSIONS, FORM_PERMISSIONS, FORM_RESULT_PERMISSIONS, FaviconService, FileSelectorDialogComponent, FileUploaderComponent, FileUrlService, HasPermissionDirective, IconComponent, IconTypeEnum, InlineSvgComponent, IsEmptyImageDirective, LANGUAGE_PERMISSIONS, LazyMultiSelectComponent, LazySelectComponent, NOTIFICATION_PERMISSIONS, PERMISSIONS, PROFILE_PERMISSION_PROVIDER, PermissionValidatorService, PlatformService, PreventDefaultDirective, PrimeModule, ROLE_ACTION_PERMISSIONS, ROLE_PERMISSIONS, SHARED_MESSAGES, SKIP_ERROR_TOAST, STORAGE_CONFIG_PERMISSIONS, TRANSLATION_KEY_PERMISSIONS, TRANSLATION_PERMISSIONS, TranslatePipe, TranslateService, UPLOAD_CONFIG_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_PERMISSIONS, USER_PERMISSION_PROVIDER, USER_PROVIDER, USER_ROLE_PERMISSIONS, UserMultiSelectComponent, UserSelectComponent, allPermissionsGuard, anyPermissionGuard, checkScrollPagination, errorCatchingInterceptor, evaluateLogicNode, evaluatePermission, formatFileSize, formatInTimezone, getAcceptString, getFileIconClass, getUserTimezone, hasAllPermissions, hasAnyPermission, hasPermission, isFileTypeAllowed, localToUtc, permissionGuard, provideValueAccessor, resolveTranslationModule, utcToLocal };
|
|
4338
4018
|
//# sourceMappingURL=flusys-ng-shared.mjs.map
|