@eintrek/erp-shell 0.1.25 → 0.1.26
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/dist/auth/access-denied.d.ts +22 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +25 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +24 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface AccessDeniedProps {
|
|
2
|
+
/** Bold headline. */
|
|
3
|
+
title?: string;
|
|
4
|
+
/** Secondary explanation — pass the page-specific denied reason here. */
|
|
5
|
+
message?: string;
|
|
6
|
+
/** Where "กลับไปหน้าหลัก" navigates (default "/"). */
|
|
7
|
+
homeHref?: string;
|
|
8
|
+
homeLabel?: string;
|
|
9
|
+
/** When set, shows the "ติดต่อฝ่ายสนับสนุน" button (URL or mailto:). */
|
|
10
|
+
supportHref?: string;
|
|
11
|
+
supportLabel?: string;
|
|
12
|
+
/** Fill the surrounding content area and vertically center (default true). */
|
|
13
|
+
fullScreen?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Central "no access" screen shared by every policy check (route-level
|
|
18
|
+
* PermissionProvider and page-level PermissionGateShell). One look everywhere:
|
|
19
|
+
* an illustration, a 403 headline, the page-specific reason, and recovery
|
|
20
|
+
* actions.
|
|
21
|
+
*/
|
|
22
|
+
export declare function AccessDenied({ title, message, homeHref, homeLabel, supportHref, supportLabel, fullScreen, className, }: AccessDeniedProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export { OrganizationSwitcher, type OrganizationSwitcherProps, type Organization
|
|
|
19
19
|
export { SidebarHeader } from "./navigation/sidebar-header";
|
|
20
20
|
export { AppSidebar, type AppSidebarProps } from "./navigation/app-sidebar";
|
|
21
21
|
export { AppLayoutShell, type AppLayoutShellProps, type AppLayoutShellOrganization, } from "./navigation/app-layout-shell";
|
|
22
|
+
export { AccessDenied, type AccessDeniedProps } from "./auth/access-denied";
|
|
22
23
|
export { PermissionGateShell, type PermissionGateShellProps, type PermissionGateSkeletonVariant, } from "./auth/permission-gate-shell";
|
|
23
24
|
export { PermissionProvider, type PermissionProviderProps, type PermissionProbe, type UsePermissionHook, } from "./auth/permission-provider";
|
|
24
25
|
export { getRequiredChildGroups, normalizePathnameForPermissionRules, resolveUiRoutePermission, type UiRoutePermissionLookup, } from "./auth/permission-utils";
|
package/dist/index.esm.js
CHANGED
|
@@ -5,7 +5,7 @@ import { useSession, signOut } from 'next-auth/react';
|
|
|
5
5
|
import { useQueryClient, MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
6
6
|
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
7
7
|
import { cn, Button, Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, BreadcrumbPage, Avatar, AvatarImage, AvatarFallback, Collapsible, CollapsibleTrigger, CollapsibleContent, Badge, Skeleton, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator, Card, CardHeader, CardContent } from '@eintrek/erp-theme';
|
|
8
|
-
import { PanelLeftClose, Menu, ChevronRight, Building2, ExternalLink, Palette, ChevronUp, Sun, Moon, Monitor, Globe, User, Loader2, LogOut, ChevronDown, ChevronsUpDown, Plus,
|
|
8
|
+
import { PanelLeftClose, Menu, ChevronRight, Building2, ExternalLink, Palette, ChevronUp, Sun, Moon, Monitor, Globe, User, Loader2, LogOut, ChevronDown, ChevronsUpDown, Plus, Sparkles, Ban, Home, Headset } from 'lucide-react';
|
|
9
9
|
import { create } from 'zustand';
|
|
10
10
|
import { persist, createJSONStorage } from 'zustand/middleware';
|
|
11
11
|
import { useRouter, usePathname, useParams } from 'next/navigation';
|
|
@@ -1151,6 +1151,27 @@ function cx(...parts) {
|
|
|
1151
1151
|
return parts.filter(Boolean).join(" ");
|
|
1152
1152
|
}
|
|
1153
1153
|
|
|
1154
|
+
/**
|
|
1155
|
+
* Central "no access" screen shared by every policy check (route-level
|
|
1156
|
+
* PermissionProvider and page-level PermissionGateShell). One look everywhere:
|
|
1157
|
+
* an illustration, a 403 headline, the page-specific reason, and recovery
|
|
1158
|
+
* actions.
|
|
1159
|
+
*/
|
|
1160
|
+
function AccessDenied({ title = "ขออภัย, คุณไม่มีสิทธิ์เข้าถึงหน้านี้ (403)", message = "คุณไม่มีสิทธิ์เข้าถึงหน้านี้ ขออภัยในความไม่สะดวก", homeHref = "/", homeLabel = "กลับไปหน้าหลัก", supportHref, supportLabel = "ติดต่อฝ่ายสนับสนุน", fullScreen = true, className, }) {
|
|
1161
|
+
const go = (href) => {
|
|
1162
|
+
if (typeof window !== "undefined")
|
|
1163
|
+
window.location.href = href;
|
|
1164
|
+
};
|
|
1165
|
+
const wrapperClass = [
|
|
1166
|
+
"flex min-w-0 flex-1 items-center justify-center p-4",
|
|
1167
|
+
fullScreen ? "min-h-[70vh]" : "",
|
|
1168
|
+
className ?? "",
|
|
1169
|
+
]
|
|
1170
|
+
.filter(Boolean)
|
|
1171
|
+
.join(" ");
|
|
1172
|
+
return (jsx("div", { className: wrapperClass, children: jsxs("div", { className: "relative w-full max-w-3xl overflow-hidden rounded-2xl border border-border/60 bg-card/60 p-8 shadow-sm backdrop-blur sm:p-10", children: [jsx(Sparkles, { className: "pointer-events-none absolute right-6 top-6 h-5 w-5 text-primary/40" }), jsxs("div", { className: "flex flex-col items-center gap-8 text-center sm:flex-row sm:text-left", children: [jsxs("div", { className: "relative shrink-0", children: [jsx("div", { className: "absolute inset-0 rounded-full bg-destructive/20 blur-2xl" }), jsx("div", { className: "relative flex h-28 w-28 items-center justify-center rounded-3xl border border-border/60 bg-gradient-to-br from-muted/40 to-background shadow-inner", children: jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-full border border-destructive/40 bg-destructive/10", children: jsx(Ban, { className: "h-8 w-8 text-destructive", strokeWidth: 2.5 }) }) })] }), jsxs("div", { className: "min-w-0 flex-1", children: [jsx("h1", { className: "text-xl font-bold text-foreground sm:text-2xl", children: title }), message ? (jsx("p", { className: "mt-3 whitespace-pre-line text-sm leading-relaxed text-muted-foreground sm:text-base", children: message })) : null, jsxs("div", { className: "mt-6 flex flex-col gap-3 sm:flex-row", children: [jsxs(Button, { type: "button", onClick: () => go(homeHref), className: "w-full sm:w-auto", children: [jsx(Home, { className: "mr-2 h-4 w-4" }), homeLabel] }), supportHref ? (jsxs(Button, { type: "button", variant: "outline", onClick: () => go(supportHref), className: "w-full sm:w-auto", children: [jsx(Headset, { className: "mr-2 h-4 w-4" }), supportLabel] })) : null] })] })] })] }) }));
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1154
1175
|
const shellClassName = "flex min-w-0 flex-1 flex-col gap-6 overflow-x-hidden";
|
|
1155
1176
|
/**
|
|
1156
1177
|
* Shared layout for “กำลังตรวจสอบสิทธิ์” (skeleton) and “ไม่มีสิทธิ์” (message).
|
|
@@ -1161,7 +1182,7 @@ function PermissionGateShell({ policyLoading, hasPolicyAccess, deniedMessage, ch
|
|
|
1161
1182
|
return (jsx("div", { className: shellClassName, children: jsx("div", { className: skeletonGridClassName, children: Array.from({ length: skeletonCount }).map((_, i) => (jsx(Card, { children: skeletonVariant === "kpi" ? (jsxs(Fragment$1, { children: [jsxs(CardHeader, { className: "flex flex-row items-center justify-between pb-2", children: [jsx(Skeleton, { className: "h-4 w-24" }), jsx(Skeleton, { className: "h-4 w-4 rounded" })] }), jsxs(CardContent, { children: [jsx(Skeleton, { className: "h-8 w-32 mb-2" }), jsx(Skeleton, { className: "h-3 w-20" })] })] })) : (jsxs(Fragment$1, { children: [jsx(CardHeader, { className: "pb-2", children: jsx(Skeleton, { className: "h-4 w-24" }) }), jsx(CardContent, { children: jsx(Skeleton, { className: "h-8 w-16" }) })] })) }, i))) }) }));
|
|
1162
1183
|
}
|
|
1163
1184
|
if (!hasPolicyAccess) {
|
|
1164
|
-
return (jsx("div", { className: shellClassName, children: jsx(
|
|
1185
|
+
return (jsx("div", { className: shellClassName, children: jsx(AccessDenied, { message: deniedMessage }) }));
|
|
1165
1186
|
}
|
|
1166
1187
|
return jsx(Fragment$1, { children: children });
|
|
1167
1188
|
}
|
|
@@ -1297,7 +1318,7 @@ function getRequiredChildGroups(pathname, rulesMap) {
|
|
|
1297
1318
|
}
|
|
1298
1319
|
|
|
1299
1320
|
function DeniedCard() {
|
|
1300
|
-
return (jsx(
|
|
1321
|
+
return (jsx(AccessDenied, { message: "\u0E04\u0E38\u0E13\u0E44\u0E21\u0E48\u0E21\u0E35\u0E2A\u0E34\u0E17\u0E18\u0E34\u0E4C\u0E40\u0E02\u0E49\u0E32\u0E16\u0E36\u0E07\u0E2B\u0E19\u0E49\u0E32\u0E19\u0E35\u0E49 \u0E2B\u0E32\u0E01\u0E04\u0E34\u0E14\u0E27\u0E48\u0E32\u0E04\u0E27\u0E23\u0E40\u0E02\u0E49\u0E32\u0E16\u0E36\u0E07\u0E44\u0E14\u0E49 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E1C\u0E39\u0E49\u0E14\u0E39\u0E41\u0E25\u0E23\u0E30\u0E1A\u0E1A\u0E02\u0E2D\u0E07\u0E2D\u0E07\u0E04\u0E4C\u0E01\u0E23" }));
|
|
1301
1322
|
}
|
|
1302
1323
|
/**
|
|
1303
1324
|
* Permission gate for a page subtree. Looks up the current pathname in the
|
|
@@ -1837,5 +1858,5 @@ const getAxiosErrorMessage = (error) => {
|
|
|
1837
1858
|
return String(error);
|
|
1838
1859
|
};
|
|
1839
1860
|
|
|
1840
|
-
export { ApiError, AppBreadcrumb, AppLayoutShell, AppSidebar, FeatureFlagsProvider, HeaderBackground, NavMain, NavTools, NavUser, OrganizationSwitcher, PermissionGateShell, PermissionProvider, PermissionRulesProvider, ReactQueryProvider, SessionBackedProfileCacheSeeder, SessionRefreshTrigger, SidebarContent, SidebarFooter, SidebarHeader, SidebarProvider, SidebarTrigger, TapMenu, ThemeProvider, instance as axiosInstance, buildUrlWithCode, canAccessNavPermissionRoute, clearAccessTokenCache, clearOrganizationId, decodeJWT, filterNavigationModulesByPermission, filterNavigationToolsByPermission, getAccessToken, getActiveModule, getActiveSubModule, getAxiosErrorMessage, getOrganizationId, getQueryClientConfig, getRequiredChildGroups, isLikelyTransientNetworkError, isPathActive, normalizePathnameForPermissionRules, resolveUiRoutePermission, runGlobalRequestPrecheck, runWithTransientRetry, setOrganizationId, toApiError, unwrapApiResponse, updateOrganizationId, useClearOrgOnUserChange, useFeatureFlag, useFeatureFlags, useInvalidateQueriesOnOrgChange, useKeycloakRoles, useOrganizationIdState, usePermissionRules, useSessionRefresh, useSidebar, useSidebarToggle };
|
|
1861
|
+
export { AccessDenied, ApiError, AppBreadcrumb, AppLayoutShell, AppSidebar, FeatureFlagsProvider, HeaderBackground, NavMain, NavTools, NavUser, OrganizationSwitcher, PermissionGateShell, PermissionProvider, PermissionRulesProvider, ReactQueryProvider, SessionBackedProfileCacheSeeder, SessionRefreshTrigger, SidebarContent, SidebarFooter, SidebarHeader, SidebarProvider, SidebarTrigger, TapMenu, ThemeProvider, instance as axiosInstance, buildUrlWithCode, canAccessNavPermissionRoute, clearAccessTokenCache, clearOrganizationId, decodeJWT, filterNavigationModulesByPermission, filterNavigationToolsByPermission, getAccessToken, getActiveModule, getActiveSubModule, getAxiosErrorMessage, getOrganizationId, getQueryClientConfig, getRequiredChildGroups, isLikelyTransientNetworkError, isPathActive, normalizePathnameForPermissionRules, resolveUiRoutePermission, runGlobalRequestPrecheck, runWithTransientRetry, setOrganizationId, toApiError, unwrapApiResponse, updateOrganizationId, useClearOrgOnUserChange, useFeatureFlag, useFeatureFlags, useInvalidateQueriesOnOrgChange, useKeycloakRoles, useOrganizationIdState, usePermissionRules, useSessionRefresh, useSidebar, useSidebarToggle };
|
|
1841
1862
|
//# sourceMappingURL=index.esm.js.map
|