@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.esm.js
CHANGED
|
@@ -719,7 +719,7 @@ function AppBreadcrumb({ labels = {}, homeLabel = "แดชบอร์ด", ro
|
|
|
719
719
|
})] }) }));
|
|
720
720
|
}
|
|
721
721
|
|
|
722
|
-
function NavUser({ organization, profileHref, selectOrganizationHref = "/select-organization", signInRedirectHref = "/auth/signin", } = {}) {
|
|
722
|
+
function NavUser({ organization, avatarSrc, profileHref, selectOrganizationHref = "/select-organization", signInRedirectHref = "/auth/signin", } = {}) {
|
|
723
723
|
const { data: session, status } = useSession();
|
|
724
724
|
const router = useRouter();
|
|
725
725
|
const { theme, setTheme } = useTheme();
|
|
@@ -733,7 +733,10 @@ function NavUser({ organization, profileHref, selectOrganizationHref = "/select-
|
|
|
733
733
|
? {
|
|
734
734
|
name: session.user.name || "ผู้ใช้",
|
|
735
735
|
email: session.user.email || "",
|
|
736
|
-
|
|
736
|
+
// avatarSrc first: the NextAuth session carries no picture unless the
|
|
737
|
+
// host app deliberately puts one in the JWT, so relying on
|
|
738
|
+
// session.user.image alone left every user on their initials forever.
|
|
739
|
+
avatar: avatarSrc || session.user.image || undefined,
|
|
737
740
|
}
|
|
738
741
|
: null;
|
|
739
742
|
const getInitials = (name) => {
|
|
@@ -800,7 +803,14 @@ function NavUser({ organization, profileHref, selectOrganizationHref = "/select-
|
|
|
800
803
|
}
|
|
801
804
|
if (!user)
|
|
802
805
|
return null;
|
|
803
|
-
const dropdownContent = isOpen ? (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 && (jsx("div", { className: "p-4 border-b border-sidebar-border bg-sidebar-accent/30", children: jsxs("div", { className: "flex items-center gap-3", children: [
|
|
806
|
+
const dropdownContent = isOpen ? (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 && (jsx("div", { className: "p-4 border-b border-sidebar-border bg-sidebar-accent/30", children: jsxs("div", { className: "flex items-center gap-3", children: [organization.logoUrl ? (
|
|
807
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
808
|
+
jsx("img", { src: organization.logoUrl, alt: organization.name ?? "โลโก้บริษัท", className: "h-8 w-8 flex-shrink-0 rounded object-contain bg-white",
|
|
809
|
+
// A dead logo URL must not leave a broken-image glyph in the
|
|
810
|
+
// sidebar; drop back to the generic icon's empty slot.
|
|
811
|
+
onError: e => {
|
|
812
|
+
e.currentTarget.style.display = "none";
|
|
813
|
+
} })) : (jsx(Building2, { className: "h-5 w-5 text-sidebar-foreground/70 flex-shrink-0" })), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("div", { className: "font-medium text-sm sm:truncate", children: organization.name }), organization.description && (jsx("div", { className: "text-xs text-sidebar-foreground/70 truncate mt-0.5", children: organization.description }))] })] }) })), jsxs("div", { className: "p-2", children: [jsxs("div", { className: "relative", children: [jsxs("button", { onClick: () => {
|
|
804
814
|
setShowThemeMenu(!showThemeMenu);
|
|
805
815
|
setShowLanguageMenu(false);
|
|
806
816
|
}, 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: [jsx(Palette, { className: "h-4 w-4" }), jsx("span", { className: "flex-1 text-left", children: "\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E18\u0E35\u0E21" }), jsx(ChevronUp, { className: `h-4 w-4 transition-transform ${showThemeMenu ? "rotate-180" : ""}` })] }), showThemeMenu && (jsx("div", { className: "mt-1 ml-4 space-y-1", children: [
|
|
@@ -1332,8 +1342,19 @@ const getQueryClientConfig = () => ({
|
|
|
1332
1342
|
refetchOnWindowFocus: true,
|
|
1333
1343
|
},
|
|
1334
1344
|
mutations: {
|
|
1335
|
-
retry
|
|
1336
|
-
|
|
1345
|
+
// NEVER auto-retry a mutation. Unlike a query, a mutation is a side
|
|
1346
|
+
// effect on a non-idempotent endpoint (submit, create, approve), and
|
|
1347
|
+
// React Query cannot tell "the network dropped" from "the server
|
|
1348
|
+
// rejected this on business grounds".
|
|
1349
|
+
//
|
|
1350
|
+
// With retry: 1 every failed mutation fired twice. Two visible
|
|
1351
|
+
// consequences: a rejected submit showed up as two failed POSTs in the
|
|
1352
|
+
// network tab, and — far worse — a create whose response was lost in
|
|
1353
|
+
// flight would be re-sent and duplicate the record server-side.
|
|
1354
|
+
//
|
|
1355
|
+
// Retrying is the caller's decision, not a global default: the user
|
|
1356
|
+
// sees the error and presses the button again.
|
|
1357
|
+
retry: 0,
|
|
1337
1358
|
},
|
|
1338
1359
|
},
|
|
1339
1360
|
queryCache: new QueryCache({
|