@eintrek/erp-shell 0.1.18 → 0.1.20
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/index.esm.js +26 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +26 -5
- package/dist/index.js.map +1 -1
- package/dist/navigation/nav-user.d.ts +13 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -738,7 +738,7 @@ function AppBreadcrumb({ labels = {}, homeLabel = "แดชบอร์ด", ro
|
|
|
738
738
|
})] }) }));
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
-
function NavUser({ organization, profileHref, selectOrganizationHref = "/select-organization", signInRedirectHref = "/auth/signin", } = {}) {
|
|
741
|
+
function NavUser({ organization, avatarSrc, profileHref, selectOrganizationHref = "/select-organization", signInRedirectHref = "/auth/signin", } = {}) {
|
|
742
742
|
const { data: session, status } = react.useSession();
|
|
743
743
|
const router = navigation.useRouter();
|
|
744
744
|
const { theme, setTheme } = nextThemes.useTheme();
|
|
@@ -752,7 +752,10 @@ function NavUser({ organization, profileHref, selectOrganizationHref = "/select-
|
|
|
752
752
|
? {
|
|
753
753
|
name: session.user.name || "ผู้ใช้",
|
|
754
754
|
email: session.user.email || "",
|
|
755
|
-
|
|
755
|
+
// avatarSrc first: the NextAuth session carries no picture unless the
|
|
756
|
+
// host app deliberately puts one in the JWT, so relying on
|
|
757
|
+
// session.user.image alone left every user on their initials forever.
|
|
758
|
+
avatar: avatarSrc || session.user.image || undefined,
|
|
756
759
|
}
|
|
757
760
|
: null;
|
|
758
761
|
const getInitials = (name) => {
|
|
@@ -819,7 +822,14 @@ function NavUser({ organization, profileHref, selectOrganizationHref = "/select-
|
|
|
819
822
|
}
|
|
820
823
|
if (!user)
|
|
821
824
|
return null;
|
|
822
|
-
const dropdownContent = isOpen ? (jsxRuntime.jsxs("div", { "data-dropdown": "nav-user", className: "fixed w-52 sm:w-60 md:w-80 rounded-lg bg-sidebar border border-sidebar-border shadow-xl z-50 overflow-hidden\n -translate-x-[65%] -translate-y-[110%] sm:translate-x-0 sm:-translate-y-full", style: { top: `${position.top}px`, left: `${position.left}px` }, children: [organization && (jsxRuntime.jsx("div", { className: "p-4 border-b border-sidebar-border bg-sidebar-accent/30", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
825
|
+
const dropdownContent = isOpen ? (jsxRuntime.jsxs("div", { "data-dropdown": "nav-user", className: "fixed w-52 sm:w-60 md:w-80 rounded-lg bg-sidebar border border-sidebar-border shadow-xl z-50 overflow-hidden\n -translate-x-[65%] -translate-y-[110%] sm:translate-x-0 sm:-translate-y-full", style: { top: `${position.top}px`, left: `${position.left}px` }, children: [organization && (jsxRuntime.jsx("div", { className: "p-4 border-b border-sidebar-border bg-sidebar-accent/30", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [organization.logoUrl ? (
|
|
826
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
827
|
+
jsxRuntime.jsx("img", { src: organization.logoUrl, alt: organization.name ?? "โลโก้บริษัท", className: "h-8 w-8 flex-shrink-0 rounded object-contain bg-white",
|
|
828
|
+
// A dead logo URL must not leave a broken-image glyph in the
|
|
829
|
+
// sidebar; drop back to the generic icon's empty slot.
|
|
830
|
+
onError: e => {
|
|
831
|
+
e.currentTarget.style.display = "none";
|
|
832
|
+
} })) : (jsxRuntime.jsx(lucideReact.Building2, { className: "h-5 w-5 text-sidebar-foreground/70 flex-shrink-0" })), jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsx("div", { className: "font-medium text-sm sm:truncate", children: organization.name }), organization.description && (jsxRuntime.jsx("div", { className: "text-xs text-sidebar-foreground/70 truncate mt-0.5", children: organization.description }))] })] }) })), jsxRuntime.jsxs("div", { className: "p-2", children: [jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsxs("button", { onClick: () => {
|
|
823
833
|
setShowThemeMenu(!showThemeMenu);
|
|
824
834
|
setShowLanguageMenu(false);
|
|
825
835
|
}, className: "flex w-full items-center gap-3 px-3 py-2.5 text-sm text-sidebar-foreground hover:bg-sidebar-accent rounded-md transition-colors", children: [jsxRuntime.jsx(lucideReact.Palette, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { className: "flex-1 text-left", children: "\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E18\u0E35\u0E21" }), jsxRuntime.jsx(lucideReact.ChevronUp, { className: `h-4 w-4 transition-transform ${showThemeMenu ? "rotate-180" : ""}` })] }), showThemeMenu && (jsxRuntime.jsx("div", { className: "mt-1 ml-4 space-y-1", children: [
|
|
@@ -1351,8 +1361,19 @@ const getQueryClientConfig = () => ({
|
|
|
1351
1361
|
refetchOnWindowFocus: true,
|
|
1352
1362
|
},
|
|
1353
1363
|
mutations: {
|
|
1354
|
-
retry
|
|
1355
|
-
|
|
1364
|
+
// NEVER auto-retry a mutation. Unlike a query, a mutation is a side
|
|
1365
|
+
// effect on a non-idempotent endpoint (submit, create, approve), and
|
|
1366
|
+
// React Query cannot tell "the network dropped" from "the server
|
|
1367
|
+
// rejected this on business grounds".
|
|
1368
|
+
//
|
|
1369
|
+
// With retry: 1 every failed mutation fired twice. Two visible
|
|
1370
|
+
// consequences: a rejected submit showed up as two failed POSTs in the
|
|
1371
|
+
// network tab, and — far worse — a create whose response was lost in
|
|
1372
|
+
// flight would be re-sent and duplicate the record server-side.
|
|
1373
|
+
//
|
|
1374
|
+
// Retrying is the caller's decision, not a global default: the user
|
|
1375
|
+
// sees the error and presses the button again.
|
|
1376
|
+
retry: 0,
|
|
1356
1377
|
},
|
|
1357
1378
|
},
|
|
1358
1379
|
queryCache: new reactQuery.QueryCache({
|