@eintrek/erp-shell 0.1.54 → 0.1.55

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.js CHANGED
@@ -955,6 +955,13 @@ function cardRoleLine(roles, limit = CARD_ROLE_LIMIT) {
955
955
  const names = roles.map(r => r.name_th);
956
956
  return { shown: names.slice(0, limit), more: Math.max(0, names.length - limit) };
957
957
  }
958
+ /**
959
+ * Workspace profile card: owner chip + "อีก N บทบาท", without listing role
960
+ * names on the trigger (full names stay in the account menu).
961
+ */
962
+ function workspaceRoleExtra(my) {
963
+ return my.roles.length;
964
+ }
958
965
  /** Everything, for the tooltip: "เจ้าของ · ผู้ดูแลสูงสุด · พนักงานทั่วไป". */
959
966
  function roleSummary(my) {
960
967
  return [...(my.isOwner ? [OWNER_CHIP] : []), ...my.roles.map(r => r.name_th)].join(" · ");
@@ -1494,11 +1501,16 @@ function OwnerChip({ size = "card" }) {
1494
1501
  : "inline-flex shrink-0 items-center rounded-full bg-primary/10 px-1.5 text-xs font-semibold leading-[17px] text-primary", children: OWNER_CHIP }));
1495
1502
  }
1496
1503
  /**
1497
- * The card's role line: the owner's chip, then two role names and a count of
1498
- * the rest. Wraps between names rather than inside one, and truncates a name
1499
- * that is wider than the card on its own; the tooltip has everything.
1504
+ * Brand card: owner chip, then two role names and a count of the rest.
1505
+ * Workspace card: owner chip + "อีก N บทบาท" (names live in the menu).
1500
1506
  */
1501
- function CardRoles({ my, className }) {
1507
+ function CardRoles({ my, className, variant = "brand", }) {
1508
+ if (variant === "workspace") {
1509
+ const extra = workspaceRoleExtra(my);
1510
+ return (jsxRuntime.jsxs("span", { className: `flex min-w-0 flex-wrap items-center gap-1.5 ${className}`, title: roleSummary(my), children: [my.isOwner ? jsxRuntime.jsx(OwnerChip, {}) : null, !my.isOwner && my.roles[0] ? (jsxRuntime.jsx("span", { className: "truncate", children: my.roles[0].name_th })) : null, extra > 0 && (my.isOwner || my.roles.length > 1) ? (jsxRuntime.jsx("span", { className: "shrink-0 text-muted-foreground", children: my.isOwner
1511
+ ? `อีก ${extra} บทบาท`
1512
+ : `อีก ${extra - 1} บทบาท` })) : null] }));
1513
+ }
1502
1514
  const { shown, more } = cardRoleLine(my.roles);
1503
1515
  return (jsxRuntime.jsxs("span", { className: `flex min-w-0 flex-wrap items-center gap-x-1 gap-y-0.5 ${className}`, title: roleSummary(my), children: [my.isOwner ? jsxRuntime.jsx(OwnerChip, {}) : null, shown.map((name, i) => {
1504
1516
  const last = i === shown.length - 1;
@@ -1656,8 +1668,8 @@ function NavUser({ organization, avatarSrc, profileHref, selectOrganizationHref
1656
1668
  openHelp();
1657
1669
  }, 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.CircleHelp, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { className: "flex-1 text-left", children: "\u0E0A\u0E48\u0E27\u0E22\u0E40\u0E2B\u0E25\u0E37\u0E2D" })] })), jsxRuntime.jsx("button", { onClick: handleSignOut, disabled: isSigningOut, 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 disabled:opacity-50 disabled:cursor-not-allowed mt-1", children: isSigningOut ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }), jsxRuntime.jsx("span", { className: "flex-1 text-left", children: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2D\u0E2D\u0E01\u0E08\u0E32\u0E01\u0E23\u0E30\u0E1A\u0E1A..." })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(lucideReact.LogOut, { className: "h-4 w-4" }), jsxRuntime.jsx("span", { className: "flex-1 text-left", children: "\u0E2D\u0E2D\u0E01\u0E08\u0E32\u0E01\u0E23\u0E30\u0E1A\u0E1A" })] })) })] })] })) : null;
1658
1670
  if (variant === "workspace") {
1659
- return (jsxRuntime.jsx("div", { className: "mt-3.5 border-t border-sidebar-border pt-3", children: jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsxs("button", { ref: buttonRef, onClick: () => setIsOpen(!isOpen), "aria-expanded": isOpen, className: `relative flex w-full gap-[11px] rounded-lg px-3 py-1.5 text-left transition-colors hover:bg-sidebar-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring ${cardTall ? "items-start" : "items-center"}`, children: [jsxRuntime.jsxs(erpTheme.Avatar, { className: "size-[34px] shrink-0 rounded-full border-[3px] border-sidebar-accent", children: [user.avatar ? (jsxRuntime.jsx(erpTheme.AvatarImage, { src: user.avatar, alt: user.name })) : null, jsxRuntime.jsx(erpTheme.AvatarFallback, { className: "rounded-full bg-sidebar-accent text-sm font-medium text-sidebar-accent-foreground", children: getInitials(user.name) })] }), jsxRuntime.jsxs("span", { className: `grid min-w-0 flex-1 leading-tight ${cardTall ? "gap-0.5" : ""}`, children: [jsxRuntime.jsx("strong", { className: `truncate text-xs font-semibold ${cardTall ? "pr-5" : ""}`, title: user.name, children: user.name }), myRoles ? (jsxRuntime.jsx(CardRoles, { my: myRoles, className: "text-xs font-medium leading-[17px] text-sidebar-foreground/80" })) : rolesLoading ? (jsxRuntime.jsx("span", { className: "my-[3px] block h-[11px] w-20 animate-pulse rounded bg-sidebar-accent" })) : null, jsxRuntime.jsx("small", { className: "truncate text-xs text-muted-foreground", title: user.email, children: user.email })] }), jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: cardTall
1660
- ? "absolute right-3 top-[9px] size-3.5 text-muted-foreground"
1671
+ return (jsxRuntime.jsx("div", { className: "mt-2.5 border-t border-sidebar-border pt-3.5", children: jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsxs("button", { ref: buttonRef, onClick: () => setIsOpen(!isOpen), "aria-expanded": isOpen, className: `relative flex w-full gap-2.5 rounded-[14px] border border-transparent bg-sidebar-accent/50 px-2.5 py-2.5 text-left transition-colors hover:border-sidebar-border hover:bg-sidebar-accent/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring ${cardTall ? "items-start" : "items-center"}`, children: [jsxRuntime.jsxs(erpTheme.Avatar, { className: "size-[38px] shrink-0 rounded-full border border-sidebar-border", children: [user.avatar ? (jsxRuntime.jsx(erpTheme.AvatarImage, { src: user.avatar, alt: user.name })) : null, jsxRuntime.jsx(erpTheme.AvatarFallback, { className: "rounded-full bg-primary/10 text-[17px] font-medium text-primary", children: getInitials(user.name) })] }), jsxRuntime.jsxs("span", { className: "grid min-w-0 flex-1 gap-0.5 leading-tight", children: [jsxRuntime.jsx("strong", { className: `truncate text-[13px] font-semibold ${cardTall ? "pr-5" : ""}`, title: user.name, children: user.name }), jsxRuntime.jsx("small", { className: "truncate text-[11px] text-muted-foreground", title: user.email, children: user.email }), myRoles ? (jsxRuntime.jsx(CardRoles, { my: myRoles, variant: "workspace", className: "mt-0.5 text-[11px] font-medium leading-[17px] text-sidebar-foreground/80" })) : rolesLoading ? (jsxRuntime.jsx("span", { className: "my-[3px] block h-[11px] w-20 animate-pulse rounded bg-sidebar-accent" })) : null] }), jsxRuntime.jsx(lucideReact.ChevronUp, { className: cardTall
1672
+ ? "absolute right-2.5 top-3 size-3.5 text-muted-foreground"
1661
1673
  : "size-3.5 shrink-0 text-muted-foreground" })] }), typeof window !== "undefined" &&
1662
1674
  reactDom.createPortal(dropdownContent, document.body)] }) }));
1663
1675
  }
@@ -2022,7 +2034,7 @@ function AppSidebar({ modules, tools, activeModule, orgCode, approvalCounts, clo
2022
2034
  if (!open)
2023
2035
  return null;
2024
2036
  if (chrome === "workspace") {
2025
- return (jsxRuntime.jsxs("div", { className: erpTheme.cn("flex h-screen w-[244px] shrink-0 flex-col overflow-hidden border-r border-sidebar-border bg-sidebar text-sidebar-foreground",
2037
+ return (jsxRuntime.jsxs("div", { className: erpTheme.cn("flex h-screen w-[264px] shrink-0 flex-col overflow-hidden border-r border-sidebar-border bg-sidebar text-sidebar-foreground",
2026
2038
  // As a drawer (≤1024px) it floats over the page and needs the lift.
2027
2039
  "max-[1024px]:shadow-2xl", className), children: [header ? jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pt-8 pb-6", children: header }) : null, jsxRuntime.jsxs(SidebarContent, { className: "flex-1 overflow-y-auto px-[18px]", children: [jsxRuntime.jsx(NavMain, { items: modulesWithActiveState, orgCode: orgCode, approvalCounts: approvalCounts, closeOnNavigation: closeOnNavigation, chrome: "workspace", highlightActiveModule: highlightActiveModule }), jsxRuntime.jsx(NavTools, { tools: tools, closeOnNavigation: closeOnNavigation })] }), bottom ? jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pt-6", children: bottom }) : null, jsxRuntime.jsx("div", { className: "shrink-0 px-[18px] pb-3", children: footer })] }));
2028
2040
  }
@@ -3072,7 +3084,7 @@ function cx(...parts) {
3072
3084
  * name, and a spaced caption beneath it.
3073
3085
  */
3074
3086
  function WorkspaceBrand({ name, caption, mark, href, compact = false, className, }) {
3075
- const body = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: erpTheme.cn("grid shrink-0 place-items-center overflow-hidden rounded-[14px] [&>img]:size-full [&>img]:object-cover", compact ? "size-9 rounded-[11px]" : "size-11"), children: mark }), compact ? (jsxRuntime.jsx("span", { className: "sr-only", children: name })) : (jsxRuntime.jsxs("span", { className: "min-w-0", children: [jsxRuntime.jsx("span", { className: "block truncate text-2xl leading-tight font-extrabold tracking-[-0.05em]", children: name }), caption ? (jsxRuntime.jsx("small", { className: "-mt-0.5 block truncate text-xs font-semibold tracking-[0.29em] text-muted-foreground", children: caption })) : null] }))] }));
3087
+ const body = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: erpTheme.cn("grid shrink-0 place-items-center overflow-hidden rounded-[12px] bg-transparent [&>img]:size-full [&>img]:object-contain", compact ? "size-9 rounded-[11px]" : "size-11"), children: mark }), compact ? (jsxRuntime.jsx("span", { className: "sr-only", children: name })) : (jsxRuntime.jsxs("span", { className: "min-w-0", children: [jsxRuntime.jsx("span", { className: "block truncate text-2xl leading-tight font-medium tracking-[-0.05em]", children: name }), caption ? (jsxRuntime.jsx("small", { className: "mt-0.5 block truncate text-[9px] font-semibold tracking-[0.3em] text-muted-foreground", children: caption })) : null] }))] }));
3076
3088
  const cls = erpTheme.cn("flex items-center gap-[11px] rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", !compact && "px-4", className);
3077
3089
  return href ? (jsxRuntime.jsx(Link, { href: href, className: cls, "aria-label": compact ? name : undefined, children: body })) : (jsxRuntime.jsx("div", { className: cls, children: body }));
3078
3090
  }