@rolatech/angular-platform 20.3.0-beta.2
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/README.md +3 -0
- package/fesm2022/rolatech-angular-platform-application-create-DqPMquaO.mjs +129 -0
- package/fesm2022/rolatech-angular-platform-application-create-DqPMquaO.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-application-detail-BoITs_yE.mjs +54 -0
- package/fesm2022/rolatech-angular-platform-application-detail-BoITs_yE.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-application-index-BlCbJVDc.mjs +82 -0
- package/fesm2022/rolatech-angular-platform-application-index-BlCbJVDc.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-application-organization-index-D7TJ8CID.mjs +54 -0
- package/fesm2022/rolatech-angular-platform-application-organization-index-D7TJ8CID.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-application-role-index-9_XVRBgD.mjs +66 -0
- package/fesm2022/rolatech-angular-platform-application-role-index-9_XVRBgD.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-application-routes-DE5CJMgn.mjs +38 -0
- package/fesm2022/rolatech-angular-platform-application-routes-DE5CJMgn.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client-detail-BMvM7PvP.mjs +137 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client-detail-BMvM7PvP.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client-editor-75GPRUsF.mjs +281 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client-editor-75GPRUsF.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client-index-DilT3UzO.mjs +95 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client-index-DilT3UzO.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client.routes-D_VFpAgu.mjs +21 -0
- package/fesm2022/rolatech-angular-platform-platform-auth-client.routes-D_VFpAgu.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-endpoint-detail-CEaO9MFQ.mjs +57 -0
- package/fesm2022/rolatech-angular-platform-platform-endpoint-detail-CEaO9MFQ.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-endpoint-index-69W62bRP.mjs +92 -0
- package/fesm2022/rolatech-angular-platform-platform-endpoint-index-69W62bRP.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-endpoint.routes-Cj66S7N-.mjs +13 -0
- package/fesm2022/rolatech-angular-platform-platform-endpoint.routes-Cj66S7N-.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-role-index-8kRxDJiW.mjs +35 -0
- package/fesm2022/rolatech-angular-platform-platform-role-index-8kRxDJiW.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry-detail-CQ4Wk1R8.mjs +89 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry-detail-CQ4Wk1R8.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry-editor-Bd3nIfxd.mjs +246 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry-editor-Bd3nIfxd.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry-index-D4470pau.mjs +95 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry-index-D4470pau.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry.routes-DlWUwwws.mjs +21 -0
- package/fesm2022/rolatech-angular-platform-platform-service-registry.routes-DlWUwwws.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-user-detail-fzo89PHV.mjs +81 -0
- package/fesm2022/rolatech-angular-platform-platform-user-detail-fzo89PHV.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-user-index-DBT4N0zi.mjs +89 -0
- package/fesm2022/rolatech-angular-platform-platform-user-index-DBT4N0zi.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-platform-user.routes-C6OoAsWU.mjs +13 -0
- package/fesm2022/rolatech-angular-platform-platform-user.routes-C6OoAsWU.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-role-permission-page-DslhArZQ.mjs +527 -0
- package/fesm2022/rolatech-angular-platform-role-permission-page-DslhArZQ.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform-role-permission-page.routes-IiX17wDW.mjs +11 -0
- package/fesm2022/rolatech-angular-platform-role-permission-page.routes-IiX17wDW.mjs.map +1 -0
- package/fesm2022/rolatech-angular-platform.mjs +293 -0
- package/fesm2022/rolatech-angular-platform.mjs.map +1 -0
- package/package.json +33 -0
- package/types/rolatech-angular-platform.d.ts +70 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, signal, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
4
|
+
import { firstValueFrom } from 'rxjs';
|
|
5
|
+
import { RoleService } from '@rolatech/angular-services';
|
|
6
|
+
import { PlatformPageHeader, PlatformDataTable, PlatformScopeBadge } from './rolatech-angular-platform.mjs';
|
|
7
|
+
|
|
8
|
+
class PlatformRoleIndexPage {
|
|
9
|
+
roleService = inject(RoleService);
|
|
10
|
+
router = inject(Router);
|
|
11
|
+
route = inject(ActivatedRoute);
|
|
12
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
13
|
+
roles = signal([], ...(ngDevMode ? [{ debugName: "roles" }] : []));
|
|
14
|
+
async ngOnInit() {
|
|
15
|
+
this.loading.set(true);
|
|
16
|
+
try {
|
|
17
|
+
this.roles.set((await firstValueFrom(this.roleService.findPlatformRoles())) ?? []);
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
this.loading.set(false);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
openRole(roleId) {
|
|
24
|
+
void this.router.navigate([roleId, 'permissions'], { relativeTo: this.route });
|
|
25
|
+
}
|
|
26
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformRoleIndexPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
27
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: PlatformRoleIndexPage, isStandalone: true, selector: "rolatech-platform-role-index-page", ngImport: i0, template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">Platform roles</h1>\n <p class=\"text-sm text-muted-foreground\">Manage global roles and the permissions assigned to the platform workspace.</p>\n </div>\n </rolatech-platform-page-header>\n\n <rolatech-platform-data-table>\n <div table-toolbar class=\"flex items-center justify-between gap-3\">\n <h2 class=\"text-base font-semibold\">Roles</h2>\n <div class=\"text-sm text-muted-foreground\">{{ roles().length }} items</div>\n </div>\n\n <thead class=\"bg-muted/40\">\n <tr class=\"text-left\">\n <th class=\"px-4 py-3 font-medium\">Name</th>\n <th class=\"px-4 py-3 font-medium\">Code</th>\n <th class=\"px-4 py-3 font-medium\">Scope</th>\n <th class=\"px-4 py-3 font-medium\">Permissions</th>\n <th class=\"px-4 py-3 font-medium\">Status</th>\n <th class=\"px-4 py-3 font-medium\">Actions</th>\n </tr>\n </thead>\n\n <tbody>\n @if (loading()) {\n <tr>\n <td colspan=\"6\" class=\"px-4 py-10 text-center text-muted-foreground\">Loading platform roles...</td>\n </tr>\n } @else if (roles().length === 0) {\n <tr>\n <td colspan=\"6\" class=\"px-4 py-10 text-center text-muted-foreground\">No platform roles found.</td>\n </tr>\n } @else { @for (role of roles(); track role.id) {\n <tr class=\"border-t border-(--rt-border-color)\">\n <td class=\"px-4 py-3 font-medium\">{{ role.name }}</td>\n <td class=\"px-4 py-3 text-muted-foreground\">{{ role.code }}</td>\n <td class=\"px-4 py-3\">\n <rolatech-platform-scope-badge [scope]=\"role.scope\" />\n </td>\n <td class=\"px-4 py-3\">{{ role.permissionIds.length }}</td>\n <td class=\"px-4 py-3\">\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">\n {{ role.enabled ? 'Enabled' : 'Disabled' }}\n </span>\n </td>\n <td class=\"px-4 py-3\">\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm font-medium\"\n (click)=\"openRole(role.id)\"\n >\n Manage permissions\n </button>\n </td>\n </tr>\n } }\n </tbody>\n </rolatech-platform-data-table>\n</section>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: PlatformPageHeader, selector: "rolatech-platform-page-header" }, { kind: "component", type: PlatformDataTable, selector: "rolatech-platform-data-table" }, { kind: "component", type: PlatformScopeBadge, selector: "rolatech-platform-scope-badge", inputs: ["scope"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
28
|
+
}
|
|
29
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformRoleIndexPage, decorators: [{
|
|
30
|
+
type: Component,
|
|
31
|
+
args: [{ selector: 'rolatech-platform-role-index-page', standalone: true, imports: [PlatformPageHeader, PlatformDataTable, PlatformScopeBadge], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">Platform roles</h1>\n <p class=\"text-sm text-muted-foreground\">Manage global roles and the permissions assigned to the platform workspace.</p>\n </div>\n </rolatech-platform-page-header>\n\n <rolatech-platform-data-table>\n <div table-toolbar class=\"flex items-center justify-between gap-3\">\n <h2 class=\"text-base font-semibold\">Roles</h2>\n <div class=\"text-sm text-muted-foreground\">{{ roles().length }} items</div>\n </div>\n\n <thead class=\"bg-muted/40\">\n <tr class=\"text-left\">\n <th class=\"px-4 py-3 font-medium\">Name</th>\n <th class=\"px-4 py-3 font-medium\">Code</th>\n <th class=\"px-4 py-3 font-medium\">Scope</th>\n <th class=\"px-4 py-3 font-medium\">Permissions</th>\n <th class=\"px-4 py-3 font-medium\">Status</th>\n <th class=\"px-4 py-3 font-medium\">Actions</th>\n </tr>\n </thead>\n\n <tbody>\n @if (loading()) {\n <tr>\n <td colspan=\"6\" class=\"px-4 py-10 text-center text-muted-foreground\">Loading platform roles...</td>\n </tr>\n } @else if (roles().length === 0) {\n <tr>\n <td colspan=\"6\" class=\"px-4 py-10 text-center text-muted-foreground\">No platform roles found.</td>\n </tr>\n } @else { @for (role of roles(); track role.id) {\n <tr class=\"border-t border-(--rt-border-color)\">\n <td class=\"px-4 py-3 font-medium\">{{ role.name }}</td>\n <td class=\"px-4 py-3 text-muted-foreground\">{{ role.code }}</td>\n <td class=\"px-4 py-3\">\n <rolatech-platform-scope-badge [scope]=\"role.scope\" />\n </td>\n <td class=\"px-4 py-3\">{{ role.permissionIds.length }}</td>\n <td class=\"px-4 py-3\">\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">\n {{ role.enabled ? 'Enabled' : 'Disabled' }}\n </span>\n </td>\n <td class=\"px-4 py-3\">\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm font-medium\"\n (click)=\"openRole(role.id)\"\n >\n Manage permissions\n </button>\n </td>\n </tr>\n } }\n </tbody>\n </rolatech-platform-data-table>\n</section>\n", styles: [":host{display:block}\n"] }]
|
|
32
|
+
}] });
|
|
33
|
+
|
|
34
|
+
export { PlatformRoleIndexPage };
|
|
35
|
+
//# sourceMappingURL=rolatech-angular-platform-platform-role-index-8kRxDJiW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rolatech-angular-platform-platform-role-index-8kRxDJiW.mjs","sources":["../../../../packages/angular-platform/src/lib/pages/role/platform-role-index/platform-role-index.ts","../../../../packages/angular-platform/src/lib/pages/role/platform-role-index/platform-role-index.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { firstValueFrom } from 'rxjs';\nimport { RoleResponse, RoleService } from '@rolatech/angular-services';\nimport { PlatformDataTable, PlatformPageHeader, PlatformScopeBadge } from '../../../shared';\n\n@Component({\n selector: 'rolatech-platform-role-index-page',\n standalone: true,\n imports: [PlatformPageHeader, PlatformDataTable, PlatformScopeBadge],\n templateUrl: './platform-role-index.html',\n styleUrl: './platform-role-index.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PlatformRoleIndexPage implements OnInit {\n private readonly roleService = inject(RoleService);\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n\n readonly loading = signal(false);\n readonly roles = signal<RoleResponse[]>([]);\n\n async ngOnInit(): Promise<void> {\n this.loading.set(true);\n try {\n this.roles.set((await firstValueFrom(this.roleService.findPlatformRoles())) ?? []);\n } finally {\n this.loading.set(false);\n }\n }\n\n openRole(roleId: string): void {\n void this.router.navigate([roleId, 'permissions'], { relativeTo: this.route });\n }\n}\n","<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">Platform roles</h1>\n <p class=\"text-sm text-muted-foreground\">Manage global roles and the permissions assigned to the platform workspace.</p>\n </div>\n </rolatech-platform-page-header>\n\n <rolatech-platform-data-table>\n <div table-toolbar class=\"flex items-center justify-between gap-3\">\n <h2 class=\"text-base font-semibold\">Roles</h2>\n <div class=\"text-sm text-muted-foreground\">{{ roles().length }} items</div>\n </div>\n\n <thead class=\"bg-muted/40\">\n <tr class=\"text-left\">\n <th class=\"px-4 py-3 font-medium\">Name</th>\n <th class=\"px-4 py-3 font-medium\">Code</th>\n <th class=\"px-4 py-3 font-medium\">Scope</th>\n <th class=\"px-4 py-3 font-medium\">Permissions</th>\n <th class=\"px-4 py-3 font-medium\">Status</th>\n <th class=\"px-4 py-3 font-medium\">Actions</th>\n </tr>\n </thead>\n\n <tbody>\n @if (loading()) {\n <tr>\n <td colspan=\"6\" class=\"px-4 py-10 text-center text-muted-foreground\">Loading platform roles...</td>\n </tr>\n } @else if (roles().length === 0) {\n <tr>\n <td colspan=\"6\" class=\"px-4 py-10 text-center text-muted-foreground\">No platform roles found.</td>\n </tr>\n } @else { @for (role of roles(); track role.id) {\n <tr class=\"border-t border-(--rt-border-color)\">\n <td class=\"px-4 py-3 font-medium\">{{ role.name }}</td>\n <td class=\"px-4 py-3 text-muted-foreground\">{{ role.code }}</td>\n <td class=\"px-4 py-3\">\n <rolatech-platform-scope-badge [scope]=\"role.scope\" />\n </td>\n <td class=\"px-4 py-3\">{{ role.permissionIds.length }}</td>\n <td class=\"px-4 py-3\">\n <span class=\"inline-flex rounded-full border border-(--rt-border-color) px-2.5 py-1 text-xs\">\n {{ role.enabled ? 'Enabled' : 'Disabled' }}\n </span>\n </td>\n <td class=\"px-4 py-3\">\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm font-medium\"\n (click)=\"openRole(role.id)\"\n >\n Manage permissions\n </button>\n </td>\n </tr>\n } }\n </tbody>\n </rolatech-platform-data-table>\n</section>\n"],"names":[],"mappings":";;;;;;;MAca,qBAAqB,CAAA;AACf,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACjC,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,IAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAEtC,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,mDAAC;AACvB,IAAA,KAAK,GAAG,MAAM,CAAiB,EAAE,iDAAC;AAE3C,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI;YACF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,CAAC;QACpF;gBAAU;AACR,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACzB;IACF;AAEA,IAAA,QAAQ,CAAC,MAAc,EAAA;QACrB,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAChF;uGAnBW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,6FCdlC,0iFA6DA,EAAA,MAAA,EAAA,CAAA,wBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDpDY,kBAAkB,EAAA,QAAA,EAAA,+BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,iBAAiB,yEAAE,kBAAkB,EAAA,QAAA,EAAA,+BAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAKxD,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBARjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mCAAmC,EAAA,UAAA,EACjC,IAAI,EAAA,OAAA,EACP,CAAC,kBAAkB,EAAE,iBAAiB,EAAE,kBAAkB,CAAC,EAAA,eAAA,EAGnD,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,0iFAAA,EAAA,MAAA,EAAA,CAAA,wBAAA,CAAA,EAAA;;;;;"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { KeyValuePipe, JsonPipe } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, signal, Injectable, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
|
5
|
+
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
|
|
6
|
+
import { PlatformPageHeader, PlatformStatCard, PlatformDetailPanel, PlatformStatusBadge } from './rolatech-angular-platform.mjs';
|
|
7
|
+
import { firstValueFrom } from 'rxjs';
|
|
8
|
+
import { PlatformServiceRegistryService } from '@rolatech/angular-services';
|
|
9
|
+
|
|
10
|
+
class PlatformServiceRegistryDetailFacade {
|
|
11
|
+
serviceRegistryService = inject(PlatformServiceRegistryService);
|
|
12
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
13
|
+
deleting = signal(false, ...(ngDevMode ? [{ debugName: "deleting" }] : []));
|
|
14
|
+
error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
15
|
+
item = signal(null, ...(ngDevMode ? [{ debugName: "item" }] : []));
|
|
16
|
+
async load(serviceId) {
|
|
17
|
+
this.loading.set(true);
|
|
18
|
+
this.error.set(null);
|
|
19
|
+
try {
|
|
20
|
+
this.item.set(await firstValueFrom(this.serviceRegistryService.findServiceById(serviceId)));
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(error);
|
|
24
|
+
this.item.set(null);
|
|
25
|
+
this.error.set('Unable to load service registry details.');
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
this.loading.set(false);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async delete(serviceId) {
|
|
32
|
+
this.deleting.set(true);
|
|
33
|
+
this.error.set(null);
|
|
34
|
+
try {
|
|
35
|
+
await firstValueFrom(this.serviceRegistryService.deleteService(serviceId));
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(error);
|
|
40
|
+
this.error.set('Unable to delete the service registry entry.');
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
this.deleting.set(false);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryDetailFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
48
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryDetailFacade });
|
|
49
|
+
}
|
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryDetailFacade, decorators: [{
|
|
51
|
+
type: Injectable
|
|
52
|
+
}] });
|
|
53
|
+
|
|
54
|
+
class PlatformServiceRegistryDetailPage {
|
|
55
|
+
facade = inject(PlatformServiceRegistryDetailFacade);
|
|
56
|
+
route = inject(ActivatedRoute);
|
|
57
|
+
router = inject(Router);
|
|
58
|
+
snackBar = inject(MatSnackBar);
|
|
59
|
+
serviceId = this.route.snapshot.paramMap.get('serviceId') ?? '';
|
|
60
|
+
ngOnInit() {
|
|
61
|
+
if (this.serviceId) {
|
|
62
|
+
void this.facade.load(this.serviceId);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async deleteService() {
|
|
66
|
+
const item = this.facade.item();
|
|
67
|
+
if (!item) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (globalThis.confirm && !globalThis.confirm(`Delete service registry entry "${item.name}"? This cannot be undone.`)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const deleted = await this.facade.delete(this.serviceId);
|
|
74
|
+
if (!deleted) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
this.snackBar.open('Service registry entry deleted.', 'Dismiss', { duration: 3000 });
|
|
78
|
+
await this.router.navigate(['/platform/service-registry']);
|
|
79
|
+
}
|
|
80
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryDetailPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
81
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: PlatformServiceRegistryDetailPage, isStandalone: true, selector: "rolatech-platform-service-registry-detail-page", providers: [PlatformServiceRegistryDetailFacade], ngImport: i0, template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\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 service...</section>\n } @else if (facade.item(); as item) {\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-2\">\n <div class=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <a routerLink=\"../\" class=\"hover:underline cursor-pointer\">Service Registry</a>\n <span>/</span>\n <span>{{ item.name }}</span>\n </div>\n\n <div>\n <h1 class=\"text-2xl font-semibold tracking-tight\">{{ item.name }}</h1>\n <div class=\"mt-1 text-sm text-muted-foreground\">{{ item.code || item.id }}</div>\n </div>\n\n @if (item.description) {\n <p class=\"max-w-3xl text-sm text-muted-foreground\">{{ item.description }}</p>\n }\n\n <div class=\"flex flex-wrap gap-2\">\n <rolatech-platform-status-badge [status]=\"item.status || (item.enabled ? 'ENABLED' : 'DISABLED')\" />\n @if (item.healthStatus) {\n <span class=\"rt-platform-chip\">{{ item.healthStatus }}</span>\n }\n @if (item.version) {\n <span class=\"rt-platform-chip\">{{ item.version }}</span>\n }\n </div>\n </div>\n\n <div header-actions class=\"flex flex-wrap gap-3\">\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 [routerLink]=\"['/platform/service-registry', item.id, 'edit']\"\n >\n Edit\n </button>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-rose-300/40 px-4 py-2 text-sm font-medium text-rose-200\"\n [disabled]=\"facade.deleting()\"\n (click)=\"deleteService()\"\n >\n {{ facade.deleting() ? 'Deleting\u2026' : 'Delete' }}\n </button>\n </div>\n </rolatech-platform-page-header>\n\n @if (facade.error()) {\n <section class=\"rounded-2xl border border-rose-300/40 bg-rose-500/10 px-4 py-3 text-sm text-(--rt-text-primary)\">\n {{ facade.error() }}\n </section>\n }\n\n <section class=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <rolatech-platform-stat-card>\n <div stat-label>Endpoints</div>\n <div stat-value>{{ item.endpointCount }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Instances</div>\n <div stat-value>{{ item.instanceCount }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Health</div>\n <div stat-value class=\"text-sm\">{{ item.healthStatus || 'UNKNOWN' }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Updated</div>\n <div stat-value class=\"text-sm\">{{ item.updatedAt || '\u2014' }}</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>Registry Details</div>\n <div panel-description>Primary service registry metadata.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Namespace</div>\n <div class=\"font-medium\">{{ item.namespace || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Type</div>\n <div class=\"font-medium\">{{ item.serviceType || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Base URL</div>\n <div class=\"font-medium break-all\">{{ item.baseUrl || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Version</div>\n <div class=\"font-medium\">{{ item.version || '\u2014' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Tags</div>\n <div panel-description>Backend tags or labels attached to this service.</div>\n\n <div class=\"flex flex-wrap gap-2\">\n @for (tag of item.tags; track tag) {\n <span class=\"rt-platform-chip\">{{ tag }}</span>\n } @if (item.tags.length === 0) {\n <span class=\"text-sm text-muted-foreground\">No tags returned.</span>\n }\n </div>\n </rolatech-platform-detail-panel>\n </section>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Additional Attributes</div>\n <div panel-description>Unmapped backend fields are surfaced here for platform diagnostics.</div>\n\n @if (item.attributes && (item.attributes | keyvalue).length > 0) {\n <div class=\"grid gap-4 md:grid-cols-2\">\n @for (entry of item.attributes | keyvalue; track entry.key) {\n <div class=\"rounded-2xl border border-(--rt-border-color) p-4\">\n <div class=\"text-xs text-muted-foreground\">{{ entry.key }}</div>\n <div class=\"mt-2 break-all text-sm font-medium\">{{ entry.value | json }}</div>\n </div>\n }\n </div>\n } @else {\n <div class=\"rounded-2xl border border-(--rt-border-color) border-dashed p-4 text-sm text-muted-foreground\">No additional service metadata was returned.</div>\n }\n </rolatech-platform-detail-panel>\n } @else {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">\n {{ facade.error() || 'Service not found.' }}\n </section>\n }\n</section>\n", styles: [":host{display:block}.rt-platform-chip{display:inline-flex;align-items:center;border:1px solid var(--rt-outline);border-radius:9999px;padding:.25rem .75rem;font-size:.75rem;font-weight:600;background-color:color-mix(in srgb,var(--rt-brand-color) 10%,transparent);color:var(--rt-text-primary)}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "component", type: PlatformPageHeader, selector: "rolatech-platform-page-header" }, { kind: "component", type: PlatformStatCard, selector: "rolatech-platform-stat-card" }, { kind: "component", type: PlatformDetailPanel, selector: "rolatech-platform-detail-panel" }, { kind: "component", type: PlatformStatusBadge, selector: "rolatech-platform-status-badge", inputs: ["status"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
82
|
+
}
|
|
83
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryDetailPage, decorators: [{
|
|
84
|
+
type: Component,
|
|
85
|
+
args: [{ selector: 'rolatech-platform-service-registry-detail-page', standalone: true, imports: [RouterLink, KeyValuePipe, JsonPipe, MatSnackBarModule, PlatformPageHeader, PlatformStatCard, PlatformDetailPanel, PlatformStatusBadge], changeDetection: ChangeDetectionStrategy.OnPush, providers: [PlatformServiceRegistryDetailFacade], template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\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 service...</section>\n } @else if (facade.item(); as item) {\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-2\">\n <div class=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <a routerLink=\"../\" class=\"hover:underline cursor-pointer\">Service Registry</a>\n <span>/</span>\n <span>{{ item.name }}</span>\n </div>\n\n <div>\n <h1 class=\"text-2xl font-semibold tracking-tight\">{{ item.name }}</h1>\n <div class=\"mt-1 text-sm text-muted-foreground\">{{ item.code || item.id }}</div>\n </div>\n\n @if (item.description) {\n <p class=\"max-w-3xl text-sm text-muted-foreground\">{{ item.description }}</p>\n }\n\n <div class=\"flex flex-wrap gap-2\">\n <rolatech-platform-status-badge [status]=\"item.status || (item.enabled ? 'ENABLED' : 'DISABLED')\" />\n @if (item.healthStatus) {\n <span class=\"rt-platform-chip\">{{ item.healthStatus }}</span>\n }\n @if (item.version) {\n <span class=\"rt-platform-chip\">{{ item.version }}</span>\n }\n </div>\n </div>\n\n <div header-actions class=\"flex flex-wrap gap-3\">\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 [routerLink]=\"['/platform/service-registry', item.id, 'edit']\"\n >\n Edit\n </button>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-rose-300/40 px-4 py-2 text-sm font-medium text-rose-200\"\n [disabled]=\"facade.deleting()\"\n (click)=\"deleteService()\"\n >\n {{ facade.deleting() ? 'Deleting\u2026' : 'Delete' }}\n </button>\n </div>\n </rolatech-platform-page-header>\n\n @if (facade.error()) {\n <section class=\"rounded-2xl border border-rose-300/40 bg-rose-500/10 px-4 py-3 text-sm text-(--rt-text-primary)\">\n {{ facade.error() }}\n </section>\n }\n\n <section class=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <rolatech-platform-stat-card>\n <div stat-label>Endpoints</div>\n <div stat-value>{{ item.endpointCount }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Instances</div>\n <div stat-value>{{ item.instanceCount }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Health</div>\n <div stat-value class=\"text-sm\">{{ item.healthStatus || 'UNKNOWN' }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Updated</div>\n <div stat-value class=\"text-sm\">{{ item.updatedAt || '\u2014' }}</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>Registry Details</div>\n <div panel-description>Primary service registry metadata.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Namespace</div>\n <div class=\"font-medium\">{{ item.namespace || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Type</div>\n <div class=\"font-medium\">{{ item.serviceType || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Base URL</div>\n <div class=\"font-medium break-all\">{{ item.baseUrl || '\u2014' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Version</div>\n <div class=\"font-medium\">{{ item.version || '\u2014' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Tags</div>\n <div panel-description>Backend tags or labels attached to this service.</div>\n\n <div class=\"flex flex-wrap gap-2\">\n @for (tag of item.tags; track tag) {\n <span class=\"rt-platform-chip\">{{ tag }}</span>\n } @if (item.tags.length === 0) {\n <span class=\"text-sm text-muted-foreground\">No tags returned.</span>\n }\n </div>\n </rolatech-platform-detail-panel>\n </section>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Additional Attributes</div>\n <div panel-description>Unmapped backend fields are surfaced here for platform diagnostics.</div>\n\n @if (item.attributes && (item.attributes | keyvalue).length > 0) {\n <div class=\"grid gap-4 md:grid-cols-2\">\n @for (entry of item.attributes | keyvalue; track entry.key) {\n <div class=\"rounded-2xl border border-(--rt-border-color) p-4\">\n <div class=\"text-xs text-muted-foreground\">{{ entry.key }}</div>\n <div class=\"mt-2 break-all text-sm font-medium\">{{ entry.value | json }}</div>\n </div>\n }\n </div>\n } @else {\n <div class=\"rounded-2xl border border-(--rt-border-color) border-dashed p-4 text-sm text-muted-foreground\">No additional service metadata was returned.</div>\n }\n </rolatech-platform-detail-panel>\n } @else {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">\n {{ facade.error() || 'Service not found.' }}\n </section>\n }\n</section>\n", styles: [":host{display:block}.rt-platform-chip{display:inline-flex;align-items:center;border:1px solid var(--rt-outline);border-radius:9999px;padding:.25rem .75rem;font-size:.75rem;font-weight:600;background-color:color-mix(in srgb,var(--rt-brand-color) 10%,transparent);color:var(--rt-text-primary)}\n"] }]
|
|
86
|
+
}] });
|
|
87
|
+
|
|
88
|
+
export { PlatformServiceRegistryDetailPage };
|
|
89
|
+
//# sourceMappingURL=rolatech-angular-platform-platform-service-registry-detail-CQ4Wk1R8.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rolatech-angular-platform-platform-service-registry-detail-CQ4Wk1R8.mjs","sources":["../../../../packages/angular-platform/src/lib/store/platform-service-registry-detail.facade.ts","../../../../packages/angular-platform/src/lib/pages/service-registry/platform-service-registry-detail/platform-service-registry-detail.ts","../../../../packages/angular-platform/src/lib/pages/service-registry/platform-service-registry-detail/platform-service-registry-detail.html"],"sourcesContent":["import { Injectable, inject, signal } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { PlatformServiceRegistryDetailResponse, PlatformServiceRegistryService } from '@rolatech/angular-services';\n\n@Injectable()\nexport class PlatformServiceRegistryDetailFacade {\n private readonly serviceRegistryService = inject(PlatformServiceRegistryService);\n\n readonly loading = signal(false);\n readonly deleting = signal(false);\n readonly error = signal<string | null>(null);\n readonly item = signal<PlatformServiceRegistryDetailResponse | null>(null);\n\n async load(serviceId: string): Promise<void> {\n this.loading.set(true);\n this.error.set(null);\n\n try {\n this.item.set(await firstValueFrom(this.serviceRegistryService.findServiceById(serviceId)));\n } catch (error) {\n console.error(error);\n this.item.set(null);\n this.error.set('Unable to load service registry details.');\n } finally {\n this.loading.set(false);\n }\n }\n\n async delete(serviceId: string): Promise<boolean> {\n this.deleting.set(true);\n this.error.set(null);\n\n try {\n await firstValueFrom(this.serviceRegistryService.deleteService(serviceId));\n return true;\n } catch (error) {\n console.error(error);\n this.error.set('Unable to delete the service registry entry.');\n return false;\n } finally {\n this.deleting.set(false);\n }\n }\n}\n","import { JsonPipe, KeyValuePipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core';\nimport { ActivatedRoute, Router, RouterLink } from '@angular/router';\nimport { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';\nimport { PlatformDetailPanel, PlatformPageHeader, PlatformStatCard, PlatformStatusBadge } from '../../../shared';\nimport { PlatformServiceRegistryDetailFacade } from '../../../store/platform-service-registry-detail.facade';\n\n@Component({\n selector: 'rolatech-platform-service-registry-detail-page',\n standalone: true,\n imports: [RouterLink, KeyValuePipe, JsonPipe, MatSnackBarModule, PlatformPageHeader, PlatformStatCard, PlatformDetailPanel, PlatformStatusBadge],\n templateUrl: './platform-service-registry-detail.html',\n styleUrl: './platform-service-registry-detail.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [PlatformServiceRegistryDetailFacade],\n})\nexport class PlatformServiceRegistryDetailPage implements OnInit {\n readonly facade = inject(PlatformServiceRegistryDetailFacade);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly snackBar = inject(MatSnackBar);\n\n readonly serviceId = this.route.snapshot.paramMap.get('serviceId') ?? '';\n\n ngOnInit(): void {\n if (this.serviceId) {\n void this.facade.load(this.serviceId);\n }\n }\n\n async deleteService(): Promise<void> {\n const item = this.facade.item();\n if (!item) {\n return;\n }\n\n if (globalThis.confirm && !globalThis.confirm(`Delete service registry entry \"${item.name}\"? This cannot be undone.`)) {\n return;\n }\n\n const deleted = await this.facade.delete(this.serviceId);\n if (!deleted) {\n return;\n }\n\n this.snackBar.open('Service registry entry deleted.', 'Dismiss', { duration: 3000 });\n await this.router.navigate(['/platform/service-registry']);\n }\n}\n","<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\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 service...</section>\n } @else if (facade.item(); as item) {\n <rolatech-platform-page-header>\n <div header-left class=\"space-y-2\">\n <div class=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <a routerLink=\"../\" class=\"hover:underline cursor-pointer\">Service Registry</a>\n <span>/</span>\n <span>{{ item.name }}</span>\n </div>\n\n <div>\n <h1 class=\"text-2xl font-semibold tracking-tight\">{{ item.name }}</h1>\n <div class=\"mt-1 text-sm text-muted-foreground\">{{ item.code || item.id }}</div>\n </div>\n\n @if (item.description) {\n <p class=\"max-w-3xl text-sm text-muted-foreground\">{{ item.description }}</p>\n }\n\n <div class=\"flex flex-wrap gap-2\">\n <rolatech-platform-status-badge [status]=\"item.status || (item.enabled ? 'ENABLED' : 'DISABLED')\" />\n @if (item.healthStatus) {\n <span class=\"rt-platform-chip\">{{ item.healthStatus }}</span>\n }\n @if (item.version) {\n <span class=\"rt-platform-chip\">{{ item.version }}</span>\n }\n </div>\n </div>\n\n <div header-actions class=\"flex flex-wrap gap-3\">\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 [routerLink]=\"['/platform/service-registry', item.id, 'edit']\"\n >\n Edit\n </button>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl border border-rose-300/40 px-4 py-2 text-sm font-medium text-rose-200\"\n [disabled]=\"facade.deleting()\"\n (click)=\"deleteService()\"\n >\n {{ facade.deleting() ? 'Deleting…' : 'Delete' }}\n </button>\n </div>\n </rolatech-platform-page-header>\n\n @if (facade.error()) {\n <section class=\"rounded-2xl border border-rose-300/40 bg-rose-500/10 px-4 py-3 text-sm text-(--rt-text-primary)\">\n {{ facade.error() }}\n </section>\n }\n\n <section class=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n <rolatech-platform-stat-card>\n <div stat-label>Endpoints</div>\n <div stat-value>{{ item.endpointCount }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Instances</div>\n <div stat-value>{{ item.instanceCount }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Health</div>\n <div stat-value class=\"text-sm\">{{ item.healthStatus || 'UNKNOWN' }}</div>\n </rolatech-platform-stat-card>\n\n <rolatech-platform-stat-card>\n <div stat-label>Updated</div>\n <div stat-value class=\"text-sm\">{{ item.updatedAt || '—' }}</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>Registry Details</div>\n <div panel-description>Primary service registry metadata.</div>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <div>\n <div class=\"text-xs text-muted-foreground\">Namespace</div>\n <div class=\"font-medium\">{{ item.namespace || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Type</div>\n <div class=\"font-medium\">{{ item.serviceType || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Base URL</div>\n <div class=\"font-medium break-all\">{{ item.baseUrl || '—' }}</div>\n </div>\n <div>\n <div class=\"text-xs text-muted-foreground\">Version</div>\n <div class=\"font-medium\">{{ item.version || '—' }}</div>\n </div>\n </div>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Tags</div>\n <div panel-description>Backend tags or labels attached to this service.</div>\n\n <div class=\"flex flex-wrap gap-2\">\n @for (tag of item.tags; track tag) {\n <span class=\"rt-platform-chip\">{{ tag }}</span>\n } @if (item.tags.length === 0) {\n <span class=\"text-sm text-muted-foreground\">No tags returned.</span>\n }\n </div>\n </rolatech-platform-detail-panel>\n </section>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Additional Attributes</div>\n <div panel-description>Unmapped backend fields are surfaced here for platform diagnostics.</div>\n\n @if (item.attributes && (item.attributes | keyvalue).length > 0) {\n <div class=\"grid gap-4 md:grid-cols-2\">\n @for (entry of item.attributes | keyvalue; track entry.key) {\n <div class=\"rounded-2xl border border-(--rt-border-color) p-4\">\n <div class=\"text-xs text-muted-foreground\">{{ entry.key }}</div>\n <div class=\"mt-2 break-all text-sm font-medium\">{{ entry.value | json }}</div>\n </div>\n }\n </div>\n } @else {\n <div class=\"rounded-2xl border border-(--rt-border-color) border-dashed p-4 text-sm text-muted-foreground\">No additional service metadata was returned.</div>\n }\n </rolatech-platform-detail-panel>\n } @else {\n <section class=\"rounded-2xl border border-(--rt-border-color) bg-card p-10 text-center text-muted-foreground shadow-sm\">\n {{ facade.error() || 'Service not found.' }}\n </section>\n }\n</section>\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,246 @@
|
|
|
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 { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
|
|
5
|
+
import { PlatformPageHeader, PlatformDetailPanel, PlatformStickyActionBar } from './rolatech-angular-platform.mjs';
|
|
6
|
+
import { PlatformServiceRegistryService } from '@rolatech/angular-services';
|
|
7
|
+
import { firstValueFrom } from 'rxjs';
|
|
8
|
+
|
|
9
|
+
class PlatformServiceRegistryEditorFacade {
|
|
10
|
+
serviceRegistryService = inject(PlatformServiceRegistryService);
|
|
11
|
+
loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
12
|
+
saving = signal(false, ...(ngDevMode ? [{ debugName: "saving" }] : []));
|
|
13
|
+
deleting = signal(false, ...(ngDevMode ? [{ debugName: "deleting" }] : []));
|
|
14
|
+
error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
15
|
+
id = signal(null, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
16
|
+
code = signal('', ...(ngDevMode ? [{ debugName: "code" }] : []));
|
|
17
|
+
name = signal('', ...(ngDevMode ? [{ debugName: "name" }] : []));
|
|
18
|
+
namespace = signal('', ...(ngDevMode ? [{ debugName: "namespace" }] : []));
|
|
19
|
+
serviceType = signal('', ...(ngDevMode ? [{ debugName: "serviceType" }] : []));
|
|
20
|
+
version = signal('', ...(ngDevMode ? [{ debugName: "version" }] : []));
|
|
21
|
+
baseUrl = signal('', ...(ngDevMode ? [{ debugName: "baseUrl" }] : []));
|
|
22
|
+
description = signal('', ...(ngDevMode ? [{ debugName: "description" }] : []));
|
|
23
|
+
enabled = signal(true, ...(ngDevMode ? [{ debugName: "enabled" }] : []));
|
|
24
|
+
tagsText = signal('', ...(ngDevMode ? [{ debugName: "tagsText" }] : []));
|
|
25
|
+
attributesText = signal('', ...(ngDevMode ? [{ debugName: "attributesText" }] : []));
|
|
26
|
+
async load(id) {
|
|
27
|
+
this.loading.set(true);
|
|
28
|
+
this.error.set(null);
|
|
29
|
+
try {
|
|
30
|
+
const item = await firstValueFrom(this.serviceRegistryService.findServiceById(id));
|
|
31
|
+
this.patchForm(item);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error(error);
|
|
35
|
+
this.error.set('Unable to load the service registry entry.');
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
this.loading.set(false);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async save() {
|
|
42
|
+
const name = this.name().trim();
|
|
43
|
+
if (!name) {
|
|
44
|
+
this.error.set('Name is required.');
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const attributes = this.parseAttributes(this.attributesText());
|
|
48
|
+
if (attributes === undefined) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
this.saving.set(true);
|
|
52
|
+
this.error.set(null);
|
|
53
|
+
try {
|
|
54
|
+
const payload = {
|
|
55
|
+
code: this.code().trim() || null,
|
|
56
|
+
name,
|
|
57
|
+
namespace: this.namespace().trim() || null,
|
|
58
|
+
serviceType: this.serviceType().trim() || null,
|
|
59
|
+
version: this.version().trim() || null,
|
|
60
|
+
baseUrl: this.baseUrl().trim() || null,
|
|
61
|
+
description: this.description().trim() || null,
|
|
62
|
+
enabled: this.enabled(),
|
|
63
|
+
tags: this.parseList(this.tagsText()),
|
|
64
|
+
attributes,
|
|
65
|
+
};
|
|
66
|
+
const result = this.id()
|
|
67
|
+
? await firstValueFrom(this.serviceRegistryService.updateService(this.id(), payload))
|
|
68
|
+
: await firstValueFrom(this.serviceRegistryService.createService(payload));
|
|
69
|
+
this.patchForm(result);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error(error);
|
|
74
|
+
this.error.set('Unable to save the service registry entry.');
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
this.saving.set(false);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async delete(id = this.id()) {
|
|
82
|
+
if (!id) {
|
|
83
|
+
this.error.set('Service registry ID is missing.');
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
this.deleting.set(true);
|
|
87
|
+
this.error.set(null);
|
|
88
|
+
try {
|
|
89
|
+
await firstValueFrom(this.serviceRegistryService.deleteService(id));
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error(error);
|
|
94
|
+
this.error.set('Unable to delete the service registry entry.');
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
this.deleting.set(false);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
setCode(value) {
|
|
102
|
+
this.code.set(value);
|
|
103
|
+
}
|
|
104
|
+
setName(value) {
|
|
105
|
+
this.name.set(value);
|
|
106
|
+
}
|
|
107
|
+
setNamespace(value) {
|
|
108
|
+
this.namespace.set(value);
|
|
109
|
+
}
|
|
110
|
+
setServiceType(value) {
|
|
111
|
+
this.serviceType.set(value);
|
|
112
|
+
}
|
|
113
|
+
setVersion(value) {
|
|
114
|
+
this.version.set(value);
|
|
115
|
+
}
|
|
116
|
+
setBaseUrl(value) {
|
|
117
|
+
this.baseUrl.set(value);
|
|
118
|
+
}
|
|
119
|
+
setDescription(value) {
|
|
120
|
+
this.description.set(value);
|
|
121
|
+
}
|
|
122
|
+
setEnabled(value) {
|
|
123
|
+
this.enabled.set(value);
|
|
124
|
+
}
|
|
125
|
+
setTagsText(value) {
|
|
126
|
+
this.tagsText.set(value);
|
|
127
|
+
}
|
|
128
|
+
setAttributesText(value) {
|
|
129
|
+
this.attributesText.set(value);
|
|
130
|
+
}
|
|
131
|
+
patchForm(item) {
|
|
132
|
+
this.id.set(item.id);
|
|
133
|
+
this.code.set(item.code ?? '');
|
|
134
|
+
this.name.set(item.name ?? '');
|
|
135
|
+
this.namespace.set(item.namespace ?? '');
|
|
136
|
+
this.serviceType.set(item.serviceType ?? '');
|
|
137
|
+
this.version.set(item.version ?? '');
|
|
138
|
+
this.baseUrl.set(item.baseUrl ?? '');
|
|
139
|
+
this.description.set(item.description ?? '');
|
|
140
|
+
this.enabled.set(item.enabled);
|
|
141
|
+
this.tagsText.set(item.tags.join('\n'));
|
|
142
|
+
this.attributesText.set(item.attributes ? JSON.stringify(item.attributes, null, 2) : '');
|
|
143
|
+
}
|
|
144
|
+
parseList(value) {
|
|
145
|
+
return Array.from(new Set(value
|
|
146
|
+
.split(/\r?\n|,/)
|
|
147
|
+
.map((item) => item.trim())
|
|
148
|
+
.filter(Boolean)));
|
|
149
|
+
}
|
|
150
|
+
parseAttributes(value) {
|
|
151
|
+
const trimmed = value.trim();
|
|
152
|
+
if (!trimmed) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const parsed = JSON.parse(trimmed);
|
|
157
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
158
|
+
this.error.set('Additional attributes must be a JSON object.');
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
return parsed;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error(error);
|
|
165
|
+
this.error.set('Additional attributes must be valid JSON.');
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryEditorFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
170
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryEditorFacade });
|
|
171
|
+
}
|
|
172
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryEditorFacade, decorators: [{
|
|
173
|
+
type: Injectable
|
|
174
|
+
}] });
|
|
175
|
+
|
|
176
|
+
class PlatformServiceRegistryEditorPage {
|
|
177
|
+
facade = inject(PlatformServiceRegistryEditorFacade);
|
|
178
|
+
route = inject(ActivatedRoute);
|
|
179
|
+
router = inject(Router);
|
|
180
|
+
snackBar = inject(MatSnackBar);
|
|
181
|
+
serviceId = this.route.snapshot.paramMap.get('serviceId');
|
|
182
|
+
get isEdit() {
|
|
183
|
+
return !!this.serviceId;
|
|
184
|
+
}
|
|
185
|
+
ngOnInit() {
|
|
186
|
+
if (this.serviceId) {
|
|
187
|
+
void this.facade.load(this.serviceId);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
onCodeInput(event) {
|
|
191
|
+
this.facade.setCode(event.target.value);
|
|
192
|
+
}
|
|
193
|
+
onNameInput(event) {
|
|
194
|
+
this.facade.setName(event.target.value);
|
|
195
|
+
}
|
|
196
|
+
onNamespaceInput(event) {
|
|
197
|
+
this.facade.setNamespace(event.target.value);
|
|
198
|
+
}
|
|
199
|
+
onServiceTypeInput(event) {
|
|
200
|
+
this.facade.setServiceType(event.target.value);
|
|
201
|
+
}
|
|
202
|
+
onVersionInput(event) {
|
|
203
|
+
this.facade.setVersion(event.target.value);
|
|
204
|
+
}
|
|
205
|
+
onBaseUrlInput(event) {
|
|
206
|
+
this.facade.setBaseUrl(event.target.value);
|
|
207
|
+
}
|
|
208
|
+
onDescriptionInput(event) {
|
|
209
|
+
this.facade.setDescription(event.target.value);
|
|
210
|
+
}
|
|
211
|
+
onEnabledChange(event) {
|
|
212
|
+
this.facade.setEnabled(event.target.checked);
|
|
213
|
+
}
|
|
214
|
+
onTagsInput(event) {
|
|
215
|
+
this.facade.setTagsText(event.target.value);
|
|
216
|
+
}
|
|
217
|
+
onAttributesInput(event) {
|
|
218
|
+
this.facade.setAttributesText(event.target.value);
|
|
219
|
+
}
|
|
220
|
+
async save() {
|
|
221
|
+
const result = await this.facade.save();
|
|
222
|
+
if (!result) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
this.snackBar.open(this.isEdit ? 'Service registry entry updated.' : 'Service registry entry created.', 'Dismiss', {
|
|
226
|
+
duration: 3000,
|
|
227
|
+
});
|
|
228
|
+
await this.router.navigate(['/platform/service-registry', result.id]);
|
|
229
|
+
}
|
|
230
|
+
async cancel() {
|
|
231
|
+
if (this.isEdit && this.serviceId) {
|
|
232
|
+
await this.router.navigate(['/platform/service-registry', this.serviceId]);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
await this.router.navigate(['/platform/service-registry']);
|
|
236
|
+
}
|
|
237
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryEditorPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
238
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: PlatformServiceRegistryEditorPage, isStandalone: true, selector: "rolatech-platform-service-registry-editor-page", providers: [PlatformServiceRegistryEditorFacade], ngImport: i0, template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\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 Service Registry Entry } @else { Create Service Registry Entry }</h1>\n <p class=\"text-sm text-muted-foreground\">\n @if (isEdit) { Update the registered service metadata exposed to platform admins. } @else { Register a new internal or external service in the platform registry. }\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\">\n Loading service registry entry...\n </section>\n } @else {\n @if (facade.error()) {\n <section class=\"rounded-2xl border border-rose-300/40 bg-rose-500/10 px-4 py-3 text-sm text-(--rt-text-primary)\">\n {{ facade.error() }}\n </section>\n }\n\n <rolatech-platform-detail-panel>\n <div panel-title>Service Identity</div>\n <div panel-description>Core metadata used to identify and route traffic to the service.</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 placeholder=\"Authorization API\"\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 placeholder=\"auth-api\"\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\">Namespace</span>\n <input\n type=\"text\"\n [value]=\"facade.namespace()\"\n (input)=\"onNamespaceInput($event)\"\n placeholder=\"platform\"\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\">Service Type</span>\n <input\n type=\"text\"\n [value]=\"facade.serviceType()\"\n (input)=\"onServiceTypeInput($event)\"\n placeholder=\"REST\"\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\">Version</span>\n <input\n type=\"text\"\n [value]=\"facade.version()\"\n (input)=\"onVersionInput($event)\"\n placeholder=\"v1\"\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\">Base URL</span>\n <input\n type=\"text\"\n [value]=\"facade.baseUrl()\"\n (input)=\"onBaseUrlInput($event)\"\n placeholder=\"https://api.rolatech.com/auth\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\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=\"4\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n placeholder=\"Describe the service responsibility and exposure.\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.enabled()\" (change)=\"onEnabledChange($event)\" />\n <span class=\"text-sm font-medium\">Enabled</span>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Tags</div>\n <div panel-description>One value per line or comma separated.</div>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Tags</span>\n <textarea\n rows=\"8\"\n [value]=\"facade.tagsText()\"\n (input)=\"onTagsInput($event)\"\n placeholder=\"core internal\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Additional Attributes</div>\n <div panel-description>Optional JSON object stored alongside the service metadata.</div>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Attributes (JSON object)</span>\n <textarea\n rows=\"8\"\n [value]=\"facade.attributesText()\"\n (input)=\"onAttributesInput($event)\"\n placeholder='{\"team\":\"platform\"}'\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 font-mono text-sm outline-none\"\n ></textarea>\n </label>\n </rolatech-platform-detail-panel>\n </section>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>@if (isEdit) { Save changes to this service registry entry. } @else { Register this service in the platform registry. }</div>\n\n <div action-buttons class=\"flex flex-wrap gap-3\">\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)=\"cancel()\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl bg-(--rt-accent) px-4 py-2 text-sm font-medium text-(--rt-accent-foreground)\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else if (isEdit) { Save Changes } @else { Create Service }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</section>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatSnackBarModule }, { 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 });
|
|
239
|
+
}
|
|
240
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PlatformServiceRegistryEditorPage, decorators: [{
|
|
241
|
+
type: Component,
|
|
242
|
+
args: [{ selector: 'rolatech-platform-service-registry-editor-page', standalone: true, imports: [MatSnackBarModule, PlatformPageHeader, PlatformDetailPanel, PlatformStickyActionBar], changeDetection: ChangeDetectionStrategy.OnPush, providers: [PlatformServiceRegistryEditorFacade], template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\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 Service Registry Entry } @else { Create Service Registry Entry }</h1>\n <p class=\"text-sm text-muted-foreground\">\n @if (isEdit) { Update the registered service metadata exposed to platform admins. } @else { Register a new internal or external service in the platform registry. }\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\">\n Loading service registry entry...\n </section>\n } @else {\n @if (facade.error()) {\n <section class=\"rounded-2xl border border-rose-300/40 bg-rose-500/10 px-4 py-3 text-sm text-(--rt-text-primary)\">\n {{ facade.error() }}\n </section>\n }\n\n <rolatech-platform-detail-panel>\n <div panel-title>Service Identity</div>\n <div panel-description>Core metadata used to identify and route traffic to the service.</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 placeholder=\"Authorization API\"\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 placeholder=\"auth-api\"\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\">Namespace</span>\n <input\n type=\"text\"\n [value]=\"facade.namespace()\"\n (input)=\"onNamespaceInput($event)\"\n placeholder=\"platform\"\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\">Service Type</span>\n <input\n type=\"text\"\n [value]=\"facade.serviceType()\"\n (input)=\"onServiceTypeInput($event)\"\n placeholder=\"REST\"\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\">Version</span>\n <input\n type=\"text\"\n [value]=\"facade.version()\"\n (input)=\"onVersionInput($event)\"\n placeholder=\"v1\"\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\">Base URL</span>\n <input\n type=\"text\"\n [value]=\"facade.baseUrl()\"\n (input)=\"onBaseUrlInput($event)\"\n placeholder=\"https://api.rolatech.com/auth\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\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=\"4\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n placeholder=\"Describe the service responsibility and exposure.\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.enabled()\" (change)=\"onEnabledChange($event)\" />\n <span class=\"text-sm font-medium\">Enabled</span>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Tags</div>\n <div panel-description>One value per line or comma separated.</div>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Tags</span>\n <textarea\n rows=\"8\"\n [value]=\"facade.tagsText()\"\n (input)=\"onTagsInput($event)\"\n placeholder=\"core internal\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Additional Attributes</div>\n <div panel-description>Optional JSON object stored alongside the service metadata.</div>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Attributes (JSON object)</span>\n <textarea\n rows=\"8\"\n [value]=\"facade.attributesText()\"\n (input)=\"onAttributesInput($event)\"\n placeholder='{\"team\":\"platform\"}'\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 font-mono text-sm outline-none\"\n ></textarea>\n </label>\n </rolatech-platform-detail-panel>\n </section>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>@if (isEdit) { Save changes to this service registry entry. } @else { Register this service in the platform registry. }</div>\n\n <div action-buttons class=\"flex flex-wrap gap-3\">\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)=\"cancel()\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl bg-(--rt-accent) px-4 py-2 text-sm font-medium text-(--rt-accent-foreground)\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else if (isEdit) { Save Changes } @else { Create Service }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</section>\n" }]
|
|
243
|
+
}] });
|
|
244
|
+
|
|
245
|
+
export { PlatformServiceRegistryEditorPage };
|
|
246
|
+
//# sourceMappingURL=rolatech-angular-platform-platform-service-registry-editor-Bd3nIfxd.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rolatech-angular-platform-platform-service-registry-editor-Bd3nIfxd.mjs","sources":["../../../../packages/angular-platform/src/lib/store/platform-service-registry-editor.facade.ts","../../../../packages/angular-platform/src/lib/pages/service-registry/platform-service-registry-editor/platform-service-registry-editor.ts","../../../../packages/angular-platform/src/lib/pages/service-registry/platform-service-registry-editor/platform-service-registry-editor.html"],"sourcesContent":["import { Injectable, inject, signal } from '@angular/core';\nimport { PlatformServiceRegistryDetailResponse, PlatformServiceRegistryService } from '@rolatech/angular-services';\nimport { firstValueFrom } from 'rxjs';\n\n@Injectable()\nexport class PlatformServiceRegistryEditorFacade {\n private readonly serviceRegistryService = inject(PlatformServiceRegistryService);\n\n readonly loading = signal(false);\n readonly saving = signal(false);\n readonly deleting = signal(false);\n readonly error = signal<string | null>(null);\n\n readonly id = signal<string | null>(null);\n readonly code = signal('');\n readonly name = signal('');\n readonly namespace = signal('');\n readonly serviceType = signal('');\n readonly version = signal('');\n readonly baseUrl = signal('');\n readonly description = signal('');\n readonly enabled = signal(true);\n readonly tagsText = signal('');\n readonly attributesText = signal('');\n\n async load(id: string): Promise<void> {\n this.loading.set(true);\n this.error.set(null);\n\n try {\n const item = await firstValueFrom(this.serviceRegistryService.findServiceById(id));\n this.patchForm(item);\n } catch (error) {\n console.error(error);\n this.error.set('Unable to load the service registry entry.');\n } finally {\n this.loading.set(false);\n }\n }\n\n async save(): Promise<PlatformServiceRegistryDetailResponse | null> {\n const name = this.name().trim();\n if (!name) {\n this.error.set('Name is required.');\n return null;\n }\n\n const attributes = this.parseAttributes(this.attributesText());\n if (attributes === undefined) {\n return null;\n }\n\n this.saving.set(true);\n this.error.set(null);\n\n try {\n const payload = {\n code: this.code().trim() || null,\n name,\n namespace: this.namespace().trim() || null,\n serviceType: this.serviceType().trim() || null,\n version: this.version().trim() || null,\n baseUrl: this.baseUrl().trim() || null,\n description: this.description().trim() || null,\n enabled: this.enabled(),\n tags: this.parseList(this.tagsText()),\n attributes,\n };\n\n const result = this.id()\n ? await firstValueFrom(this.serviceRegistryService.updateService(this.id()!, payload))\n : await firstValueFrom(this.serviceRegistryService.createService(payload));\n\n this.patchForm(result);\n return result;\n } catch (error) {\n console.error(error);\n this.error.set('Unable to save the service registry entry.');\n return null;\n } finally {\n this.saving.set(false);\n }\n }\n\n async delete(id = this.id()): Promise<boolean> {\n if (!id) {\n this.error.set('Service registry ID is missing.');\n return false;\n }\n\n this.deleting.set(true);\n this.error.set(null);\n\n try {\n await firstValueFrom(this.serviceRegistryService.deleteService(id));\n return true;\n } catch (error) {\n console.error(error);\n this.error.set('Unable to delete the service registry entry.');\n return false;\n } finally {\n this.deleting.set(false);\n }\n }\n\n setCode(value: string): void {\n this.code.set(value);\n }\n\n setName(value: string): void {\n this.name.set(value);\n }\n\n setNamespace(value: string): void {\n this.namespace.set(value);\n }\n\n setServiceType(value: string): void {\n this.serviceType.set(value);\n }\n\n setVersion(value: string): void {\n this.version.set(value);\n }\n\n setBaseUrl(value: string): void {\n this.baseUrl.set(value);\n }\n\n setDescription(value: string): void {\n this.description.set(value);\n }\n\n setEnabled(value: boolean): void {\n this.enabled.set(value);\n }\n\n setTagsText(value: string): void {\n this.tagsText.set(value);\n }\n\n setAttributesText(value: string): void {\n this.attributesText.set(value);\n }\n\n private patchForm(item: PlatformServiceRegistryDetailResponse): void {\n this.id.set(item.id);\n this.code.set(item.code ?? '');\n this.name.set(item.name ?? '');\n this.namespace.set(item.namespace ?? '');\n this.serviceType.set(item.serviceType ?? '');\n this.version.set(item.version ?? '');\n this.baseUrl.set(item.baseUrl ?? '');\n this.description.set(item.description ?? '');\n this.enabled.set(item.enabled);\n this.tagsText.set(item.tags.join('\\n'));\n this.attributesText.set(item.attributes ? JSON.stringify(item.attributes, null, 2) : '');\n }\n\n private parseList(value: string): string[] {\n return Array.from(\n new Set(\n value\n .split(/\\r?\\n|,/)\n .map((item) => item.trim())\n .filter(Boolean),\n ),\n );\n }\n\n private parseAttributes(value: string): Record<string, unknown> | null | undefined {\n const trimmed = value.trim();\n if (!trimmed) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(trimmed);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n this.error.set('Additional attributes must be a JSON object.');\n return undefined;\n }\n\n return parsed as Record<string, unknown>;\n } catch (error) {\n console.error(error);\n this.error.set('Additional attributes must be valid JSON.');\n return undefined;\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';\nimport { PlatformDetailPanel, PlatformPageHeader, PlatformStickyActionBar } from '../../../shared';\nimport { PlatformServiceRegistryEditorFacade } from '../../../store/platform-service-registry-editor.facade';\n\n@Component({\n selector: 'rolatech-platform-service-registry-editor-page',\n standalone: true,\n imports: [MatSnackBarModule, PlatformPageHeader, PlatformDetailPanel, PlatformStickyActionBar],\n templateUrl: './platform-service-registry-editor.html',\n styleUrl: './platform-service-registry-editor.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [PlatformServiceRegistryEditorFacade],\n})\nexport class PlatformServiceRegistryEditorPage implements OnInit {\n readonly facade = inject(PlatformServiceRegistryEditorFacade);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly snackBar = inject(MatSnackBar);\n\n readonly serviceId = this.route.snapshot.paramMap.get('serviceId');\n\n get isEdit(): boolean {\n return !!this.serviceId;\n }\n\n ngOnInit(): void {\n if (this.serviceId) {\n void this.facade.load(this.serviceId);\n }\n }\n\n onCodeInput(event: Event): void {\n this.facade.setCode((event.target as HTMLInputElement).value);\n }\n\n onNameInput(event: Event): void {\n this.facade.setName((event.target as HTMLInputElement).value);\n }\n\n onNamespaceInput(event: Event): void {\n this.facade.setNamespace((event.target as HTMLInputElement).value);\n }\n\n onServiceTypeInput(event: Event): void {\n this.facade.setServiceType((event.target as HTMLInputElement).value);\n }\n\n onVersionInput(event: Event): void {\n this.facade.setVersion((event.target as HTMLInputElement).value);\n }\n\n onBaseUrlInput(event: Event): void {\n this.facade.setBaseUrl((event.target as HTMLInputElement).value);\n }\n\n onDescriptionInput(event: Event): void {\n this.facade.setDescription((event.target as HTMLTextAreaElement).value);\n }\n\n onEnabledChange(event: Event): void {\n this.facade.setEnabled((event.target as HTMLInputElement).checked);\n }\n\n onTagsInput(event: Event): void {\n this.facade.setTagsText((event.target as HTMLTextAreaElement).value);\n }\n\n onAttributesInput(event: Event): void {\n this.facade.setAttributesText((event.target as HTMLTextAreaElement).value);\n }\n\n async save(): Promise<void> {\n const result = await this.facade.save();\n if (!result) {\n return;\n }\n\n this.snackBar.open(this.isEdit ? 'Service registry entry updated.' : 'Service registry entry created.', 'Dismiss', {\n duration: 3000,\n });\n await this.router.navigate(['/platform/service-registry', result.id]);\n }\n\n async cancel(): Promise<void> {\n if (this.isEdit && this.serviceId) {\n await this.router.navigate(['/platform/service-registry', this.serviceId]);\n return;\n }\n\n await this.router.navigate(['/platform/service-registry']);\n }\n}\n","<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\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 Service Registry Entry } @else { Create Service Registry Entry }</h1>\n <p class=\"text-sm text-muted-foreground\">\n @if (isEdit) { Update the registered service metadata exposed to platform admins. } @else { Register a new internal or external service in the platform registry. }\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\">\n Loading service registry entry...\n </section>\n } @else {\n @if (facade.error()) {\n <section class=\"rounded-2xl border border-rose-300/40 bg-rose-500/10 px-4 py-3 text-sm text-(--rt-text-primary)\">\n {{ facade.error() }}\n </section>\n }\n\n <rolatech-platform-detail-panel>\n <div panel-title>Service Identity</div>\n <div panel-description>Core metadata used to identify and route traffic to the service.</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 placeholder=\"Authorization API\"\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 placeholder=\"auth-api\"\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\">Namespace</span>\n <input\n type=\"text\"\n [value]=\"facade.namespace()\"\n (input)=\"onNamespaceInput($event)\"\n placeholder=\"platform\"\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\">Service Type</span>\n <input\n type=\"text\"\n [value]=\"facade.serviceType()\"\n (input)=\"onServiceTypeInput($event)\"\n placeholder=\"REST\"\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\">Version</span>\n <input\n type=\"text\"\n [value]=\"facade.version()\"\n (input)=\"onVersionInput($event)\"\n placeholder=\"v1\"\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\">Base URL</span>\n <input\n type=\"text\"\n [value]=\"facade.baseUrl()\"\n (input)=\"onBaseUrlInput($event)\"\n placeholder=\"https://api.rolatech.com/auth\"\n class=\"h-10 rounded-xl border border-(--rt-border-color) px-3 text-sm outline-none\"\n />\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=\"4\"\n [value]=\"facade.description()\"\n (input)=\"onDescriptionInput($event)\"\n placeholder=\"Describe the service responsibility and exposure.\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n\n <label class=\"flex items-center gap-2 pt-8\">\n <input type=\"checkbox\" [checked]=\"facade.enabled()\" (change)=\"onEnabledChange($event)\" />\n <span class=\"text-sm font-medium\">Enabled</span>\n </label>\n </div>\n </rolatech-platform-detail-panel>\n\n <section class=\"grid gap-6 xl:grid-cols-2\">\n <rolatech-platform-detail-panel>\n <div panel-title>Tags</div>\n <div panel-description>One value per line or comma separated.</div>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Tags</span>\n <textarea\n rows=\"8\"\n [value]=\"facade.tagsText()\"\n (input)=\"onTagsInput($event)\"\n placeholder=\"core internal\"\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 text-sm outline-none\"\n ></textarea>\n </label>\n </rolatech-platform-detail-panel>\n\n <rolatech-platform-detail-panel>\n <div panel-title>Additional Attributes</div>\n <div panel-description>Optional JSON object stored alongside the service metadata.</div>\n\n <label class=\"flex flex-col gap-2\">\n <span class=\"text-sm font-medium\">Attributes (JSON object)</span>\n <textarea\n rows=\"8\"\n [value]=\"facade.attributesText()\"\n (input)=\"onAttributesInput($event)\"\n placeholder='{\"team\":\"platform\"}'\n class=\"rounded-xl border border-(--rt-border-color) px-3 py-2 font-mono text-sm outline-none\"\n ></textarea>\n </label>\n </rolatech-platform-detail-panel>\n </section>\n\n <rolatech-platform-sticky-action-bar>\n <div action-message>@if (isEdit) { Save changes to this service registry entry. } @else { Register this service in the platform registry. }</div>\n\n <div action-buttons class=\"flex flex-wrap gap-3\">\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)=\"cancel()\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n class=\"inline-flex items-center rounded-xl bg-(--rt-accent) px-4 py-2 text-sm font-medium text-(--rt-accent-foreground)\"\n [disabled]=\"facade.saving()\"\n (click)=\"save()\"\n >\n @if (facade.saving()) { Saving... } @else if (isEdit) { Save Changes } @else { Create Service }\n </button>\n </div>\n </rolatech-platform-sticky-action-bar>\n }\n</section>\n"],"names":[],"mappings":"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"}
|