@almadar/ui 5.8.0 → 5.9.0
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/avl/index.cjs +308 -1
- package/dist/avl/index.js +308 -1
- package/dist/components/atoms/AnimatedGraphic.d.ts +2 -0
- package/dist/components/atoms/AnimatedReveal.d.ts +2 -0
- package/dist/components/atoms/Badge.d.ts +2 -0
- package/dist/components/atoms/Box.d.ts +2 -0
- package/dist/components/atoms/Button.d.ts +2 -0
- package/dist/components/atoms/Card.d.ts +2 -0
- package/dist/components/atoms/Checkbox.d.ts +2 -0
- package/dist/components/atoms/FilterPill.d.ts +2 -0
- package/dist/components/atoms/Input.d.ts +2 -0
- package/dist/components/atoms/Label.d.ts +2 -0
- package/dist/components/atoms/Radio.d.ts +2 -0
- package/dist/components/atoms/RangeSlider.d.ts +2 -0
- package/dist/components/atoms/Select.d.ts +2 -0
- package/dist/components/atoms/Spinner.d.ts +2 -0
- package/dist/components/atoms/StatusDot.d.ts +2 -0
- package/dist/components/atoms/Textarea.d.ts +2 -0
- package/dist/components/atoms/TrendIndicator.d.ts +2 -0
- package/dist/components/index.cjs +312 -3
- package/dist/components/index.js +312 -4
- package/dist/components/molecules/TableView.d.ts +105 -0
- package/dist/components/molecules/index.d.ts +1 -0
- package/dist/docs/index.d.cts +8 -0
- package/dist/marketing/index.d.cts +12 -0
- package/dist/providers/index.cjs +308 -1
- package/dist/providers/index.js +308 -1
- package/dist/runtime/index.cjs +308 -1
- package/dist/runtime/index.js +308 -1
- package/package.json +1 -1
package/dist/runtime/index.cjs
CHANGED
|
@@ -28941,6 +28941,311 @@ var init_Lightbox = __esm({
|
|
|
28941
28941
|
Lightbox.displayName = "Lightbox";
|
|
28942
28942
|
}
|
|
28943
28943
|
});
|
|
28944
|
+
function columnLabel(col) {
|
|
28945
|
+
return col.header ?? col.label ?? col.key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
28946
|
+
}
|
|
28947
|
+
function statusVariant4(value) {
|
|
28948
|
+
const v = value.toLowerCase();
|
|
28949
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online", "ok"].includes(v)) return "success";
|
|
28950
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warn", "warning"].includes(v)) return "warning";
|
|
28951
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
28952
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
28953
|
+
return "default";
|
|
28954
|
+
}
|
|
28955
|
+
function formatCell(value, format) {
|
|
28956
|
+
if (value === void 0 || value === null) return "";
|
|
28957
|
+
switch (format) {
|
|
28958
|
+
case "date": {
|
|
28959
|
+
const d = new Date(String(value));
|
|
28960
|
+
return isNaN(d.getTime()) ? String(value) : d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
28961
|
+
}
|
|
28962
|
+
case "currency":
|
|
28963
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
28964
|
+
case "number":
|
|
28965
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
28966
|
+
case "percent":
|
|
28967
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
28968
|
+
case "boolean":
|
|
28969
|
+
return value ? "Yes" : "No";
|
|
28970
|
+
default:
|
|
28971
|
+
return String(value);
|
|
28972
|
+
}
|
|
28973
|
+
}
|
|
28974
|
+
function groupData2(items, field) {
|
|
28975
|
+
const groups = /* @__PURE__ */ new Map();
|
|
28976
|
+
for (const item of items) {
|
|
28977
|
+
const key = String(getNestedValue(item, field) ?? "");
|
|
28978
|
+
const group = groups.get(key);
|
|
28979
|
+
if (group) group.push(item);
|
|
28980
|
+
else groups.set(key, [item]);
|
|
28981
|
+
}
|
|
28982
|
+
return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
|
|
28983
|
+
}
|
|
28984
|
+
function TableView({
|
|
28985
|
+
entity,
|
|
28986
|
+
columns,
|
|
28987
|
+
fields,
|
|
28988
|
+
itemActions,
|
|
28989
|
+
selectable = false,
|
|
28990
|
+
selectEvent,
|
|
28991
|
+
selectedIds,
|
|
28992
|
+
sortEvent,
|
|
28993
|
+
sortColumn,
|
|
28994
|
+
sortDirection,
|
|
28995
|
+
className,
|
|
28996
|
+
emptyMessage,
|
|
28997
|
+
isLoading = false,
|
|
28998
|
+
error = null,
|
|
28999
|
+
groupBy,
|
|
29000
|
+
pageSize = 0,
|
|
29001
|
+
children,
|
|
29002
|
+
renderItem: _schemaRenderItem,
|
|
29003
|
+
look = "dense",
|
|
29004
|
+
// DnD props consumed by useDataDnd.
|
|
29005
|
+
dragGroup,
|
|
29006
|
+
accepts,
|
|
29007
|
+
sortable,
|
|
29008
|
+
dropEvent,
|
|
29009
|
+
reorderEvent,
|
|
29010
|
+
positionEvent,
|
|
29011
|
+
dndItemIdField,
|
|
29012
|
+
dndRoot
|
|
29013
|
+
}) {
|
|
29014
|
+
const eventBus = useEventBus();
|
|
29015
|
+
const { t } = useTranslate();
|
|
29016
|
+
const [visibleCount, setVisibleCount] = React85__namespace.default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
29017
|
+
const [localSelected, setLocalSelected] = React85__namespace.default.useState(/* @__PURE__ */ new Set());
|
|
29018
|
+
const colDefs = columns ?? fields ?? [];
|
|
29019
|
+
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
29020
|
+
const dnd = useDataDnd({
|
|
29021
|
+
items: allDataRaw,
|
|
29022
|
+
layout: "list",
|
|
29023
|
+
dragGroup,
|
|
29024
|
+
accepts,
|
|
29025
|
+
sortable,
|
|
29026
|
+
dropEvent,
|
|
29027
|
+
reorderEvent,
|
|
29028
|
+
positionEvent,
|
|
29029
|
+
dndItemIdField,
|
|
29030
|
+
dndRoot
|
|
29031
|
+
});
|
|
29032
|
+
const ordered = dnd.orderedItems;
|
|
29033
|
+
const data = pageSize > 0 ? ordered.slice(0, visibleCount) : ordered;
|
|
29034
|
+
const hasMore = pageSize > 0 && visibleCount < ordered.length;
|
|
29035
|
+
const hasRenderProp = typeof children === "function";
|
|
29036
|
+
const idField = dndItemIdField ?? "id";
|
|
29037
|
+
const selected = selectedIds ? new Set(selectedIds) : localSelected;
|
|
29038
|
+
const emitSelection = (next) => {
|
|
29039
|
+
if (!selectedIds) setLocalSelected(next);
|
|
29040
|
+
if (selectEvent) {
|
|
29041
|
+
const payload = { selectedIds: Array.from(next) };
|
|
29042
|
+
eventBus.emit(`UI:${selectEvent}`, payload);
|
|
29043
|
+
}
|
|
29044
|
+
};
|
|
29045
|
+
const allSelected = selectable && data.length > 0 && data.every((r, i) => selected.has(String(r[idField] ?? i)));
|
|
29046
|
+
const toggleAll = () => {
|
|
29047
|
+
if (allSelected) emitSelection(/* @__PURE__ */ new Set());
|
|
29048
|
+
else emitSelection(new Set(data.map((r, i) => String(r[idField] ?? i))));
|
|
29049
|
+
};
|
|
29050
|
+
const toggleRow = (id) => {
|
|
29051
|
+
const next = new Set(selected);
|
|
29052
|
+
if (next.has(id)) next.delete(id);
|
|
29053
|
+
else next.add(id);
|
|
29054
|
+
emitSelection(next);
|
|
29055
|
+
};
|
|
29056
|
+
const handleSort = (col) => {
|
|
29057
|
+
if (!col.sortable || !sortEvent) return;
|
|
29058
|
+
const dir = sortColumn === (col.field ?? col.key) && sortDirection === "asc" ? "desc" : "asc";
|
|
29059
|
+
eventBus.emit(`UI:${sortEvent}`, { column: col.field ?? col.key, direction: dir });
|
|
29060
|
+
};
|
|
29061
|
+
const handleActionClick = (action, row) => (e) => {
|
|
29062
|
+
e.stopPropagation();
|
|
29063
|
+
const payload = {
|
|
29064
|
+
id: row.id,
|
|
29065
|
+
row
|
|
29066
|
+
};
|
|
29067
|
+
eventBus.emit(`UI:${action.event}`, payload);
|
|
29068
|
+
};
|
|
29069
|
+
if (isLoading) {
|
|
29070
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading\u2026" }) });
|
|
29071
|
+
}
|
|
29072
|
+
if (error) {
|
|
29073
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
29074
|
+
}
|
|
29075
|
+
if (data.length === 0) {
|
|
29076
|
+
const emptyNode = /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: emptyMessage || t("empty.noItems") || "No records" }) });
|
|
29077
|
+
return dnd.enabled ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
|
|
29078
|
+
}
|
|
29079
|
+
const lk = LOOKS[look];
|
|
29080
|
+
const header = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29081
|
+
Box,
|
|
29082
|
+
{
|
|
29083
|
+
role: "row",
|
|
29084
|
+
className: cn(
|
|
29085
|
+
"flex items-center gap-3 sticky top-0 z-10",
|
|
29086
|
+
"bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
|
|
29087
|
+
"text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
|
|
29088
|
+
lk.headPad
|
|
29089
|
+
),
|
|
29090
|
+
children: [
|
|
29091
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
|
|
29092
|
+
colDefs.map((col) => {
|
|
29093
|
+
const active = sortColumn === (col.field ?? col.key);
|
|
29094
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29095
|
+
Box,
|
|
29096
|
+
{
|
|
29097
|
+
role: "columnheader",
|
|
29098
|
+
onClick: () => handleSort(col),
|
|
29099
|
+
className: cn(
|
|
29100
|
+
"flex items-center gap-1 min-w-0",
|
|
29101
|
+
col.width ?? "flex-1",
|
|
29102
|
+
alignClass[col.align ?? "left"],
|
|
29103
|
+
col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
|
|
29104
|
+
),
|
|
29105
|
+
children: [
|
|
29106
|
+
col.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: col.icon, size: "xs" }),
|
|
29107
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: columnLabel(col) }),
|
|
29108
|
+
col.sortable && sortEvent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
29109
|
+
Icon,
|
|
29110
|
+
{
|
|
29111
|
+
name: active ? sortDirection === "asc" ? "chevron-up" : "chevron-down" : "chevrons-up-down",
|
|
29112
|
+
size: "xs",
|
|
29113
|
+
className: cn("flex-shrink-0", active ? "text-foreground" : "opacity-40")
|
|
29114
|
+
}
|
|
29115
|
+
)
|
|
29116
|
+
]
|
|
29117
|
+
},
|
|
29118
|
+
col.key
|
|
29119
|
+
);
|
|
29120
|
+
}),
|
|
29121
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
|
|
29122
|
+
]
|
|
29123
|
+
}
|
|
29124
|
+
);
|
|
29125
|
+
const renderRow = (row, index) => {
|
|
29126
|
+
const id = String(row[idField] ?? index);
|
|
29127
|
+
const rowInner = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29128
|
+
Box,
|
|
29129
|
+
{
|
|
29130
|
+
role: "row",
|
|
29131
|
+
"data-entity-row": true,
|
|
29132
|
+
"data-entity-id": id,
|
|
29133
|
+
className: cn(
|
|
29134
|
+
"group flex items-center gap-3 transition-colors duration-fast",
|
|
29135
|
+
lk.rowPad,
|
|
29136
|
+
lk.divider && "border-b border-[var(--color-table-border)]",
|
|
29137
|
+
lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
|
|
29138
|
+
"hover:bg-[var(--color-surface-subtle)]",
|
|
29139
|
+
look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
|
|
29140
|
+
),
|
|
29141
|
+
children: [
|
|
29142
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29143
|
+
Checkbox,
|
|
29144
|
+
{
|
|
29145
|
+
checked: selected.has(id),
|
|
29146
|
+
onChange: () => toggleRow(id),
|
|
29147
|
+
"aria-label": `Select row ${id}`
|
|
29148
|
+
}
|
|
29149
|
+
) }),
|
|
29150
|
+
hasRenderProp ? /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 min-w-0", children: children(row, index) }) : colDefs.map((col) => {
|
|
29151
|
+
const raw = getNestedValue(row, col.field ?? col.key);
|
|
29152
|
+
const cellBase = cn(
|
|
29153
|
+
"flex items-center min-w-0",
|
|
29154
|
+
col.width ?? "flex-1",
|
|
29155
|
+
alignClass[col.align ?? "left"],
|
|
29156
|
+
weightClass[col.weight ?? "normal"],
|
|
29157
|
+
col.className
|
|
29158
|
+
);
|
|
29159
|
+
if (col.format === "badge" && raw != null && raw !== "") {
|
|
29160
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
|
|
29161
|
+
}
|
|
29162
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
|
|
29163
|
+
}),
|
|
29164
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29165
|
+
Button,
|
|
29166
|
+
{
|
|
29167
|
+
variant: action.variant ?? "ghost",
|
|
29168
|
+
size: "sm",
|
|
29169
|
+
onClick: handleActionClick(action, row),
|
|
29170
|
+
"data-testid": `action-${action.event}`,
|
|
29171
|
+
"data-row-id": String(row.id),
|
|
29172
|
+
className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
|
|
29173
|
+
children: [
|
|
29174
|
+
action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
29175
|
+
action.label
|
|
29176
|
+
]
|
|
29177
|
+
},
|
|
29178
|
+
i
|
|
29179
|
+
)) })
|
|
29180
|
+
]
|
|
29181
|
+
}
|
|
29182
|
+
);
|
|
29183
|
+
return dnd.isZone ? /* @__PURE__ */ jsxRuntime.jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsxRuntime.jsx(React85__namespace.default.Fragment, { children: rowInner }, id);
|
|
29184
|
+
};
|
|
29185
|
+
const items = data.map((row) => row);
|
|
29186
|
+
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
29187
|
+
let runningIndex = 0;
|
|
29188
|
+
const body = /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React85__namespace.default.Fragment, { children: [
|
|
29189
|
+
group.label && /* @__PURE__ */ jsxRuntime.jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
29190
|
+
group.items.map((row) => renderRow(row, runningIndex++))
|
|
29191
|
+
] }, gi)) });
|
|
29192
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29193
|
+
Box,
|
|
29194
|
+
{
|
|
29195
|
+
role: "table",
|
|
29196
|
+
className: cn("w-full text-sm", className),
|
|
29197
|
+
children: [
|
|
29198
|
+
header,
|
|
29199
|
+
dnd.wrapContainer(body),
|
|
29200
|
+
hasMore && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p2) => p2 + (pageSize || 5)), children: [
|
|
29201
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
29202
|
+
t("common.showMore"),
|
|
29203
|
+
" (",
|
|
29204
|
+
ordered.length - visibleCount,
|
|
29205
|
+
" remaining)"
|
|
29206
|
+
] }) })
|
|
29207
|
+
]
|
|
29208
|
+
}
|
|
29209
|
+
);
|
|
29210
|
+
}
|
|
29211
|
+
var alignClass, weightClass, LOOKS;
|
|
29212
|
+
var init_TableView = __esm({
|
|
29213
|
+
"components/molecules/TableView.tsx"() {
|
|
29214
|
+
"use client";
|
|
29215
|
+
init_cn();
|
|
29216
|
+
init_getNestedValue();
|
|
29217
|
+
init_useEventBus();
|
|
29218
|
+
init_useTranslate();
|
|
29219
|
+
init_Box();
|
|
29220
|
+
init_Stack();
|
|
29221
|
+
init_Typography();
|
|
29222
|
+
init_Badge();
|
|
29223
|
+
init_Button();
|
|
29224
|
+
init_Icon();
|
|
29225
|
+
init_Checkbox();
|
|
29226
|
+
init_Divider();
|
|
29227
|
+
init_useDataDnd();
|
|
29228
|
+
logger.createLogger("almadar:ui:table-view");
|
|
29229
|
+
alignClass = {
|
|
29230
|
+
left: "justify-start text-left",
|
|
29231
|
+
center: "justify-center text-center",
|
|
29232
|
+
right: "justify-end text-right"
|
|
29233
|
+
};
|
|
29234
|
+
weightClass = {
|
|
29235
|
+
normal: "",
|
|
29236
|
+
medium: "font-medium",
|
|
29237
|
+
semibold: "font-semibold"
|
|
29238
|
+
};
|
|
29239
|
+
LOOKS = {
|
|
29240
|
+
dense: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true },
|
|
29241
|
+
spacious: { rowPad: "px-5 py-4", headPad: "px-5 py-3", striped: false, divider: true },
|
|
29242
|
+
striped: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: true, divider: false },
|
|
29243
|
+
borderless: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: false },
|
|
29244
|
+
bordered: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true }
|
|
29245
|
+
};
|
|
29246
|
+
TableView.displayName = "TableView";
|
|
29247
|
+
}
|
|
29248
|
+
});
|
|
28944
29249
|
function formatNumber(value, format) {
|
|
28945
29250
|
if (value == null) return "0";
|
|
28946
29251
|
const v = typeof value === "number" ? value : value;
|
|
@@ -41640,7 +41945,7 @@ function VerifyModePanel({
|
|
|
41640
41945
|
}
|
|
41641
41946
|
prevCountRef.current = transitions.length;
|
|
41642
41947
|
}, [transitions.length, expanded]);
|
|
41643
|
-
const hudBottom = typeof document !== "undefined" ? document.getElementById("runtime-debugger-portal")
|
|
41948
|
+
const hudBottom = typeof document !== "undefined" ? document.getElementById("runtime-debugger-portal") : null;
|
|
41644
41949
|
const panel = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
41645
41950
|
"div",
|
|
41646
41951
|
{
|
|
@@ -45879,6 +46184,7 @@ var init_component_registry_generated = __esm({
|
|
|
45879
46184
|
init_Switch();
|
|
45880
46185
|
init_TabbedContainer();
|
|
45881
46186
|
init_Table();
|
|
46187
|
+
init_TableView();
|
|
45882
46188
|
init_Tabs();
|
|
45883
46189
|
init_TagCloud();
|
|
45884
46190
|
init_TagInput();
|
|
@@ -46196,6 +46502,7 @@ var init_component_registry_generated = __esm({
|
|
|
46196
46502
|
"Switch": Switch,
|
|
46197
46503
|
"TabbedContainer": TabbedContainer,
|
|
46198
46504
|
"Table": Table,
|
|
46505
|
+
"TableView": TableView,
|
|
46199
46506
|
"Tabs": Tabs,
|
|
46200
46507
|
"TagCloud": TagCloud,
|
|
46201
46508
|
"TagInput": TagInput,
|
package/dist/runtime/index.js
CHANGED
|
@@ -28892,6 +28892,311 @@ var init_Lightbox = __esm({
|
|
|
28892
28892
|
Lightbox.displayName = "Lightbox";
|
|
28893
28893
|
}
|
|
28894
28894
|
});
|
|
28895
|
+
function columnLabel(col) {
|
|
28896
|
+
return col.header ?? col.label ?? col.key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
28897
|
+
}
|
|
28898
|
+
function statusVariant4(value) {
|
|
28899
|
+
const v = value.toLowerCase();
|
|
28900
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online", "ok"].includes(v)) return "success";
|
|
28901
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warn", "warning"].includes(v)) return "warning";
|
|
28902
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
28903
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
28904
|
+
return "default";
|
|
28905
|
+
}
|
|
28906
|
+
function formatCell(value, format) {
|
|
28907
|
+
if (value === void 0 || value === null) return "";
|
|
28908
|
+
switch (format) {
|
|
28909
|
+
case "date": {
|
|
28910
|
+
const d = new Date(String(value));
|
|
28911
|
+
return isNaN(d.getTime()) ? String(value) : d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
28912
|
+
}
|
|
28913
|
+
case "currency":
|
|
28914
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
28915
|
+
case "number":
|
|
28916
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
28917
|
+
case "percent":
|
|
28918
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
28919
|
+
case "boolean":
|
|
28920
|
+
return value ? "Yes" : "No";
|
|
28921
|
+
default:
|
|
28922
|
+
return String(value);
|
|
28923
|
+
}
|
|
28924
|
+
}
|
|
28925
|
+
function groupData2(items, field) {
|
|
28926
|
+
const groups = /* @__PURE__ */ new Map();
|
|
28927
|
+
for (const item of items) {
|
|
28928
|
+
const key = String(getNestedValue(item, field) ?? "");
|
|
28929
|
+
const group = groups.get(key);
|
|
28930
|
+
if (group) group.push(item);
|
|
28931
|
+
else groups.set(key, [item]);
|
|
28932
|
+
}
|
|
28933
|
+
return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
|
|
28934
|
+
}
|
|
28935
|
+
function TableView({
|
|
28936
|
+
entity,
|
|
28937
|
+
columns,
|
|
28938
|
+
fields,
|
|
28939
|
+
itemActions,
|
|
28940
|
+
selectable = false,
|
|
28941
|
+
selectEvent,
|
|
28942
|
+
selectedIds,
|
|
28943
|
+
sortEvent,
|
|
28944
|
+
sortColumn,
|
|
28945
|
+
sortDirection,
|
|
28946
|
+
className,
|
|
28947
|
+
emptyMessage,
|
|
28948
|
+
isLoading = false,
|
|
28949
|
+
error = null,
|
|
28950
|
+
groupBy,
|
|
28951
|
+
pageSize = 0,
|
|
28952
|
+
children,
|
|
28953
|
+
renderItem: _schemaRenderItem,
|
|
28954
|
+
look = "dense",
|
|
28955
|
+
// DnD props consumed by useDataDnd.
|
|
28956
|
+
dragGroup,
|
|
28957
|
+
accepts,
|
|
28958
|
+
sortable,
|
|
28959
|
+
dropEvent,
|
|
28960
|
+
reorderEvent,
|
|
28961
|
+
positionEvent,
|
|
28962
|
+
dndItemIdField,
|
|
28963
|
+
dndRoot
|
|
28964
|
+
}) {
|
|
28965
|
+
const eventBus = useEventBus();
|
|
28966
|
+
const { t } = useTranslate();
|
|
28967
|
+
const [visibleCount, setVisibleCount] = React85__default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
28968
|
+
const [localSelected, setLocalSelected] = React85__default.useState(/* @__PURE__ */ new Set());
|
|
28969
|
+
const colDefs = columns ?? fields ?? [];
|
|
28970
|
+
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
28971
|
+
const dnd = useDataDnd({
|
|
28972
|
+
items: allDataRaw,
|
|
28973
|
+
layout: "list",
|
|
28974
|
+
dragGroup,
|
|
28975
|
+
accepts,
|
|
28976
|
+
sortable,
|
|
28977
|
+
dropEvent,
|
|
28978
|
+
reorderEvent,
|
|
28979
|
+
positionEvent,
|
|
28980
|
+
dndItemIdField,
|
|
28981
|
+
dndRoot
|
|
28982
|
+
});
|
|
28983
|
+
const ordered = dnd.orderedItems;
|
|
28984
|
+
const data = pageSize > 0 ? ordered.slice(0, visibleCount) : ordered;
|
|
28985
|
+
const hasMore = pageSize > 0 && visibleCount < ordered.length;
|
|
28986
|
+
const hasRenderProp = typeof children === "function";
|
|
28987
|
+
const idField = dndItemIdField ?? "id";
|
|
28988
|
+
const selected = selectedIds ? new Set(selectedIds) : localSelected;
|
|
28989
|
+
const emitSelection = (next) => {
|
|
28990
|
+
if (!selectedIds) setLocalSelected(next);
|
|
28991
|
+
if (selectEvent) {
|
|
28992
|
+
const payload = { selectedIds: Array.from(next) };
|
|
28993
|
+
eventBus.emit(`UI:${selectEvent}`, payload);
|
|
28994
|
+
}
|
|
28995
|
+
};
|
|
28996
|
+
const allSelected = selectable && data.length > 0 && data.every((r, i) => selected.has(String(r[idField] ?? i)));
|
|
28997
|
+
const toggleAll = () => {
|
|
28998
|
+
if (allSelected) emitSelection(/* @__PURE__ */ new Set());
|
|
28999
|
+
else emitSelection(new Set(data.map((r, i) => String(r[idField] ?? i))));
|
|
29000
|
+
};
|
|
29001
|
+
const toggleRow = (id) => {
|
|
29002
|
+
const next = new Set(selected);
|
|
29003
|
+
if (next.has(id)) next.delete(id);
|
|
29004
|
+
else next.add(id);
|
|
29005
|
+
emitSelection(next);
|
|
29006
|
+
};
|
|
29007
|
+
const handleSort = (col) => {
|
|
29008
|
+
if (!col.sortable || !sortEvent) return;
|
|
29009
|
+
const dir = sortColumn === (col.field ?? col.key) && sortDirection === "asc" ? "desc" : "asc";
|
|
29010
|
+
eventBus.emit(`UI:${sortEvent}`, { column: col.field ?? col.key, direction: dir });
|
|
29011
|
+
};
|
|
29012
|
+
const handleActionClick = (action, row) => (e) => {
|
|
29013
|
+
e.stopPropagation();
|
|
29014
|
+
const payload = {
|
|
29015
|
+
id: row.id,
|
|
29016
|
+
row
|
|
29017
|
+
};
|
|
29018
|
+
eventBus.emit(`UI:${action.event}`, payload);
|
|
29019
|
+
};
|
|
29020
|
+
if (isLoading) {
|
|
29021
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading\u2026" }) });
|
|
29022
|
+
}
|
|
29023
|
+
if (error) {
|
|
29024
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
29025
|
+
}
|
|
29026
|
+
if (data.length === 0) {
|
|
29027
|
+
const emptyNode = /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: emptyMessage || t("empty.noItems") || "No records" }) });
|
|
29028
|
+
return dnd.enabled ? /* @__PURE__ */ jsx(Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
|
|
29029
|
+
}
|
|
29030
|
+
const lk = LOOKS[look];
|
|
29031
|
+
const header = /* @__PURE__ */ jsxs(
|
|
29032
|
+
Box,
|
|
29033
|
+
{
|
|
29034
|
+
role: "row",
|
|
29035
|
+
className: cn(
|
|
29036
|
+
"flex items-center gap-3 sticky top-0 z-10",
|
|
29037
|
+
"bg-[var(--color-surface-subtle)] border-b border-[var(--color-table-border)]",
|
|
29038
|
+
"text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
|
|
29039
|
+
lk.headPad
|
|
29040
|
+
),
|
|
29041
|
+
children: [
|
|
29042
|
+
selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
|
|
29043
|
+
colDefs.map((col) => {
|
|
29044
|
+
const active = sortColumn === (col.field ?? col.key);
|
|
29045
|
+
return /* @__PURE__ */ jsxs(
|
|
29046
|
+
Box,
|
|
29047
|
+
{
|
|
29048
|
+
role: "columnheader",
|
|
29049
|
+
onClick: () => handleSort(col),
|
|
29050
|
+
className: cn(
|
|
29051
|
+
"flex items-center gap-1 min-w-0",
|
|
29052
|
+
col.width ?? "flex-1",
|
|
29053
|
+
alignClass[col.align ?? "left"],
|
|
29054
|
+
col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
|
|
29055
|
+
),
|
|
29056
|
+
children: [
|
|
29057
|
+
col.icon && /* @__PURE__ */ jsx(Icon, { name: col.icon, size: "xs" }),
|
|
29058
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: columnLabel(col) }),
|
|
29059
|
+
col.sortable && sortEvent && /* @__PURE__ */ jsx(
|
|
29060
|
+
Icon,
|
|
29061
|
+
{
|
|
29062
|
+
name: active ? sortDirection === "asc" ? "chevron-up" : "chevron-down" : "chevrons-up-down",
|
|
29063
|
+
size: "xs",
|
|
29064
|
+
className: cn("flex-shrink-0", active ? "text-foreground" : "opacity-40")
|
|
29065
|
+
}
|
|
29066
|
+
)
|
|
29067
|
+
]
|
|
29068
|
+
},
|
|
29069
|
+
col.key
|
|
29070
|
+
);
|
|
29071
|
+
}),
|
|
29072
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "w-px flex-shrink-0", "aria-hidden": true })
|
|
29073
|
+
]
|
|
29074
|
+
}
|
|
29075
|
+
);
|
|
29076
|
+
const renderRow = (row, index) => {
|
|
29077
|
+
const id = String(row[idField] ?? index);
|
|
29078
|
+
const rowInner = /* @__PURE__ */ jsxs(
|
|
29079
|
+
Box,
|
|
29080
|
+
{
|
|
29081
|
+
role: "row",
|
|
29082
|
+
"data-entity-row": true,
|
|
29083
|
+
"data-entity-id": id,
|
|
29084
|
+
className: cn(
|
|
29085
|
+
"group flex items-center gap-3 transition-colors duration-fast",
|
|
29086
|
+
lk.rowPad,
|
|
29087
|
+
lk.divider && "border-b border-[var(--color-table-border)]",
|
|
29088
|
+
lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
|
|
29089
|
+
"hover:bg-[var(--color-surface-subtle)]",
|
|
29090
|
+
look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-table-border)] [&>*:last-child]:border-r-0"
|
|
29091
|
+
),
|
|
29092
|
+
children: [
|
|
29093
|
+
selectable && /* @__PURE__ */ jsx(Box, { className: "w-8 flex-shrink-0 flex items-center", children: /* @__PURE__ */ jsx(
|
|
29094
|
+
Checkbox,
|
|
29095
|
+
{
|
|
29096
|
+
checked: selected.has(id),
|
|
29097
|
+
onChange: () => toggleRow(id),
|
|
29098
|
+
"aria-label": `Select row ${id}`
|
|
29099
|
+
}
|
|
29100
|
+
) }),
|
|
29101
|
+
hasRenderProp ? /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(row, index) }) : colDefs.map((col) => {
|
|
29102
|
+
const raw = getNestedValue(row, col.field ?? col.key);
|
|
29103
|
+
const cellBase = cn(
|
|
29104
|
+
"flex items-center min-w-0",
|
|
29105
|
+
col.width ?? "flex-1",
|
|
29106
|
+
alignClass[col.align ?? "left"],
|
|
29107
|
+
weightClass[col.weight ?? "normal"],
|
|
29108
|
+
col.className
|
|
29109
|
+
);
|
|
29110
|
+
if (col.format === "badge" && raw != null && raw !== "") {
|
|
29111
|
+
return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
|
|
29112
|
+
}
|
|
29113
|
+
return /* @__PURE__ */ jsx(Box, { role: "cell", className: cn(cellBase, "truncate block"), children: formatCell(raw, col.format) }, col.key);
|
|
29114
|
+
}),
|
|
29115
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxs(
|
|
29116
|
+
Button,
|
|
29117
|
+
{
|
|
29118
|
+
variant: action.variant ?? "ghost",
|
|
29119
|
+
size: "sm",
|
|
29120
|
+
onClick: handleActionClick(action, row),
|
|
29121
|
+
"data-testid": `action-${action.event}`,
|
|
29122
|
+
"data-row-id": String(row.id),
|
|
29123
|
+
className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
|
|
29124
|
+
children: [
|
|
29125
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
29126
|
+
action.label
|
|
29127
|
+
]
|
|
29128
|
+
},
|
|
29129
|
+
i
|
|
29130
|
+
)) })
|
|
29131
|
+
]
|
|
29132
|
+
}
|
|
29133
|
+
);
|
|
29134
|
+
return dnd.isZone ? /* @__PURE__ */ jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsx(React85__default.Fragment, { children: rowInner }, id);
|
|
29135
|
+
};
|
|
29136
|
+
const items = data.map((row) => row);
|
|
29137
|
+
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
29138
|
+
let runningIndex = 0;
|
|
29139
|
+
const body = /* @__PURE__ */ jsx(Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxs(React85__default.Fragment, { children: [
|
|
29140
|
+
group.label && /* @__PURE__ */ jsx(Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
29141
|
+
group.items.map((row) => renderRow(row, runningIndex++))
|
|
29142
|
+
] }, gi)) });
|
|
29143
|
+
return /* @__PURE__ */ jsxs(
|
|
29144
|
+
Box,
|
|
29145
|
+
{
|
|
29146
|
+
role: "table",
|
|
29147
|
+
className: cn("w-full text-sm", className),
|
|
29148
|
+
children: [
|
|
29149
|
+
header,
|
|
29150
|
+
dnd.wrapContainer(body),
|
|
29151
|
+
hasMore && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p2) => p2 + (pageSize || 5)), children: [
|
|
29152
|
+
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
29153
|
+
t("common.showMore"),
|
|
29154
|
+
" (",
|
|
29155
|
+
ordered.length - visibleCount,
|
|
29156
|
+
" remaining)"
|
|
29157
|
+
] }) })
|
|
29158
|
+
]
|
|
29159
|
+
}
|
|
29160
|
+
);
|
|
29161
|
+
}
|
|
29162
|
+
var alignClass, weightClass, LOOKS;
|
|
29163
|
+
var init_TableView = __esm({
|
|
29164
|
+
"components/molecules/TableView.tsx"() {
|
|
29165
|
+
"use client";
|
|
29166
|
+
init_cn();
|
|
29167
|
+
init_getNestedValue();
|
|
29168
|
+
init_useEventBus();
|
|
29169
|
+
init_useTranslate();
|
|
29170
|
+
init_Box();
|
|
29171
|
+
init_Stack();
|
|
29172
|
+
init_Typography();
|
|
29173
|
+
init_Badge();
|
|
29174
|
+
init_Button();
|
|
29175
|
+
init_Icon();
|
|
29176
|
+
init_Checkbox();
|
|
29177
|
+
init_Divider();
|
|
29178
|
+
init_useDataDnd();
|
|
29179
|
+
createLogger("almadar:ui:table-view");
|
|
29180
|
+
alignClass = {
|
|
29181
|
+
left: "justify-start text-left",
|
|
29182
|
+
center: "justify-center text-center",
|
|
29183
|
+
right: "justify-end text-right"
|
|
29184
|
+
};
|
|
29185
|
+
weightClass = {
|
|
29186
|
+
normal: "",
|
|
29187
|
+
medium: "font-medium",
|
|
29188
|
+
semibold: "font-semibold"
|
|
29189
|
+
};
|
|
29190
|
+
LOOKS = {
|
|
29191
|
+
dense: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true },
|
|
29192
|
+
spacious: { rowPad: "px-5 py-4", headPad: "px-5 py-3", striped: false, divider: true },
|
|
29193
|
+
striped: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: true, divider: false },
|
|
29194
|
+
borderless: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: false },
|
|
29195
|
+
bordered: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true }
|
|
29196
|
+
};
|
|
29197
|
+
TableView.displayName = "TableView";
|
|
29198
|
+
}
|
|
29199
|
+
});
|
|
28895
29200
|
function formatNumber(value, format) {
|
|
28896
29201
|
if (value == null) return "0";
|
|
28897
29202
|
const v = typeof value === "number" ? value : value;
|
|
@@ -41591,7 +41896,7 @@ function VerifyModePanel({
|
|
|
41591
41896
|
}
|
|
41592
41897
|
prevCountRef.current = transitions.length;
|
|
41593
41898
|
}, [transitions.length, expanded]);
|
|
41594
|
-
const hudBottom = typeof document !== "undefined" ? document.getElementById("runtime-debugger-portal")
|
|
41899
|
+
const hudBottom = typeof document !== "undefined" ? document.getElementById("runtime-debugger-portal") : null;
|
|
41595
41900
|
const panel = /* @__PURE__ */ jsxs(
|
|
41596
41901
|
"div",
|
|
41597
41902
|
{
|
|
@@ -45830,6 +46135,7 @@ var init_component_registry_generated = __esm({
|
|
|
45830
46135
|
init_Switch();
|
|
45831
46136
|
init_TabbedContainer();
|
|
45832
46137
|
init_Table();
|
|
46138
|
+
init_TableView();
|
|
45833
46139
|
init_Tabs();
|
|
45834
46140
|
init_TagCloud();
|
|
45835
46141
|
init_TagInput();
|
|
@@ -46147,6 +46453,7 @@ var init_component_registry_generated = __esm({
|
|
|
46147
46453
|
"Switch": Switch,
|
|
46148
46454
|
"TabbedContainer": TabbedContainer,
|
|
46149
46455
|
"Table": Table,
|
|
46456
|
+
"TableView": TableView,
|
|
46150
46457
|
"Tabs": Tabs,
|
|
46151
46458
|
"TagCloud": TagCloud,
|
|
46152
46459
|
"TagInput": TagInput,
|