@oondemand/oon-core-front 0.3.12 → 0.3.14
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.d.ts +17 -1
- package/dist/index.js +121 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -246,6 +246,7 @@ interface OonColumnDef {
|
|
|
246
246
|
permissions?: string[];
|
|
247
247
|
capabilities?: string[];
|
|
248
248
|
}
|
|
249
|
+
type OonFormFieldWidget = "default" | "checkbox";
|
|
249
250
|
interface OonFormFieldDef {
|
|
250
251
|
field: string;
|
|
251
252
|
label?: string;
|
|
@@ -255,6 +256,19 @@ interface OonFormFieldDef {
|
|
|
255
256
|
/** model relacionada quando kind === "ref". */
|
|
256
257
|
ref?: string;
|
|
257
258
|
renderer?: string;
|
|
259
|
+
/** Controle visual pontual sem substituir a página/formulário inteiro. */
|
|
260
|
+
widget?: OonFormFieldWidget;
|
|
261
|
+
/** Valor persistido quando um checkbox está marcado. Default: true. */
|
|
262
|
+
checkedValue?: string | number | boolean;
|
|
263
|
+
/** Valor persistido quando um checkbox está desmarcado. Default: false. */
|
|
264
|
+
uncheckedValue?: string | number | boolean;
|
|
265
|
+
/** Agrupa campos relacionados em um bloco visual comum. */
|
|
266
|
+
group?: string;
|
|
267
|
+
/** Rótulo exibido uma vez acima do grupo. Default: group. */
|
|
268
|
+
groupLabel?: string;
|
|
269
|
+
groupDescription?: string;
|
|
270
|
+
/** Exibe controles do mesmo grupo na mesma linha quando houver espaço. */
|
|
271
|
+
inline?: boolean;
|
|
258
272
|
permissions?: string[];
|
|
259
273
|
capabilities?: string[];
|
|
260
274
|
}
|
|
@@ -412,7 +426,7 @@ interface CollectionViewDef {
|
|
|
412
426
|
mode?: CollectionMode;
|
|
413
427
|
/** modo "full": colunas explícitas. */
|
|
414
428
|
columns?: OonColumnDef[];
|
|
415
|
-
/**
|
|
429
|
+
/** Campos explícitos ou overrides pontuais sobre a metadata do model. */
|
|
416
430
|
form?: OonFormFieldDef[];
|
|
417
431
|
importExport?: boolean;
|
|
418
432
|
renderer?: string;
|
|
@@ -583,6 +597,8 @@ interface CentralUiManifest {
|
|
|
583
597
|
path?: string;
|
|
584
598
|
label?: string;
|
|
585
599
|
section?: string;
|
|
600
|
+
/** Overrides pontuais de campos; os demais continuam vindo da metadata. */
|
|
601
|
+
form?: OonFormFieldDef[];
|
|
586
602
|
list?: OonCollectionListConfig;
|
|
587
603
|
relations?: Record<string, OonRelationDef>;
|
|
588
604
|
detailModal?: OonDetailModalConfig;
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { StrictMode } from "react";
|
|
|
3
3
|
import { createRoot } from "react-dom/client";
|
|
4
4
|
|
|
5
5
|
// src/app/OonApp.tsx
|
|
6
|
-
import { useMemo as
|
|
6
|
+
import { useMemo as useMemo7 } from "react";
|
|
7
7
|
import { RouterProvider } from "react-router-dom";
|
|
8
8
|
|
|
9
9
|
// src/api/createRestClient.ts
|
|
@@ -953,7 +953,7 @@ function DataGrid({
|
|
|
953
953
|
}
|
|
954
954
|
|
|
955
955
|
// src/components/internal/DynamicForm.tsx
|
|
956
|
-
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
956
|
+
import { useEffect as useEffect4, useMemo as useMemo4, useState as useState5 } from "react";
|
|
957
957
|
import { Box as Box4, Button as Button4, Flex as Flex4, Heading as Heading2, Input as Input3, NativeSelect as NativeSelect2, SimpleGrid, Stack as Stack2, Text as Text5, Textarea } from "@chakra-ui/react";
|
|
958
958
|
|
|
959
959
|
// src/components/internal/ReferenceSelect.tsx
|
|
@@ -1443,10 +1443,25 @@ var controlProps = (invalid) => ({
|
|
|
1443
1443
|
boxShadow: invalid ? "0 0 0 3px rgba(220,38,38,.08)" : void 0,
|
|
1444
1444
|
fontSize: "11px"
|
|
1445
1445
|
});
|
|
1446
|
+
function buildItems(fields) {
|
|
1447
|
+
const items = [];
|
|
1448
|
+
const renderedGroups = /* @__PURE__ */ new Set();
|
|
1449
|
+
fields.forEach((field) => {
|
|
1450
|
+
if (!field.group) {
|
|
1451
|
+
items.push({ type: "field", field });
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
if (renderedGroups.has(field.group)) return;
|
|
1455
|
+
renderedGroups.add(field.group);
|
|
1456
|
+
items.push({ type: "group", id: field.group, fields: fields.filter((candidate) => candidate.group === field.group) });
|
|
1457
|
+
});
|
|
1458
|
+
return items;
|
|
1459
|
+
}
|
|
1446
1460
|
function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submitting, error, onSubmit, onCancel, onFieldChange }) {
|
|
1447
1461
|
const [values, setValues] = useState5(() => Object.fromEntries(fields.map((field) => [field.field, toValue(initialValues?.[field.field], field.kind)])));
|
|
1448
1462
|
const [errors, setErrors] = useState5({});
|
|
1449
1463
|
const [dismissed, setDismissed] = useState5(false);
|
|
1464
|
+
const items = useMemo4(() => buildItems(fields), [fields]);
|
|
1450
1465
|
useEffect4(() => {
|
|
1451
1466
|
const listener = (event) => {
|
|
1452
1467
|
if (event.key !== "Escape" || event.defaultPrevented || submitting) return;
|
|
@@ -1496,6 +1511,83 @@ function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submi
|
|
|
1496
1511
|
setErrors({});
|
|
1497
1512
|
onSubmit(payload);
|
|
1498
1513
|
};
|
|
1514
|
+
const renderField = (field, grouped = false) => {
|
|
1515
|
+
const label = fieldLabel({ name: field.field, label: field.label });
|
|
1516
|
+
const message = errors[field.field];
|
|
1517
|
+
const id = idFor(field.field);
|
|
1518
|
+
const errorId = message ? errorIdFor(field.field) : void 0;
|
|
1519
|
+
const multiline = isMultiline(field);
|
|
1520
|
+
const span = field.span === 2 || multiline;
|
|
1521
|
+
const wrap = (control, showLabel = true) => /* @__PURE__ */ jsxs5(Box4, { minW: grouped ? "150px" : void 0, flex: grouped ? "0 1 auto" : void 0, gridColumn: !grouped && span ? "1 / -1" : void 0, children: [
|
|
1522
|
+
showLabel ? /* @__PURE__ */ jsx9(Label, { id, label, required: field.required }) : null,
|
|
1523
|
+
control,
|
|
1524
|
+
/* @__PURE__ */ jsx9(ErrorText, { id: errorId, text: message })
|
|
1525
|
+
] }, field.field);
|
|
1526
|
+
if (field.widget === "checkbox") {
|
|
1527
|
+
const checkedValue = String(field.checkedValue ?? true);
|
|
1528
|
+
const uncheckedValue = String(field.uncheckedValue ?? false);
|
|
1529
|
+
const checked = (values[field.field] ?? uncheckedValue) === checkedValue;
|
|
1530
|
+
return wrap(
|
|
1531
|
+
/* @__PURE__ */ jsxs5(
|
|
1532
|
+
Box4,
|
|
1533
|
+
{
|
|
1534
|
+
as: "label",
|
|
1535
|
+
display: "flex",
|
|
1536
|
+
minH: "37px",
|
|
1537
|
+
px: "11px",
|
|
1538
|
+
alignItems: "center",
|
|
1539
|
+
gap: "8px",
|
|
1540
|
+
color: "#344054",
|
|
1541
|
+
bg: checked ? "#F0F7FF" : "white",
|
|
1542
|
+
borderWidth: "1px",
|
|
1543
|
+
borderColor: message ? "#DC2626" : checked ? "#8FC9E7" : "#D5DDE3",
|
|
1544
|
+
borderRadius: "7px",
|
|
1545
|
+
cursor: "pointer",
|
|
1546
|
+
transition: "background .15s ease, border-color .15s ease",
|
|
1547
|
+
_hover: { borderColor: "#8FC9E7", bg: "#F7FBFE" },
|
|
1548
|
+
children: [
|
|
1549
|
+
/* @__PURE__ */ jsx9(
|
|
1550
|
+
"input",
|
|
1551
|
+
{
|
|
1552
|
+
id,
|
|
1553
|
+
type: "checkbox",
|
|
1554
|
+
checked,
|
|
1555
|
+
"aria-invalid": !!message,
|
|
1556
|
+
"aria-describedby": errorId,
|
|
1557
|
+
style: { width: 16, height: 16, accentColor: "#0474AF", cursor: "pointer" },
|
|
1558
|
+
onChange: (event) => change(field.field, event.currentTarget.checked ? checkedValue : uncheckedValue)
|
|
1559
|
+
}
|
|
1560
|
+
),
|
|
1561
|
+
/* @__PURE__ */ jsxs5(Text5, { as: "span", fontSize: "11px", fontWeight: "600", children: [
|
|
1562
|
+
label,
|
|
1563
|
+
field.required ? /* @__PURE__ */ jsx9(Text5, { as: "span", color: "#DC2626", children: " *" }) : null
|
|
1564
|
+
] })
|
|
1565
|
+
]
|
|
1566
|
+
}
|
|
1567
|
+
),
|
|
1568
|
+
false
|
|
1569
|
+
);
|
|
1570
|
+
}
|
|
1571
|
+
if (field.kind === "ref" && field.ref) return wrap(/* @__PURE__ */ jsx9(ReferenceSelect, { field: field.field, inputId: id, errorId, label, refModel: field.ref, value: values[field.field] ?? "", initialValue: initialValues?.[field.field], required: field.required, invalid: !!message, error: message, onChange: (value) => change(field.field, value) }));
|
|
1572
|
+
if (field.kind === "enum" && field.options?.length) return wrap(/* @__PURE__ */ jsxs5(NativeSelect2.Root, { size: "sm", children: [
|
|
1573
|
+
/* @__PURE__ */ jsxs5(NativeSelect2.Field, { id, "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), onChange: (event) => change(field.field, event.currentTarget.value), children: [
|
|
1574
|
+
/* @__PURE__ */ jsx9("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
1575
|
+
field.options.map((option) => /* @__PURE__ */ jsx9("option", { value: option, children: option }, option))
|
|
1576
|
+
] }),
|
|
1577
|
+
/* @__PURE__ */ jsx9(NativeSelect2.Indicator, {})
|
|
1578
|
+
] }));
|
|
1579
|
+
if (field.kind === "boolean") return wrap(/* @__PURE__ */ jsxs5(NativeSelect2.Root, { size: "sm", children: [
|
|
1580
|
+
/* @__PURE__ */ jsxs5(NativeSelect2.Field, { id, "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), onChange: (event) => change(field.field, event.currentTarget.value), children: [
|
|
1581
|
+
/* @__PURE__ */ jsx9("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
1582
|
+
/* @__PURE__ */ jsx9("option", { value: "true", children: "Sim" }),
|
|
1583
|
+
/* @__PURE__ */ jsx9("option", { value: "false", children: "N\xE3o" })
|
|
1584
|
+
] }),
|
|
1585
|
+
/* @__PURE__ */ jsx9(NativeSelect2.Indicator, {})
|
|
1586
|
+
] }));
|
|
1587
|
+
if (multiline) return wrap(/* @__PURE__ */ jsx9(Textarea, { id, rows: field.rows ?? 4, resize: "vertical", "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), lineHeight: "1.5", onChange: (event) => change(field.field, event.currentTarget.value) }));
|
|
1588
|
+
const type = field.kind === "date" ? "date" : ["number", "currency", "currencyConverted"].includes(field.kind ?? "") ? "number" : "text";
|
|
1589
|
+
return wrap(/* @__PURE__ */ jsx9(Input3, { id, type, step: type === "number" ? "any" : void 0, autoComplete: "off", "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), onChange: (event) => change(field.field, event.currentTarget.value) }));
|
|
1590
|
+
};
|
|
1499
1591
|
const invalid = fields.filter((field) => errors[field.field]);
|
|
1500
1592
|
const generic = dismissed ? null : messageOf(error);
|
|
1501
1593
|
return /* @__PURE__ */ jsx9(Flex4, { position: "fixed", inset: 0, zIndex: 1e3, align: "center", justify: "center", p: { base: 2, md: 6 }, bg: "rgba(15,23,42,.48)", backdropFilter: "blur(2px)", onMouseDown: (event) => {
|
|
@@ -1525,38 +1617,15 @@ function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submi
|
|
|
1525
1617
|
/* @__PURE__ */ jsx9(AlertIcon, {}),
|
|
1526
1618
|
generic
|
|
1527
1619
|
] }) : null,
|
|
1528
|
-
/* @__PURE__ */ jsx9(SimpleGrid, { columns: { base: 1, lg: 2 }, gapX: "16px", gapY: "15px", children:
|
|
1529
|
-
|
|
1530
|
-
const
|
|
1531
|
-
const
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
/* @__PURE__ */ jsx9(Label, { id, label, required: field.required }),
|
|
1538
|
-
control,
|
|
1539
|
-
/* @__PURE__ */ jsx9(ErrorText, { id: errorId, text: message })
|
|
1540
|
-
] }, field.field);
|
|
1541
|
-
if (field.kind === "ref" && field.ref) return wrap(/* @__PURE__ */ jsx9(ReferenceSelect, { field: field.field, inputId: id, errorId, label, refModel: field.ref, value: values[field.field] ?? "", initialValue: initialValues?.[field.field], required: field.required, invalid: !!message, error: message, onChange: (value) => change(field.field, value) }));
|
|
1542
|
-
if (field.kind === "enum" && field.options?.length) return wrap(/* @__PURE__ */ jsxs5(NativeSelect2.Root, { size: "sm", children: [
|
|
1543
|
-
/* @__PURE__ */ jsxs5(NativeSelect2.Field, { id, "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), onChange: (event) => change(field.field, event.currentTarget.value), children: [
|
|
1544
|
-
/* @__PURE__ */ jsx9("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
1545
|
-
field.options.map((option) => /* @__PURE__ */ jsx9("option", { value: option, children: option }, option))
|
|
1546
|
-
] }),
|
|
1547
|
-
/* @__PURE__ */ jsx9(NativeSelect2.Indicator, {})
|
|
1548
|
-
] }));
|
|
1549
|
-
if (field.kind === "boolean") return wrap(/* @__PURE__ */ jsxs5(NativeSelect2.Root, { size: "sm", children: [
|
|
1550
|
-
/* @__PURE__ */ jsxs5(NativeSelect2.Field, { id, "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), onChange: (event) => change(field.field, event.currentTarget.value), children: [
|
|
1551
|
-
/* @__PURE__ */ jsx9("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
1552
|
-
/* @__PURE__ */ jsx9("option", { value: "true", children: "Sim" }),
|
|
1553
|
-
/* @__PURE__ */ jsx9("option", { value: "false", children: "N\xE3o" })
|
|
1554
|
-
] }),
|
|
1555
|
-
/* @__PURE__ */ jsx9(NativeSelect2.Indicator, {})
|
|
1556
|
-
] }));
|
|
1557
|
-
if (multiline) return wrap(/* @__PURE__ */ jsx9(Textarea, { id, rows: field.rows ?? 4, resize: "vertical", "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), lineHeight: "1.5", onChange: (event) => change(field.field, event.currentTarget.value) }));
|
|
1558
|
-
const type = field.kind === "date" ? "date" : ["number", "currency", "currencyConverted"].includes(field.kind ?? "") ? "number" : "text";
|
|
1559
|
-
return wrap(/* @__PURE__ */ jsx9(Input3, { id, type, step: type === "number" ? "any" : void 0, autoComplete: "off", "aria-invalid": !!message, "aria-describedby": errorId, value: values[field.field] ?? "", ...controlProps(!!message), onChange: (event) => change(field.field, event.currentTarget.value) }));
|
|
1620
|
+
/* @__PURE__ */ jsx9(SimpleGrid, { columns: { base: 1, lg: 2 }, gapX: "16px", gapY: "15px", children: items.map((item) => {
|
|
1621
|
+
if (item.type === "field") return renderField(item.field);
|
|
1622
|
+
const first = item.fields[0];
|
|
1623
|
+
const inline = item.fields.some((field) => field.inline !== false);
|
|
1624
|
+
return /* @__PURE__ */ jsxs5(Box4, { gridColumn: "1 / -1", p: "12px", bg: "#FAFCFD", borderWidth: "1px", borderColor: "#E5E9ED", borderRadius: "9px", children: [
|
|
1625
|
+
/* @__PURE__ */ jsx9(Text5, { color: "#344054", fontSize: "11px", fontWeight: "700", children: first.groupLabel ?? item.id }),
|
|
1626
|
+
first.groupDescription ? /* @__PURE__ */ jsx9(Text5, { mt: "2px", mb: "10px", color: "#667085", fontSize: "10px", children: first.groupDescription }) : /* @__PURE__ */ jsx9(Box4, { h: "8px" }),
|
|
1627
|
+
/* @__PURE__ */ jsx9(Flex4, { direction: inline ? "row" : "column", wrap: "wrap", gap: "9px", children: item.fields.map((field) => renderField(field, true)) })
|
|
1628
|
+
] }, item.id);
|
|
1560
1629
|
}) })
|
|
1561
1630
|
] }) }),
|
|
1562
1631
|
/* @__PURE__ */ jsxs5(Flex4, { minH: "68px", px: "20px", py: "14px", justify: "flex-end", gap: "9px", borderTopWidth: "1px", borderColor: "#E5E9ED", children: [
|
|
@@ -1571,7 +1640,7 @@ function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submi
|
|
|
1571
1640
|
}
|
|
1572
1641
|
|
|
1573
1642
|
// src/components/internal/CoreDetailModal.tsx
|
|
1574
|
-
import { useEffect as useEffect6, useMemo as
|
|
1643
|
+
import { useEffect as useEffect6, useMemo as useMemo6, useState as useState9 } from "react";
|
|
1575
1644
|
import { Box as Box8, Button as Button8, Flex as Flex7, Heading as Heading3, Text as Text10 } from "@chakra-ui/react";
|
|
1576
1645
|
import { useQuery as useQuery6, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
1577
1646
|
|
|
@@ -1632,7 +1701,7 @@ function CoreSummaryCards({ cards = [], parent, relations }) {
|
|
|
1632
1701
|
}
|
|
1633
1702
|
|
|
1634
1703
|
// src/components/internal/CoreRelatedGrid.tsx
|
|
1635
|
-
import { useMemo as
|
|
1704
|
+
import { useMemo as useMemo5, useState as useState7 } from "react";
|
|
1636
1705
|
import { Badge as Badge3, Box as Box6, Button as Button6, Flex as Flex5, Table as Table2, Text as Text8 } from "@chakra-ui/react";
|
|
1637
1706
|
import { useMutation, useQuery as useQuery5, useQueryClient } from "@tanstack/react-query";
|
|
1638
1707
|
|
|
@@ -1748,7 +1817,7 @@ function CoreRelatedGrid({ tab, parent, relations, refreshToken, onRefresh }) {
|
|
|
1748
1817
|
const parentValue = relation ? parent[relation.parentKey ?? "_id"] : void 0;
|
|
1749
1818
|
const key = ["oon", "related", relation?.model, relation?.foreignKey, parentValue, refreshToken];
|
|
1750
1819
|
const query = useQuery5({ queryKey: key, enabled: !!relation && parentValue != null, queryFn: () => resource.list({ [relation.foreignKey]: parentValue, pageSize: 1e3 }) });
|
|
1751
|
-
const columns =
|
|
1820
|
+
const columns = useMemo5(() => (tab.columns?.length ? tab.columns : schema?.fields.slice(0, 8).map((f) => f.name) ?? []).map((column) => normalizeColumn(column, schema)).filter((column) => !column.hidden), [tab.columns, schema]);
|
|
1752
1821
|
const [drafts, setDrafts] = useState7({});
|
|
1753
1822
|
const [errors, setErrors] = useState7({});
|
|
1754
1823
|
const editable = tab.type === "relatedGrid" && tab.editable && tab.editMode === "inline";
|
|
@@ -1876,7 +1945,7 @@ function CoreDetailModal({ model, title, config, recordId, initialRecord, initia
|
|
|
1876
1945
|
useEffect6(() => {
|
|
1877
1946
|
if (parentQuery.data) setParent(parentQuery.data);
|
|
1878
1947
|
}, [parentQuery.data]);
|
|
1879
|
-
const formFields =
|
|
1948
|
+
const formFields = useMemo6(() => schema ? formFieldsFromMeta(schema.fields) : [], [schema]);
|
|
1880
1949
|
const refresh = (targets) => {
|
|
1881
1950
|
const list = targets?.length ? targets : ["self"];
|
|
1882
1951
|
if (list.includes("parent") || list.includes("all")) {
|
|
@@ -1912,13 +1981,24 @@ function CoreDetailModal({ model, title, config, recordId, initialRecord, initia
|
|
|
1912
1981
|
|
|
1913
1982
|
// src/components/CoreCollection.tsx
|
|
1914
1983
|
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1984
|
+
function mergeFormFields(metadataFields, overrides) {
|
|
1985
|
+
if (!overrides?.length) return metadataFields;
|
|
1986
|
+
const byField = new Map(overrides.map((field) => [field.field, field]));
|
|
1987
|
+
const merged = metadataFields.map((field) => ({ ...field, ...byField.get(field.field) }));
|
|
1988
|
+
const known = new Set(metadataFields.map((field) => field.field));
|
|
1989
|
+
overrides.forEach((field) => {
|
|
1990
|
+
if (!known.has(field.field)) merged.push(field);
|
|
1991
|
+
});
|
|
1992
|
+
return merged;
|
|
1993
|
+
}
|
|
1915
1994
|
function CoreCollection({ model, label, section = "Cole\xE7\xE3o", mode = "dynamic", endpoint, columns, form, importExport, list, relations, detailModal }) {
|
|
1916
1995
|
const needsSchema = mode !== "full" || !columns || !form || !endpoint;
|
|
1917
1996
|
const schemaQuery = useModelSchema(needsSchema ? model : "");
|
|
1918
1997
|
const schema = schemaQuery.data;
|
|
1919
1998
|
const basePath = endpoint ?? schema?.basePath ?? `/${model.toLowerCase()}s`;
|
|
1920
1999
|
const resolvedColumns = (list?.columns?.length ? list.columns.map((column) => normalizeColumn(column, schema)) : columns) ?? (schema ? columnsFromMeta(schema.fields) : []);
|
|
1921
|
-
const
|
|
2000
|
+
const metadataForm = schema ? formFieldsFromMeta(schema.fields) : [];
|
|
2001
|
+
const resolvedForm = mode === "full" && form?.length ? form : mergeFormFields(metadataForm, form);
|
|
1922
2002
|
const resource = useOonResource(basePath);
|
|
1923
2003
|
const queryClient = useQueryClient3();
|
|
1924
2004
|
const [formState, setFormState] = useState10({ open: false });
|
|
@@ -3438,7 +3518,7 @@ function localLoginUrl() {
|
|
|
3438
3518
|
return `/login?redirect=${encodeURIComponent(current)}`;
|
|
3439
3519
|
}
|
|
3440
3520
|
function OonApp({ config }) {
|
|
3441
|
-
const { http, storage, router } =
|
|
3521
|
+
const { http, storage, router } = useMemo7(() => {
|
|
3442
3522
|
const storage2 = createTokenStorage(config.app.id);
|
|
3443
3523
|
const externalLoginUrl = config.auth?.loginUrl ?? config.api.meusAppsUrl;
|
|
3444
3524
|
const http2 = createRestClient({
|
|
@@ -3533,6 +3613,7 @@ function manifestToConfig(manifest, runtime) {
|
|
|
3533
3613
|
path: c.path,
|
|
3534
3614
|
label: c.label,
|
|
3535
3615
|
section: c.section,
|
|
3616
|
+
form: c.form,
|
|
3536
3617
|
list: c.list,
|
|
3537
3618
|
relations: c.relations,
|
|
3538
3619
|
detailModal: c.detailModal
|