@eintrek/erp-shell 0.1.53 → 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.esm.js +32 -20
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +31 -19
- package/dist/index.js.map +1 -1
- package/dist/navigation/my-roles.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -595,13 +595,13 @@ const TapMenu = ({ tabDatas, starterTab, currentTabIndex, variant = "main", }) =
|
|
|
595
595
|
tabDatas.map((tab, index) => {
|
|
596
596
|
if (isMainTab) {
|
|
597
597
|
// Main tab style: text with border-bottom indicator
|
|
598
|
-
return (jsxRuntime.jsx("button", { type: "button", onClick: () => handleTabClick(index, tab.route), className: `w-fit lg:!w-41 h-10 p-2 text-
|
|
598
|
+
return (jsxRuntime.jsx("button", { type: "button", onClick: () => handleTabClick(index, tab.route), className: `w-fit lg:!w-41 h-10 p-2 text-xs lg:text-base text-white ${currentTab === index
|
|
599
599
|
? "border-b-4 border-white text-white"
|
|
600
600
|
: ""}`, children: tab.label }, index));
|
|
601
601
|
}
|
|
602
602
|
else {
|
|
603
603
|
// Sub-tab style: rounded button style
|
|
604
|
-
return (jsxRuntime.jsx(erpTheme.Button, { type: "button", variant: currentTab === index ? "default" : "outline", onClick: () => handleTabClick(index, tab.route), className: "h-7 lg:!h-10 text-
|
|
604
|
+
return (jsxRuntime.jsx(erpTheme.Button, { type: "button", variant: currentTab === index ? "default" : "outline", onClick: () => handleTabClick(index, tab.route), className: "h-7 lg:!h-10 text-xs lg:text-base p-1 lg:p-2 min-w-[20px] lg:min-w-41 w-fit rounded-[12px] lg:rounded-[40px]", children: tab.label }, index));
|
|
605
605
|
}
|
|
606
606
|
}) }), tabDatas[currentTab]?.page] }));
|
|
607
607
|
};
|
|
@@ -800,14 +800,14 @@ function AppBreadcrumb({ labels = {}, homeLabel = "แดชบอร์ด", ro
|
|
|
800
800
|
if (segments.length === 0) {
|
|
801
801
|
return jsxRuntime.jsx("h1", { className: "text-xl font-semibold", children: homeLabel });
|
|
802
802
|
}
|
|
803
|
-
return (jsxRuntime.jsx(erpTheme.Breadcrumb, { children: jsxRuntime.jsxs(erpTheme.BreadcrumbList, { children: [jsxRuntime.jsx(erpTheme.BreadcrumbItem, { children: jsxRuntime.jsx(erpTheme.BreadcrumbLink, { asChild: true, children: jsxRuntime.jsx(Link, { href: "/", className: "font-thai text-
|
|
803
|
+
return (jsxRuntime.jsx(erpTheme.Breadcrumb, { children: jsxRuntime.jsxs(erpTheme.BreadcrumbList, { children: [jsxRuntime.jsx(erpTheme.BreadcrumbItem, { children: jsxRuntime.jsx(erpTheme.BreadcrumbLink, { asChild: true, children: jsxRuntime.jsx(Link, { href: "/", className: "font-thai text-xs font-normal text-[var(--header-fg-muted,rgb(255_255_255/0.8))] hover:text-[var(--header-fg,white)] transition-colors", children: rootLabel }) }) }), segments.map((segment, index) => {
|
|
804
804
|
const href = "/" + segments.slice(0, index + 1).join("/");
|
|
805
805
|
const isLast = index === segments.length - 1;
|
|
806
806
|
// A record id is not a place. Falling back to the raw segment put a
|
|
807
807
|
// 36-character uuid in the trail, which pushed everything before it
|
|
808
808
|
// off a phone and told the reader nothing they could use.
|
|
809
809
|
const label = labels[segment] ?? (isRecordID(segment) ? "รายละเอียด" : segment);
|
|
810
|
-
return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx(erpTheme.BreadcrumbSeparator, { className: "text-[var(--header-fg-muted,rgb(255_255_255/0.8))]", children: jsxRuntime.jsx(lucideReact.ChevronRight, { strokeWidth: 2, className: "h-4 w-4" }) }), jsxRuntime.jsx(erpTheme.BreadcrumbItem, { children: isLast ? (jsxRuntime.jsx(erpTheme.BreadcrumbPage, { className: "font-thai text-
|
|
810
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx(erpTheme.BreadcrumbSeparator, { className: "text-[var(--header-fg-muted,rgb(255_255_255/0.8))]", children: jsxRuntime.jsx(lucideReact.ChevronRight, { strokeWidth: 2, className: "h-4 w-4" }) }), jsxRuntime.jsx(erpTheme.BreadcrumbItem, { children: isLast ? (jsxRuntime.jsx(erpTheme.BreadcrumbPage, { className: "font-thai text-xs font-normal text-[var(--header-fg,rgb(255_255_255/0.95))] leading-none", children: decodeURIComponent(label) })) : (jsxRuntime.jsx(erpTheme.BreadcrumbLink, { asChild: true, children: jsxRuntime.jsx(Link, { href: href, className: "font-thai text-xs font-normal text-[var(--header-fg-muted,rgb(255_255_255/0.8))] hover:text-[var(--header-fg,white)] transition-colors leading-none", children: decodeURIComponent(label) }) })) })] }, `${segment}-${index}`));
|
|
811
811
|
})] }) }));
|
|
812
812
|
}
|
|
813
813
|
/**
|
|
@@ -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(" · ");
|
|
@@ -1491,14 +1498,19 @@ function useMyRoles(organizationId, enabled = true) {
|
|
|
1491
1498
|
function OwnerChip({ size = "card" }) {
|
|
1492
1499
|
return (jsxRuntime.jsx("span", { className: size === "menu"
|
|
1493
1500
|
? "inline-flex shrink-0 items-center rounded-md bg-primary/10 px-2 py-0.5 text-xs font-semibold text-primary"
|
|
1494
|
-
: "inline-flex shrink-0 items-center rounded-full bg-primary/10 px-1.5 text-
|
|
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
|
-
*
|
|
1498
|
-
*
|
|
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-
|
|
1660
|
-
? "absolute right-
|
|
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
|
}
|
|
@@ -1896,17 +1908,17 @@ function NavMain({ items, orgCode, closeOnNavigation = false, approvalCounts, ch
|
|
|
1896
1908
|
const { itemUrl, activeSubItemUrl, isItemActive } = states[index];
|
|
1897
1909
|
const IconComp = item.icon;
|
|
1898
1910
|
const workspaceButton = workspace
|
|
1899
|
-
? "h-auto gap-3 rounded-[10px] px-3 py-2.5 text-
|
|
1911
|
+
? "h-auto gap-3 rounded-[10px] px-3 py-2.5 text-xs " +
|
|
1900
1912
|
(isItemActive
|
|
1901
1913
|
? "bg-sidebar-accent font-bold text-sidebar-accent-foreground"
|
|
1902
1914
|
: "font-medium text-sidebar-foreground/70")
|
|
1903
1915
|
: "";
|
|
1904
1916
|
const icon = workspace && IconComp ? (jsxRuntime.jsx(IconComp, { className: "size-[18px] shrink-0" })) : null;
|
|
1905
|
-
const badge = workspace && item.badge !== undefined && item.badge !== "" ? (jsxRuntime.jsx("span", { className: "ml-auto min-w-5 rounded-[5px] bg-primary/15 px-1 text-center text-
|
|
1917
|
+
const badge = workspace && item.badge !== undefined && item.badge !== "" ? (jsxRuntime.jsx("span", { className: "ml-auto min-w-5 rounded-[5px] bg-primary/15 px-1 text-center text-xs leading-5 font-bold tabular-nums text-primary", children: item.badge })) : null;
|
|
1906
1918
|
return (jsxRuntime.jsxs(React__namespace.Fragment, { children: [groupHeading, jsxRuntime.jsx(erpTheme.Collapsible, { asChild: true, open: openIds.has(item.id), onOpenChange: open => setItemOpen(item.id, open), className: "group/collapsible", children: jsxRuntime.jsxs(SidebarMenuItem, { children: [jsxRuntime.jsx(erpTheme.CollapsibleTrigger, { asChild: true, children: jsxRuntime.jsx(SidebarMenuButton, { asChild: !item.subModules || item.subModules.length === 0, isActive: isItemActive, className: "data-[state=open]:text-sidebar-accent-foreground " +
|
|
1907
1919
|
workspaceButton, children: item.subModules && item.subModules.length > 0 ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [icon, jsxRuntime.jsx("span", { id: item.id, children: item.titleTh }), jsxRuntime.jsx(lucideReact.ChevronRight, { className: "ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" })] })) : (jsxRuntime.jsxs(Link, { href: itemUrl, prefetch: false, className: "flex items-center w-full min-w-0 flex-1 " +
|
|
1908
1920
|
(workspace ? "gap-3" : "gap-2"), onClick: handleNavLinkClick, "aria-current": isItemActive ? "page" : undefined, children: [icon, jsxRuntime.jsx("span", { id: item.id, className: "flex-1 truncate", title: item.titleTh, children: item.titleTh }), badge] })) }) }), item.subModules && item.subModules.length > 0 && (jsxRuntime.jsx(erpTheme.CollapsibleContent, { children: jsxRuntime.jsx(SidebarMenuSub, { className: workspace
|
|
1909
|
-
? "mx-0 mt-1 mb-3 ml-[21px] gap-0.5 border-l border-sidebar-border pl-2.5 [&_a]:h-auto [&_a]:gap-[11px] [&_a]:px-3 [&_a]:py-2 [&_a]:text-
|
|
1921
|
+
? "mx-0 mt-1 mb-3 ml-[21px] gap-0.5 border-l border-sidebar-border pl-2.5 [&_a]:h-auto [&_a]:gap-[11px] [&_a]:px-3 [&_a]:py-2 [&_a]:text-xs [&_svg]:!size-[17px]"
|
|
1910
1922
|
: undefined, children: item.subModules.map(subItem => {
|
|
1911
1923
|
const subItemUrl = buildUrlWithCode(code, subItem.url);
|
|
1912
1924
|
const isSubItemActive = subItemUrl === activeSubItemUrl;
|
|
@@ -1992,7 +2004,7 @@ function OrganizationSwitcher({ activeOrganization, isContextLoading = false, or
|
|
|
1992
2004
|
};
|
|
1993
2005
|
const isLoading = isLoadingOrgs || isContextLoading;
|
|
1994
2006
|
if (placement === "header") {
|
|
1995
|
-
const face = (interactive) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(OrgMark, { logoUrl: activeOrganization?.logoUrl, size: "header" }), jsxRuntime.jsxs("span", { className: "min-w-0 text-left", children: [jsxRuntime.jsx("small", { className: "block text-
|
|
2007
|
+
const face = (interactive) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(OrgMark, { logoUrl: activeOrganization?.logoUrl, size: "header" }), jsxRuntime.jsxs("span", { className: "min-w-0 text-left", children: [jsxRuntime.jsx("small", { className: "block text-xs leading-tight text-[var(--header-fg-muted,currentColor)] max-sm:text-xs", children: "\u0E2D\u0E07\u0E04\u0E4C\u0E01\u0E23\u0E17\u0E35\u0E48\u0E01\u0E33\u0E25\u0E31\u0E07\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19" }), isLoading ? (jsxRuntime.jsx(erpTheme.Skeleton, { className: "mt-1 h-3.5 w-28" })) : (jsxRuntime.jsx("strong", { className: "block max-w-[220px] truncate text-xs font-semibold text-[var(--header-fg,currentColor)] max-sm:max-w-[140px] max-sm:text-xs", children: activeOrganization?.name || "เลือกองค์กร" }))] }), interactive ? (isPending ? (jsxRuntime.jsx(lucideReact.Loader2, { className: "ml-1 size-3.5 shrink-0 animate-spin text-[var(--header-fg-muted,currentColor)]" })) : (jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "ml-1 size-3.5 shrink-0 text-[var(--header-fg-muted,currentColor)]" }))) : null] }));
|
|
1996
2008
|
const faceClass = erpTheme.cn("flex items-center gap-2.5 rounded-lg py-1.5 max-sm:gap-2", className);
|
|
1997
2009
|
if (isLoading || organizations.length <= 1) {
|
|
1998
2010
|
return jsxRuntime.jsx("div", { className: faceClass, children: face(false) });
|
|
@@ -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-[
|
|
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
|
}
|
|
@@ -2643,7 +2655,7 @@ function HelpAttachField({ state, disabled, id }) {
|
|
|
2643
2655
|
return (jsxRuntime.jsxs("div", { className: "grid gap-2", children: [jsxRuntime.jsxs("div", { className: "flex flex-wrap items-start gap-2", children: [items.map(it => (jsxRuntime.jsx(AttachThumb, { item: it, onRemove: () => attach.remove(it.key), disabled: disabled }, it.key))), jsxRuntime.jsxs(erpTheme.Button, { type: "button", variant: "outline", size: "sm", disabled: disabled || full, onClick: () => {
|
|
2644
2656
|
attach.dismissRejections();
|
|
2645
2657
|
input.current?.click();
|
|
2646
|
-
}, "aria-controls": id, className: items.length > 0 ? "h-16 w-16 flex-col gap-1 p-1 text-
|
|
2658
|
+
}, "aria-controls": id, className: items.length > 0 ? "h-16 w-16 flex-col gap-1 p-1 text-xs" : "gap-1.5", children: [jsxRuntime.jsx(lucideReact.ImagePlus, { className: "h-4 w-4" }), "\u0E41\u0E19\u0E1A\u0E23\u0E39\u0E1B"] }), jsxRuntime.jsx("input", { ref: input, id: id, type: "file", accept: HELP_IMAGE_ACCEPT, multiple: true, tabIndex: -1, "aria-hidden": "true", className: "sr-only", onChange: e => {
|
|
2647
2659
|
const files = e.currentTarget.files;
|
|
2648
2660
|
if (files && files.length > 0)
|
|
2649
2661
|
attach.add(Array.from(files));
|
|
@@ -2655,7 +2667,7 @@ function AttachThumb({ item, onRemove, disabled }) {
|
|
|
2655
2667
|
return (jsxRuntime.jsxs("figure", { className: "relative m-0 w-16", children: [jsxRuntime.jsxs("div", { className: "relative h-16 w-16 overflow-hidden rounded-md border bg-muted " +
|
|
2656
2668
|
(failed ? "border-destructive" : "border-border"), children: [item.preview ? (
|
|
2657
2669
|
// eslint-disable-next-line @next/next/no-img-element
|
|
2658
|
-
jsxRuntime.jsx("img", { src: item.preview, alt: item.name, className: "h-full w-full object-cover" })) : null, item.status === "uploading" ? (jsxRuntime.jsx("div", { role: "progressbar", "aria-label": `กำลังอัปโหลด ${item.name}`, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(item.progress * 100), className: "absolute inset-x-1 bottom-1 h-1.5 overflow-hidden rounded-full bg-background/80", children: jsxRuntime.jsx("div", { className: "h-full bg-primary transition-[width]", style: { width: `${Math.round(item.progress * 100)}%` } }) })) : null] }), jsxRuntime.jsx("button", { type: "button", onClick: onRemove, disabled: disabled, "aria-label": `ลบรูป ${item.name}`, title: "\u0E25\u0E1A\u0E23\u0E39\u0E1B", className: "absolute -right-1.5 -top-1.5 grid size-5 place-items-center rounded-full border border-border bg-background text-muted-foreground shadow-sm hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50", children: jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" }) }), jsxRuntime.jsx("figcaption", { className: "mt-0.5 truncate text-
|
|
2670
|
+
jsxRuntime.jsx("img", { src: item.preview, alt: item.name, className: "h-full w-full object-cover" })) : null, item.status === "uploading" ? (jsxRuntime.jsx("div", { role: "progressbar", "aria-label": `กำลังอัปโหลด ${item.name}`, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(item.progress * 100), className: "absolute inset-x-1 bottom-1 h-1.5 overflow-hidden rounded-full bg-background/80", children: jsxRuntime.jsx("div", { className: "h-full bg-primary transition-[width]", style: { width: `${Math.round(item.progress * 100)}%` } }) })) : null] }), jsxRuntime.jsx("button", { type: "button", onClick: onRemove, disabled: disabled, "aria-label": `ลบรูป ${item.name}`, title: "\u0E25\u0E1A\u0E23\u0E39\u0E1B", className: "absolute -right-1.5 -top-1.5 grid size-5 place-items-center rounded-full border border-border bg-background text-muted-foreground shadow-sm hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50", children: jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" }) }), jsxRuntime.jsx("figcaption", { className: "mt-0.5 truncate text-xs leading-tight text-muted-foreground", title: item.name, children: failed ? jsxRuntime.jsx("span", { className: "text-destructive", children: "\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08" }) : kb(item.size) })] }));
|
|
2659
2671
|
}
|
|
2660
2672
|
/** Images already sent: thumbnails that open the full image. */
|
|
2661
2673
|
function HelpImageStrip({ images, size = "md" }) {
|
|
@@ -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-[
|
|
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
|
}
|