@rolatech/angular-platform 20.3.0-beta.2 → 20.3.0-beta.3

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.
Files changed (37) hide show
  1. package/fesm2022/rolatech-angular-platform-application-create-CwJeutMN.mjs +138 -0
  2. package/fesm2022/rolatech-angular-platform-application-create-CwJeutMN.mjs.map +1 -0
  3. package/fesm2022/rolatech-angular-platform-application-detail-Bzgydts3.mjs +54 -0
  4. package/fesm2022/rolatech-angular-platform-application-detail-Bzgydts3.mjs.map +1 -0
  5. package/fesm2022/rolatech-angular-platform-application-member-detail-D3ESzMBX.mjs +72 -0
  6. package/fesm2022/rolatech-angular-platform-application-member-detail-D3ESzMBX.mjs.map +1 -0
  7. package/fesm2022/rolatech-angular-platform-application-member-index-D7po13YP.mjs +135 -0
  8. package/fesm2022/rolatech-angular-platform-application-member-index-D7po13YP.mjs.map +1 -0
  9. package/fesm2022/rolatech-angular-platform-application-organization-index-CX4KNdF7.mjs +55 -0
  10. package/fesm2022/rolatech-angular-platform-application-organization-index-CX4KNdF7.mjs.map +1 -0
  11. package/fesm2022/rolatech-angular-platform-application-role-index-BymGtx1Z.mjs +67 -0
  12. package/fesm2022/rolatech-angular-platform-application-role-index-BymGtx1Z.mjs.map +1 -0
  13. package/fesm2022/{rolatech-angular-platform-application-routes-DE5CJMgn.mjs → rolatech-angular-platform-application-routes-kbstcOg1.mjs} +16 -8
  14. package/fesm2022/rolatech-angular-platform-application-routes-kbstcOg1.mjs.map +1 -0
  15. package/fesm2022/rolatech-angular-platform-application-workspace-shell-MPkdKJ2X.mjs +73 -0
  16. package/fesm2022/rolatech-angular-platform-application-workspace-shell-MPkdKJ2X.mjs.map +1 -0
  17. package/fesm2022/rolatech-angular-platform-role-permission-index-CkFgu7BW.mjs +139 -0
  18. package/fesm2022/rolatech-angular-platform-role-permission-index-CkFgu7BW.mjs.map +1 -0
  19. package/fesm2022/{rolatech-angular-platform-role-permission-page-DslhArZQ.mjs → rolatech-angular-platform-role-permission-page-CgRpVi8e.mjs} +12 -3
  20. package/fesm2022/rolatech-angular-platform-role-permission-page-CgRpVi8e.mjs.map +1 -0
  21. package/fesm2022/{rolatech-angular-platform-role-permission-page.routes-IiX17wDW.mjs → rolatech-angular-platform-role-permission-page.routes-D8wuIMCR.mjs} +2 -2
  22. package/fesm2022/{rolatech-angular-platform-role-permission-page.routes-IiX17wDW.mjs.map → rolatech-angular-platform-role-permission-page.routes-D8wuIMCR.mjs.map} +1 -1
  23. package/fesm2022/rolatech-angular-platform.mjs +19 -3
  24. package/fesm2022/rolatech-angular-platform.mjs.map +1 -1
  25. package/package.json +1 -1
  26. package/fesm2022/rolatech-angular-platform-application-create-DqPMquaO.mjs +0 -129
  27. package/fesm2022/rolatech-angular-platform-application-create-DqPMquaO.mjs.map +0 -1
  28. package/fesm2022/rolatech-angular-platform-application-detail-BoITs_yE.mjs +0 -54
  29. package/fesm2022/rolatech-angular-platform-application-detail-BoITs_yE.mjs.map +0 -1
  30. package/fesm2022/rolatech-angular-platform-application-organization-index-D7TJ8CID.mjs +0 -54
  31. package/fesm2022/rolatech-angular-platform-application-organization-index-D7TJ8CID.mjs.map +0 -1
  32. package/fesm2022/rolatech-angular-platform-application-role-index-9_XVRBgD.mjs +0 -66
  33. package/fesm2022/rolatech-angular-platform-application-role-index-9_XVRBgD.mjs.map +0 -1
  34. package/fesm2022/rolatech-angular-platform-application-routes-DE5CJMgn.mjs.map +0 -1
  35. package/fesm2022/rolatech-angular-platform-platform-role-index-8kRxDJiW.mjs +0 -35
  36. package/fesm2022/rolatech-angular-platform-platform-role-index-8kRxDJiW.mjs.map +0 -1
  37. package/fesm2022/rolatech-angular-platform-role-permission-page-DslhArZQ.mjs.map +0 -1
@@ -0,0 +1,138 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, Injectable, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { ActivatedRoute, Router } from '@angular/router';
4
+ import { PlatformPageHeader, PlatformDetailPanel, PlatformStickyActionBar } from './rolatech-angular-platform.mjs';
5
+ import { firstValueFrom } from 'rxjs';
6
+ import { ApplicationService } from '@rolatech/angular-services';
7
+ import { A as ApplicationWorkspaceShell } from './rolatech-angular-platform-application-workspace-shell-MPkdKJ2X.mjs';
8
+
9
+ class ApplicationCreateFacade {
10
+ applicationService = inject(ApplicationService);
11
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
12
+ saving = signal(false, ...(ngDevMode ? [{ debugName: "saving" }] : []));
13
+ error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
14
+ id = signal(null, ...(ngDevMode ? [{ debugName: "id" }] : []));
15
+ name = signal('', ...(ngDevMode ? [{ debugName: "name" }] : []));
16
+ code = signal('', ...(ngDevMode ? [{ debugName: "code" }] : []));
17
+ type = signal('', ...(ngDevMode ? [{ debugName: "type" }] : []));
18
+ description = signal('', ...(ngDevMode ? [{ debugName: "description" }] : []));
19
+ active = signal(true, ...(ngDevMode ? [{ debugName: "active" }] : []));
20
+ async load(id) {
21
+ this.loading.set(true);
22
+ this.error.set(null);
23
+ try {
24
+ const item = await firstValueFrom(this.applicationService.findApplicationById(id));
25
+ this.id.set(item.id);
26
+ this.name.set(item.name);
27
+ this.code.set(item.code);
28
+ this.type.set(item.type ?? '');
29
+ this.description.set(item.description ?? '');
30
+ this.active.set(item.active);
31
+ }
32
+ catch (error) {
33
+ console.error(error);
34
+ this.error.set('Unable to load the application.');
35
+ }
36
+ finally {
37
+ this.loading.set(false);
38
+ }
39
+ }
40
+ async save() {
41
+ this.saving.set(true);
42
+ this.error.set(null);
43
+ try {
44
+ const payload = {
45
+ name: this.name(),
46
+ code: this.code(),
47
+ type: this.type() || null,
48
+ description: this.description() || null,
49
+ active: this.active(),
50
+ };
51
+ if (this.id()) {
52
+ await firstValueFrom(this.applicationService.updateApplication(this.id(), payload));
53
+ }
54
+ else {
55
+ const created = await firstValueFrom(this.applicationService.createApplication(payload));
56
+ this.id.set(created.id);
57
+ }
58
+ }
59
+ catch (error) {
60
+ console.error(error);
61
+ this.error.set('Unable to save the application.');
62
+ }
63
+ finally {
64
+ this.saving.set(false);
65
+ }
66
+ }
67
+ setName(value) {
68
+ this.name.set(value);
69
+ }
70
+ setCode(value) {
71
+ this.code.set(value);
72
+ }
73
+ setType(value) {
74
+ this.type.set(value);
75
+ }
76
+ setDescription(value) {
77
+ this.description.set(value);
78
+ }
79
+ setActive(value) {
80
+ this.active.set(value);
81
+ }
82
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationCreateFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
83
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationCreateFacade });
84
+ }
85
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationCreateFacade, decorators: [{
86
+ type: Injectable
87
+ }] });
88
+
89
+ class ApplicationCreate {
90
+ facade = inject(ApplicationCreateFacade);
91
+ route = inject(ActivatedRoute);
92
+ router = inject(Router);
93
+ id = this.route.snapshot.paramMap.get('appId') ?? this.route.snapshot.paramMap.get('id');
94
+ routePath = this.route.snapshot.routeConfig?.path ?? '';
95
+ get isEdit() {
96
+ return !!this.id;
97
+ }
98
+ get isSettings() {
99
+ return this.routePath.includes('settings');
100
+ }
101
+ ngOnInit() {
102
+ if (this.id) {
103
+ void this.facade.load(this.id);
104
+ }
105
+ }
106
+ onNameInput(event) {
107
+ this.facade.setName(event.target.value);
108
+ }
109
+ onCodeInput(event) {
110
+ this.facade.setCode(event.target.value);
111
+ }
112
+ onTypeInput(event) {
113
+ this.facade.setType(event.target.value);
114
+ }
115
+ onDescriptionInput(event) {
116
+ this.facade.setDescription(event.target.value);
117
+ }
118
+ onActiveChange(event) {
119
+ this.facade.setActive(event.target.checked);
120
+ }
121
+ async save() {
122
+ await this.facade.save();
123
+ if (this.isSettings && this.id) {
124
+ await this.router.navigate(['/platform/applications', this.id]);
125
+ return;
126
+ }
127
+ await this.router.navigate(['../'], { relativeTo: this.route });
128
+ }
129
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationCreate, deps: [], target: i0.ɵɵFactoryTarget.Component });
130
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: ApplicationCreate, isStandalone: true, selector: "rolatech-application-create", providers: [ApplicationCreateFacade], ngImport: i0, template: "@if (isSettings && id) {\n<rolatech-application-workspace-shell [appId]=\"id\" activeTab=\"settings\" sectionTitle=\"Settings\" sectionDescription=\"Update core application configuration.\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else {\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Set core application properties.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Name</span>\n <input\n type=\"text\"\n [value]=\"facade.name()\"\n (input)=\"onNameInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Code</span>\n <input\n type=\"text\"\n [value]=\"facade.code()\"\n (input)=\"onCodeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Type</span>\n <input\n type=\"text\"\n [value]=\"facade.type()\"\n (input)=\"onTypeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.active()\" (change)=\"onActiveChange($event)\" />\n <span class=\"text-sm font-medium\">Active</span>\n </label>\n\n <label class=\"md:col-span-2 flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Description</span>\n <textarea\n rows=\"5\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>Update and save this application configuration.</div>\n\n <div action-buttons>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else { Save Changes }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</rolatech-application-workspace-shell>\n} @else {\n<section class=\"flex flex-col gap-6 p-6\">\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">@if (isEdit) { Edit Application } @else { Create Application }</h1>\n <p class=\"text-sm text-muted-foreground\">\n @if (isEdit) { Update application information. } @else { Create a new application for the platform. }\n </p>\n </div>\n </rolatech-platform-page-header>\n\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else {\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Set core application properties.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Name</span>\n <input\n type=\"text\"\n [value]=\"facade.name()\"\n (input)=\"onNameInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Code</span>\n <input\n type=\"text\"\n [value]=\"facade.code()\"\n (input)=\"onCodeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Type</span>\n <input\n type=\"text\"\n [value]=\"facade.type()\"\n (input)=\"onTypeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.active()\" (change)=\"onActiveChange($event)\" />\n <span class=\"text-sm font-medium\">Active</span>\n </label>\n\n <label class=\"md:col-span-2 flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Description</span>\n <textarea\n rows=\"5\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>@if (isEdit) { Update and save this application. } @else { Save this new application. }</div>\n\n <div action-buttons>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else { Save }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</section>\n}\n", dependencies: [{ kind: "component", type: ApplicationWorkspaceShell, selector: "rolatech-application-workspace-shell", inputs: ["appId", "activeTab", "sectionTitle", "sectionDescription", "showEditButton"] }, { kind: "component", type: PlatformPageHeader, selector: "rolatech-platform-page-header" }, { kind: "component", type: PlatformDetailPanel, selector: "rolatech-platform-detail-panel" }, { kind: "component", type: PlatformStickyActionBar, selector: "rolatech-platform-sticky-action-bar" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
131
+ }
132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationCreate, decorators: [{
133
+ type: Component,
134
+ args: [{ selector: 'rolatech-application-create', standalone: true, imports: [ApplicationWorkspaceShell, PlatformPageHeader, PlatformDetailPanel, PlatformStickyActionBar], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ApplicationCreateFacade], template: "@if (isSettings && id) {\n<rolatech-application-workspace-shell [appId]=\"id\" activeTab=\"settings\" sectionTitle=\"Settings\" sectionDescription=\"Update core application configuration.\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else {\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Set core application properties.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Name</span>\n <input\n type=\"text\"\n [value]=\"facade.name()\"\n (input)=\"onNameInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Code</span>\n <input\n type=\"text\"\n [value]=\"facade.code()\"\n (input)=\"onCodeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Type</span>\n <input\n type=\"text\"\n [value]=\"facade.type()\"\n (input)=\"onTypeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.active()\" (change)=\"onActiveChange($event)\" />\n <span class=\"text-sm font-medium\">Active</span>\n </label>\n\n <label class=\"md:col-span-2 flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Description</span>\n <textarea\n rows=\"5\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>Update and save this application configuration.</div>\n\n <div action-buttons>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else { Save Changes }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</rolatech-application-workspace-shell>\n} @else {\n<section class=\"flex flex-col gap-6 p-6\">\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">@if (isEdit) { Edit Application } @else { Create Application }</h1>\n <p class=\"text-sm text-muted-foreground\">\n @if (isEdit) { Update application information. } @else { Create a new application for the platform. }\n </p>\n </div>\n </rolatech-platform-page-header>\n\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else {\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Set core application properties.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Name</span>\n <input\n type=\"text\"\n [value]=\"facade.name()\"\n (input)=\"onNameInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Code</span>\n <input\n type=\"text\"\n [value]=\"facade.code()\"\n (input)=\"onCodeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Type</span>\n <input\n type=\"text\"\n [value]=\"facade.type()\"\n (input)=\"onTypeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.active()\" (change)=\"onActiveChange($event)\" />\n <span class=\"text-sm font-medium\">Active</span>\n </label>\n\n <label class=\"md:col-span-2 flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Description</span>\n <textarea\n rows=\"5\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>@if (isEdit) { Update and save this application. } @else { Save this new application. }</div>\n\n <div action-buttons>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else { Save }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</section>\n}\n" }]
135
+ }] });
136
+
137
+ export { ApplicationCreate };
138
+ //# sourceMappingURL=rolatech-angular-platform-application-create-CwJeutMN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rolatech-angular-platform-application-create-CwJeutMN.mjs","sources":["../../../../packages/angular-platform/src/lib/store/application-create.facade.ts","../../../../packages/angular-platform/src/lib/pages/application/application-create/application-create.ts","../../../../packages/angular-platform/src/lib/pages/application/application-create/application-create.html"],"sourcesContent":["import { Injectable, inject, signal } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { ApplicationService } from '@rolatech/angular-services';\n\n@Injectable()\nexport class ApplicationCreateFacade {\n private readonly applicationService = inject(ApplicationService);\n\n readonly loading = signal(false);\n readonly saving = signal(false);\n readonly error = signal<string | null>(null);\n\n readonly id = signal<string | null>(null);\n\n readonly name = signal('');\n readonly code = signal('');\n readonly type = signal('');\n readonly description = signal('');\n readonly active = signal(true);\n\n async load(id: string): Promise<void> {\n this.loading.set(true);\n this.error.set(null);\n try {\n const item = await firstValueFrom(this.applicationService.findApplicationById(id));\n this.id.set(item.id);\n this.name.set(item.name);\n this.code.set(item.code);\n this.type.set(item.type ?? '');\n this.description.set(item.description ?? '');\n this.active.set(item.active);\n } catch (error) {\n console.error(error);\n this.error.set('Unable to load the application.');\n } finally {\n this.loading.set(false);\n }\n }\n\n async save(): Promise<void> {\n this.saving.set(true);\n this.error.set(null);\n try {\n const payload = {\n name: this.name(),\n code: this.code(),\n type: this.type() || null,\n description: this.description() || null,\n active: this.active(),\n };\n\n if (this.id()) {\n await firstValueFrom(this.applicationService.updateApplication(this.id()!, payload));\n } else {\n const created = await firstValueFrom(this.applicationService.createApplication(payload));\n this.id.set(created.id);\n }\n } catch (error) {\n console.error(error);\n this.error.set('Unable to save the application.');\n } finally {\n this.saving.set(false);\n }\n }\n\n setName(value: string): void {\n this.name.set(value);\n }\n\n setCode(value: string): void {\n this.code.set(value);\n }\n\n setType(value: string): void {\n this.type.set(value);\n }\n\n setDescription(value: string): void {\n this.description.set(value);\n }\n\n setActive(value: boolean): void {\n this.active.set(value);\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { PlatformPageHeader, PlatformDetailPanel, PlatformStickyActionBar } from '../../../shared';\nimport { ApplicationCreateFacade } from '../../../store/application-create.facade';\nimport { ApplicationWorkspaceShell } from '../application-workspace-shell/application-workspace-shell';\n\n@Component({\n selector: 'rolatech-application-create',\n standalone: true,\n imports: [ApplicationWorkspaceShell, PlatformPageHeader, PlatformDetailPanel, PlatformStickyActionBar],\n templateUrl: './application-create.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [ApplicationCreateFacade],\n})\nexport class ApplicationCreate implements OnInit {\n readonly facade = inject(ApplicationCreateFacade);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n\n readonly id = this.route.snapshot.paramMap.get('appId') ?? this.route.snapshot.paramMap.get('id');\n readonly routePath = this.route.snapshot.routeConfig?.path ?? '';\n\n get isEdit(): boolean {\n return !!this.id;\n }\n\n get isSettings(): boolean {\n return this.routePath.includes('settings');\n }\n\n ngOnInit(): void {\n if (this.id) {\n void this.facade.load(this.id);\n }\n }\n\n onNameInput(event: Event): void {\n this.facade.setName((event.target as HTMLInputElement).value);\n }\n\n onCodeInput(event: Event): void {\n this.facade.setCode((event.target as HTMLInputElement).value);\n }\n\n onTypeInput(event: Event): void {\n this.facade.setType((event.target as HTMLInputElement).value);\n }\n\n onDescriptionInput(event: Event): void {\n this.facade.setDescription((event.target as HTMLTextAreaElement).value);\n }\n\n onActiveChange(event: Event): void {\n this.facade.setActive((event.target as HTMLInputElement).checked);\n }\n\n async save(): Promise<void> {\n await this.facade.save();\n if (this.isSettings && this.id) {\n await this.router.navigate(['/platform/applications', this.id]);\n return;\n }\n\n await this.router.navigate(['../'], { relativeTo: this.route });\n }\n}\n","@if (isSettings && id) {\n<rolatech-application-workspace-shell [appId]=\"id\" activeTab=\"settings\" sectionTitle=\"Settings\" sectionDescription=\"Update core application configuration.\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else {\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Set core application properties.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Name</span>\n <input\n type=\"text\"\n [value]=\"facade.name()\"\n (input)=\"onNameInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Code</span>\n <input\n type=\"text\"\n [value]=\"facade.code()\"\n (input)=\"onCodeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Type</span>\n <input\n type=\"text\"\n [value]=\"facade.type()\"\n (input)=\"onTypeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.active()\" (change)=\"onActiveChange($event)\" />\n <span class=\"text-sm font-medium\">Active</span>\n </label>\n\n <label class=\"md:col-span-2 flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Description</span>\n <textarea\n rows=\"5\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>Update and save this application configuration.</div>\n\n <div action-buttons>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else { Save Changes }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</rolatech-application-workspace-shell>\n} @else {\n<section class=\"flex flex-col gap-6 p-6\">\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">@if (isEdit) { Edit Application } @else { Create Application }</h1>\n <p class=\"text-sm text-muted-foreground\">\n @if (isEdit) { Update application information. } @else { Create a new application for the platform. }\n </p>\n </div>\n </rolatech-platform-page-header>\n\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else {\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Set core application properties.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Name</span>\n <input\n type=\"text\"\n [value]=\"facade.name()\"\n (input)=\"onNameInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Code</span>\n <input\n type=\"text\"\n [value]=\"facade.code()\"\n (input)=\"onCodeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Type</span>\n <input\n type=\"text\"\n [value]=\"facade.type()\"\n (input)=\"onTypeInput($event)\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.active()\" (change)=\"onActiveChange($event)\" />\n <span class=\"text-sm font-medium\">Active</span>\n </label>\n\n <label class=\"md:col-span-2 flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Description</span>\n <textarea\n rows=\"5\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>@if (isEdit) { Update and save this application. } @else { Save this new application. }</div>\n\n <div action-buttons>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else { Save }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</section>\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, Injectable, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { ActivatedRoute } from '@angular/router';
4
+ import { PlatformDetailPanel } from './rolatech-angular-platform.mjs';
5
+ import { A as ApplicationWorkspaceShell } from './rolatech-angular-platform-application-workspace-shell-MPkdKJ2X.mjs';
6
+ import { firstValueFrom } from 'rxjs';
7
+ import { ApplicationService } from '@rolatech/angular-services';
8
+
9
+ class ApplicationDetailFacade {
10
+ applicationService = inject(ApplicationService);
11
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
12
+ item = signal(null, ...(ngDevMode ? [{ debugName: "item" }] : []));
13
+ error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
14
+ async load(id) {
15
+ this.loading.set(true);
16
+ this.error.set(null);
17
+ try {
18
+ this.item.set(await firstValueFrom(this.applicationService.findApplicationById(id)));
19
+ }
20
+ catch (error) {
21
+ console.error(error);
22
+ this.item.set(null);
23
+ this.error.set('Unable to load the application.');
24
+ }
25
+ finally {
26
+ this.loading.set(false);
27
+ }
28
+ }
29
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationDetailFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
30
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationDetailFacade });
31
+ }
32
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationDetailFacade, decorators: [{
33
+ type: Injectable
34
+ }] });
35
+
36
+ class ApplicationDetail {
37
+ facade = inject(ApplicationDetailFacade);
38
+ route = inject(ActivatedRoute);
39
+ id = this.route.snapshot.paramMap.get('appId') ?? this.route.snapshot.paramMap.get('id') ?? '';
40
+ ngOnInit() {
41
+ if (this.id) {
42
+ void this.facade.load(this.id);
43
+ }
44
+ }
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationDetail, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: ApplicationDetail, isStandalone: true, selector: "rolatech-application-detail", providers: [ApplicationDetailFacade], ngImport: i0, template: "<rolatech-application-workspace-shell [appId]=\"id\" activeTab=\"overview\" [showEditButton]=\"true\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else if (facade.item(); as item) {\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Core application details.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Name</div>\n <div class=\"font-medium\">{{ item.name }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Code</div>\n <div class=\"font-medium\">{{ item.code }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Type</div>\n <div class=\"font-medium\">{{ item.type || '-' }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Status</div>\n <div class=\"font-medium\">{{ item.status }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Structure Summary</div>\n <div panel-description>Top-level related resources under this application.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Organizations</div>\n <div class=\"font-medium\">{{ item.organizationCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Roles</div>\n <div class=\"font-medium\">{{ item.roleCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Members</div>\n <div class=\"font-medium\">{{ item.memberCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Created At</div>\n <div class=\"font-medium\">{{ item.createdAt || '-' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n </section>\n }\n</rolatech-application-workspace-shell>\n", dependencies: [{ kind: "component", type: ApplicationWorkspaceShell, selector: "rolatech-application-workspace-shell", inputs: ["appId", "activeTab", "sectionTitle", "sectionDescription", "showEditButton"] }, { kind: "component", type: PlatformDetailPanel, selector: "rolatech-platform-detail-panel" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
47
+ }
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationDetail, decorators: [{
49
+ type: Component,
50
+ args: [{ selector: 'rolatech-application-detail', standalone: true, imports: [ApplicationWorkspaceShell, PlatformDetailPanel], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ApplicationDetailFacade], template: "<rolatech-application-workspace-shell [appId]=\"id\" activeTab=\"overview\" [showEditButton]=\"true\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else if (facade.item(); as item) {\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Core application details.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Name</div>\n <div class=\"font-medium\">{{ item.name }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Code</div>\n <div class=\"font-medium\">{{ item.code }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Type</div>\n <div class=\"font-medium\">{{ item.type || '-' }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Status</div>\n <div class=\"font-medium\">{{ item.status }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Structure Summary</div>\n <div panel-description>Top-level related resources under this application.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Organizations</div>\n <div class=\"font-medium\">{{ item.organizationCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Roles</div>\n <div class=\"font-medium\">{{ item.roleCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Members</div>\n <div class=\"font-medium\">{{ item.memberCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Created At</div>\n <div class=\"font-medium\">{{ item.createdAt || '-' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n </section>\n }\n</rolatech-application-workspace-shell>\n" }]
51
+ }] });
52
+
53
+ export { ApplicationDetail };
54
+ //# sourceMappingURL=rolatech-angular-platform-application-detail-Bzgydts3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rolatech-angular-platform-application-detail-Bzgydts3.mjs","sources":["../../../../packages/angular-platform/src/lib/store/application-detail.facade.ts","../../../../packages/angular-platform/src/lib/pages/application/application-detail/application-detail.ts","../../../../packages/angular-platform/src/lib/pages/application/application-detail/application-detail.html"],"sourcesContent":["import { Injectable, inject, signal } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { ApplicationService } from '@rolatech/angular-services';\nimport { ApplicationDetailModel } from '../model/application.models';\n\n@Injectable()\nexport class ApplicationDetailFacade {\n private readonly applicationService = inject(ApplicationService);\n\n readonly loading = signal(false);\n readonly item = signal<ApplicationDetailModel | null>(null);\n readonly error = signal<string | null>(null);\n\n async load(id: string): Promise<void> {\n this.loading.set(true);\n this.error.set(null);\n try {\n this.item.set(await firstValueFrom(this.applicationService.findApplicationById(id)));\n } catch (error) {\n console.error(error);\n this.item.set(null);\n this.error.set('Unable to load the application.');\n } finally {\n this.loading.set(false);\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { PlatformDetailPanel } from '../../../shared';\nimport { ApplicationWorkspaceShell } from '../application-workspace-shell/application-workspace-shell';\nimport { ApplicationDetailFacade } from '../../../store/application-detail.facade';\n\n@Component({\n selector: 'rolatech-application-detail',\n standalone: true,\n imports: [ApplicationWorkspaceShell, PlatformDetailPanel],\n templateUrl: './application-detail.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [ApplicationDetailFacade],\n})\nexport class ApplicationDetail implements OnInit {\n readonly facade = inject(ApplicationDetailFacade);\n private readonly route = inject(ActivatedRoute);\n\n readonly id = this.route.snapshot.paramMap.get('appId') ?? this.route.snapshot.paramMap.get('id') ?? '';\n\n ngOnInit(): void {\n if (this.id) {\n void this.facade.load(this.id);\n }\n }\n}\n","<rolatech-application-workspace-shell [appId]=\"id\" activeTab=\"overview\" [showEditButton]=\"true\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading application...</section>\n } @else if (facade.item(); as item) {\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Core application details.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Name</div>\n <div class=\"font-medium\">{{ item.name }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Code</div>\n <div class=\"font-medium\">{{ item.code }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Type</div>\n <div class=\"font-medium\">{{ item.type || '-' }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Status</div>\n <div class=\"font-medium\">{{ item.status }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Structure Summary</div>\n <div panel-description>Top-level related resources under this application.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Organizations</div>\n <div class=\"font-medium\">{{ item.organizationCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Roles</div>\n <div class=\"font-medium\">{{ item.roleCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Members</div>\n <div class=\"font-medium\">{{ item.memberCount }}</div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Created At</div>\n <div class=\"font-medium\">{{ item.createdAt || '-' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n </section>\n }\n</rolatech-application-workspace-shell>\n"],"names":[],"mappings":";;;;;;;;MAMa,uBAAuB,CAAA;AACjB,IAAA,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC;AAEvD,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,mDAAC;AACvB,IAAA,IAAI,GAAG,MAAM,CAAgC,IAAI,gDAAC;AAClD,IAAA,KAAK,GAAG,MAAM,CAAgB,IAAI,iDAAC;IAE5C,MAAM,IAAI,CAAC,EAAU,EAAA;AACnB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;AACpB,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AACpB,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AACnB,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC;QACnD;gBAAU;AACR,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACzB;IACF;uGAnBW,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAvB,uBAAuB,EAAA,CAAA;;2FAAvB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBADnC;;;MCSY,iBAAiB,CAAA;AACnB,IAAA,MAAM,GAAG,MAAM,CAAC,uBAAuB,CAAC;AAChC,IAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAEtC,IAAA,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;IAEvG,QAAQ,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,EAAE,EAAE;YACX,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC;IACF;uGAVW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,SAAA,EAFjB,CAAC,uBAAuB,CAAC,0BCZtC,6wEA6DA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDpDY,yBAAyB,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,WAAA,EAAA,cAAA,EAAA,oBAAA,EAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,mBAAmB,EAAA,QAAA,EAAA,gCAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAK7C,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAR7B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,6BAA6B,EAAA,UAAA,EAC3B,IAAI,EAAA,OAAA,EACP,CAAC,yBAAyB,EAAE,mBAAmB,CAAC,EAAA,eAAA,EAExC,uBAAuB,CAAC,MAAM,EAAA,SAAA,EACpC,CAAC,uBAAuB,CAAC,EAAA,QAAA,EAAA,6wEAAA,EAAA;;;;;"}
@@ -0,0 +1,72 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, Injectable, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { ActivatedRoute, RouterLink } from '@angular/router';
4
+ import { PlatformStatCard, PlatformDetailPanel } from './rolatech-angular-platform.mjs';
5
+ import { firstValueFrom } from 'rxjs';
6
+ import { ApplicationService } from '@rolatech/angular-services';
7
+ import { A as ApplicationWorkspaceShell } from './rolatech-angular-platform-application-workspace-shell-MPkdKJ2X.mjs';
8
+
9
+ class ApplicationMemberDetailFacade {
10
+ applicationService = inject(ApplicationService);
11
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
12
+ error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
13
+ item = signal(null, ...(ngDevMode ? [{ debugName: "item" }] : []));
14
+ displayName = computed(() => {
15
+ const item = this.item();
16
+ if (!item) {
17
+ return '';
18
+ }
19
+ return item.name || item.fullName || [item.firstName, item.lastName].filter(Boolean).join(' ').trim() || item.username || item.email || item.memberId;
20
+ }, ...(ngDevMode ? [{ debugName: "displayName" }] : []));
21
+ organizationCount = computed(() => this.item()?.organizations?.length ?? this.item()?.organizationCount ?? 0, ...(ngDevMode ? [{ debugName: "organizationCount" }] : []));
22
+ applicationRoleCount = computed(() => this.item()?.applicationRoles?.length ?? this.item()?.roles.length ?? 0, ...(ngDevMode ? [{ debugName: "applicationRoleCount" }] : []));
23
+ platformRoleCount = computed(() => this.item()?.platformRoles?.length ?? 0, ...(ngDevMode ? [{ debugName: "platformRoleCount" }] : []));
24
+ permissionCount = computed(() => this.item()?.permissions?.length ?? 0, ...(ngDevMode ? [{ debugName: "permissionCount" }] : []));
25
+ async load(appId, memberId) {
26
+ if (!appId || !memberId) {
27
+ this.item.set(null);
28
+ this.error.set('Member context is missing.');
29
+ return;
30
+ }
31
+ this.loading.set(true);
32
+ this.error.set(null);
33
+ try {
34
+ this.item.set(await firstValueFrom(this.applicationService.findApplicationMemberById(appId, memberId)));
35
+ }
36
+ catch (error) {
37
+ console.error(error);
38
+ this.item.set(null);
39
+ this.error.set('Unable to load application member details.');
40
+ }
41
+ finally {
42
+ this.loading.set(false);
43
+ }
44
+ }
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationMemberDetailFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
46
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationMemberDetailFacade });
47
+ }
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationMemberDetailFacade, decorators: [{
49
+ type: Injectable
50
+ }] });
51
+
52
+ class ApplicationMemberDetail {
53
+ facade = inject(ApplicationMemberDetailFacade);
54
+ route = inject(ActivatedRoute);
55
+ appId = this.route.snapshot.paramMap.get('appId') ?? '';
56
+ memberId = this.route.snapshot.paramMap.get('memberId') ?? '';
57
+ ngOnInit() {
58
+ void this.facade.load(this.appId, this.memberId);
59
+ }
60
+ verificationLabel(value) {
61
+ return value ? 'Verified' : 'Pending';
62
+ }
63
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationMemberDetail, deps: [], target: i0.ɵɵFactoryTarget.Component });
64
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: ApplicationMemberDetail, isStandalone: true, selector: "rolatech-application-member-detail", providers: [ApplicationMemberDetailFacade], ngImport: i0, template: "<rolatech-application-workspace-shell [appId]=\"appId\" activeTab=\"members\" sectionTitle=\"Member Detail\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading member...</section>\n } @else if (facade.item(); as item) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-6 shadow-sm\">\n <div class=\"flex flex-wrap items-start justify-between gap-4\">\n <div class=\"space-y-2\">\n <div class=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <a [routerLink]=\"['/platform/applications', appId, 'members']\" class=\"hover:underline cursor-pointer\">Members</a>\n <span>/</span>\n <span>{{ facade.displayName() }}</span>\n </div>\n\n <div>\n <h2 class=\"text-xl font-semibold tracking-tight\">{{ facade.displayName() }}</h2>\n <div class=\"mt-1 text-sm text-muted-foreground\">@if (item.username) { &#64;{{ item.username }} } @else { {{ item.userId || item.memberId }} }</div>\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">{{ item.status || 'UNKNOWN' }}</span>\n @for (role of item.applicationRoles ?? item.roles; track role) {\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">{{ role }}</span>\n }\n </div>\n </div>\n\n <a\n [routerLink]=\"['/platform/applications', appId, 'members']\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium cursor-pointer\"\n >\n Back to Members\n </a>\n </div>\n </section>\n\n <section class=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <rolatech-platform-stat-card>\n <div stat-label>Organizations</div>\n <div stat-value>{{ facade.organizationCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Application Roles</div>\n <div stat-value>{{ facade.applicationRoleCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Platform Roles</div>\n <div stat-value>{{ facade.platformRoleCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Permissions</div>\n <div stat-value>{{ facade.permissionCount() }}</div>\n </rolatech-platform-stat-card>\n </section>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Primary user identity and contact details.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Member ID</div>\n <div class=\"font-medium break-all\">{{ item.memberId }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">User ID</div>\n <div class=\"font-medium break-all\">{{ item.userId || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">First Name</div>\n <div class=\"font-medium\">{{ item.firstName || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Last Name</div>\n <div class=\"font-medium\">{{ item.lastName || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Email</div>\n <div class=\"font-medium\">{{ item.email || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Phone</div>\n <div class=\"font-medium\">{{ item.phone || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Joined At</div>\n <div class=\"font-medium\">{{ item.joinedAt || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Status</div>\n <div class=\"font-medium\">{{ item.status || 'UNKNOWN' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Verification</div>\n <div panel-description>Contact and identity verification state returned by the API.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Email Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.emailVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Phone Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.phoneVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Identity Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.identityVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Verification Status</div>\n <div class=\"font-medium\">{{ item.verification?.status || '\u2014' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n </section>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Application Access</div>\n <div panel-description>Application-level and inherited platform roles for this member.</div>\n\n <div class=\"space-y-4\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Application Roles</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (role of item.applicationRoles ?? item.roles; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (!((item.applicationRoles ?? item.roles).length)) {\n <span class=\"text-sm text-muted-foreground\">No application roles returned.</span>\n }\n </div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Platform Roles</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (role of item.platformRoles ?? []; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (!(item.platformRoles?.length)) {\n <span class=\"text-sm text-muted-foreground\">No platform roles returned.</span>\n }\n </div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Permissions</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (permission of (item.permissions ?? []).slice(0, 12); track permission) {\n <span class=\"rt-platform-chip\">{{ permission }}</span>\n } @if (!(item.permissions?.length)) {\n <span class=\"text-sm text-muted-foreground\">No permission details returned.</span>\n } @if ((item.permissions?.length ?? 0) > 12) {\n <span class=\"text-sm text-muted-foreground\">+{{ (item.permissions?.length ?? 0) - 12 }} more</span>\n }\n </div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Organization Memberships</div>\n <div panel-description>Organizations this member belongs to inside the application.</div>\n\n <div class=\"space-y-3\">\n @for (organization of item.organizations ?? []; track organization.orgId) {\n <a class=\"rt-platform-link-block cursor-pointer\" [routerLink]=\"['/platform/organizations', organization.orgId]\">\n <div class=\"flex items-center justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ organization.orgName || organization.orgCode || organization.orgId }}</div>\n <div class=\"text-sm text-muted-foreground break-all\">{{ organization.orgId }}</div>\n </div>\n <div class=\"text-sm text-muted-foreground\">{{ organization.roles.length }} roles</div>\n </div>\n\n <div class=\"mt-3 flex flex-wrap gap-2\">\n @for (role of organization.roles; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (organization.roles.length === 0) {\n <span class=\"text-sm text-muted-foreground\">No organization roles</span>\n }\n </div>\n </a>\n } @if (!(item.organizations?.length)) {\n <div class=\"rounded-2xl border border-(--rt-border-color) border-dashed p-4 text-sm text-muted-foreground\">\n No organization memberships returned.\n </div>\n }\n </div>\n </rolatech-platform-detail-panel>\n </section>\n } @else {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">\n Application member not found.\n </section>\n }\n</rolatech-application-workspace-shell>\n", styles: [""], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: ApplicationWorkspaceShell, selector: "rolatech-application-workspace-shell", inputs: ["appId", "activeTab", "sectionTitle", "sectionDescription", "showEditButton"] }, { kind: "component", type: PlatformStatCard, selector: "rolatech-platform-stat-card" }, { kind: "component", type: PlatformDetailPanel, selector: "rolatech-platform-detail-panel" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
65
+ }
66
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ApplicationMemberDetail, decorators: [{
67
+ type: Component,
68
+ args: [{ selector: 'rolatech-application-member-detail', standalone: true, imports: [RouterLink, ApplicationWorkspaceShell, PlatformStatCard, PlatformDetailPanel], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ApplicationMemberDetailFacade], template: "<rolatech-application-workspace-shell [appId]=\"appId\" activeTab=\"members\" sectionTitle=\"Member Detail\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading member...</section>\n } @else if (facade.item(); as item) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-6 shadow-sm\">\n <div class=\"flex flex-wrap items-start justify-between gap-4\">\n <div class=\"space-y-2\">\n <div class=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <a [routerLink]=\"['/platform/applications', appId, 'members']\" class=\"hover:underline cursor-pointer\">Members</a>\n <span>/</span>\n <span>{{ facade.displayName() }}</span>\n </div>\n\n <div>\n <h2 class=\"text-xl font-semibold tracking-tight\">{{ facade.displayName() }}</h2>\n <div class=\"mt-1 text-sm text-muted-foreground\">@if (item.username) { &#64;{{ item.username }} } @else { {{ item.userId || item.memberId }} }</div>\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">{{ item.status || 'UNKNOWN' }}</span>\n @for (role of item.applicationRoles ?? item.roles; track role) {\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">{{ role }}</span>\n }\n </div>\n </div>\n\n <a\n [routerLink]=\"['/platform/applications', appId, 'members']\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium cursor-pointer\"\n >\n Back to Members\n </a>\n </div>\n </section>\n\n <section class=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <rolatech-platform-stat-card>\n <div stat-label>Organizations</div>\n <div stat-value>{{ facade.organizationCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Application Roles</div>\n <div stat-value>{{ facade.applicationRoleCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Platform Roles</div>\n <div stat-value>{{ facade.platformRoleCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Permissions</div>\n <div stat-value>{{ facade.permissionCount() }}</div>\n </rolatech-platform-stat-card>\n </section>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Primary user identity and contact details.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Member ID</div>\n <div class=\"font-medium break-all\">{{ item.memberId }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">User ID</div>\n <div class=\"font-medium break-all\">{{ item.userId || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">First Name</div>\n <div class=\"font-medium\">{{ item.firstName || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Last Name</div>\n <div class=\"font-medium\">{{ item.lastName || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Email</div>\n <div class=\"font-medium\">{{ item.email || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Phone</div>\n <div class=\"font-medium\">{{ item.phone || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Joined At</div>\n <div class=\"font-medium\">{{ item.joinedAt || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Status</div>\n <div class=\"font-medium\">{{ item.status || 'UNKNOWN' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Verification</div>\n <div panel-description>Contact and identity verification state returned by the API.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Email Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.emailVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Phone Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.phoneVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Identity Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.identityVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Verification Status</div>\n <div class=\"font-medium\">{{ item.verification?.status || '\u2014' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n </section>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Application Access</div>\n <div panel-description>Application-level and inherited platform roles for this member.</div>\n\n <div class=\"space-y-4\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Application Roles</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (role of item.applicationRoles ?? item.roles; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (!((item.applicationRoles ?? item.roles).length)) {\n <span class=\"text-sm text-muted-foreground\">No application roles returned.</span>\n }\n </div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Platform Roles</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (role of item.platformRoles ?? []; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (!(item.platformRoles?.length)) {\n <span class=\"text-sm text-muted-foreground\">No platform roles returned.</span>\n }\n </div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Permissions</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (permission of (item.permissions ?? []).slice(0, 12); track permission) {\n <span class=\"rt-platform-chip\">{{ permission }}</span>\n } @if (!(item.permissions?.length)) {\n <span class=\"text-sm text-muted-foreground\">No permission details returned.</span>\n } @if ((item.permissions?.length ?? 0) > 12) {\n <span class=\"text-sm text-muted-foreground\">+{{ (item.permissions?.length ?? 0) - 12 }} more</span>\n }\n </div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Organization Memberships</div>\n <div panel-description>Organizations this member belongs to inside the application.</div>\n\n <div class=\"space-y-3\">\n @for (organization of item.organizations ?? []; track organization.orgId) {\n <a class=\"rt-platform-link-block cursor-pointer\" [routerLink]=\"['/platform/organizations', organization.orgId]\">\n <div class=\"flex items-center justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ organization.orgName || organization.orgCode || organization.orgId }}</div>\n <div class=\"text-sm text-muted-foreground break-all\">{{ organization.orgId }}</div>\n </div>\n <div class=\"text-sm text-muted-foreground\">{{ organization.roles.length }} roles</div>\n </div>\n\n <div class=\"mt-3 flex flex-wrap gap-2\">\n @for (role of organization.roles; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (organization.roles.length === 0) {\n <span class=\"text-sm text-muted-foreground\">No organization roles</span>\n }\n </div>\n </a>\n } @if (!(item.organizations?.length)) {\n <div class=\"rounded-2xl border border-(--rt-border-color) border-dashed p-4 text-sm text-muted-foreground\">\n No organization memberships returned.\n </div>\n }\n </div>\n </rolatech-platform-detail-panel>\n </section>\n } @else {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">\n Application member not found.\n </section>\n }\n</rolatech-application-workspace-shell>\n" }]
69
+ }] });
70
+
71
+ export { ApplicationMemberDetail };
72
+ //# sourceMappingURL=rolatech-angular-platform-application-member-detail-D3ESzMBX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rolatech-angular-platform-application-member-detail-D3ESzMBX.mjs","sources":["../../../../packages/angular-platform/src/lib/store/application-member-detail.facade.ts","../../../../packages/angular-platform/src/lib/pages/application/application-member-detail/application-member-detail.ts","../../../../packages/angular-platform/src/lib/pages/application/application-member-detail/application-member-detail.html"],"sourcesContent":["import { Injectable, computed, inject, signal } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { ApplicationMemberDetailResponse, ApplicationService } from '@rolatech/angular-services';\n\n@Injectable()\nexport class ApplicationMemberDetailFacade {\n private readonly applicationService = inject(ApplicationService);\n\n readonly loading = signal(false);\n readonly error = signal<string | null>(null);\n readonly item = signal<ApplicationMemberDetailResponse | null>(null);\n\n readonly displayName = computed(() => {\n const item = this.item();\n if (!item) {\n return '';\n }\n\n return item.name || item.fullName || [item.firstName, item.lastName].filter(Boolean).join(' ').trim() || item.username || item.email || item.memberId;\n });\n\n readonly organizationCount = computed(() => this.item()?.organizations?.length ?? this.item()?.organizationCount ?? 0);\n readonly applicationRoleCount = computed(() => this.item()?.applicationRoles?.length ?? this.item()?.roles.length ?? 0);\n readonly platformRoleCount = computed(() => this.item()?.platformRoles?.length ?? 0);\n readonly permissionCount = computed(() => this.item()?.permissions?.length ?? 0);\n\n async load(appId: string, memberId: string): Promise<void> {\n if (!appId || !memberId) {\n this.item.set(null);\n this.error.set('Member context is missing.');\n return;\n }\n\n this.loading.set(true);\n this.error.set(null);\n\n try {\n this.item.set(await firstValueFrom(this.applicationService.findApplicationMemberById(appId, memberId)));\n } catch (error) {\n console.error(error);\n this.item.set(null);\n this.error.set('Unable to load application member details.');\n } finally {\n this.loading.set(false);\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport {\n PlatformDetailPanel,\n PlatformStatCard,\n} from '../../../shared';\nimport { ApplicationMemberDetailFacade } from '../../../store/application-member-detail.facade';\nimport { ApplicationWorkspaceShell } from '../application-workspace-shell/application-workspace-shell';\n\n@Component({\n selector: 'rolatech-application-member-detail',\n standalone: true,\n imports: [RouterLink, ApplicationWorkspaceShell, PlatformStatCard, PlatformDetailPanel],\n templateUrl: './application-member-detail.html',\n styleUrl: './application-member-detail.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [ApplicationMemberDetailFacade],\n})\nexport class ApplicationMemberDetail implements OnInit {\n readonly facade = inject(ApplicationMemberDetailFacade);\n private readonly route = inject(ActivatedRoute);\n\n readonly appId = this.route.snapshot.paramMap.get('appId') ?? '';\n readonly memberId = this.route.snapshot.paramMap.get('memberId') ?? '';\n\n ngOnInit(): void {\n void this.facade.load(this.appId, this.memberId);\n }\n\n verificationLabel(value: boolean | null | undefined): string {\n return value ? 'Verified' : 'Pending';\n }\n}\n","<rolatech-application-workspace-shell [appId]=\"appId\" activeTab=\"members\" sectionTitle=\"Member Detail\">\n @if (facade.loading()) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">Loading member...</section>\n } @else if (facade.item(); as item) {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-6 shadow-sm\">\n <div class=\"flex flex-wrap items-start justify-between gap-4\">\n <div class=\"space-y-2\">\n <div class=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <a [routerLink]=\"['/platform/applications', appId, 'members']\" class=\"hover:underline cursor-pointer\">Members</a>\n <span>/</span>\n <span>{{ facade.displayName() }}</span>\n </div>\n\n <div>\n <h2 class=\"text-xl font-semibold tracking-tight\">{{ facade.displayName() }}</h2>\n <div class=\"mt-1 text-sm text-muted-foreground\">@if (item.username) { &#64;{{ item.username }} } @else { {{ item.userId || item.memberId }} }</div>\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">{{ item.status || 'UNKNOWN' }}</span>\n @for (role of item.applicationRoles ?? item.roles; track role) {\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">{{ role }}</span>\n }\n </div>\n </div>\n\n <a\n [routerLink]=\"['/platform/applications', appId, 'members']\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-4 py-2 text-sm font-medium cursor-pointer\"\n >\n Back to Members\n </a>\n </div>\n </section>\n\n <section class=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <rolatech-platform-stat-card>\n <div stat-label>Organizations</div>\n <div stat-value>{{ facade.organizationCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Application Roles</div>\n <div stat-value>{{ facade.applicationRoleCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Platform Roles</div>\n <div stat-value>{{ facade.platformRoleCount() }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Permissions</div>\n <div stat-value>{{ facade.permissionCount() }}</div>\n </rolatech-platform-stat-card>\n </section>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Basic Information</div>\n <div panel-description>Primary user identity and contact details.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Member ID</div>\n <div class=\"font-medium break-all\">{{ item.memberId }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">User ID</div>\n <div class=\"font-medium break-all\">{{ item.userId || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">First Name</div>\n <div class=\"font-medium\">{{ item.firstName || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Last Name</div>\n <div class=\"font-medium\">{{ item.lastName || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Email</div>\n <div class=\"font-medium\">{{ item.email || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Phone</div>\n <div class=\"font-medium\">{{ item.phone || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Joined At</div>\n <div class=\"font-medium\">{{ item.joinedAt || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Status</div>\n <div class=\"font-medium\">{{ item.status || 'UNKNOWN' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Verification</div>\n <div panel-description>Contact and identity verification state returned by the API.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Email Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.emailVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Phone Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.phoneVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Identity Verification</div>\n <div class=\"font-medium\">{{ verificationLabel(item.verification?.identityVerified) }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Verification Status</div>\n <div class=\"font-medium\">{{ item.verification?.status || '—' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n </section>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Application Access</div>\n <div panel-description>Application-level and inherited platform roles for this member.</div>\n\n <div class=\"space-y-4\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Application Roles</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (role of item.applicationRoles ?? item.roles; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (!((item.applicationRoles ?? item.roles).length)) {\n <span class=\"text-sm text-muted-foreground\">No application roles returned.</span>\n }\n </div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Platform Roles</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (role of item.platformRoles ?? []; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (!(item.platformRoles?.length)) {\n <span class=\"text-sm text-muted-foreground\">No platform roles returned.</span>\n }\n </div>\n </div>\n\n <div>\n <div class=\"text-xs text-muted-foreground\">Permissions</div>\n <div class=\"mt-2 flex flex-wrap gap-2\">\n @for (permission of (item.permissions ?? []).slice(0, 12); track permission) {\n <span class=\"rt-platform-chip\">{{ permission }}</span>\n } @if (!(item.permissions?.length)) {\n <span class=\"text-sm text-muted-foreground\">No permission details returned.</span>\n } @if ((item.permissions?.length ?? 0) > 12) {\n <span class=\"text-sm text-muted-foreground\">+{{ (item.permissions?.length ?? 0) - 12 }} more</span>\n }\n </div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Organization Memberships</div>\n <div panel-description>Organizations this member belongs to inside the application.</div>\n\n <div class=\"space-y-3\">\n @for (organization of item.organizations ?? []; track organization.orgId) {\n <a class=\"rt-platform-link-block cursor-pointer\" [routerLink]=\"['/platform/organizations', organization.orgId]\">\n <div class=\"flex items-center justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ organization.orgName || organization.orgCode || organization.orgId }}</div>\n <div class=\"text-sm text-muted-foreground break-all\">{{ organization.orgId }}</div>\n </div>\n <div class=\"text-sm text-muted-foreground\">{{ organization.roles.length }} roles</div>\n </div>\n\n <div class=\"mt-3 flex flex-wrap gap-2\">\n @for (role of organization.roles; track role) {\n <span class=\"rt-platform-chip\">{{ role }}</span>\n } @if (organization.roles.length === 0) {\n <span class=\"text-sm text-muted-foreground\">No organization roles</span>\n }\n </div>\n </a>\n } @if (!(item.organizations?.length)) {\n <div class=\"rounded-2xl border border-(--rt-border-color) border-dashed p-4 text-sm text-muted-foreground\">\n No organization memberships returned.\n </div>\n }\n </div>\n </rolatech-platform-detail-panel>\n </section>\n } @else {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">\n Application member not found.\n </section>\n }\n</rolatech-application-workspace-shell>\n"],"names":[],"mappings":"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"}