@open-mercato/ui 0.5.1-develop.2663.2c29774b5b → 0.5.1-develop.2681.c559bb2bc3
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/.turbo/turbo-build.log +2 -2
- package/dist/backend/CrudForm.js +187 -39
- package/dist/backend/CrudForm.js.map +2 -2
- package/dist/backend/Page.js +12 -4
- package/dist/backend/Page.js.map +2 -2
- package/dist/backend/confirm-dialog/ConfirmDialog.js +7 -4
- package/dist/backend/confirm-dialog/ConfirmDialog.js.map +2 -2
- package/dist/backend/crud/CollapsibleGroup.js +88 -0
- package/dist/backend/crud/CollapsibleGroup.js.map +7 -0
- package/dist/backend/crud/CollapsibleZoneLayout.js +178 -0
- package/dist/backend/crud/CollapsibleZoneLayout.js.map +7 -0
- package/dist/backend/crud/useGroupCollapse.js +24 -0
- package/dist/backend/crud/useGroupCollapse.js.map +7 -0
- package/dist/backend/crud/useGroupOrder.js +61 -0
- package/dist/backend/crud/useGroupOrder.js.map +7 -0
- package/dist/backend/crud/usePersistedBooleanFlag.js +29 -0
- package/dist/backend/crud/usePersistedBooleanFlag.js.map +7 -0
- package/dist/backend/crud/useZoneCollapse.js +24 -0
- package/dist/backend/crud/useZoneCollapse.js.map +7 -0
- package/dist/backend/detail/AttachmentsSection.js +77 -33
- package/dist/backend/detail/AttachmentsSection.js.map +2 -2
- package/dist/backend/detail/NotesSection.js +82 -6
- package/dist/backend/detail/NotesSection.js.map +2 -2
- package/dist/backend/icons/lucideRegistry.generated.js +16 -2
- package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
- package/dist/backend/inputs/SwitchableMarkdownInput.js +3 -1
- package/dist/backend/inputs/SwitchableMarkdownInput.js.map +2 -2
- package/dist/primitives/avatar.js +59 -0
- package/dist/primitives/avatar.js.map +7 -0
- package/package.json +3 -3
- package/src/backend/CrudForm.tsx +230 -21
- package/src/backend/Page.tsx +20 -4
- package/src/backend/__tests__/AttachmentsSection.test.tsx +82 -0
- package/src/backend/__tests__/CollapsibleZoneLayout.test.tsx +171 -0
- package/src/backend/__tests__/CrudForm.validation.test.tsx +4 -4
- package/src/backend/__tests__/NotesSection.test.tsx +63 -0
- package/src/backend/confirm-dialog/ConfirmDialog.tsx +9 -4
- package/src/backend/crud/CollapsibleGroup.tsx +111 -0
- package/src/backend/crud/CollapsibleZoneLayout.tsx +234 -0
- package/src/backend/crud/__tests__/useGroupCollapse.test.ts +38 -0
- package/src/backend/crud/__tests__/useGroupOrder.test.ts +63 -0
- package/src/backend/crud/__tests__/usePersistedBooleanFlag.test.ts +49 -0
- package/src/backend/crud/__tests__/useZoneCollapse.test.ts +31 -0
- package/src/backend/crud/useGroupCollapse.ts +22 -0
- package/src/backend/crud/useGroupOrder.ts +74 -0
- package/src/backend/crud/usePersistedBooleanFlag.ts +35 -0
- package/src/backend/crud/useZoneCollapse.ts +22 -0
- package/src/backend/detail/AttachmentsSection.tsx +81 -38
- package/src/backend/detail/NotesSection.tsx +99 -6
- package/src/backend/icons/lucideRegistry.generated.tsx +16 -2
- package/src/backend/inputs/SwitchableMarkdownInput.tsx +3 -1
- package/src/primitives/__tests__/avatar.test.tsx +64 -0
- package/src/primitives/avatar.tsx +75 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Generated lucide registry with
|
|
2
|
-
Found
|
|
1
|
+
Generated lucide registry with 134 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
|
|
2
|
+
Found 264 entry points
|
|
3
3
|
ui built successfully
|
package/dist/backend/CrudForm.js
CHANGED
|
@@ -3,6 +3,9 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import Link from "next/link";
|
|
5
5
|
import { useRouter } from "next/navigation";
|
|
6
|
+
import { DndContext, closestCenter, PointerSensor, KeyboardSensor, useSensor, useSensors } from "@dnd-kit/core";
|
|
7
|
+
import { SortableContext, verticalListSortingStrategy, useSortable } from "@dnd-kit/sortable";
|
|
8
|
+
import { CSS } from "@dnd-kit/utilities";
|
|
6
9
|
import { DataLoader } from "../primitives/DataLoader.js";
|
|
7
10
|
import { flash } from "./FlashMessages.js";
|
|
8
11
|
import dynamic from "next/dynamic";
|
|
@@ -67,6 +70,8 @@ import { VersionHistoryAction } from "./version-history/VersionHistoryAction.js"
|
|
|
67
70
|
import { parseBooleanWithDefault } from "@open-mercato/shared/lib/boolean";
|
|
68
71
|
import { cn } from "@open-mercato/shared/lib/utils";
|
|
69
72
|
import { useInjectionDataWidgets } from "./injection/useInjectionDataWidgets.js";
|
|
73
|
+
import { CollapsibleGroup } from "./crud/CollapsibleGroup.js";
|
|
74
|
+
import { useGroupOrder } from "./crud/useGroupOrder.js";
|
|
70
75
|
import { InjectedField } from "./injection/InjectedField.js";
|
|
71
76
|
import { evaluateInjectedVisibility } from "./injection/visibility-utils.js";
|
|
72
77
|
import { ComponentReplacementHandles } from "@open-mercato/shared/modules/widgets/component-registry";
|
|
@@ -180,6 +185,16 @@ class FieldDefinitionsManagerErrorBoundary extends React.Component {
|
|
|
180
185
|
return this.props.children;
|
|
181
186
|
}
|
|
182
187
|
}
|
|
188
|
+
function SortableGroupItem({ id, children, disabled }) {
|
|
189
|
+
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id, disabled });
|
|
190
|
+
const style = {
|
|
191
|
+
transform: CSS.Transform.toString(transform),
|
|
192
|
+
transition,
|
|
193
|
+
opacity: isDragging ? 0.5 : 1,
|
|
194
|
+
position: "relative"
|
|
195
|
+
};
|
|
196
|
+
return /* @__PURE__ */ jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners, children });
|
|
197
|
+
}
|
|
183
198
|
function CrudForm({
|
|
184
199
|
schema,
|
|
185
200
|
fields,
|
|
@@ -205,6 +220,8 @@ function CrudForm({
|
|
|
205
220
|
customEntity = false,
|
|
206
221
|
embedded = false,
|
|
207
222
|
hideFooterActions = false,
|
|
223
|
+
trackDirtyWhenEmbedded = false,
|
|
224
|
+
onDirtyChange,
|
|
208
225
|
extraActions,
|
|
209
226
|
versionHistory,
|
|
210
227
|
contentHeader,
|
|
@@ -213,6 +230,8 @@ function CrudForm({
|
|
|
213
230
|
customFieldsetBindings,
|
|
214
231
|
injectionSpotId,
|
|
215
232
|
replacementHandle,
|
|
233
|
+
collapsibleGroups,
|
|
234
|
+
sortableGroups,
|
|
216
235
|
shouldBypassUnsavedChangesGuard
|
|
217
236
|
}) {
|
|
218
237
|
React.useEffect(() => {
|
|
@@ -262,6 +281,12 @@ function CrudForm({
|
|
|
262
281
|
const [fieldsetEditorTarget, setFieldsetEditorTarget] = React.useState(null);
|
|
263
282
|
const [isInDialog, setIsInDialog] = React.useState(false);
|
|
264
283
|
const rootRef = React.useRef(null);
|
|
284
|
+
const collapsibleGroupsEnabled = Boolean(collapsibleGroups);
|
|
285
|
+
const collapsiblePageType = typeof collapsibleGroups === "object" ? collapsibleGroups.pageType : formId;
|
|
286
|
+
const collapsibleChevronPosition = typeof collapsibleGroups === "object" ? collapsibleGroups.chevronPosition : void 0;
|
|
287
|
+
const groupCollapseRefs = React.useRef(/* @__PURE__ */ new Map());
|
|
288
|
+
const sortableGroupsEnabled = Boolean(sortableGroups);
|
|
289
|
+
const sortablePageType = typeof sortableGroups === "object" ? sortableGroups.pageType : formId;
|
|
265
290
|
const fieldsetManagerRef = React.useRef(null);
|
|
266
291
|
const resolvedEntityIdsKey = React.useMemo(() => buildResolvedEntityIdsKey(entityId, entityIds), [entityId, entityIds]);
|
|
267
292
|
const resolvedEntityIds = React.useMemo(
|
|
@@ -320,7 +345,7 @@ function CrudForm({
|
|
|
320
345
|
shouldBypassUnsavedChangesGuardRef.current = shouldBypassUnsavedChangesGuard;
|
|
321
346
|
}, [shouldBypassUnsavedChangesGuard]);
|
|
322
347
|
React.useEffect(() => {
|
|
323
|
-
if (embedded) {
|
|
348
|
+
if (embedded && !trackDirtyWhenEmbedded) {
|
|
324
349
|
isDirtyRef.current = false;
|
|
325
350
|
setHasUnsavedChanges(false);
|
|
326
351
|
return;
|
|
@@ -335,7 +360,10 @@ function CrudForm({
|
|
|
335
360
|
const dirty = currentSnapshot !== snapshot;
|
|
336
361
|
isDirtyRef.current = dirty;
|
|
337
362
|
setHasUnsavedChanges(dirty);
|
|
338
|
-
}, [embedded, values]);
|
|
363
|
+
}, [embedded, trackDirtyWhenEmbedded, values]);
|
|
364
|
+
React.useEffect(() => {
|
|
365
|
+
onDirtyChange?.(hasUnsavedChanges);
|
|
366
|
+
}, [hasUnsavedChanges, onDirtyChange]);
|
|
339
367
|
const allowNextNavigation = React.useCallback(() => {
|
|
340
368
|
navigationPromptBypassRef.current = true;
|
|
341
369
|
if (typeof window !== "undefined") {
|
|
@@ -389,7 +417,7 @@ function CrudForm({
|
|
|
389
417
|
}
|
|
390
418
|
}, [allowNextNavigation, confirm, t]);
|
|
391
419
|
React.useEffect(() => {
|
|
392
|
-
if (embedded || !hasUnsavedChanges) return;
|
|
420
|
+
if (embedded && !trackDirtyWhenEmbedded || !hasUnsavedChanges) return;
|
|
393
421
|
const beforeUnloadHandler = (event) => {
|
|
394
422
|
if (!isDirtyRef.current) return;
|
|
395
423
|
event.preventDefault();
|
|
@@ -463,7 +491,7 @@ function CrudForm({
|
|
|
463
491
|
window.history.pushState = originalPushState;
|
|
464
492
|
window.history.replaceState = originalReplaceState;
|
|
465
493
|
};
|
|
466
|
-
}, [allowNextNavigation, clearDirtyState, confirmUnsavedChanges, embedded, hasUnsavedChanges, router]);
|
|
494
|
+
}, [allowNextNavigation, clearDirtyState, confirmUnsavedChanges, embedded, hasUnsavedChanges, router, trackDirtyWhenEmbedded]);
|
|
467
495
|
const { widgets: injectionWidgets } = useInjectionWidgets(resolvedInjectionSpotId, {
|
|
468
496
|
context: injectionContext,
|
|
469
497
|
triggerOnLoad: true
|
|
@@ -1241,6 +1269,33 @@ function CrudForm({
|
|
|
1241
1269
|
return [...baseGroups.length ? baseGroups : autoGroup, ...injectionGroupCards];
|
|
1242
1270
|
}, [allFields, groupsWithInjectedFields, injectionGroupCards, shouldAutoGroup]);
|
|
1243
1271
|
const useGroupedLayout = resolvedGroupsForLayout.length > 0;
|
|
1272
|
+
const defaultGroupIds = React.useMemo(() => resolvedGroupsForLayout.map((g) => g.id), [resolvedGroupsForLayout]);
|
|
1273
|
+
const { orderedIds: sortedGroupIds, reorder: reorderGroups } = useGroupOrder(
|
|
1274
|
+
sortablePageType,
|
|
1275
|
+
defaultGroupIds
|
|
1276
|
+
);
|
|
1277
|
+
const sortableSensors = useSensors(
|
|
1278
|
+
useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
|
|
1279
|
+
useSensor(KeyboardSensor)
|
|
1280
|
+
);
|
|
1281
|
+
const handleGroupDragEnd = React.useCallback((event) => {
|
|
1282
|
+
const { active, over } = event;
|
|
1283
|
+
if (!over || active.id === over.id) return;
|
|
1284
|
+
const oldIndex = sortedGroupIds.indexOf(String(active.id));
|
|
1285
|
+
const newIndex = sortedGroupIds.indexOf(String(over.id));
|
|
1286
|
+
if (oldIndex !== -1 && newIndex !== -1) reorderGroups(oldIndex, newIndex);
|
|
1287
|
+
}, [sortedGroupIds, reorderGroups]);
|
|
1288
|
+
React.useEffect(() => {
|
|
1289
|
+
if (!collapsibleGroupsEnabled || Object.keys(errors).length === 0) return;
|
|
1290
|
+
const errorFieldIds = new Set(Object.keys(errors));
|
|
1291
|
+
for (const g of resolvedGroupsForLayout) {
|
|
1292
|
+
const groupFieldIds = (g.fields ?? []).map((f) => typeof f === "string" ? f : f.id);
|
|
1293
|
+
const hasError = groupFieldIds.some((id) => errorFieldIds.has(id));
|
|
1294
|
+
if (hasError) {
|
|
1295
|
+
groupCollapseRefs.current.get(g.id)?.expand();
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
}, [errors, collapsibleGroupsEnabled, resolvedGroupsForLayout]);
|
|
1244
1299
|
const stackedInjectionWidgets = React.useMemo(
|
|
1245
1300
|
() => (injectionWidgets ?? []).filter((widget) => (widget.placement?.kind ?? "stack") === "stack"),
|
|
1246
1301
|
[injectionWidgets]
|
|
@@ -2149,39 +2204,104 @@ function CrudForm({
|
|
|
2149
2204
|
);
|
|
2150
2205
|
}, [formReadOnly, handleReadOnlyFocusCapture, handleReadOnlyKeyDownCapture, readOnlyOverlay]);
|
|
2151
2206
|
if (useGroupedLayout) {
|
|
2207
|
+
const sortedGroups = sortableGroupsEnabled ? [...resolvedGroupsForLayout].sort((a, b) => {
|
|
2208
|
+
const ai = sortedGroupIds.indexOf(a.id);
|
|
2209
|
+
const bi = sortedGroupIds.indexOf(b.id);
|
|
2210
|
+
return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);
|
|
2211
|
+
}) : resolvedGroupsForLayout;
|
|
2152
2212
|
const col1 = [];
|
|
2153
2213
|
const col2 = [];
|
|
2154
|
-
for (const g of
|
|
2214
|
+
for (const g of sortedGroups) {
|
|
2155
2215
|
if ((g.column ?? 1) === 2) col2.push(g);
|
|
2156
2216
|
else col1.push(g);
|
|
2157
2217
|
}
|
|
2218
|
+
const col1Ids = col1.map((g) => g.id);
|
|
2158
2219
|
const renderGroupedCards = (items) => {
|
|
2159
2220
|
const nodes = [];
|
|
2160
2221
|
for (const g of items) {
|
|
2161
2222
|
const isCustomFieldsGroup = g.kind === "customFields";
|
|
2162
2223
|
if (isCustomFieldsGroup) {
|
|
2163
2224
|
if (isLoadingCustomFields) {
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2225
|
+
const loadingContent = /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card p-4", children: /* @__PURE__ */ jsx(
|
|
2226
|
+
DataLoader,
|
|
2227
|
+
{
|
|
2228
|
+
isLoading: true,
|
|
2229
|
+
loadingMessage: resolvedCustomFieldsLoadingMessage,
|
|
2230
|
+
spinnerSize: "md",
|
|
2231
|
+
className: "min-h-[1px]",
|
|
2232
|
+
children: /* @__PURE__ */ jsx("div", {})
|
|
2233
|
+
}
|
|
2234
|
+
) }, `${g.id}-loading`);
|
|
2235
|
+
if (collapsibleGroupsEnabled && g.title) {
|
|
2236
|
+
nodes.push(
|
|
2237
|
+
/* @__PURE__ */ jsx(
|
|
2238
|
+
CollapsibleGroup,
|
|
2239
|
+
{
|
|
2240
|
+
groupId: g.id,
|
|
2241
|
+
title: t(g.title, g.title),
|
|
2242
|
+
pageType: collapsiblePageType,
|
|
2243
|
+
chevronPosition: collapsibleChevronPosition,
|
|
2244
|
+
children: loadingContent
|
|
2245
|
+
},
|
|
2246
|
+
`${g.id}-loading-collapsible`
|
|
2247
|
+
)
|
|
2248
|
+
);
|
|
2249
|
+
} else {
|
|
2250
|
+
nodes.push(loadingContent);
|
|
2251
|
+
}
|
|
2176
2252
|
continue;
|
|
2177
2253
|
}
|
|
2254
|
+
const customFieldsInnerNodes = [];
|
|
2178
2255
|
if (g.component) {
|
|
2179
|
-
|
|
2256
|
+
customFieldsInnerNodes.push(
|
|
2180
2257
|
/* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card px-4 py-3", children: g.component({ values, setValue, errors }) }, `${g.id}-component`)
|
|
2181
2258
|
);
|
|
2182
2259
|
}
|
|
2183
2260
|
const renderedSections = renderCustomFieldsContent();
|
|
2184
|
-
if (renderedSections.length)
|
|
2261
|
+
if (renderedSections.length) customFieldsInnerNodes.push(...renderedSections);
|
|
2262
|
+
if (collapsibleGroupsEnabled && g.title) {
|
|
2263
|
+
const customFieldCount = customFieldLayout.reduce(
|
|
2264
|
+
(sum, entity) => sum + entity.sections.reduce(
|
|
2265
|
+
(sSum, section) => sSum + section.groups.reduce(
|
|
2266
|
+
(gSum, group) => gSum + group.fields.length,
|
|
2267
|
+
0
|
|
2268
|
+
),
|
|
2269
|
+
0
|
|
2270
|
+
),
|
|
2271
|
+
0
|
|
2272
|
+
);
|
|
2273
|
+
const customFieldErrors = customFieldLayout.reduce(
|
|
2274
|
+
(sum, entity) => sum + entity.sections.reduce(
|
|
2275
|
+
(sSum, section) => sSum + section.groups.reduce(
|
|
2276
|
+
(gSum, group) => gSum + group.fields.filter((f) => errors[f.id]).length,
|
|
2277
|
+
0
|
|
2278
|
+
),
|
|
2279
|
+
0
|
|
2280
|
+
),
|
|
2281
|
+
0
|
|
2282
|
+
);
|
|
2283
|
+
nodes.push(
|
|
2284
|
+
/* @__PURE__ */ jsx(
|
|
2285
|
+
CollapsibleGroup,
|
|
2286
|
+
{
|
|
2287
|
+
ref: (handle) => {
|
|
2288
|
+
if (handle) groupCollapseRefs.current.set(g.id, handle);
|
|
2289
|
+
else groupCollapseRefs.current.delete(g.id);
|
|
2290
|
+
},
|
|
2291
|
+
groupId: g.id,
|
|
2292
|
+
title: t(g.title, g.title),
|
|
2293
|
+
pageType: collapsiblePageType,
|
|
2294
|
+
errorCount: customFieldErrors,
|
|
2295
|
+
fieldCount: customFieldCount,
|
|
2296
|
+
chevronPosition: collapsibleChevronPosition,
|
|
2297
|
+
children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: customFieldsInnerNodes })
|
|
2298
|
+
},
|
|
2299
|
+
g.id
|
|
2300
|
+
)
|
|
2301
|
+
);
|
|
2302
|
+
} else {
|
|
2303
|
+
nodes.push(...customFieldsInnerNodes);
|
|
2304
|
+
}
|
|
2185
2305
|
continue;
|
|
2186
2306
|
}
|
|
2187
2307
|
const componentNode = g.component ? g.component({ values, setValue, errors }) : null;
|
|
@@ -2192,28 +2312,56 @@ function CrudForm({
|
|
|
2192
2312
|
continue;
|
|
2193
2313
|
}
|
|
2194
2314
|
const groupFields = resolveGroupFields(g);
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2315
|
+
const groupFieldIds = (g.fields ?? []).map((f) => typeof f === "string" ? f : f.id);
|
|
2316
|
+
const groupErrorCount = groupFieldIds.filter((id) => errors[id]).length;
|
|
2317
|
+
const groupContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2318
|
+
g.description ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: t(g.description, g.description) }) : null,
|
|
2319
|
+
componentNode ? /* @__PURE__ */ jsx("div", { children: componentNode }) : null,
|
|
2320
|
+
/* @__PURE__ */ jsx(
|
|
2321
|
+
DataLoader,
|
|
2322
|
+
{
|
|
2323
|
+
isLoading: false,
|
|
2324
|
+
loadingMessage: resolvedLoadingMessage,
|
|
2325
|
+
spinnerSize: "md",
|
|
2326
|
+
className: "min-h-[1px]",
|
|
2327
|
+
children: groupFields.length > 0 ? renderFields(groupFields) : /* @__PURE__ */ jsx("div", { className: "min-h-[1px]" })
|
|
2328
|
+
}
|
|
2329
|
+
)
|
|
2330
|
+
] });
|
|
2331
|
+
if (collapsibleGroupsEnabled && g.title) {
|
|
2332
|
+
nodes.push(
|
|
2200
2333
|
/* @__PURE__ */ jsx(
|
|
2201
|
-
|
|
2334
|
+
CollapsibleGroup,
|
|
2202
2335
|
{
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2336
|
+
ref: (handle) => {
|
|
2337
|
+
if (handle) groupCollapseRefs.current.set(g.id, handle);
|
|
2338
|
+
else groupCollapseRefs.current.delete(g.id);
|
|
2339
|
+
},
|
|
2340
|
+
groupId: g.id,
|
|
2341
|
+
title: t(g.title, g.title),
|
|
2342
|
+
pageType: collapsiblePageType,
|
|
2343
|
+
errorCount: groupErrorCount,
|
|
2344
|
+
fieldCount: groupFields.length,
|
|
2345
|
+
chevronPosition: collapsibleChevronPosition,
|
|
2346
|
+
children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: groupContent })
|
|
2347
|
+
},
|
|
2348
|
+
g.id
|
|
2209
2349
|
)
|
|
2210
|
-
|
|
2211
|
-
|
|
2350
|
+
);
|
|
2351
|
+
} else {
|
|
2352
|
+
nodes.push(
|
|
2353
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card px-4 py-3 space-y-3", children: [
|
|
2354
|
+
g.title ? /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: t(g.title, g.title) }) : null,
|
|
2355
|
+
groupContent
|
|
2356
|
+
] }, g.id)
|
|
2357
|
+
);
|
|
2358
|
+
}
|
|
2212
2359
|
}
|
|
2213
2360
|
return nodes;
|
|
2214
2361
|
};
|
|
2215
|
-
const
|
|
2362
|
+
const col1Nodes = renderGroupedCards(col1);
|
|
2216
2363
|
const col2Content = renderGroupedCards(col2);
|
|
2364
|
+
const col1Content = sortableGroupsEnabled ? col1Nodes.map((node, i) => /* @__PURE__ */ jsx(SortableGroupItem, { id: col1[i]?.id ?? String(i), children: node }, col1[i]?.id ?? i)) : col1Nodes;
|
|
2217
2365
|
const hasSecondaryColumn = col2Content.length > 0;
|
|
2218
2366
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", ref: rootRef, "data-component-handle": resolvedReplacementHandle, children: [
|
|
2219
2367
|
!embedded ? /* @__PURE__ */ jsx(
|
|
@@ -2261,12 +2409,12 @@ function CrudForm({
|
|
|
2261
2409
|
{
|
|
2262
2410
|
className: hasSecondaryColumn ? "grid grid-cols-1 lg:grid-cols-[7fr_3fr] gap-4" : "grid grid-cols-1 gap-4",
|
|
2263
2411
|
children: [
|
|
2264
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-3", children: col1Content }),
|
|
2412
|
+
sortableGroupsEnabled ? /* @__PURE__ */ jsx(DndContext, { sensors: sortableSensors, collisionDetection: closestCenter, onDragEnd: handleGroupDragEnd, children: /* @__PURE__ */ jsx(SortableContext, { items: col1Ids, strategy: verticalListSortingStrategy, children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: col1Content }) }) }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: col1Content }),
|
|
2265
2413
|
hasSecondaryColumn ? /* @__PURE__ */ jsx("div", { className: "space-y-3", children: col2Content }) : null
|
|
2266
2414
|
]
|
|
2267
2415
|
}
|
|
2268
2416
|
),
|
|
2269
|
-
formError && !Object.keys(errors).length ? /* @__PURE__ */ jsx("div", { className: "text-sm text-
|
|
2417
|
+
formError && !Object.keys(errors).length ? /* @__PURE__ */ jsx("div", { className: "text-sm text-status-error-text", children: formError }) : null,
|
|
2270
2418
|
hideFooterActions || formReadOnly ? null : /* @__PURE__ */ jsx(
|
|
2271
2419
|
FormFooter,
|
|
2272
2420
|
{
|
|
@@ -2362,7 +2510,7 @@ function CrudForm({
|
|
|
2362
2510
|
f.id
|
|
2363
2511
|
);
|
|
2364
2512
|
}) }),
|
|
2365
|
-
formError && !Object.keys(errors).length ? /* @__PURE__ */ jsx("div", { className: "text-sm text-
|
|
2513
|
+
formError && !Object.keys(errors).length ? /* @__PURE__ */ jsx("div", { className: "text-sm text-status-error-text", children: formError }) : null,
|
|
2366
2514
|
hideFooterActions || formReadOnly ? null : /* @__PURE__ */ jsx(
|
|
2367
2515
|
FormFooter,
|
|
2368
2516
|
{
|
|
@@ -2962,7 +3110,7 @@ const FieldControl = React.memo(
|
|
|
2962
3110
|
children: [
|
|
2963
3111
|
field.type !== "checkbox" && field.label.trim().length > 0 ? /* @__PURE__ */ jsxs("label", { className: "block text-sm font-medium", children: [
|
|
2964
3112
|
field.label,
|
|
2965
|
-
field.required ? /* @__PURE__ */ jsx("span", { className: "text-
|
|
3113
|
+
field.required ? /* @__PURE__ */ jsx("span", { className: "text-status-error-text", children: " *" }) : null
|
|
2966
3114
|
] }) : null,
|
|
2967
3115
|
field.type === "text" && /* @__PURE__ */ jsx(
|
|
2968
3116
|
TextInput,
|
|
@@ -3194,7 +3342,7 @@ const FieldControl = React.memo(
|
|
|
3194
3342
|
/* @__PURE__ */ jsx(Info, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }),
|
|
3195
3343
|
/* @__PURE__ */ jsx("div", { children: field.description })
|
|
3196
3344
|
] }) : null,
|
|
3197
|
-
error ? /* @__PURE__ */ jsx("div", { className: "text-xs text-
|
|
3345
|
+
error ? /* @__PURE__ */ jsx("div", { className: "text-xs text-status-error-text", children: error }) : null
|
|
3198
3346
|
]
|
|
3199
3347
|
}
|
|
3200
3348
|
);
|