@nsxbet/admin-sdk 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/auth/client/bff.js +19 -14
- package/dist/auth/client/in-memory.js +11 -14
- package/dist/auth/client/interface.d.ts +5 -0
- package/dist/auth/client/permission-match.d.ts +1 -0
- package/dist/auth/client/permission-match.js +13 -0
- package/dist/auth/client/rbac-resolution.d.ts +29 -0
- package/dist/auth/client/rbac-resolution.js +22 -0
- package/dist/auth/client/resolved-role-cache.d.ts +11 -0
- package/dist/auth/client/resolved-role-cache.js +54 -0
- package/dist/components/AuthProvider.d.ts +3 -1
- package/dist/components/AuthProvider.js +95 -23
- package/dist/i18n/locales/en-US.json +66 -1
- package/dist/i18n/locales/es.json +66 -1
- package/dist/i18n/locales/pt-BR.json +66 -1
- package/dist/i18n/locales/ro.json +66 -1
- package/dist/registry/types/manifest.d.ts +3 -1
- package/dist/sdk-version.js +1 -1
- package/dist/shell/AdminShell.js +13 -8
- package/dist/shell/components/HomePage.js +1 -1
- package/dist/shell/components/LeftNav.js +46 -4
- package/dist/shell/components/MainContent.js +25 -0
- package/dist/shell/components/RegistryPage.js +3 -3
- package/dist/shell/components/access-control/AccessControlAuditPage.d.ts +1 -0
- package/dist/shell/components/access-control/AccessControlAuditPage.js +135 -0
- package/dist/shell/components/access-control/AccessControlGroupDetailPage.d.ts +1 -0
- package/dist/shell/components/access-control/AccessControlGroupDetailPage.js +224 -0
- package/dist/shell/components/access-control/AccessControlGroupsPage.d.ts +1 -0
- package/dist/shell/components/access-control/AccessControlGroupsPage.js +183 -0
- package/dist/shell/components/access-control/AccessControlLayout.d.ts +8 -0
- package/dist/shell/components/access-control/AccessControlLayout.js +23 -0
- package/dist/shell/components/access-control/AccessControlMemberPicker.d.ts +10 -0
- package/dist/shell/components/access-control/AccessControlMemberPicker.js +44 -0
- package/dist/shell/components/access-control/AccessControlPermissionPicker.d.ts +8 -0
- package/dist/shell/components/access-control/AccessControlPermissionPicker.js +38 -0
- package/dist/shell/components/access-control/AccessControlUserPage.d.ts +1 -0
- package/dist/shell/components/access-control/AccessControlUserPage.js +42 -0
- package/dist/shell/components/access-control/AccessControlUsersListPage.d.ts +1 -0
- package/dist/shell/components/access-control/AccessControlUsersListPage.js +111 -0
- package/dist/shell/components/access-control/api.d.ts +111 -0
- package/dist/shell/components/access-control/api.js +119 -0
- package/dist/shell/components/access-control/index.d.ts +8 -0
- package/dist/shell/components/access-control/index.js +8 -0
- package/dist/shell/components/index.d.ts +1 -0
- package/dist/shell/components/index.js +1 -0
- package/dist/vite/plugins.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { useNavigate, useOutletContext } from "react-router-dom";
|
|
4
|
+
import { Button, Badge, DataTable, EmptyState, Input, LoadingState, } from "@nsxbet/admin-ui";
|
|
5
|
+
import { useFetch } from "../../../hooks/useFetch";
|
|
6
|
+
import { useI18n } from "../../../hooks/useI18n";
|
|
7
|
+
import { createAccessControlApi } from "./api";
|
|
8
|
+
const PAGE_SIZE = 20;
|
|
9
|
+
export function AccessControlUsersListPage() {
|
|
10
|
+
const { t } = useI18n();
|
|
11
|
+
const fetcher = useFetch();
|
|
12
|
+
const navigate = useNavigate();
|
|
13
|
+
const { apiUrl } = useOutletContext();
|
|
14
|
+
const api = useMemo(() => createAccessControlApi(fetcher, apiUrl), [fetcher, apiUrl]);
|
|
15
|
+
const apiRef = useRef(api);
|
|
16
|
+
apiRef.current = api;
|
|
17
|
+
const [search, setSearch] = useState("");
|
|
18
|
+
const [committedSearch, setCommittedSearch] = useState("");
|
|
19
|
+
const [users, setUsers] = useState([]);
|
|
20
|
+
const [hasLoaded, setHasLoaded] = useState(false);
|
|
21
|
+
const [isFiltering, setIsFiltering] = useState(false);
|
|
22
|
+
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
23
|
+
const [error, setError] = useState(null);
|
|
24
|
+
const [nextCursor, setNextCursor] = useState(null);
|
|
25
|
+
const sentinelRef = useRef(null);
|
|
26
|
+
const commitSearch = useCallback(() => setCommittedSearch(search), [search]);
|
|
27
|
+
const filterParams = useMemo(() => ({
|
|
28
|
+
search: committedSearch || undefined,
|
|
29
|
+
limit: PAGE_SIZE,
|
|
30
|
+
}), [committedSearch]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
let cancelled = false;
|
|
33
|
+
const load = async () => {
|
|
34
|
+
try {
|
|
35
|
+
setIsFiltering(true);
|
|
36
|
+
setError(null);
|
|
37
|
+
const page = await apiRef.current.listKnownUsers(filterParams);
|
|
38
|
+
if (cancelled)
|
|
39
|
+
return;
|
|
40
|
+
setUsers(page.items);
|
|
41
|
+
setNextCursor(page.nextCursor);
|
|
42
|
+
setHasLoaded(true);
|
|
43
|
+
}
|
|
44
|
+
catch (nextError) {
|
|
45
|
+
if (cancelled)
|
|
46
|
+
return;
|
|
47
|
+
setError(nextError instanceof Error ? nextError.message : "Unknown error");
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
if (!cancelled)
|
|
51
|
+
setIsFiltering(false);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
load();
|
|
55
|
+
return () => { cancelled = true; };
|
|
56
|
+
}, [filterParams]);
|
|
57
|
+
const loadMoreRef = useRef();
|
|
58
|
+
const loadMore = useCallback(async () => {
|
|
59
|
+
if (!nextCursor || isLoadingMore)
|
|
60
|
+
return;
|
|
61
|
+
try {
|
|
62
|
+
setIsLoadingMore(true);
|
|
63
|
+
const page = await apiRef.current.listKnownUsers({ ...filterParams, cursor: nextCursor });
|
|
64
|
+
setUsers((prev) => [...prev, ...page.items]);
|
|
65
|
+
setNextCursor(page.nextCursor);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// silent
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
setIsLoadingMore(false);
|
|
72
|
+
}
|
|
73
|
+
}, [filterParams, nextCursor, isLoadingMore]);
|
|
74
|
+
loadMoreRef.current = loadMore;
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const sentinel = sentinelRef.current;
|
|
77
|
+
if (!sentinel || !nextCursor)
|
|
78
|
+
return;
|
|
79
|
+
const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting)
|
|
80
|
+
loadMoreRef.current?.(); }, { rootMargin: "200px" });
|
|
81
|
+
observer.observe(sentinel);
|
|
82
|
+
return () => observer.disconnect();
|
|
83
|
+
}, [nextCursor]);
|
|
84
|
+
const columns = useMemo(() => [
|
|
85
|
+
{
|
|
86
|
+
accessor: "displayName",
|
|
87
|
+
header: t("accessControlPage.columnName"),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
accessor: "email",
|
|
91
|
+
header: t("accessControlPage.columnEmail"),
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
accessor: "subject",
|
|
95
|
+
header: t("accessControlPage.columnSubject"),
|
|
96
|
+
cell: (_value, row) => (_jsx(Badge, { variant: "outline", className: "font-mono text-xs", children: row.subject })),
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
accessor: "id",
|
|
100
|
+
header: t("common.actions"),
|
|
101
|
+
sticky: "right",
|
|
102
|
+
cell: (_value, row) => (_jsx(Button, { variant: "outline", size: "sm", onClick: () => navigate(`/_access-control/users/${row.id}`), children: t("accessControlPage.inspectUser") })),
|
|
103
|
+
},
|
|
104
|
+
], [t, navigate]);
|
|
105
|
+
const showInitialLoading = !hasLoaded && isFiltering;
|
|
106
|
+
const showTable = hasLoaded && !error;
|
|
107
|
+
return (_jsxs("section", { "data-testid": "access-control-users-list-page", className: "space-y-4", children: [_jsx("h2", { className: "text-xl font-semibold", children: t("accessControlPage.usersTitle") }), _jsx(Input, { placeholder: t("common.search"), value: search, onChange: (event) => setSearch(event.target.value), onKeyDown: (event) => { if (event.key === "Enter")
|
|
108
|
+
commitSearch(); }, onBlur: commitSearch, className: "max-w-xs" }), showInitialLoading ? (_jsx(LoadingState, { text: t("common.loading") })) : error ? (_jsx(EmptyState, { title: t("common.error"), description: error })) : showTable ? (_jsxs("div", { children: [_jsx("div", { className: isFiltering
|
|
109
|
+
? "pointer-events-none opacity-50 transition-opacity duration-200"
|
|
110
|
+
: "transition-opacity duration-200", children: _jsx(DataTable, { data: users, columns: columns, emptyState: _jsx(EmptyState, { title: t("accessControlPage.noUsersTitle"), description: t("accessControlPage.noUsersDescription") }) }) }), nextCursor !== null && (_jsx("div", { ref: sentinelRef, className: "flex justify-center py-4", children: isLoadingMore && (_jsx("div", { className: "min-h-0 py-2", children: _jsx(LoadingState, { text: t("common.loading") }) })) }))] })) : null] }));
|
|
111
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export interface AccessControlGroup {
|
|
2
|
+
id: number;
|
|
3
|
+
displayName: string;
|
|
4
|
+
systemKey: string | null;
|
|
5
|
+
isProtected: boolean;
|
|
6
|
+
activatedAt: string;
|
|
7
|
+
deactivatedAt: string | null;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
updatedAt: string;
|
|
10
|
+
}
|
|
11
|
+
export interface AccessControlGroupPage {
|
|
12
|
+
items: AccessControlGroup[];
|
|
13
|
+
nextCursor: number | null;
|
|
14
|
+
}
|
|
15
|
+
export interface AccessControlGroupMember {
|
|
16
|
+
id: number;
|
|
17
|
+
subject: string;
|
|
18
|
+
email: string;
|
|
19
|
+
displayName: string;
|
|
20
|
+
}
|
|
21
|
+
export interface AccessControlGroupDetail extends AccessControlGroup {
|
|
22
|
+
members: AccessControlGroupMember[];
|
|
23
|
+
permissions: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface AccessControlResolvedRolesResponse {
|
|
26
|
+
user: {
|
|
27
|
+
id: number;
|
|
28
|
+
subject: string;
|
|
29
|
+
email: string;
|
|
30
|
+
displayName: string;
|
|
31
|
+
};
|
|
32
|
+
roles: string[];
|
|
33
|
+
groups: Array<{
|
|
34
|
+
id: number;
|
|
35
|
+
displayName: string;
|
|
36
|
+
permissions: string[];
|
|
37
|
+
}>;
|
|
38
|
+
attribution: Array<{
|
|
39
|
+
permission: string;
|
|
40
|
+
groups: Array<{
|
|
41
|
+
id: number;
|
|
42
|
+
displayName: string;
|
|
43
|
+
}>;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
export interface AccessControlCatalogItem {
|
|
47
|
+
permission: string;
|
|
48
|
+
source: "platform" | "module";
|
|
49
|
+
sourceKey: string;
|
|
50
|
+
namespace: string;
|
|
51
|
+
assignable: boolean;
|
|
52
|
+
orphaned: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface AccessControlAuditEvent {
|
|
55
|
+
id: number;
|
|
56
|
+
occurredAt: string;
|
|
57
|
+
actorUserId: number | null;
|
|
58
|
+
actorEmailSnapshot: string;
|
|
59
|
+
eventType: string;
|
|
60
|
+
targetType: string;
|
|
61
|
+
targetId: string;
|
|
62
|
+
summary: string;
|
|
63
|
+
}
|
|
64
|
+
export interface AccessControlAuditPage {
|
|
65
|
+
items: AccessControlAuditEvent[];
|
|
66
|
+
nextCursor: number | null;
|
|
67
|
+
}
|
|
68
|
+
export interface AccessControlUserSummary {
|
|
69
|
+
id: number;
|
|
70
|
+
subject: string;
|
|
71
|
+
email: string;
|
|
72
|
+
displayName: string;
|
|
73
|
+
}
|
|
74
|
+
export interface AccessControlUserPage {
|
|
75
|
+
items: AccessControlUserSummary[];
|
|
76
|
+
nextCursor: number | null;
|
|
77
|
+
}
|
|
78
|
+
export declare function createAccessControlApi(fetcher: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>, apiUrl?: string): {
|
|
79
|
+
listGroups(options?: {
|
|
80
|
+
status?: "active" | "inactive";
|
|
81
|
+
search?: string;
|
|
82
|
+
cursor?: number;
|
|
83
|
+
limit?: number;
|
|
84
|
+
}): Promise<AccessControlGroupPage>;
|
|
85
|
+
getGroupDetail(groupId: number): Promise<AccessControlGroupDetail>;
|
|
86
|
+
createGroup(displayName: string): Promise<AccessControlGroup>;
|
|
87
|
+
updateGroup(groupId: number, displayName: string): Promise<AccessControlGroup>;
|
|
88
|
+
deactivateGroup(groupId: number): Promise<AccessControlGroup>;
|
|
89
|
+
reactivateGroup(groupId: number): Promise<AccessControlGroup>;
|
|
90
|
+
listKnownUsers(options?: {
|
|
91
|
+
search?: string;
|
|
92
|
+
cursor?: number;
|
|
93
|
+
limit?: number;
|
|
94
|
+
}): Promise<AccessControlUserPage>;
|
|
95
|
+
getResolvedRoles(userId: string): Promise<AccessControlResolvedRolesResponse>;
|
|
96
|
+
listAuditEvents(filters: {
|
|
97
|
+
eventType?: string;
|
|
98
|
+
actorEmail?: string;
|
|
99
|
+
targetType?: string;
|
|
100
|
+
targetId?: string;
|
|
101
|
+
cursor?: number;
|
|
102
|
+
limit?: number;
|
|
103
|
+
}): Promise<AccessControlAuditPage>;
|
|
104
|
+
getPermissionCatalog(): Promise<{
|
|
105
|
+
items: AccessControlCatalogItem[];
|
|
106
|
+
}>;
|
|
107
|
+
addGroupMembers(groupId: number, userIds: number[]): Promise<void>;
|
|
108
|
+
removeGroupMember(groupId: number, userId: number): Promise<void>;
|
|
109
|
+
assignGroupPermissions(groupId: number, permissions: string[]): Promise<void>;
|
|
110
|
+
removeGroupPermission(groupId: number, permission: string): Promise<void>;
|
|
111
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
function buildApiBaseUrl(apiUrl) {
|
|
2
|
+
if (!apiUrl) {
|
|
3
|
+
return "/api";
|
|
4
|
+
}
|
|
5
|
+
const normalized = apiUrl.replace(/\/+$/, "");
|
|
6
|
+
return normalized.endsWith("/api") ? normalized : `${normalized}/api`;
|
|
7
|
+
}
|
|
8
|
+
async function request(fetcher, url, init) {
|
|
9
|
+
const response = await fetcher(url, {
|
|
10
|
+
headers: {
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
...init?.headers,
|
|
13
|
+
},
|
|
14
|
+
...init,
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
const error = await response.text();
|
|
18
|
+
throw new Error(error || `Request failed: ${response.status}`);
|
|
19
|
+
}
|
|
20
|
+
const text = await response.text();
|
|
21
|
+
if (!text) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return JSON.parse(text);
|
|
25
|
+
}
|
|
26
|
+
export function createAccessControlApi(fetcher, apiUrl) {
|
|
27
|
+
const baseUrl = buildApiBaseUrl(apiUrl);
|
|
28
|
+
return {
|
|
29
|
+
listGroups(options = {}) {
|
|
30
|
+
const params = new URLSearchParams();
|
|
31
|
+
if (options.status)
|
|
32
|
+
params.set("status", options.status);
|
|
33
|
+
if (options.search)
|
|
34
|
+
params.set("search", options.search);
|
|
35
|
+
if (options.cursor)
|
|
36
|
+
params.set("cursor", String(options.cursor));
|
|
37
|
+
if (options.limit)
|
|
38
|
+
params.set("limit", String(options.limit));
|
|
39
|
+
const query = params.toString();
|
|
40
|
+
return request(fetcher, `${baseUrl}/access-control/groups${query ? `?${query}` : ""}`);
|
|
41
|
+
},
|
|
42
|
+
getGroupDetail(groupId) {
|
|
43
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}`);
|
|
44
|
+
},
|
|
45
|
+
createGroup(displayName) {
|
|
46
|
+
return request(fetcher, `${baseUrl}/access-control/groups`, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
body: JSON.stringify({ displayName }),
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
updateGroup(groupId, displayName) {
|
|
52
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}`, {
|
|
53
|
+
method: "PATCH",
|
|
54
|
+
body: JSON.stringify({ displayName }),
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
deactivateGroup(groupId) {
|
|
58
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}/deactivate`, { method: "POST" });
|
|
59
|
+
},
|
|
60
|
+
reactivateGroup(groupId) {
|
|
61
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}/reactivate`, { method: "POST" });
|
|
62
|
+
},
|
|
63
|
+
listKnownUsers(options = {}) {
|
|
64
|
+
const params = new URLSearchParams();
|
|
65
|
+
if (options.search)
|
|
66
|
+
params.set("search", options.search);
|
|
67
|
+
if (options.cursor)
|
|
68
|
+
params.set("cursor", String(options.cursor));
|
|
69
|
+
if (options.limit)
|
|
70
|
+
params.set("limit", String(options.limit));
|
|
71
|
+
const query = params.toString();
|
|
72
|
+
return request(fetcher, `${baseUrl}/access-control/users${query ? `?${query}` : ""}`);
|
|
73
|
+
},
|
|
74
|
+
getResolvedRoles(userId) {
|
|
75
|
+
const path = userId === "me"
|
|
76
|
+
? `${baseUrl}/access-control/users/me/resolved-roles`
|
|
77
|
+
: `${baseUrl}/access-control/users/${userId}/resolved-roles`;
|
|
78
|
+
return request(fetcher, path);
|
|
79
|
+
},
|
|
80
|
+
listAuditEvents(filters) {
|
|
81
|
+
const params = new URLSearchParams();
|
|
82
|
+
if (filters.eventType)
|
|
83
|
+
params.set("eventType", filters.eventType);
|
|
84
|
+
if (filters.actorEmail)
|
|
85
|
+
params.set("actorEmail", filters.actorEmail);
|
|
86
|
+
if (filters.targetType)
|
|
87
|
+
params.set("targetType", filters.targetType);
|
|
88
|
+
if (filters.targetId)
|
|
89
|
+
params.set("targetId", filters.targetId);
|
|
90
|
+
if (filters.cursor)
|
|
91
|
+
params.set("cursor", String(filters.cursor));
|
|
92
|
+
if (filters.limit)
|
|
93
|
+
params.set("limit", String(filters.limit));
|
|
94
|
+
const query = params.toString();
|
|
95
|
+
return request(fetcher, `${baseUrl}/access-control/audit${query ? `?${query}` : ""}`);
|
|
96
|
+
},
|
|
97
|
+
getPermissionCatalog() {
|
|
98
|
+
return request(fetcher, `${baseUrl}/access-control/catalog`);
|
|
99
|
+
},
|
|
100
|
+
addGroupMembers(groupId, userIds) {
|
|
101
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}/members`, {
|
|
102
|
+
method: "POST",
|
|
103
|
+
body: JSON.stringify({ userIds: userIds.map(Number) }),
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
removeGroupMember(groupId, userId) {
|
|
107
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}/members/${userId}`, { method: "DELETE" });
|
|
108
|
+
},
|
|
109
|
+
assignGroupPermissions(groupId, permissions) {
|
|
110
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}/permissions`, {
|
|
111
|
+
method: "POST",
|
|
112
|
+
body: JSON.stringify({ permissions }),
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
removeGroupPermission(groupId, permission) {
|
|
116
|
+
return request(fetcher, `${baseUrl}/access-control/groups/${groupId}/permissions/${encodeURIComponent(permission)}`, { method: "DELETE" });
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { AccessControlLayout } from "./AccessControlLayout";
|
|
2
|
+
export { AccessControlGroupsPage } from "./AccessControlGroupsPage";
|
|
3
|
+
export { AccessControlGroupDetailPage } from "./AccessControlGroupDetailPage";
|
|
4
|
+
export { AccessControlUsersListPage } from "./AccessControlUsersListPage";
|
|
5
|
+
export { AccessControlUserPage } from "./AccessControlUserPage";
|
|
6
|
+
export { AccessControlAuditPage } from "./AccessControlAuditPage";
|
|
7
|
+
export { AccessControlMemberPicker } from "./AccessControlMemberPicker";
|
|
8
|
+
export { AccessControlPermissionPicker } from "./AccessControlPermissionPicker";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { AccessControlLayout } from "./AccessControlLayout";
|
|
2
|
+
export { AccessControlGroupsPage } from "./AccessControlGroupsPage";
|
|
3
|
+
export { AccessControlGroupDetailPage } from "./AccessControlGroupDetailPage";
|
|
4
|
+
export { AccessControlUsersListPage } from "./AccessControlUsersListPage";
|
|
5
|
+
export { AccessControlUserPage } from "./AccessControlUserPage";
|
|
6
|
+
export { AccessControlAuditPage } from "./AccessControlAuditPage";
|
|
7
|
+
export { AccessControlMemberPicker } from "./AccessControlMemberPicker";
|
|
8
|
+
export { AccessControlPermissionPicker } from "./AccessControlPermissionPicker";
|
|
@@ -11,3 +11,4 @@ export { RegistryStatusBanner } from "./RegistryStatusBanner";
|
|
|
11
11
|
export type { RegistryStatusBannerProps } from "./RegistryStatusBanner";
|
|
12
12
|
export { RegistryUnavailable } from "./RegistryUnavailable";
|
|
13
13
|
export type { RegistryUnavailableProps } from "./RegistryUnavailable";
|
|
14
|
+
export { AccessControlLayout, AccessControlGroupsPage, AccessControlGroupDetailPage, AccessControlUsersListPage, AccessControlUserPage, AccessControlAuditPage, AccessControlMemberPicker, AccessControlPermissionPicker, } from "./access-control";
|
|
@@ -7,3 +7,4 @@ export { RegistryPage } from "./RegistryPage";
|
|
|
7
7
|
export { HomePage } from "./HomePage";
|
|
8
8
|
export { RegistryStatusBanner } from "./RegistryStatusBanner";
|
|
9
9
|
export { RegistryUnavailable } from "./RegistryUnavailable";
|
|
10
|
+
export { AccessControlLayout, AccessControlGroupsPage, AccessControlGroupDetailPage, AccessControlUsersListPage, AccessControlUserPage, AccessControlAuditPage, AccessControlMemberPicker, AccessControlPermissionPicker, } from "./access-control";
|
package/dist/vite/plugins.js
CHANGED
|
@@ -24,9 +24,9 @@ export function generateModuleManifestPlugin(options = {}) {
|
|
|
24
24
|
return;
|
|
25
25
|
const metadata = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
26
26
|
const manifest = {
|
|
27
|
+
...metadata,
|
|
27
28
|
entry: spaEntry,
|
|
28
29
|
sdkVersion: SDK_PACKAGE_VERSION,
|
|
29
|
-
...metadata,
|
|
30
30
|
};
|
|
31
31
|
const outDir = outputOptions.dir || "dist";
|
|
32
32
|
const outputPath = join(outDir, "module.manifest.json");
|