@flusys/ng-auth 9.2.2 → 9.3.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.
- package/fesm2022/{flusys-ng-auth-administration-page.component-C9cMjTFU.mjs → flusys-ng-auth-administration-page.component-CxQYkCc1.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-administration-page.component-C9cMjTFU.mjs.map → flusys-ng-auth-administration-page.component-CxQYkCc1.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-branch-form.component-xttRMwxT.mjs → flusys-ng-auth-branch-form.component-DtoM4SET.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-branch-form.component-xttRMwxT.mjs.map → flusys-ng-auth-branch-form.component-DtoM4SET.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-branch-list.component-SeGvWdUO.mjs → flusys-ng-auth-branch-list.component-CP9VFx_8.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-branch-list.component-SeGvWdUO.mjs.map → flusys-ng-auth-branch-list.component-CP9VFx_8.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-company-form.component-BPrFxqto.mjs → flusys-ng-auth-company-form.component-C1HXjgn-.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-company-form.component-BPrFxqto.mjs.map → flusys-ng-auth-company-form.component-C1HXjgn-.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-company-list.component-jEtVFxYE.mjs → flusys-ng-auth-company-list.component-jkyaG-hS.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-company-list.component-jEtVFxYE.mjs.map → flusys-ng-auth-company-list.component-jkyaG-hS.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-forgot-password-page.component-JnLtR304.mjs → flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-forgot-password-page.component-JnLtR304.mjs.map → flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-login-page.component-R8gMWdLZ.mjs → flusys-ng-auth-login-page.component-Bz-bbY3U.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-login-page.component-R8gMWdLZ.mjs.map → flusys-ng-auth-login-page.component-Bz-bbY3U.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs → flusys-ng-auth-profile-page.component-Dg25DA0i.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs.map → flusys-ng-auth-profile-page.component-Dg25DA0i.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-register-page.component-B0me9tCm.mjs → flusys-ng-auth-register-page.component-Cb-ycJHR.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-register-page.component-B0me9tCm.mjs.map → flusys-ng-auth-register-page.component-Cb-ycJHR.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-reset-password-page.component-DnULwTow.mjs → flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-reset-password-page.component-DnULwTow.mjs.map → flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-social-callback-page.component-DTrdtpbR.mjs → flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-social-callback-page.component-DTrdtpbR.mjs.map → flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-social-config-page.component-Ce7yrJtX.mjs → flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-social-config-page.component-Ce7yrJtX.mjs.map → flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-user-form.component-cY4cmjV_.mjs → flusys-ng-auth-user-form.component-o0MbxMQn.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-user-form.component-cY4cmjV_.mjs.map → flusys-ng-auth-user-form.component-o0MbxMQn.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-user-list.component-Dhq8Hygo.mjs → flusys-ng-auth-user-list.component-MHHsLH9r.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-user-list.component-Dhq8Hygo.mjs.map → flusys-ng-auth-user-list.component-MHHsLH9r.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-verify-email-page.component-C3CLhAip.mjs → flusys-ng-auth-verify-email-page.component-3qcv2X_u.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-verify-email-page.component-C3CLhAip.mjs.map → flusys-ng-auth-verify-email-page.component-3qcv2X_u.mjs.map} +1 -1
- package/fesm2022/flusys-ng-auth.mjs +87 -87
- package/package.json +5 -5
|
@@ -54,7 +54,7 @@ var AdministrationPageComponent = class AdministrationPageComponent {
|
|
|
54
54
|
}, ...ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []);
|
|
55
55
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
56
56
|
minVersion: "12.0.0",
|
|
57
|
-
version: "22.2.
|
|
57
|
+
version: "22.2.3",
|
|
58
58
|
ngImport: i0,
|
|
59
59
|
type: AdministrationPageComponent,
|
|
60
60
|
deps: [],
|
|
@@ -62,7 +62,7 @@ var AdministrationPageComponent = class AdministrationPageComponent {
|
|
|
62
62
|
});
|
|
63
63
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
64
64
|
minVersion: "14.0.0",
|
|
65
|
-
version: "22.2.
|
|
65
|
+
version: "22.2.3",
|
|
66
66
|
type: AdministrationPageComponent,
|
|
67
67
|
isStandalone: true,
|
|
68
68
|
selector: "lib-administration-page",
|
|
@@ -112,7 +112,7 @@ var AdministrationPageComponent = class AdministrationPageComponent {
|
|
|
112
112
|
};
|
|
113
113
|
i0.ɵɵngDeclareClassMetadata({
|
|
114
114
|
minVersion: "12.0.0",
|
|
115
|
-
version: "22.2.
|
|
115
|
+
version: "22.2.3",
|
|
116
116
|
ngImport: i0,
|
|
117
117
|
type: AdministrationPageComponent,
|
|
118
118
|
decorators: [{
|
|
@@ -143,4 +143,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
143
143
|
});
|
|
144
144
|
export { AdministrationPageComponent };
|
|
145
145
|
|
|
146
|
-
//# sourceMappingURL=flusys-ng-auth-administration-page.component-
|
|
146
|
+
//# sourceMappingURL=flusys-ng-auth-administration-page.component-CxQYkCc1.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-administration-page.component-
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-administration-page.component-CxQYkCc1.mjs","names":[],"sources":["../../../projects/ng-auth/pages/administration/administration-page.component.ts"],"sourcesContent":["import { Component, computed, inject } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { APP_CONFIG, isCompanyFeatureEnabled } from '@flusys/ng-core';\nimport {\n BRANCH_PERMISSIONS,\n COMPANY_PERMISSIONS,\n PermissionValidatorService,\n RouterTabItem,\n RouterTabsComponent,\n SOCIAL_AUTH_CONFIG_PERMISSIONS,\n TranslatePipe,\n TranslateService,\n USER_PERMISSIONS,\n} from '@flusys/ng-shared';\n\ninterface ITab {\n id: string;\n labelKey: string;\n icon: string;\n route: string;\n permission: string;\n requiresCompanyFeature?: boolean;\n}\n\n/**\n * Administration Page Component\n * Unified administration page with tabs for:\n * - Users (always visible) - includes permission management via dialogs\n * - Companies (only if company feature enabled)\n * - Branches (only if company feature enabled)\n * - Social Config (social sign-in provider credentials)\n */\n@Component({\n selector: 'lib-administration-page',\n imports: [RouterOutlet, TranslatePipe, RouterTabsComponent],\n template: `\n <div class=\"p-4\">\n <div class=\"mb-4\">\n <h1 class=\"text-2xl font-bold m-0\">{{ 'administrative.title' | translate }}</h1>\n <p class=\"text-muted-color mt-1\">{{ 'administrative.subtitle' | translate }}</p>\n </div>\n\n <lib-router-tabs [tabs]=\"visibleTabs()\" class=\"mb-4\" />\n\n <div>\n <router-outlet />\n </div>\n </div>\n `,\n})\nexport class AdministrationPageComponent {\n private readonly appConfig = inject(APP_CONFIG);\n private readonly permissionValidator = inject(PermissionValidatorService);\n private readonly translateService = inject(TranslateService);\n\n private readonly allTabs: ITab[] = [\n {\n id: 'users',\n labelKey: 'administrative.user.title',\n icon: 'users',\n route: 'users',\n permission: USER_PERMISSIONS.READ,\n },\n {\n id: 'companies',\n labelKey: 'administrative.company.title',\n icon: 'building',\n route: 'company',\n permission: COMPANY_PERMISSIONS.READ,\n requiresCompanyFeature: true,\n },\n {\n id: 'branches',\n labelKey: 'administrative.branch.title',\n icon: 'sitemap',\n route: 'branch',\n permission: BRANCH_PERMISSIONS.READ,\n requiresCompanyFeature: true,\n },\n {\n id: 'social-config',\n labelKey: 'social.config.title',\n icon: 'key',\n route: 'social-config',\n permission: SOCIAL_AUTH_CONFIG_PERMISSIONS.READ,\n },\n ];\n\n readonly companyFeatureEnabled = computed(() => isCompanyFeatureEnabled(this.appConfig));\n\n readonly visibleTabs = computed<RouterTabItem[]>(() => {\n return this.allTabs\n .filter((tab) => {\n const hasCompanyFeature = !tab.requiresCompanyFeature || this.companyFeatureEnabled();\n const hasPermission = this.permissionValidator.hasPermission(tab.permission);\n return hasCompanyFeature && hasPermission;\n })\n .map((tab) => ({\n id: tab.id,\n label: this.translateService.translate(tab.labelKey),\n icon: tab.icon,\n route: tab.route,\n }));\n });\n}\n"],"mappings":";;;;;AAkDA,IAAa,8BAAb,MAAa,4BAA2B;CACrB,YAAY,OAAO,UAAU;CAC7B,sBAAsB,OAAO,0BAA0B;CACvD,mBAAmB,OAAO,gBAAgB;CAE1C,UAAkB;EACjC;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,iBAAiB;EAC9B;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,oBAAoB;GAChC,wBAAwB;EACzB;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,mBAAmB;GAC/B,wBAAwB;EACzB;EACD;GACE,IAAI;GACJ,UAAU;GACV,MAAM;GACN,OAAO;GACP,YAAY,+BAA+B;EAC5C;CACF;CAEQ,wBAAwB,eAAe,wBAAwB,KAAK,SAAS,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,wBAAA,CAAA,+BAAA,CAAA,CAAA;CAE/E,cAAc,eAA+B;EACpD,OAAO,KAAK,QACT,QAAQ,QAAO;GACd,MAAM,oBAAoB,CAAC,IAAI,0BAA0B,KAAK,sBAAqB;GACnF,MAAM,gBAAgB,KAAK,oBAAoB,cAAc,IAAI,UAAU;GAC3E,OAAO,qBAAqB;EAC9B,CAAC,CAAC,CACD,KAAK,SAAS;GACb,IAAI,IAAI;GACR,OAAO,KAAK,iBAAiB,UAAU,IAAI,QAAQ;GACnD,MAAM,IAAI;GACV,OAAO,IAAI;EACZ,EAAC;CACN,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CArDS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAA2B,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAA3B,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAA2B,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UAf5B;;;;;;;;;;;;;;EAaT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MAdS;IAAY,UAAA;IAAA,QAAA,CAAA,QAAA,kBAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,UAAA,CAAA,QAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAiB;IAAmB,UAAA;IAAA,QAAA,CAAA,MAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAlC;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AAgB1B,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAA2B,YAAA,CAAA;EAlBvC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IAAC;IAAc;IAAe;GAAmB;GAC1D,UAAU;;;;;;;;;;;;;;EAcX,CAAA"}
|
|
@@ -213,7 +213,7 @@ var BranchFormComponent = class BranchFormComponent {
|
|
|
213
213
|
}
|
|
214
214
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
215
215
|
minVersion: "12.0.0",
|
|
216
|
-
version: "22.2.
|
|
216
|
+
version: "22.2.3",
|
|
217
217
|
ngImport: i0,
|
|
218
218
|
type: BranchFormComponent,
|
|
219
219
|
deps: [],
|
|
@@ -221,7 +221,7 @@ var BranchFormComponent = class BranchFormComponent {
|
|
|
221
221
|
});
|
|
222
222
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
223
223
|
minVersion: "17.0.0",
|
|
224
|
-
version: "22.2.
|
|
224
|
+
version: "22.2.3",
|
|
225
225
|
type: BranchFormComponent,
|
|
226
226
|
isStandalone: true,
|
|
227
227
|
selector: "lib-branch-form",
|
|
@@ -563,7 +563,7 @@ var BranchFormComponent = class BranchFormComponent {
|
|
|
563
563
|
};
|
|
564
564
|
i0.ɵɵngDeclareClassMetadata({
|
|
565
565
|
minVersion: "12.0.0",
|
|
566
|
-
version: "22.2.
|
|
566
|
+
version: "22.2.3",
|
|
567
567
|
ngImport: i0,
|
|
568
568
|
type: BranchFormComponent,
|
|
569
569
|
decorators: [{
|
|
@@ -740,4 +740,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
740
740
|
});
|
|
741
741
|
export { BranchFormComponent };
|
|
742
742
|
|
|
743
|
-
//# sourceMappingURL=flusys-ng-auth-branch-form.component-
|
|
743
|
+
//# sourceMappingURL=flusys-ng-auth-branch-form.component-DtoM4SET.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-branch-form.component-xttRMwxT.mjs","names":[],"sources":["../../../projects/ng-auth/pages/branch/branch-form.component.ts"],"sourcesContent":["import { Component, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport {\n CardComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n SelectComponent,\n TreeNode,\n TreeSelectComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n buildBranchTreeNodes,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n IBranch,\n ICreateBranchRequest,\n IUpdateBranchRequest,\n} from '../../interfaces/branch.interface';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { BranchApiService } from '../../services/branch-api.service';\nimport { CompanyApiService } from '../../services/company-api.service';\n\nconst BRANCH_FORM_FIELDS = [\n 'id',\n 'companyId',\n 'parentId',\n 'name',\n 'slug',\n 'email',\n 'phone',\n 'address',\n 'isActive',\n 'readOnly',\n];\n\n/** Branch form model interface */\ninterface IBranchFormModel {\n companyId: string;\n parentId: string | null;\n name: string;\n slug: string;\n email: string;\n phone: string;\n address: string;\n isActive: boolean;\n}\n\n/**\n * Branch Form Component\n * Handles creating and editing branches.\n * Defaults to current company context.\n */\n@Component({\n selector: 'lib-branch-form',\n imports: [\n CardComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n FormField,\n TranslatePipe,\n ],\n template: `\n <f-card>\n <ng-template #header>\n <div class=\"flex justify-between items-center p-4\">\n <h2 class=\"text-xl font-semibold m-0\">\n {{\n isEditMode()\n ? ('administrative.branch.edit' | translate)\n : ('administrative.branch.new' | translate)\n }}\n </h2>\n </div>\n </ng-template>\n\n <form\n (submit)=\"onSubmit($event)\"\n class=\"grid grid-cols-1 md:grid-cols-2 gap-4\"\n >\n <!-- Company Selection -->\n @if (!isEditMode()) {\n <div class=\"flex flex-col gap-2\">\n <label for=\"companyId\" class=\"font-medium\"\n >{{ 'shared.company' | translate }} *</label\n >\n <f-select\n inputId=\"companyId\"\n [options]=\"companies()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [formField]=\"branchForm.companyId\"\n [placeholder]=\"'administrative.company.select' | translate\"\n />\n </div>\n }\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"parentId\" class=\"font-medium\">{{\n 'administrative.branch.parent' | translate\n }}</label>\n <f-treeselect\n inputId=\"parentId\"\n [options]=\"parentTreeNodes()\"\n [formField]=\"branchForm.parentId\"\n [placeholder]=\"'administrative.branch.select.parent' | translate\"\n [filterPlaceholder]=\"'shared.search' | translate\"\n [emptyMessage]=\"'administrative.branch.no.branches' | translate\"\n [filter]=\"true\"\n [showClear]=\"true\"\n />\n </div>\n\n <!-- Name -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"name\" class=\"font-medium\"\n >{{ 'administrative.branch.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"branchForm.name\"\n (blur)=\"generateSlug()\"\n [placeholder]=\"'administrative.branch.name.placeholder' | translate\"\n />\n </div>\n\n <!-- Slug -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"slug\" class=\"font-medium\"\n >{{ 'administrative.branch.slug' | translate }} *</label\n >\n <input\n fInputText\n id=\"slug\"\n [formField]=\"branchForm.slug\"\n [placeholder]=\"'administrative.branch.slug.placeholder' | translate\"\n />\n </div>\n\n <!-- Email -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"email\" class=\"font-medium\">{{\n 'administrative.email.label' | translate\n }}</label>\n <input\n fInputText\n id=\"email\"\n type=\"email\"\n [formField]=\"branchForm.email\"\n [placeholder]=\"'administrative.email.placeholder' | translate\"\n />\n </div>\n\n <!-- Phone -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"phone\" class=\"font-medium\">{{\n 'administrative.phone.label' | translate\n }}</label>\n <input\n fInputText\n id=\"phone\"\n [formField]=\"branchForm.phone\"\n [placeholder]=\"'administrative.phone.placeholder' | translate\"\n />\n </div>\n\n <!-- Is Active -->\n <div class=\"flex items-center pt-6\">\n <f-checkbox [formField]=\"branchForm.isActive\" [label]=\"'shared.active' | translate\" />\n </div>\n\n <!-- Address -->\n <div class=\"flex flex-col gap-2 md:col-span-2\">\n <label for=\"address\" class=\"font-medium\">{{\n 'administrative.address.label' | translate\n }}</label>\n <textarea\n id=\"address\"\n fInputText\n [formField]=\"branchForm.address\"\n [placeholder]=\"'administrative.address.placeholder' | translate\"\n rows=\"3\"\n ></textarea>\n </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-4 md:col-span-2 pt-4\">\n <button\n fButton\n type=\"button\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (click)=\"navigateToList()\"\n >\n <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>\n </button>\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ \n isEditMode()\n ? ('shared.update' | translate)\n : ('shared.create' | translate)\n }}</span>\n </button>\n </div>\n </form>\n </f-card>\n `,\n})\nexport class BranchFormComponent {\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly messageService = inject(MessageService);\n private readonly branchService = inject(BranchApiService);\n private readonly companyService = inject(CompanyApiService);\n private readonly authState = inject(AuthStateService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(key: string, vars?: Record<string, unknown>): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n // Route params as signals\n private readonly routeParams = toSignal(this.route.paramMap);\n private readonly queryParams = toSignal(this.route.queryParamMap);\n\n /** Loading state */\n readonly isLoading = signal(false);\n\n /** Existing branch data when editing */\n readonly existingBranch = signal<IBranch | null>(null);\n\n /** Whether in edit mode */\n readonly isEditMode = computed(() => !!this.existingBranch());\n\n /** Companies list for dropdown */\n readonly companies = this.companyService.data;\n\n private readonly companyBranches = signal<IBranch[]>([]);\n\n readonly parentTreeNodes = computed<TreeNode<IBranch>[]>(() =>\n buildBranchTreeNodes(this.companyBranches(), this.existingBranch()?.id),\n );\n\n private readonly selectedCompanyId = computed(() => this.formModel().companyId);\n\n // ============================================\n // Form (Signal Forms)\n // ============================================\n\n /** Form model */\n readonly formModel = signal<IBranchFormModel>({\n companyId: '',\n parentId: null,\n name: '',\n slug: '',\n email: '',\n phone: '',\n address: '',\n isActive: true,\n });\n\n /** Form with validation schema */\n readonly branchForm = form(this.formModel, (f) => {\n required(f.companyId, {\n message: this.translate('auth.validation.company.required'),\n });\n required(f.name, { message: this.translate('shared.name.required') });\n required(f.slug, {\n message: this.translate('administrative.branch.slug.required'),\n });\n });\n\n /** Check if form is valid */\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return (\n model.companyId.trim().length > 0 &&\n model.name.trim().length > 0 &&\n model.slug.trim().length > 0\n );\n });\n\n constructor() {\n // Load companies on initialization\n this.companyService.fetchList('', {\n pagination: { currentPage: 0, pageSize: 100 },\n });\n\n // Effect to handle route-based initialization\n effect(() => {\n const params = this.routeParams();\n const query = this.queryParams();\n if (!params) return;\n\n const id = params.get('id');\n if (id && id !== 'new') {\n this.loadBranch(id);\n } else {\n // Set company from query params or current company\n const queryCompanyId = query?.get('companyId');\n const currentCompanyId = this.authState.company()?.id;\n const companyId = queryCompanyId || currentCompanyId;\n\n const parentId = query?.get('parentId') || null;\n this.formModel.update((m) => ({\n ...m,\n companyId: companyId || m.companyId,\n parentId,\n }));\n }\n });\n\n effect(() => {\n const companyId = this.selectedCompanyId();\n untracked(() => this.loadCompanyBranches(companyId));\n });\n }\n\n private async loadCompanyBranches(companyId: string): Promise<void> {\n this.companyBranches.set([]);\n if (!companyId) return;\n try {\n const response = await this.branchService.getAll({\n filter: { companyId },\n pagination: { currentPage: 0, pageSize: 1000 },\n select: ['id', 'name', 'parentId', 'serial'],\n });\n if (this.selectedCompanyId() !== companyId) return;\n this.companyBranches.set(response?.success ? (response.data ?? []) : []);\n const parentId = this.formModel().parentId;\n if (parentId && !this.companyBranches().some((b) => b.id === parentId)) {\n this.formModel.update((m) => ({ ...m, parentId: null }));\n }\n } catch {\n // Error handled by global interceptor\n }\n }\n\n async loadBranch(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.branchService.findById(id, BRANCH_FORM_FIELDS);\n if (response.success && response.data) {\n this.existingBranch.set(response.data);\n this.formModel.set(this.toFormModel(response.data));\n }\n } catch {\n this.router.navigate(['/administration/branch']);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private toFormModel(branch: IBranch): IBranchFormModel {\n return {\n companyId: branch.companyId,\n parentId: branch.parentId ?? null,\n name: branch.name,\n slug: branch.slug,\n email: branch.email || '',\n phone: branch.phone || '',\n address: branch.address || '',\n isActive: branch.isActive,\n };\n }\n\n generateSlug(): void {\n const model = this.formModel();\n if (!model.slug && model.name) {\n const slug = model.name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n this.formModel.update((m) => ({ ...m, slug }));\n }\n }\n\n async onSubmit(event: Event): Promise<void> {\n event.preventDefault();\n\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n try {\n if (this.isEditMode() && this.existingBranch()) {\n await this.updateBranch();\n } else {\n await this.createBranch();\n }\n this.navigateToList();\n } catch {\n // Error handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private async updateBranch(): Promise<void> {\n const model = this.formModel();\n const updateData: IUpdateBranchRequest = {\n id: this.existingBranch()!.id,\n name: model.name,\n slug: model.slug,\n ...this.buildOptionalFields(model),\n };\n const response = await this.branchService.update(updateData);\n this.onSaveSuccess(\n response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<string, unknown>,\n )\n : response.message,\n );\n }\n\n private async createBranch(): Promise<void> {\n const model = this.formModel();\n const createData: ICreateBranchRequest = {\n companyId: model.companyId,\n name: model.name,\n slug: model.slug,\n ...this.buildOptionalFields(model),\n };\n const response = await this.branchService.insert(createData);\n this.onSaveSuccess(\n response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<string, string | number>,\n )\n : (response.message ?? ''),\n );\n }\n\n private buildOptionalFields(model: IBranchFormModel) {\n return {\n parentId: model.parentId || null,\n email: model.email || undefined,\n phone: model.phone || undefined,\n address: model.address || undefined,\n isActive: model.isActive,\n };\n }\n\n private onSaveSuccess(message: string): void {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: message,\n });\n }\n\n private getTargetCompanyId(): string | null {\n return (\n this.existingBranch()?.companyId || this.formModel().companyId || null\n );\n }\n\n protected navigateToList(): void {\n const companyId = this.getTargetCompanyId();\n this.router.navigate(['/administration/branch'], {\n queryParams: companyId ? { companyId } : {},\n });\n }\n}\n"],"mappings":";;;;;;;;AA6BA,MAAM,qBAAqB;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AA0LD,IAAa,sBAAb,MAAa,oBAAmB;CACb,SAAS,OAAO,MAAM;CACtB,QAAQ,OAAO,cAAc;CAC7B,iBAAiB,OAAO,cAAc;CACtC,gBAAgB,OAAO,gBAAgB;CACvC,iBAAiB,OAAO,iBAAiB;CACzC,YAAY,OAAO,gBAAgB;CACnC,mBAAmB,OAAO,kBAAkB,EAC3D,UAAU,KACX,CAAA;CAEO,UAAU,KAAa,MAA8B;EAC3D,OAAO,KAAK,kBAAkB,UAAU,KAAK,IAAI,KAAK;CACxD;CAGiB,cAAc,SAAS,KAAK,MAAM,QAAQ;CAC1C,cAAc,SAAS,KAAK,MAAM,aAAa;CAGvD,YAAY,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAGzB,iBAAiB,OAAuB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAG7C,aAAa,eAAe,CAAC,CAAC,KAAK,eAAc,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAGpD,YAAY,KAAK,eAAe;CAExB,kBAAkB,OAAkB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAE/C,kBAAkB,eACzB,qBAAqB,KAAK,gBAAe,GAAI,KAAK,eAAc,CAAE,EAAE,EAAE,GACvE,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CAEgB,oBAAoB,eAAe,KAAK,UAAS,CAAE,CAAC,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;CAOtE,YAAY,OAAyB;EAC5C,WAAW;EACX,UAAU;EACV,MAAM;EACN,MAAM;EACN,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;CACX,GAAC,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAGO,aAAa,KAAK,KAAK,YAAY,MAAK;EAC/C,SAAS,EAAE,WAAW,EACpB,SAAS,KAAK,UAAU,kCAAkC,EAC3D,CAAA;EACD,SAAS,EAAE,MAAM,EAAE,SAAS,KAAK,UAAU,sBAAsB,EAAC,CAAE;EACpE,SAAS,EAAE,MAAM,EACf,SAAS,KAAK,UAAU,qCAAqC,EAC9D,CAAA;CACH,CAAC;CAGQ,cAAc,eAAc;EACnC,MAAM,QAAQ,KAAK,UAAS;EAC5B,OACE,MAAM,UAAU,KAAI,CAAE,CAAC,SAAS,KAChC,MAAM,KAAK,KAAI,CAAE,CAAC,SAAS,KAC3B,MAAM,KAAK,KAAI,CAAE,CAAC,SAAS;CAE/B,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEF,cAAA;EAEE,KAAK,eAAe,UAAU,IAAI,EAChC,YAAY;GAAE,aAAa;GAAG,UAAU;EAAG,EAC5C,CAAA;EAGD,aAAY;GACV,MAAM,SAAS,KAAK,YAAW;GAC/B,MAAM,QAAQ,KAAK,YAAW;GAC9B,IAAI,CAAC,QAAQ;GAEb,MAAM,KAAK,OAAO,IAAI,IAAI;GAC1B,IAAI,MAAM,OAAO,OACf,KAAK,WAAW,EAAE;QACb;IAEL,MAAM,iBAAiB,OAAO,IAAI,WAAW;IAC7C,MAAM,mBAAmB,KAAK,UAAU,QAAO,CAAE,EAAE;IACnD,MAAM,YAAY,kBAAkB;IAEpC,MAAM,WAAW,OAAO,IAAI,UAAU,KAAK;IAC3C,KAAK,UAAU,QAAQ,OAAO;KAC5B,GAAG;KACH,WAAW,aAAa,EAAE;KAC1B;IACD,EAAC;GACJ;EACF,CAAC;EAED,aAAY;GACV,MAAM,YAAY,KAAK,kBAAiB;GACxC,gBAAgB,KAAK,oBAAoB,SAAS,CAAC;EACrD,CAAC;CACH;CAEQ,MAAM,oBAAoB,WAAiB;EACjD,KAAK,gBAAgB,IAAI,CAAA,CAAE;EAC3B,IAAI,CAAC,WAAW;EAChB,IAAI;GACF,MAAM,WAAW,MAAM,KAAK,cAAc,OAAO;IAC/C,QAAQ,EAAE,UAAS;IACnB,YAAY;KAAE,aAAa;KAAG,UAAU;IAAI;IAC5C,QAAQ;KAAC;KAAM;KAAQ;KAAY;IAAQ;GAC5C,CAAA;GACD,IAAI,KAAK,kBAAiB,MAAO,WAAW;GAC5C,KAAK,gBAAgB,IAAI,UAAU,UAAW,SAAS,QAAQ,CAAA,IAAM,CAAA,CAAE;GACvE,MAAM,WAAW,KAAK,UAAS,CAAE,CAAC;GAClC,IAAI,YAAY,CAAC,KAAK,gBAAe,CAAE,CAAC,MAAM,MAAM,EAAE,OAAO,QAAQ,GACnE,KAAK,UAAU,QAAQ,OAAO;IAAE,GAAG;IAAG,UAAU;GAAI,EAAG;EAE3D,QAAQ,CAER;CACF;CAEA,MAAM,WAAW,IAAU;EACzB,KAAK,UAAU,IAAI,IAAI;EACvB,IAAI;GACF,MAAM,WAAW,MAAM,KAAK,cAAc,SAAS,IAAI,kBAAkB;GACzE,IAAI,SAAS,WAAW,SAAS,MAAM;IACrC,KAAK,eAAe,IAAI,SAAS,IAAI;IACrC,KAAK,UAAU,IAAI,KAAK,YAAY,SAAS,IAAI,CAAC;GACpD;EACF,QAAQ;GACN,KAAK,OAAO,SAAS,CAAC,wBAAwB,CAAC;EACjD,UAAU;GACR,KAAK,UAAU,IAAI,KAAK;EAC1B;CACF;CAEQ,YAAY,QAAe;EACjC,OAAO;GACL,WAAW,OAAO;GAClB,UAAU,OAAO,YAAY;GAC7B,MAAM,OAAO;GACb,MAAM,OAAO;GACb,OAAO,OAAO,SAAS;GACvB,OAAO,OAAO,SAAS;GACvB,SAAS,OAAO,WAAW;GAC3B,UAAU,OAAO;EAClB;CACH;CAEA,eAAY;EACV,MAAM,QAAQ,KAAK,UAAS;EAC5B,IAAI,CAAC,MAAM,QAAQ,MAAM,MAAM;GAC7B,MAAM,OAAO,MAAM,KAChB,YAAW,CAAE,CACb,QAAQ,eAAe,GAAG,CAAC,CAC3B,QAAQ,UAAU,EAAE;GACvB,KAAK,UAAU,QAAQ,OAAO;IAAE,GAAG;IAAG;GAAI,EAAG;EAC/C;CACF;CAEA,MAAM,SAAS,OAAY;EACzB,MAAM,eAAc;EAEpB,IAAI,CAAC,KAAK,YAAW,GAAI;GACvB,KAAK,eAAe,IAAI;IACtB,UAAU;IACV,SAAS,KAAK,UAAU,yBAAyB;IACjD,QAAQ,KAAK,UAAU,6BAA6B;GACrD,CAAA;GACD;EACF;EAEA,KAAK,UAAU,IAAI,IAAI;EAEvB,IAAI;GACF,IAAI,KAAK,WAAU,KAAM,KAAK,eAAc,GAC1C,MAAM,KAAK,aAAY;QAEvB,MAAM,KAAK,aAAY;GAEzB,KAAK,eAAc;EACrB,QAAQ,CAER,UAAU;GACR,KAAK,UAAU,IAAI,KAAK;EAC1B;CACF;CAEQ,MAAM,eAAY;EACxB,MAAM,QAAQ,KAAK,UAAS;EAC5B,MAAM,aAAmC;GACvC,IAAI,KAAK,eAAc,CAAG,CAAC;GAC3B,MAAM,MAAM;GACZ,MAAM,MAAM;GACZ,GAAG,KAAK,oBAAoB,KAAK;EAClC;EACD,MAAM,WAAW,MAAM,KAAK,cAAc,OAAO,UAAU;EAC3D,KAAK,cACH,SAAS,aACL,KAAK,UACH,SAAS,YACT,SAAS,gBAA2C,IAEtD,SAAS,OAAO;CAExB;CAEQ,MAAM,eAAY;EACxB,MAAM,QAAQ,KAAK,UAAS;EAC5B,MAAM,aAAmC;GACvC,WAAW,MAAM;GACjB,MAAM,MAAM;GACZ,MAAM,MAAM;GACZ,GAAG,KAAK,oBAAoB,KAAK;EAClC;EACD,MAAM,WAAW,MAAM,KAAK,cAAc,OAAO,UAAU;EAC3D,KAAK,cACH,SAAS,aACL,KAAK,UACH,SAAS,YACT,SAAS,gBAAmD,IAE7D,SAAS,WAAW,EAAG;CAEhC;CAEQ,oBAAoB,OAAuB;EACjD,OAAO;GACL,UAAU,MAAM,YAAY;GAC5B,OAAO,MAAM,SAAS;GACtB,OAAO,MAAM,SAAS;GACtB,SAAS,MAAM,WAAW;GAC1B,UAAU,MAAM;EACjB;CACH;CAEQ,cAAc,SAAe;EACnC,KAAK,eAAe,IAAI;GACtB,UAAU;GACV,SAAS,KAAK,UAAU,gBAAgB;GACxC,QAAQ;EACT,CAAA;CACH;CAEQ,qBAAkB;EACxB,OACE,KAAK,eAAc,CAAE,EAAE,aAAa,KAAK,UAAS,CAAE,CAAC,aAAa;CAEtE;CAEU,iBAAc;EACtB,MAAM,YAAY,KAAK,mBAAkB;EACzC,KAAK,OAAO,SAAS,CAAC,wBAAwB,GAAG,EAC/C,aAAa,YAAY,EAAE,UAAS,IAAK,CAAA,EAC1C,CAAA;CACH;CA1QW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAmB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UA1JpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwJT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MAlKC;IAAa,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACb;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAChB;IAAkB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAClB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;IAAmB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACnB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;IAAS,UAAA;IAAA,QAAA,CAAA,WAAA;IAAA,UAAA,CAAA,WAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACT;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AA4JJ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA;EAvK/B,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD;GACD,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyJX,CAAA"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-branch-form.component-DtoM4SET.mjs","names":[],"sources":["../../../projects/ng-auth/pages/branch/branch-form.component.ts"],"sourcesContent":["import { Component, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport {\n CardComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n SelectComponent,\n TreeNode,\n TreeSelectComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n buildBranchTreeNodes,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n IBranch,\n ICreateBranchRequest,\n IUpdateBranchRequest,\n} from '../../interfaces/branch.interface';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { BranchApiService } from '../../services/branch-api.service';\nimport { CompanyApiService } from '../../services/company-api.service';\n\nconst BRANCH_FORM_FIELDS = [\n 'id',\n 'companyId',\n 'parentId',\n 'name',\n 'slug',\n 'email',\n 'phone',\n 'address',\n 'isActive',\n 'readOnly',\n];\n\n/** Branch form model interface */\ninterface IBranchFormModel {\n companyId: string;\n parentId: string | null;\n name: string;\n slug: string;\n email: string;\n phone: string;\n address: string;\n isActive: boolean;\n}\n\n/**\n * Branch Form Component\n * Handles creating and editing branches.\n * Defaults to current company context.\n */\n@Component({\n selector: 'lib-branch-form',\n imports: [\n CardComponent,\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n SelectComponent,\n TreeSelectComponent,\n UiIconComponent,\n FormField,\n TranslatePipe,\n ],\n template: `\n <f-card>\n <ng-template #header>\n <div class=\"flex justify-between items-center p-4\">\n <h2 class=\"text-xl font-semibold m-0\">\n {{\n isEditMode()\n ? ('administrative.branch.edit' | translate)\n : ('administrative.branch.new' | translate)\n }}\n </h2>\n </div>\n </ng-template>\n\n <form\n (submit)=\"onSubmit($event)\"\n class=\"grid grid-cols-1 md:grid-cols-2 gap-4\"\n >\n <!-- Company Selection -->\n @if (!isEditMode()) {\n <div class=\"flex flex-col gap-2\">\n <label for=\"companyId\" class=\"font-medium\"\n >{{ 'shared.company' | translate }} *</label\n >\n <f-select\n inputId=\"companyId\"\n [options]=\"companies()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [formField]=\"branchForm.companyId\"\n [placeholder]=\"'administrative.company.select' | translate\"\n />\n </div>\n }\n\n <div class=\"flex flex-col gap-2\">\n <label for=\"parentId\" class=\"font-medium\">{{\n 'administrative.branch.parent' | translate\n }}</label>\n <f-treeselect\n inputId=\"parentId\"\n [options]=\"parentTreeNodes()\"\n [formField]=\"branchForm.parentId\"\n [placeholder]=\"'administrative.branch.select.parent' | translate\"\n [filterPlaceholder]=\"'shared.search' | translate\"\n [emptyMessage]=\"'administrative.branch.no.branches' | translate\"\n [filter]=\"true\"\n [showClear]=\"true\"\n />\n </div>\n\n <!-- Name -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"name\" class=\"font-medium\"\n >{{ 'administrative.branch.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"branchForm.name\"\n (blur)=\"generateSlug()\"\n [placeholder]=\"'administrative.branch.name.placeholder' | translate\"\n />\n </div>\n\n <!-- Slug -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"slug\" class=\"font-medium\"\n >{{ 'administrative.branch.slug' | translate }} *</label\n >\n <input\n fInputText\n id=\"slug\"\n [formField]=\"branchForm.slug\"\n [placeholder]=\"'administrative.branch.slug.placeholder' | translate\"\n />\n </div>\n\n <!-- Email -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"email\" class=\"font-medium\">{{\n 'administrative.email.label' | translate\n }}</label>\n <input\n fInputText\n id=\"email\"\n type=\"email\"\n [formField]=\"branchForm.email\"\n [placeholder]=\"'administrative.email.placeholder' | translate\"\n />\n </div>\n\n <!-- Phone -->\n <div class=\"flex flex-col gap-2\">\n <label for=\"phone\" class=\"font-medium\">{{\n 'administrative.phone.label' | translate\n }}</label>\n <input\n fInputText\n id=\"phone\"\n [formField]=\"branchForm.phone\"\n [placeholder]=\"'administrative.phone.placeholder' | translate\"\n />\n </div>\n\n <!-- Is Active -->\n <div class=\"flex items-center pt-6\">\n <f-checkbox [formField]=\"branchForm.isActive\" [label]=\"'shared.active' | translate\" />\n </div>\n\n <!-- Address -->\n <div class=\"flex flex-col gap-2 md:col-span-2\">\n <label for=\"address\" class=\"font-medium\">{{\n 'administrative.address.label' | translate\n }}</label>\n <textarea\n id=\"address\"\n fInputText\n [formField]=\"branchForm.address\"\n [placeholder]=\"'administrative.address.placeholder' | translate\"\n rows=\"3\"\n ></textarea>\n </div>\n\n <!-- Actions -->\n <div class=\"flex justify-end gap-4 md:col-span-2 pt-4\">\n <button\n fButton\n type=\"button\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (click)=\"navigateToList()\"\n >\n <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>\n </button>\n <button\n fButton\n type=\"submit\"\n [disabled]=\"!isFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ \n isEditMode()\n ? ('shared.update' | translate)\n : ('shared.create' | translate)\n }}</span>\n </button>\n </div>\n </form>\n </f-card>\n `,\n})\nexport class BranchFormComponent {\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly messageService = inject(MessageService);\n private readonly branchService = inject(BranchApiService);\n private readonly companyService = inject(CompanyApiService);\n private readonly authState = inject(AuthStateService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(key: string, vars?: Record<string, unknown>): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n // Route params as signals\n private readonly routeParams = toSignal(this.route.paramMap);\n private readonly queryParams = toSignal(this.route.queryParamMap);\n\n /** Loading state */\n readonly isLoading = signal(false);\n\n /** Existing branch data when editing */\n readonly existingBranch = signal<IBranch | null>(null);\n\n /** Whether in edit mode */\n readonly isEditMode = computed(() => !!this.existingBranch());\n\n /** Companies list for dropdown */\n readonly companies = this.companyService.data;\n\n private readonly companyBranches = signal<IBranch[]>([]);\n\n readonly parentTreeNodes = computed<TreeNode<IBranch>[]>(() =>\n buildBranchTreeNodes(this.companyBranches(), this.existingBranch()?.id),\n );\n\n private readonly selectedCompanyId = computed(() => this.formModel().companyId);\n\n // ============================================\n // Form (Signal Forms)\n // ============================================\n\n /** Form model */\n readonly formModel = signal<IBranchFormModel>({\n companyId: '',\n parentId: null,\n name: '',\n slug: '',\n email: '',\n phone: '',\n address: '',\n isActive: true,\n });\n\n /** Form with validation schema */\n readonly branchForm = form(this.formModel, (f) => {\n required(f.companyId, {\n message: this.translate('auth.validation.company.required'),\n });\n required(f.name, { message: this.translate('shared.name.required') });\n required(f.slug, {\n message: this.translate('administrative.branch.slug.required'),\n });\n });\n\n /** Check if form is valid */\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return (\n model.companyId.trim().length > 0 &&\n model.name.trim().length > 0 &&\n model.slug.trim().length > 0\n );\n });\n\n constructor() {\n // Load companies on initialization\n this.companyService.fetchList('', {\n pagination: { currentPage: 0, pageSize: 100 },\n });\n\n // Effect to handle route-based initialization\n effect(() => {\n const params = this.routeParams();\n const query = this.queryParams();\n if (!params) return;\n\n const id = params.get('id');\n if (id && id !== 'new') {\n this.loadBranch(id);\n } else {\n // Set company from query params or current company\n const queryCompanyId = query?.get('companyId');\n const currentCompanyId = this.authState.company()?.id;\n const companyId = queryCompanyId || currentCompanyId;\n\n const parentId = query?.get('parentId') || null;\n this.formModel.update((m) => ({\n ...m,\n companyId: companyId || m.companyId,\n parentId,\n }));\n }\n });\n\n effect(() => {\n const companyId = this.selectedCompanyId();\n untracked(() => this.loadCompanyBranches(companyId));\n });\n }\n\n private async loadCompanyBranches(companyId: string): Promise<void> {\n this.companyBranches.set([]);\n if (!companyId) return;\n try {\n const response = await this.branchService.getAll({\n filter: { companyId },\n pagination: { currentPage: 0, pageSize: 1000 },\n select: ['id', 'name', 'parentId', 'serial'],\n });\n if (this.selectedCompanyId() !== companyId) return;\n this.companyBranches.set(response?.success ? (response.data ?? []) : []);\n const parentId = this.formModel().parentId;\n if (parentId && !this.companyBranches().some((b) => b.id === parentId)) {\n this.formModel.update((m) => ({ ...m, parentId: null }));\n }\n } catch {\n // Error handled by global interceptor\n }\n }\n\n async loadBranch(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.branchService.findById(id, BRANCH_FORM_FIELDS);\n if (response.success && response.data) {\n this.existingBranch.set(response.data);\n this.formModel.set(this.toFormModel(response.data));\n }\n } catch {\n this.router.navigate(['/administration/branch']);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private toFormModel(branch: IBranch): IBranchFormModel {\n return {\n companyId: branch.companyId,\n parentId: branch.parentId ?? null,\n name: branch.name,\n slug: branch.slug,\n email: branch.email || '',\n phone: branch.phone || '',\n address: branch.address || '',\n isActive: branch.isActive,\n };\n }\n\n generateSlug(): void {\n const model = this.formModel();\n if (!model.slug && model.name) {\n const slug = model.name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n this.formModel.update((m) => ({ ...m, slug }));\n }\n }\n\n async onSubmit(event: Event): Promise<void> {\n event.preventDefault();\n\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n try {\n if (this.isEditMode() && this.existingBranch()) {\n await this.updateBranch();\n } else {\n await this.createBranch();\n }\n this.navigateToList();\n } catch {\n // Error handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n\n private async updateBranch(): Promise<void> {\n const model = this.formModel();\n const updateData: IUpdateBranchRequest = {\n id: this.existingBranch()!.id,\n name: model.name,\n slug: model.slug,\n ...this.buildOptionalFields(model),\n };\n const response = await this.branchService.update(updateData);\n this.onSaveSuccess(\n response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<string, unknown>,\n )\n : response.message,\n );\n }\n\n private async createBranch(): Promise<void> {\n const model = this.formModel();\n const createData: ICreateBranchRequest = {\n companyId: model.companyId,\n name: model.name,\n slug: model.slug,\n ...this.buildOptionalFields(model),\n };\n const response = await this.branchService.insert(createData);\n this.onSaveSuccess(\n response.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<string, string | number>,\n )\n : (response.message ?? ''),\n );\n }\n\n private buildOptionalFields(model: IBranchFormModel) {\n return {\n parentId: model.parentId || null,\n email: model.email || undefined,\n phone: model.phone || undefined,\n address: model.address || undefined,\n isActive: model.isActive,\n };\n }\n\n private onSaveSuccess(message: string): void {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: message,\n });\n }\n\n private getTargetCompanyId(): string | null {\n return (\n this.existingBranch()?.companyId || this.formModel().companyId || null\n );\n }\n\n protected navigateToList(): void {\n const companyId = this.getTargetCompanyId();\n this.router.navigate(['/administration/branch'], {\n queryParams: companyId ? { companyId } : {},\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -135,7 +135,7 @@ var BranchListComponent = class BranchListComponent {
|
|
|
135
135
|
}
|
|
136
136
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
137
137
|
minVersion: "12.0.0",
|
|
138
|
-
version: "22.2.
|
|
138
|
+
version: "22.2.3",
|
|
139
139
|
ngImport: i0,
|
|
140
140
|
type: BranchListComponent,
|
|
141
141
|
deps: [],
|
|
@@ -143,7 +143,7 @@ var BranchListComponent = class BranchListComponent {
|
|
|
143
143
|
});
|
|
144
144
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
145
145
|
minVersion: "17.0.0",
|
|
146
|
-
version: "22.2.
|
|
146
|
+
version: "22.2.3",
|
|
147
147
|
type: BranchListComponent,
|
|
148
148
|
isStandalone: true,
|
|
149
149
|
selector: "lib-branch-list",
|
|
@@ -581,7 +581,7 @@ var BranchListComponent = class BranchListComponent {
|
|
|
581
581
|
};
|
|
582
582
|
i0.ɵɵngDeclareClassMetadata({
|
|
583
583
|
minVersion: "12.0.0",
|
|
584
|
-
version: "22.2.
|
|
584
|
+
version: "22.2.3",
|
|
585
585
|
ngImport: i0,
|
|
586
586
|
type: BranchListComponent,
|
|
587
587
|
decorators: [{
|
|
@@ -772,4 +772,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
772
772
|
});
|
|
773
773
|
export { BranchListComponent };
|
|
774
774
|
|
|
775
|
-
//# sourceMappingURL=flusys-ng-auth-branch-list.component-
|
|
775
|
+
//# sourceMappingURL=flusys-ng-auth-branch-list.component-CP9VFx_8.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-branch-list.component-SeGvWdUO.mjs","names":[],"sources":["../../../projects/ng-auth/utils/branch-tree.utils.ts","../../../projects/ng-auth/pages/branch/branch-list.component.ts"],"sourcesContent":["import {\n buildBranchHierarchy,\n collectBranchDescendantIds,\n filterBranchHierarchy,\n IBranchHierarchyItem,\n} from '@flusys/ng-shared';\nimport { TreeNode } from '@flusys/ng-ui';\nimport { IBranch } from '../interfaces/branch.interface';\n\nfunction matchesSearch(branch: IBranch, term: string): boolean {\n return [branch.name, branch.slug, branch.email, branch.phone].some((v) =>\n v?.toLowerCase().includes(term),\n );\n}\n\nexport function buildBranchTree(\n branches: IBranch[],\n search = '',\n): TreeNode<IBranch>[] {\n const term = search.trim().toLowerCase();\n const hierarchy = buildBranchHierarchy(branches);\n const items = term\n ? filterBranchHierarchy(hierarchy, (branch) => matchesSearch(branch, term))\n : hierarchy;\n\n const convert = (list: IBranchHierarchyItem<IBranch>[]): TreeNode<IBranch>[] =>\n list.map(({ data, children }) => {\n const childNodes = convert(children);\n return {\n key: data.id,\n data,\n children: childNodes,\n leaf: !childNodes.length,\n expanded: !!term && childNodes.length > 0,\n };\n });\n\n return convert(items);\n}\n\nexport function countBranchDescendants(\n branches: IBranch[],\n branchId: string,\n): number {\n return collectBranchDescendantIds(branches, branchId).length;\n}\n","import { Component, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { FormsModule } from '@angular/forms';\nimport {\n BRANCH_PERMISSIONS,\n HasPermissionDirective,\n TranslatePipe,\n TranslateService,\n USER_PERMISSIONS,\n} from '@flusys/ng-shared';\nimport {\n CardComponent,\n ConfirmationService,\n FButtonDirective,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n MessageService,\n SelectComponent,\n TagComponent,\n TooltipDirective,\n TreeNode,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { BranchPermittedUsersDialogComponent } from '../../components/branch-permitted-users-dialog.component';\nimport { IBranch } from '../../interfaces/branch.interface';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { BranchApiService } from '../../services/branch-api.service';\nimport { CompanyApiService } from '../../services/company-api.service';\nimport {\n buildBranchTree,\n countBranchDescendants,\n} from '../../utils/branch-tree.utils';\n\nconst BRANCH_FETCH_LIMIT = 1000;\n\n@Component({\n selector: 'lib-branch-list',\n imports: [\n FormsModule,\n CardComponent,\n FButtonDirective,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n SelectComponent,\n TagComponent,\n TooltipDirective,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n HasPermissionDirective,\n BranchPermittedUsersDialogComponent,\n TranslatePipe,\n ],\n template: `\n <f-card>\n <ng-template #header>\n <div\n class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-4\"\n >\n <div\n class=\"flex flex-col sm:flex-row items-start sm:items-center gap-3 sm:gap-4 w-full sm:w-auto\"\n >\n <h2 class=\"text-xl font-semibold m-0\">\n {{ 'administrative.branch.title' | translate }}\n </h2>\n @if (companies().length > 1) {\n <f-select\n [options]=\"companies()\"\n [ngModel]=\"selectedCompanyId()\"\n (ngModelChange)=\"\n selectedCompanyId.set($event); loadBranches()\n \"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'administrative.company.select' | translate\"\n styleClass=\"w-full sm:w-64\"\n />\n }\n </div>\n <div class=\"flex items-center gap-3 w-full sm:w-auto\">\n <f-iconfield class=\"w-full sm:w-64\">\n <f-inputicon icon=\"search\" />\n <input\n fInputText\n type=\"text\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchChange($event)\"\n [placeholder]=\"'shared.search' | translate\"\n />\n </f-iconfield>\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.CREATE\"\n [disabled]=\"!selectedCompanyId()\"\n (click)=\"onCreate()\"\n >\n <ui-icon pButtonIcon name=\"plus\"></ui-icon>\n <span pButtonLabel>{{\n 'administrative.branch.add' | translate\n }}</span>\n </button>\n </div>\n </div>\n </ng-template>\n\n <div class=\"overflow-x-auto\">\n <f-treetable\n [value]=\"treeNodes()\"\n [loading]=\"isLoading()\"\n dataKey=\"id\"\n [tableStyle]=\"{ 'min-width': '50rem' }\"\n >\n <ng-template #header>\n <tr>\n <th>{{ 'administrative.branch.name' | translate }}</th>\n <th>{{ 'administrative.branch.slug' | translate }}</th>\n <th>{{ 'administrative.email.label' | translate }}</th>\n <th>{{ 'administrative.phone.label' | translate }}</th>\n <th>{{ 'shared.status' | translate }}</th>\n <th class=\"w-[160px]\">{{ 'shared.actions' | translate }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-rowNode let-branch=\"rowData\">\n <tr>\n <td>\n <f-treetabletoggler [rowNode]=\"rowNode\" />\n {{ branch.name }}\n </td>\n <td>{{ branch.slug }}</td>\n <td>{{ branch.email || '-' }}</td>\n <td>{{ branch.phone || '-' }}</td>\n <td>\n <f-tag\n [value]=\"\n branch.isActive\n ? ('shared.active' | translate)\n : ('shared.inactive' | translate)\n \"\n [severity]=\"branch.isActive ? 'success' : 'danger'\"\n />\n </td>\n <td>\n <div class=\"flex gap-2\">\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.CREATE\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"success\"\n [fTooltip]=\"'administrative.branch.add.child' | translate\"\n (click)=\"onAddChild(branch)\"\n >\n <ui-icon pButtonIcon name=\"git-branch-plus\"></ui-icon>\n </button>\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.UPDATE\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"info\"\n [fTooltip]=\"'shared.edit' | translate\"\n (click)=\"onEdit(branch)\"\n >\n <ui-icon pButtonIcon name=\"pencil\"></ui-icon>\n </button>\n <button\n fButton\n *hasPermission=\"USER_PERMISSIONS.READ\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"secondary\"\n [fTooltip]=\"'administrative.permission.view.users' | translate\"\n (click)=\"onViewUsers(branch)\"\n >\n <ui-icon pButtonIcon name=\"users\"></ui-icon>\n </button>\n @if (!branch.readOnly) {\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.DELETE\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"danger\"\n [fTooltip]=\"'shared.delete' | translate\"\n (click)=\"onDelete(branch)\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n }\n </div>\n </td>\n </tr>\n </ng-template>\n <ng-template #emptymessage>\n <tr>\n <td colspan=\"6\" class=\"text-center py-8\">\n @if (!selectedCompanyId()) {\n {{ 'administrative.branch.select.company.first' | translate }}\n } @else {\n {{ 'administrative.branch.no.branches' | translate }}\n }\n </td>\n </tr>\n </ng-template>\n </f-treetable>\n </div>\n </f-card>\n\n <lib-branch-permitted-users-dialog\n [visible]=\"permittedUsersDialogVisible()\"\n [branch]=\"selectedBranch()\"\n (closed)=\"permittedUsersDialogVisible.set(false)\"\n />\n `,\n})\nexport class BranchListComponent {\n // Permission constants for template\n readonly BRANCH_PERMISSIONS = BRANCH_PERMISSIONS;\n readonly USER_PERMISSIONS = USER_PERMISSIONS;\n\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly messageService = inject(MessageService);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly branchService = inject(BranchApiService);\n private readonly companyService = inject(CompanyApiService);\n private readonly authState = inject(AuthStateService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(key: string, vars?: Record<string, unknown>): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n private readonly queryParamMap = toSignal(this.route.queryParamMap);\n private initialized = false;\n\n /** Selected company ID (signal for zoneless change detection) */\n readonly selectedCompanyId = signal<string | null>(null);\n\n /** Companies list for dropdown */\n readonly companies = this.companyService.data;\n\n readonly isLoading = this.branchService.isLoading;\n\n readonly permittedUsersDialogVisible = signal(false);\n readonly selectedBranch = signal<IBranch | null>(null);\n\n private readonly _searchTerm = signal('');\n readonly searchTerm = this._searchTerm.asReadonly();\n\n readonly treeNodes = computed<TreeNode<IBranch>[]>(() =>\n buildBranchTree(this.branchService.data(), this._searchTerm()),\n );\n\n constructor() {\n effect(() => {\n const params = this.queryParamMap();\n if (this.initialized) return;\n\n this.initialized = true;\n\n // Use untracked to avoid nested effect error when initializing resources\n untracked(() => {\n this.companyService.fetchList('', {\n pagination: { currentPage: 0, pageSize: 100 },\n });\n\n const queryCompanyId = params?.get('companyId') || null;\n const currentCompanyId = this.authState.company()?.id;\n const companyId = queryCompanyId || currentCompanyId || null;\n\n this.selectedCompanyId.set(companyId);\n\n if (companyId) {\n this.loadBranches();\n }\n });\n });\n }\n\n loadBranches(): void {\n const companyId = this.selectedCompanyId();\n if (!companyId) return;\n\n this.branchService.fetchList('', {\n filter: { companyId },\n pagination: { currentPage: 0, pageSize: BRANCH_FETCH_LIMIT },\n });\n }\n\n onSearchChange(value: string): void {\n this._searchTerm.set(value);\n }\n\n onCreate(): void {\n this.router.navigate(['/administration/branch/new'], {\n queryParams: { companyId: this.selectedCompanyId() },\n });\n }\n\n onAddChild(branch: IBranch): void {\n this.router.navigate(['/administration/branch/new'], {\n queryParams: { companyId: this.selectedCompanyId(), parentId: branch.id },\n });\n }\n\n onEdit(branch: IBranch): void {\n this.router.navigate(['/administration/branch', branch.id]);\n }\n\n onViewUsers(branch: IBranch): void {\n this.selectedBranch.set(branch);\n this.permittedUsersDialogVisible.set(true);\n }\n\n onDelete(branch: IBranch): void {\n const descendantCount = countBranchDescendants(\n this.branchService.data(),\n branch.id,\n );\n this.confirmationService.confirm({\n message: descendantCount\n ? this.translate('administrative.branch.confirm.delete.with.children', {\n name: branch.name,\n count: descendantCount,\n })\n : this.translate('shared.confirm.delete.item', { name: branch.name }),\n header: this.translate('administrative.branch.delete.title'),\n icon: 'exclamation-triangle',\n acceptButtonStyleClass: 'p-button-danger',\n accept: async () => {\n try {\n const response = await this.branchService.delete({\n id: branch.id,\n type: 'permanent',\n });\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response?.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<string, unknown>,\n )\n : response?.message,\n });\n this.branchService.reload();\n } catch {\n // Error toast handled by global interceptor\n }\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-branch-list.component-CP9VFx_8.mjs","names":[],"sources":["../../../projects/ng-auth/utils/branch-tree.utils.ts","../../../projects/ng-auth/pages/branch/branch-list.component.ts"],"sourcesContent":["import {\n buildBranchHierarchy,\n collectBranchDescendantIds,\n filterBranchHierarchy,\n IBranchHierarchyItem,\n} from '@flusys/ng-shared';\nimport { TreeNode } from '@flusys/ng-ui';\nimport { IBranch } from '../interfaces/branch.interface';\n\nfunction matchesSearch(branch: IBranch, term: string): boolean {\n return [branch.name, branch.slug, branch.email, branch.phone].some((v) =>\n v?.toLowerCase().includes(term),\n );\n}\n\nexport function buildBranchTree(\n branches: IBranch[],\n search = '',\n): TreeNode<IBranch>[] {\n const term = search.trim().toLowerCase();\n const hierarchy = buildBranchHierarchy(branches);\n const items = term\n ? filterBranchHierarchy(hierarchy, (branch) => matchesSearch(branch, term))\n : hierarchy;\n\n const convert = (list: IBranchHierarchyItem<IBranch>[]): TreeNode<IBranch>[] =>\n list.map(({ data, children }) => {\n const childNodes = convert(children);\n return {\n key: data.id,\n data,\n children: childNodes,\n leaf: !childNodes.length,\n expanded: !!term && childNodes.length > 0,\n };\n });\n\n return convert(items);\n}\n\nexport function countBranchDescendants(\n branches: IBranch[],\n branchId: string,\n): number {\n return collectBranchDescendantIds(branches, branchId).length;\n}\n","import { Component, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { FormsModule } from '@angular/forms';\nimport {\n BRANCH_PERMISSIONS,\n HasPermissionDirective,\n TranslatePipe,\n TranslateService,\n USER_PERMISSIONS,\n} from '@flusys/ng-shared';\nimport {\n CardComponent,\n ConfirmationService,\n FButtonDirective,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n MessageService,\n SelectComponent,\n TagComponent,\n TooltipDirective,\n TreeNode,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { BranchPermittedUsersDialogComponent } from '../../components/branch-permitted-users-dialog.component';\nimport { IBranch } from '../../interfaces/branch.interface';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { BranchApiService } from '../../services/branch-api.service';\nimport { CompanyApiService } from '../../services/company-api.service';\nimport {\n buildBranchTree,\n countBranchDescendants,\n} from '../../utils/branch-tree.utils';\n\nconst BRANCH_FETCH_LIMIT = 1000;\n\n@Component({\n selector: 'lib-branch-list',\n imports: [\n FormsModule,\n CardComponent,\n FButtonDirective,\n IconFieldComponent,\n InputIconComponent,\n InputTextDirective,\n SelectComponent,\n TagComponent,\n TooltipDirective,\n TreeTableComponent,\n TreeTableTogglerComponent,\n UiIconComponent,\n HasPermissionDirective,\n BranchPermittedUsersDialogComponent,\n TranslatePipe,\n ],\n template: `\n <f-card>\n <ng-template #header>\n <div\n class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-4\"\n >\n <div\n class=\"flex flex-col sm:flex-row items-start sm:items-center gap-3 sm:gap-4 w-full sm:w-auto\"\n >\n <h2 class=\"text-xl font-semibold m-0\">\n {{ 'administrative.branch.title' | translate }}\n </h2>\n @if (companies().length > 1) {\n <f-select\n [options]=\"companies()\"\n [ngModel]=\"selectedCompanyId()\"\n (ngModelChange)=\"\n selectedCompanyId.set($event); loadBranches()\n \"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'administrative.company.select' | translate\"\n styleClass=\"w-full sm:w-64\"\n />\n }\n </div>\n <div class=\"flex items-center gap-3 w-full sm:w-auto\">\n <f-iconfield class=\"w-full sm:w-64\">\n <f-inputicon icon=\"search\" />\n <input\n fInputText\n type=\"text\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchChange($event)\"\n [placeholder]=\"'shared.search' | translate\"\n />\n </f-iconfield>\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.CREATE\"\n [disabled]=\"!selectedCompanyId()\"\n (click)=\"onCreate()\"\n >\n <ui-icon pButtonIcon name=\"plus\"></ui-icon>\n <span pButtonLabel>{{\n 'administrative.branch.add' | translate\n }}</span>\n </button>\n </div>\n </div>\n </ng-template>\n\n <div class=\"overflow-x-auto\">\n <f-treetable\n [value]=\"treeNodes()\"\n [loading]=\"isLoading()\"\n dataKey=\"id\"\n [tableStyle]=\"{ 'min-width': '50rem' }\"\n >\n <ng-template #header>\n <tr>\n <th>{{ 'administrative.branch.name' | translate }}</th>\n <th>{{ 'administrative.branch.slug' | translate }}</th>\n <th>{{ 'administrative.email.label' | translate }}</th>\n <th>{{ 'administrative.phone.label' | translate }}</th>\n <th>{{ 'shared.status' | translate }}</th>\n <th class=\"w-[160px]\">{{ 'shared.actions' | translate }}</th>\n </tr>\n </ng-template>\n <ng-template #body let-rowNode let-branch=\"rowData\">\n <tr>\n <td>\n <f-treetabletoggler [rowNode]=\"rowNode\" />\n {{ branch.name }}\n </td>\n <td>{{ branch.slug }}</td>\n <td>{{ branch.email || '-' }}</td>\n <td>{{ branch.phone || '-' }}</td>\n <td>\n <f-tag\n [value]=\"\n branch.isActive\n ? ('shared.active' | translate)\n : ('shared.inactive' | translate)\n \"\n [severity]=\"branch.isActive ? 'success' : 'danger'\"\n />\n </td>\n <td>\n <div class=\"flex gap-2\">\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.CREATE\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"success\"\n [fTooltip]=\"'administrative.branch.add.child' | translate\"\n (click)=\"onAddChild(branch)\"\n >\n <ui-icon pButtonIcon name=\"git-branch-plus\"></ui-icon>\n </button>\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.UPDATE\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"info\"\n [fTooltip]=\"'shared.edit' | translate\"\n (click)=\"onEdit(branch)\"\n >\n <ui-icon pButtonIcon name=\"pencil\"></ui-icon>\n </button>\n <button\n fButton\n *hasPermission=\"USER_PERMISSIONS.READ\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"secondary\"\n [fTooltip]=\"'administrative.permission.view.users' | translate\"\n (click)=\"onViewUsers(branch)\"\n >\n <ui-icon pButtonIcon name=\"users\"></ui-icon>\n </button>\n @if (!branch.readOnly) {\n <button\n fButton\n *hasPermission=\"BRANCH_PERMISSIONS.DELETE\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"danger\"\n [fTooltip]=\"'shared.delete' | translate\"\n (click)=\"onDelete(branch)\"\n >\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n </button>\n }\n </div>\n </td>\n </tr>\n </ng-template>\n <ng-template #emptymessage>\n <tr>\n <td colspan=\"6\" class=\"text-center py-8\">\n @if (!selectedCompanyId()) {\n {{ 'administrative.branch.select.company.first' | translate }}\n } @else {\n {{ 'administrative.branch.no.branches' | translate }}\n }\n </td>\n </tr>\n </ng-template>\n </f-treetable>\n </div>\n </f-card>\n\n <lib-branch-permitted-users-dialog\n [visible]=\"permittedUsersDialogVisible()\"\n [branch]=\"selectedBranch()\"\n (closed)=\"permittedUsersDialogVisible.set(false)\"\n />\n `,\n})\nexport class BranchListComponent {\n // Permission constants for template\n readonly BRANCH_PERMISSIONS = BRANCH_PERMISSIONS;\n readonly USER_PERMISSIONS = USER_PERMISSIONS;\n\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n private readonly messageService = inject(MessageService);\n private readonly confirmationService = inject(ConfirmationService);\n private readonly branchService = inject(BranchApiService);\n private readonly companyService = inject(CompanyApiService);\n private readonly authState = inject(AuthStateService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(key: string, vars?: Record<string, unknown>): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n private readonly queryParamMap = toSignal(this.route.queryParamMap);\n private initialized = false;\n\n /** Selected company ID (signal for zoneless change detection) */\n readonly selectedCompanyId = signal<string | null>(null);\n\n /** Companies list for dropdown */\n readonly companies = this.companyService.data;\n\n readonly isLoading = this.branchService.isLoading;\n\n readonly permittedUsersDialogVisible = signal(false);\n readonly selectedBranch = signal<IBranch | null>(null);\n\n private readonly _searchTerm = signal('');\n readonly searchTerm = this._searchTerm.asReadonly();\n\n readonly treeNodes = computed<TreeNode<IBranch>[]>(() =>\n buildBranchTree(this.branchService.data(), this._searchTerm()),\n );\n\n constructor() {\n effect(() => {\n const params = this.queryParamMap();\n if (this.initialized) return;\n\n this.initialized = true;\n\n // Use untracked to avoid nested effect error when initializing resources\n untracked(() => {\n this.companyService.fetchList('', {\n pagination: { currentPage: 0, pageSize: 100 },\n });\n\n const queryCompanyId = params?.get('companyId') || null;\n const currentCompanyId = this.authState.company()?.id;\n const companyId = queryCompanyId || currentCompanyId || null;\n\n this.selectedCompanyId.set(companyId);\n\n if (companyId) {\n this.loadBranches();\n }\n });\n });\n }\n\n loadBranches(): void {\n const companyId = this.selectedCompanyId();\n if (!companyId) return;\n\n this.branchService.fetchList('', {\n filter: { companyId },\n pagination: { currentPage: 0, pageSize: BRANCH_FETCH_LIMIT },\n });\n }\n\n onSearchChange(value: string): void {\n this._searchTerm.set(value);\n }\n\n onCreate(): void {\n this.router.navigate(['/administration/branch/new'], {\n queryParams: { companyId: this.selectedCompanyId() },\n });\n }\n\n onAddChild(branch: IBranch): void {\n this.router.navigate(['/administration/branch/new'], {\n queryParams: { companyId: this.selectedCompanyId(), parentId: branch.id },\n });\n }\n\n onEdit(branch: IBranch): void {\n this.router.navigate(['/administration/branch', branch.id]);\n }\n\n onViewUsers(branch: IBranch): void {\n this.selectedBranch.set(branch);\n this.permittedUsersDialogVisible.set(true);\n }\n\n onDelete(branch: IBranch): void {\n const descendantCount = countBranchDescendants(\n this.branchService.data(),\n branch.id,\n );\n this.confirmationService.confirm({\n message: descendantCount\n ? this.translate('administrative.branch.confirm.delete.with.children', {\n name: branch.name,\n count: descendantCount,\n })\n : this.translate('shared.confirm.delete.item', { name: branch.name }),\n header: this.translate('administrative.branch.delete.title'),\n icon: 'exclamation-triangle',\n acceptButtonStyleClass: 'p-button-danger',\n accept: async () => {\n try {\n const response = await this.branchService.delete({\n id: branch.id,\n type: 'permanent',\n });\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response?.messageKey\n ? this.translate(\n response.messageKey,\n response.messageVariables as Record<string, unknown>,\n )\n : response?.message,\n });\n this.branchService.reload();\n } catch {\n // Error toast handled by global interceptor\n }\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -93,7 +93,7 @@ var CompanyFormComponent = class CompanyFormComponent {
|
|
|
93
93
|
}
|
|
94
94
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
95
95
|
minVersion: "12.0.0",
|
|
96
|
-
version: "22.2.
|
|
96
|
+
version: "22.2.3",
|
|
97
97
|
ngImport: i0,
|
|
98
98
|
type: CompanyFormComponent,
|
|
99
99
|
deps: [],
|
|
@@ -101,7 +101,7 @@ var CompanyFormComponent = class CompanyFormComponent {
|
|
|
101
101
|
});
|
|
102
102
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
103
103
|
minVersion: "17.2.0",
|
|
104
|
-
version: "22.2.
|
|
104
|
+
version: "22.2.3",
|
|
105
105
|
type: CompanyFormComponent,
|
|
106
106
|
isStandalone: true,
|
|
107
107
|
selector: "lib-company-form",
|
|
@@ -164,7 +164,7 @@ var CompanyFormComponent = class CompanyFormComponent {
|
|
|
164
164
|
};
|
|
165
165
|
i0.ɵɵngDeclareClassMetadata({
|
|
166
166
|
minVersion: "12.0.0",
|
|
167
|
-
version: "22.2.
|
|
167
|
+
version: "22.2.3",
|
|
168
168
|
ngImport: i0,
|
|
169
169
|
type: CompanyFormComponent,
|
|
170
170
|
decorators: [{
|
|
@@ -195,4 +195,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
195
195
|
});
|
|
196
196
|
export { CompanyFormComponent };
|
|
197
197
|
|
|
198
|
-
//# sourceMappingURL=flusys-ng-auth-company-form.component-
|
|
198
|
+
//# sourceMappingURL=flusys-ng-auth-company-form.component-C1HXjgn-.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-company-form.component-
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-company-form.component-C1HXjgn-.mjs","names":[],"sources":["../../../projects/ng-auth/pages/company/company-form.component.ts"],"sourcesContent":["import { Component, computed, inject, viewChild } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute } from '@angular/router';\nimport {\n BaseFormComponent,\n IFormField,\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { ICompany } from '../../interfaces/company.interface';\nimport { CompanyApiService } from '../../services/company-api.service';\n\n@Component({\n selector: 'lib-company-form',\n imports: [BaseFormComponent, TranslatePipe],\n template: `\n <lib-base-form\n [fields]=\"fields\"\n [service]=\"companyService\"\n [editId]=\"editId()\"\n [cancelRoute]=\"'/administration/company'\"\n [navigateOnSuccess]=\"'/administration/company'\"\n [createTitle]=\"'administrative.company.new' | translate\"\n [editTitle]=\"'administrative.company.edit' | translate\"\n [mapToRequest]=\"buildRequest\"\n [mapFromEntity]=\"toFormModel\"\n (onValueChange)=\"onFormValueChange($event)\"\n />\n `,\n})\nexport class CompanyFormComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly translateAdapter = inject(TranslateService, { optional: true });\n\n readonly companyService = inject(CompanyApiService);\n readonly formRef = viewChild(BaseFormComponent);\n\n private readonly routeParams = toSignal(this.route.paramMap);\n\n readonly editId = computed(() => {\n const id = this.routeParams()?.get('id');\n return id && id !== 'new' ? id : null;\n });\n\n readonly fields: IFormField[] = [\n {\n key: 'name',\n type: 'text',\n label: this.t('administrative.company.name'),\n placeholder: this.t('administrative.company.name.placeholder'),\n required: true,\n },\n {\n key: 'slug',\n type: 'text',\n label: this.t('administrative.company.slug'),\n placeholder: this.t('administrative.company.slug.placeholder'),\n required: true,\n },\n {\n key: 'email',\n type: 'email',\n label: this.t('administrative.email.label'),\n placeholder: this.t('administrative.email.placeholder'),\n },\n {\n key: 'phone',\n type: 'text',\n label: this.t('administrative.phone.label'),\n placeholder: this.t('administrative.phone.placeholder'),\n },\n {\n key: 'website',\n type: 'text',\n label: this.t('administrative.company.website'),\n placeholder: this.t('administrative.company.website.placeholder'),\n },\n {\n key: 'isActive',\n type: 'toggle',\n label: this.t('shared.active'),\n },\n {\n key: 'address',\n type: 'textarea',\n label: this.t('administrative.address.label'),\n placeholder: this.t('administrative.address.placeholder'),\n fullWidth: true,\n rows: 3,\n },\n ];\n\n readonly buildRequest = (data: Record<string, unknown>, editId: string | null): unknown => ({\n ...(editId ? { id: editId } : {}),\n name: data['name'] as string,\n slug: data['slug'] as string,\n email: (data['email'] as string) || undefined,\n phone: (data['phone'] as string) || undefined,\n website: (data['website'] as string) || undefined,\n address: (data['address'] as string) || undefined,\n isActive: data['isActive'] as boolean,\n });\n\n readonly toFormModel = (entity: unknown): Record<string, unknown> => {\n const c = entity as ICompany;\n return {\n name: c.name,\n slug: c.slug,\n email: c.email ?? '',\n phone: c.phone ?? '',\n website: c.website ?? '',\n address: c.address ?? '',\n isActive: c.isActive,\n };\n };\n\n onFormValueChange(data: Record<string, unknown>): void {\n const name = (data['name'] as string) ?? '';\n const slug = (data['slug'] as string) ?? '';\n if (name && !slug) {\n this.formRef()?.setFieldValue(\n 'slug',\n name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''),\n );\n }\n }\n\n private t(key: string, vars?: Record<string, string | number>): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n}\n"],"mappings":"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"}
|
|
@@ -65,7 +65,7 @@ var CompanyListComponent = class CompanyListComponent {
|
|
|
65
65
|
}
|
|
66
66
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
67
67
|
minVersion: "12.0.0",
|
|
68
|
-
version: "22.2.
|
|
68
|
+
version: "22.2.3",
|
|
69
69
|
ngImport: i0,
|
|
70
70
|
type: CompanyListComponent,
|
|
71
71
|
deps: [],
|
|
@@ -73,7 +73,7 @@ var CompanyListComponent = class CompanyListComponent {
|
|
|
73
73
|
});
|
|
74
74
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
75
75
|
minVersion: "14.0.0",
|
|
76
|
-
version: "22.2.
|
|
76
|
+
version: "22.2.3",
|
|
77
77
|
type: CompanyListComponent,
|
|
78
78
|
isStandalone: true,
|
|
79
79
|
selector: "lib-company-list",
|
|
@@ -185,7 +185,7 @@ var CompanyListComponent = class CompanyListComponent {
|
|
|
185
185
|
};
|
|
186
186
|
i0.ɵɵngDeclareClassMetadata({
|
|
187
187
|
minVersion: "12.0.0",
|
|
188
|
-
version: "22.2.
|
|
188
|
+
version: "22.2.3",
|
|
189
189
|
ngImport: i0,
|
|
190
190
|
type: CompanyListComponent,
|
|
191
191
|
decorators: [{
|
|
@@ -238,4 +238,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
238
238
|
});
|
|
239
239
|
export { CompanyListComponent };
|
|
240
240
|
|
|
241
|
-
//# sourceMappingURL=flusys-ng-auth-company-list.component-
|
|
241
|
+
//# sourceMappingURL=flusys-ng-auth-company-list.component-jkyaG-hS.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-company-list.component-
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-company-list.component-jkyaG-hS.mjs","names":[],"sources":["../../../projects/ng-auth/pages/company/company-list.component.ts"],"sourcesContent":["import { Component, computed, inject, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport {\n BaseListComponent,\n BaseListTemplateDirective,\n BRANCH_PERMISSIONS,\n COMPANY_PERMISSIONS,\n ITableAction,\n ITableColumn,\n PermissionValidatorService,\n TranslatePipe,\n TranslateService,\n USER_PERMISSIONS,\n} from '@flusys/ng-shared';\nimport { TagComponent } from '@flusys/ng-ui';\nimport { CompanyPermittedUsersDialogComponent } from '../../components/company-permitted-users-dialog.component';\nimport { ICompany } from '../../interfaces/company.interface';\nimport { CompanyApiService } from '../../services/company-api.service';\n\n@Component({\n selector: 'lib-company-list',\n imports: [\n BaseListComponent,\n BaseListTemplateDirective,\n TagComponent,\n CompanyPermittedUsersDialogComponent,\n TranslatePipe,\n ],\n template: `\n <lib-base-list\n [columns]=\"columns\"\n [actions]=\"rowActions\"\n [service]=\"companyService\"\n [title]=\"'administrative.company.title' | translate\"\n [searchable]=\"true\"\n [showCreateButton]=\"canCreate()\"\n [createButtonLabel]=\"'administrative.company.add' | translate\"\n [createRoute]=\"'/administration/company/new'\"\n [editRoute]=\"'/administration/company'\"\n [deleteConfirmField]=\"'name'\"\n [deleteType]=\"'permanent'\"\n [canEdit]=\"canEditFn\"\n [canDelete]=\"canDeleteFn\"\n >\n <ng-template baseListTemplate=\"isActive\" let-item>\n <f-tag\n [value]=\"\n asCompany(item).isActive\n ? ('shared.active' | translate)\n : ('shared.inactive' | translate)\n \"\n [severity]=\"asCompany(item).isActive ? 'success' : 'danger'\"\n />\n </ng-template>\n </lib-base-list>\n\n <lib-company-permitted-users-dialog\n [visible]=\"permittedUsersDialogVisible()\"\n [company]=\"selectedCompany()\"\n (closed)=\"permittedUsersDialogVisible.set(false)\"\n />\n `,\n})\nexport class CompanyListComponent {\n private readonly permissionValidator = inject(PermissionValidatorService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n private readonly router = inject(Router);\n\n readonly companyService = inject(CompanyApiService);\n\n readonly canCreate = computed(() =>\n this.permissionValidator.hasPermission(COMPANY_PERMISSIONS.CREATE),\n );\n readonly canEditFn = (_item: unknown) =>\n this.permissionValidator.hasPermission(COMPANY_PERMISSIONS.UPDATE);\n readonly canDeleteFn = (item: unknown) =>\n !(item as ICompany).readOnly &&\n this.permissionValidator.hasPermission(COMPANY_PERMISSIONS.DELETE);\n\n readonly permittedUsersDialogVisible = signal(false);\n readonly selectedCompany = signal<ICompany | null>(null);\n\n readonly rowActions: ITableAction[] = [\n {\n icon: 'building',\n tooltip: 'administrative.branch.view.branches',\n severity: 'secondary',\n show: () =>\n this.permissionValidator.hasPermission(BRANCH_PERMISSIONS.READ),\n handler: (c) =>\n this.router.navigate(['/administration/branch'], {\n queryParams: { companyId: (c as ICompany).id },\n }),\n },\n {\n icon: 'users',\n tooltip: 'administrative.permission.view.users',\n severity: 'secondary',\n show: () => this.permissionValidator.hasPermission(USER_PERMISSIONS.READ),\n handler: (c) => {\n this.selectedCompany.set(c as ICompany);\n this.permittedUsersDialogVisible.set(true);\n },\n },\n ];\n\n readonly columns: ITableColumn[] = [\n {\n field: 'name',\n header: this.t('administrative.company.name'),\n type: 'text',\n },\n {\n field: 'slug',\n header: this.t('administrative.company.slug'),\n type: 'text',\n },\n {\n field: 'email',\n header: this.t('administrative.email.label'),\n type: 'text',\n },\n {\n field: 'phone',\n header: this.t('administrative.phone.label'),\n type: 'text',\n },\n { field: 'isActive', header: this.t('shared.status'), type: 'custom' },\n ];\n\n asCompany(item: unknown): ICompany {\n return item as ICompany;\n }\n\n private t(key: string): string {\n return this.translateAdapter?.translate(key) ?? key;\n }\n}\n"],"mappings":"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"}
|
|
@@ -50,7 +50,7 @@ var ForgotPasswordPageComponent = class ForgotPasswordPageComponent {
|
|
|
50
50
|
}
|
|
51
51
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
52
52
|
minVersion: "12.0.0",
|
|
53
|
-
version: "22.2.
|
|
53
|
+
version: "22.2.3",
|
|
54
54
|
ngImport: i0,
|
|
55
55
|
type: ForgotPasswordPageComponent,
|
|
56
56
|
deps: [],
|
|
@@ -58,7 +58,7 @@ var ForgotPasswordPageComponent = class ForgotPasswordPageComponent {
|
|
|
58
58
|
});
|
|
59
59
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
60
60
|
minVersion: "17.0.0",
|
|
61
|
-
version: "22.2.
|
|
61
|
+
version: "22.2.3",
|
|
62
62
|
type: ForgotPasswordPageComponent,
|
|
63
63
|
isStandalone: true,
|
|
64
64
|
selector: "lib-forgot-password-page",
|
|
@@ -257,7 +257,7 @@ var ForgotPasswordPageComponent = class ForgotPasswordPageComponent {
|
|
|
257
257
|
};
|
|
258
258
|
i0.ɵɵngDeclareClassMetadata({
|
|
259
259
|
minVersion: "12.0.0",
|
|
260
|
-
version: "22.2.
|
|
260
|
+
version: "22.2.3",
|
|
261
261
|
ngImport: i0,
|
|
262
262
|
type: ForgotPasswordPageComponent,
|
|
263
263
|
decorators: [{
|
|
@@ -381,4 +381,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
381
381
|
});
|
|
382
382
|
export { ForgotPasswordPageComponent };
|
|
383
383
|
|
|
384
|
-
//# sourceMappingURL=flusys-ng-auth-forgot-password-page.component-
|
|
384
|
+
//# sourceMappingURL=flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-forgot-password-page.component-
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs","names":[],"sources":["../../../projects/ng-auth/pages/forgot-password/forgot-password-page.component.ts"],"sourcesContent":["import { Component, computed, DestroyRef, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport {\n email as emailValidator,\n form,\n FormField,\n required,\n} from '@angular/forms/signals';\nimport { RouterLink } from '@angular/router';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport { FButtonDirective, InputTextDirective, MessageService, UiIconComponent } from '@flusys/ng-ui';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { finalize, tap } from 'rxjs';\nimport { AuthApiService } from '../../services/auth-api.service';\n\ninterface IForgotPasswordFormModel {\n email: string;\n}\n\n@Component({\n selector: 'lib-forgot-password-page',\n imports: [\n RouterLink,\n FButtonDirective,\n InputTextDirective,\n UiIconComponent,\n FormField,\n AppFloatingConfigurator,\n TranslatePipe,\n ],\n template: `\n <app-floating-configurator />\n <div\n class=\"bg-surface-ground flex items-center justify-center min-h-screen\"\n >\n <div\n class=\"flex flex-col items-center justify-center w-full max-w-[32rem] px-4\"\n >\n <div\n class=\"w-full\"\n style=\"border-radius: var(--f-content-border-radius); padding: 0.3rem; background: linear-gradient(180deg, var(--primary-color) 10%, rgba(33, 150, 243, 0) 30%)\"\n >\n <div\n class=\"w-full py-8 px-4 sm:py-12 sm:px-8 md:py-16 md:px-12\"\n style=\"border-radius: var(--f-content-border-radius); background: var(--f-content-background)\"\n >\n @if (!emailSent()) {\n <div class=\"text-center mb-8\">\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.forgot.password.title' | translate }}\n </div>\n <span class=\"text-muted-color font-medium\">\n {{ 'auth.forgot.password.subtitle' | translate }}\n </span>\n </div>\n\n <form (submit)=\"onSubmit($event)\">\n <label\n for=\"email\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.email.label' | translate }}\n </label>\n <input\n fInputText\n id=\"email\"\n type=\"email\"\n [placeholder]=\"'auth.email.placeholder' | translate\"\n class=\"w-full mb-6\"\n [formField]=\"forgotForm.email\"\n autocomplete=\"email\"\n />\n\n <button\n fButton\n class=\"w-full mb-4\"\n type=\"submit\"\n [disabled]=\"!isFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'auth.forgot.password.send.reset.link' | translate }}</span>\n </button>\n\n <div class=\"flex items-center justify-center gap-2\">\n <span class=\"font-medium\">{{\n 'auth.forgot.password.remember.password' | translate\n }}</span>\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.sign.in' | translate }}\n </a>\n </div>\n </form>\n } @else {\n <div class=\"text-center\">\n <div class=\"flex justify-center mb-6\">\n <ui-icon name=\"envelope\" class=\"text-6xl text-primary\"></ui-icon>\n </div>\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.forgot.password.check.email' | translate }}\n </div>\n <p class=\"text-muted-color font-medium mb-6\">\n {{\n 'auth.forgot.password.email.sent.to'\n | translate: { email: submittedEmail() }\n }}\n </p>\n <p class=\"text-sm text-muted-color mb-6\">\n {{ 'auth.forgot.password.didnt.receive' | translate }}\n <span\n class=\"text-primary cursor-pointer font-semibold\"\n (click)=\"resetForm()\"\n >\n {{ 'auth.forgot.password.try.again' | translate }} </span\n >.\n </p>\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.back.to.sign.in' | translate }}\n </a>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n `,\n})\nexport class ForgotPasswordPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly messageService = inject(MessageService);\n private readonly authApi = inject(AuthApiService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(key: string, vars?: Record<string, string>): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n readonly isLoading = signal(false);\n readonly emailSent = signal(false);\n readonly submittedEmail = signal('');\n readonly formModel = signal<IForgotPasswordFormModel>({ email: '' });\n readonly forgotForm = form(this.formModel, (f) => {\n required(f.email, {\n message: this.translate('auth.validation.email.required'),\n });\n emailValidator(f.email, {\n message: this.translate('shared.invalid.email'),\n });\n });\n readonly isFormValid = computed(() => this.forgotForm().valid());\n\n onSubmit(event: Event): void {\n event.preventDefault();\n\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.invalid.email'),\n });\n return;\n }\n\n this.isLoading.set(true);\n const email = this.formModel().email;\n\n // Always show success (security: don't reveal if email exists)\n this.authApi\n .forgotPassword(email)\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n tap({\n next: () => this.showEmailSent(email),\n }),\n finalize(() => this.isLoading.set(false)),\n )\n .subscribe({ error: () => {} });\n }\n\n private showEmailSent(email: string): void {\n this.submittedEmail.set(email);\n this.emailSent.set(true);\n }\n\n resetForm(): void {\n this.emailSent.set(false);\n this.submittedEmail.set('');\n this.formModel.set({ email: '' });\n }\n}\n"],"mappings":"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"}
|
|
@@ -247,7 +247,7 @@ var LoginPageComponent = class LoginPageComponent {
|
|
|
247
247
|
}
|
|
248
248
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
249
249
|
minVersion: "12.0.0",
|
|
250
|
-
version: "22.2.
|
|
250
|
+
version: "22.2.3",
|
|
251
251
|
ngImport: i0,
|
|
252
252
|
type: LoginPageComponent,
|
|
253
253
|
deps: [],
|
|
@@ -255,7 +255,7 @@ var LoginPageComponent = class LoginPageComponent {
|
|
|
255
255
|
});
|
|
256
256
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
257
257
|
minVersion: "17.0.0",
|
|
258
|
-
version: "22.2.
|
|
258
|
+
version: "22.2.3",
|
|
259
259
|
type: LoginPageComponent,
|
|
260
260
|
isStandalone: true,
|
|
261
261
|
selector: "lib-login-page",
|
|
@@ -768,7 +768,7 @@ var LoginPageComponent = class LoginPageComponent {
|
|
|
768
768
|
};
|
|
769
769
|
i0.ɵɵngDeclareClassMetadata({
|
|
770
770
|
minVersion: "12.0.0",
|
|
771
|
-
version: "22.2.
|
|
771
|
+
version: "22.2.3",
|
|
772
772
|
ngImport: i0,
|
|
773
773
|
type: LoginPageComponent,
|
|
774
774
|
decorators: [{
|
|
@@ -1071,4 +1071,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1071
1071
|
});
|
|
1072
1072
|
export { LoginPageComponent };
|
|
1073
1073
|
|
|
1074
|
-
//# sourceMappingURL=flusys-ng-auth-login-page.component-
|
|
1074
|
+
//# sourceMappingURL=flusys-ng-auth-login-page.component-Bz-bbY3U.mjs.map
|