@oondemand/oon-core-front 0.3.27 → 0.3.29
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 +48 -4
- package/dist/index.js +291 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28,11 +28,12 @@ function normalizeError(err) {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
const envelope = data?.error;
|
|
31
|
+
const legacyDetails = envelope && envelope.details === void 0 && envelope.field ? envelope : void 0;
|
|
31
32
|
return {
|
|
32
33
|
code: envelope?.code || codeFromStatus(status),
|
|
33
34
|
message: envelope?.message || data?.message || err.message || "Erro inesperado.",
|
|
34
35
|
status,
|
|
35
|
-
details: envelope?.details,
|
|
36
|
+
details: envelope?.details ?? legacyDetails,
|
|
36
37
|
requestId: envelope?.requestId || err.response?.headers?.["x-request-id"]
|
|
37
38
|
};
|
|
38
39
|
}
|
|
@@ -1035,6 +1036,11 @@ function ChevronIcon2({ open }) {
|
|
|
1035
1036
|
function ClearIcon() {
|
|
1036
1037
|
return /* @__PURE__ */ jsx8("svg", { viewBox: "0 0 20 20", width: "14", height: "14", "aria-hidden": "true", children: /* @__PURE__ */ jsx8("path", { d: "m6 6 8 8M14 6l-8 8", fill: "none", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round" }) });
|
|
1037
1038
|
}
|
|
1039
|
+
function cleanFilters(filters) {
|
|
1040
|
+
return Object.fromEntries(
|
|
1041
|
+
Object.entries(filters ?? {}).filter(([, value]) => value !== void 0 && value !== null && value !== "")
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1038
1044
|
function ReferenceSelect({
|
|
1039
1045
|
field,
|
|
1040
1046
|
inputId,
|
|
@@ -1046,9 +1052,16 @@ function ReferenceSelect({
|
|
|
1046
1052
|
required,
|
|
1047
1053
|
invalid,
|
|
1048
1054
|
error,
|
|
1055
|
+
filters,
|
|
1056
|
+
emptyFields = [],
|
|
1057
|
+
disabled = false,
|
|
1058
|
+
disabledMessage,
|
|
1049
1059
|
onChange
|
|
1050
1060
|
}) {
|
|
1051
1061
|
const initialLabel = useMemo3(() => initialReferenceLabel(initialValue), [initialValue]);
|
|
1062
|
+
const resolvedFilters = useMemo3(() => cleanFilters(filters), [filters]);
|
|
1063
|
+
const filtersKey = useMemo3(() => JSON.stringify(resolvedFilters), [resolvedFilters]);
|
|
1064
|
+
const emptyFieldsKey = useMemo3(() => JSON.stringify(emptyFields), [emptyFields]);
|
|
1052
1065
|
const [selectedLabel, setSelectedLabel] = useState4(initialLabel);
|
|
1053
1066
|
const [search, setSearch] = useState4("");
|
|
1054
1067
|
const [debouncedSearch, setDebouncedSearch] = useState4("");
|
|
@@ -1069,6 +1082,11 @@ function ReferenceSelect({
|
|
|
1069
1082
|
if (!value) setSelectedLabel("");
|
|
1070
1083
|
else if (initialLabel) setSelectedLabel(initialLabel);
|
|
1071
1084
|
}, [initialLabel, value]);
|
|
1085
|
+
useEffect3(() => {
|
|
1086
|
+
if (!disabled) return;
|
|
1087
|
+
setOpen(false);
|
|
1088
|
+
setActiveIndex(-1);
|
|
1089
|
+
}, [disabled]);
|
|
1072
1090
|
useEffect3(() => {
|
|
1073
1091
|
if (!open) return;
|
|
1074
1092
|
const onPointerDown = (event) => {
|
|
@@ -1085,9 +1103,14 @@ function ReferenceSelect({
|
|
|
1085
1103
|
window.setTimeout(() => searchRef.current?.focus(), 0);
|
|
1086
1104
|
}, [open]);
|
|
1087
1105
|
const listQuery = useQuery3({
|
|
1088
|
-
queryKey: ["oon", "reference-options", refModel, basePath, debouncedSearch],
|
|
1089
|
-
queryFn: () => resource.list({
|
|
1090
|
-
|
|
1106
|
+
queryKey: ["oon", "reference-options", refModel, basePath, debouncedSearch, filtersKey, emptyFieldsKey],
|
|
1107
|
+
queryFn: () => resource.list({
|
|
1108
|
+
pageIndex: 0,
|
|
1109
|
+
pageSize: emptyFields.length ? 200 : 30,
|
|
1110
|
+
searchTerm: debouncedSearch || void 0,
|
|
1111
|
+
...resolvedFilters
|
|
1112
|
+
}),
|
|
1113
|
+
enabled: !!schema && open && !disabled,
|
|
1091
1114
|
staleTime: 3e4
|
|
1092
1115
|
});
|
|
1093
1116
|
const currentQuery = useQuery3({
|
|
@@ -1100,11 +1123,17 @@ function ReferenceSelect({
|
|
|
1100
1123
|
if (!currentQuery.data) return;
|
|
1101
1124
|
setSelectedLabel(referenceOptionLabel(currentQuery.data, schema?.searchable));
|
|
1102
1125
|
}, [currentQuery.data, schema?.searchable]);
|
|
1103
|
-
const items = listQuery.data?.results ?? []
|
|
1126
|
+
const items = (listQuery.data?.results ?? []).filter(
|
|
1127
|
+
(record) => emptyFields.every((fieldName) => {
|
|
1128
|
+
const candidate = record[fieldName];
|
|
1129
|
+
return candidate === void 0 || candidate === null || candidate === "";
|
|
1130
|
+
})
|
|
1131
|
+
);
|
|
1104
1132
|
const listId = `oon-reference-${field}`;
|
|
1105
1133
|
const resolvedInputId = inputId ?? `oon-reference-input-${field}`;
|
|
1106
1134
|
const activeOptionId = activeIndex >= 0 ? `${listId}-option-${activeIndex}` : void 0;
|
|
1107
1135
|
const openList = (seed = "") => {
|
|
1136
|
+
if (disabled) return;
|
|
1108
1137
|
if (seed) setSearch(seed);
|
|
1109
1138
|
setOpen(true);
|
|
1110
1139
|
setActiveIndex((current) => current >= 0 ? current : 0);
|
|
@@ -1139,6 +1168,7 @@ function ReferenceSelect({
|
|
|
1139
1168
|
return next;
|
|
1140
1169
|
});
|
|
1141
1170
|
};
|
|
1171
|
+
const placeholder = disabled ? disabledMessage ?? "Selecione primeiro o campo relacionado." : "Selecione ou digite para pesquisar...";
|
|
1142
1172
|
return /* @__PURE__ */ jsxs4(Box3, { ref: rootRef, position: "relative", children: [
|
|
1143
1173
|
/* @__PURE__ */ jsxs4(
|
|
1144
1174
|
Button3,
|
|
@@ -1161,6 +1191,7 @@ function ReferenceSelect({
|
|
|
1161
1191
|
fontSize: "11px",
|
|
1162
1192
|
fontWeight: "400",
|
|
1163
1193
|
textAlign: "left",
|
|
1194
|
+
disabled,
|
|
1164
1195
|
"aria-haspopup": "listbox",
|
|
1165
1196
|
"aria-expanded": open,
|
|
1166
1197
|
"aria-controls": listId,
|
|
@@ -1170,6 +1201,7 @@ function ReferenceSelect({
|
|
|
1170
1201
|
"aria-describedby": error ? errorId : void 0,
|
|
1171
1202
|
onClick: () => open ? closeList() : openList(),
|
|
1172
1203
|
onKeyDown: (event) => {
|
|
1204
|
+
if (disabled) return;
|
|
1173
1205
|
if (event.key === "ArrowDown") {
|
|
1174
1206
|
event.preventDefault();
|
|
1175
1207
|
if (!open) openList();
|
|
@@ -1200,10 +1232,11 @@ function ReferenceSelect({
|
|
|
1200
1232
|
},
|
|
1201
1233
|
_hover: { bg: "white", borderColor: "#B9C7D1" },
|
|
1202
1234
|
_focusVisible: { borderColor: invalid ? "#DC2626" : "#0F8DD0", boxShadow: invalid ? "0 0 0 3px rgba(220,38,38,.08)" : "0 0 0 3px rgba(15,141,208,.10)" },
|
|
1235
|
+
_disabled: { cursor: "not-allowed", color: "#98A2B3", bg: "#F8FAFC", opacity: 1 },
|
|
1203
1236
|
children: [
|
|
1204
|
-
/* @__PURE__ */ jsx8(Text4, { as: "span", minW: 0, flex: "1", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", color: selectedLabel || value ? "#475467" : "#98A2B3", children: selectedLabel || (value ? String(value) :
|
|
1237
|
+
/* @__PURE__ */ jsx8(Text4, { as: "span", minW: 0, flex: "1", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", color: selectedLabel || value ? "#475467" : "#98A2B3", children: selectedLabel || (value ? String(value) : placeholder) }),
|
|
1205
1238
|
/* @__PURE__ */ jsxs4(Flex3, { as: "span", align: "center", gap: 1, flex: "0 0 auto", color: "#98A2B3", children: [
|
|
1206
|
-
value ? /* @__PURE__ */ jsx8(
|
|
1239
|
+
value && !disabled ? /* @__PURE__ */ jsx8(
|
|
1207
1240
|
Box3,
|
|
1208
1241
|
{
|
|
1209
1242
|
as: "span",
|
|
@@ -1331,7 +1364,8 @@ function ReferenceSelect({
|
|
|
1331
1364
|
}) })
|
|
1332
1365
|
]
|
|
1333
1366
|
}
|
|
1334
|
-
) : null
|
|
1367
|
+
) : null,
|
|
1368
|
+
error ? /* @__PURE__ */ jsx8(Text4, { id: errorId, role: "alert", mt: "5px", color: "#DC2626", fontSize: "10px", fontWeight: "500", children: error }) : null
|
|
1335
1369
|
] });
|
|
1336
1370
|
}
|
|
1337
1371
|
|
|
@@ -1464,6 +1498,16 @@ function buildItems(fields) {
|
|
|
1464
1498
|
});
|
|
1465
1499
|
return items;
|
|
1466
1500
|
}
|
|
1501
|
+
function resolveReference(field, values) {
|
|
1502
|
+
const filters = { ...field.referenceFilters ?? {} };
|
|
1503
|
+
const missing = [];
|
|
1504
|
+
Object.entries(field.referenceFilterFrom ?? {}).forEach(([queryField, formField]) => {
|
|
1505
|
+
const value = values[formField];
|
|
1506
|
+
if (value) filters[queryField] = value;
|
|
1507
|
+
else missing.push(formField);
|
|
1508
|
+
});
|
|
1509
|
+
return { filters, disabled: missing.length > 0 };
|
|
1510
|
+
}
|
|
1467
1511
|
function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submitting, error, onSubmit, onCancel, onFieldChange }) {
|
|
1468
1512
|
const [values, setValues] = useState5(() => Object.fromEntries(fields.map((field) => [field.field, toValue(initialValues?.[field.field], field.kind)])));
|
|
1469
1513
|
const [errors, setErrors] = useState5({});
|
|
@@ -1489,12 +1533,23 @@ function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submi
|
|
|
1489
1533
|
const first = fields.find((field) => next[field.field]);
|
|
1490
1534
|
if (first) focusField(first.field);
|
|
1491
1535
|
}, [error]);
|
|
1492
|
-
const change = (
|
|
1493
|
-
|
|
1536
|
+
const change = (fieldName, value) => {
|
|
1537
|
+
const extendedFields = fields;
|
|
1538
|
+
const dependentFields = extendedFields.filter(
|
|
1539
|
+
(candidate) => Object.values(candidate.referenceFilterFrom ?? {}).includes(fieldName)
|
|
1540
|
+
);
|
|
1541
|
+
setValues((current) => {
|
|
1542
|
+
const changed = current[fieldName] !== value;
|
|
1543
|
+
const next = { ...current, [fieldName]: value };
|
|
1544
|
+
if (changed) dependentFields.forEach((candidate) => {
|
|
1545
|
+
next[candidate.field] = "";
|
|
1546
|
+
});
|
|
1547
|
+
return next;
|
|
1548
|
+
});
|
|
1494
1549
|
setErrors((current) => {
|
|
1495
|
-
if (!current[field]) return current;
|
|
1496
1550
|
const next = { ...current };
|
|
1497
|
-
delete next[
|
|
1551
|
+
delete next[fieldName];
|
|
1552
|
+
dependentFields.forEach((candidate) => delete next[candidate.field]);
|
|
1498
1553
|
return next;
|
|
1499
1554
|
});
|
|
1500
1555
|
setDismissed(true);
|
|
@@ -1575,7 +1630,10 @@ function DynamicForm({ title, eyebrow = "Cadastro", fields, initialValues, submi
|
|
|
1575
1630
|
false
|
|
1576
1631
|
);
|
|
1577
1632
|
}
|
|
1578
|
-
if (field.kind === "ref" && field.ref)
|
|
1633
|
+
if (field.kind === "ref" && field.ref) {
|
|
1634
|
+
const reference = resolveReference(field, values);
|
|
1635
|
+
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, filters: reference.filters, emptyFields: field.referenceEmptyFields, disabled: reference.disabled, disabledMessage: field.referenceDisabledMessage, onChange: (value) => change(field.field, value) }));
|
|
1636
|
+
}
|
|
1579
1637
|
if (field.kind === "enum" && field.options?.length) return wrap(/* @__PURE__ */ jsxs5(NativeSelect2.Root, { size: "sm", children: [
|
|
1580
1638
|
/* @__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
1639
|
/* @__PURE__ */ jsx9("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
@@ -1905,6 +1963,63 @@ function toValue2(value, kind) {
|
|
|
1905
1963
|
function isMultiline2(field) {
|
|
1906
1964
|
return /observa|descricao|mensagem|detalhe|necessidade/i.test(field.field);
|
|
1907
1965
|
}
|
|
1966
|
+
function messageOf3(error) {
|
|
1967
|
+
if (!error) return null;
|
|
1968
|
+
if (typeof error === "string") return error;
|
|
1969
|
+
if (error instanceof Error) return error.message;
|
|
1970
|
+
if (typeof error === "object") {
|
|
1971
|
+
const record = error;
|
|
1972
|
+
if (typeof record.message === "string") return record.message;
|
|
1973
|
+
if (record.error && typeof record.error === "object") {
|
|
1974
|
+
const nested = record.error;
|
|
1975
|
+
if (typeof nested.message === "string") return nested.message;
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
return "N\xE3o foi poss\xEDvel salvar o registro.";
|
|
1979
|
+
}
|
|
1980
|
+
function fieldErrorsOf(error) {
|
|
1981
|
+
if (!error || typeof error !== "object") return {};
|
|
1982
|
+
const record = error;
|
|
1983
|
+
const envelope = record.error && typeof record.error === "object" ? record.error : void 0;
|
|
1984
|
+
const details = record.details ?? envelope?.details ?? envelope;
|
|
1985
|
+
const result = {};
|
|
1986
|
+
const visit = (value) => {
|
|
1987
|
+
if (!value) return;
|
|
1988
|
+
if (Array.isArray(value)) {
|
|
1989
|
+
value.forEach(visit);
|
|
1990
|
+
return;
|
|
1991
|
+
}
|
|
1992
|
+
if (typeof value !== "object") return;
|
|
1993
|
+
const item = value;
|
|
1994
|
+
if (typeof item.field === "string" && typeof item.message === "string") {
|
|
1995
|
+
result[item.field] = item.message;
|
|
1996
|
+
}
|
|
1997
|
+
Object.values(item).forEach((nested) => {
|
|
1998
|
+
if (nested !== item.field && nested !== item.message) visit(nested);
|
|
1999
|
+
});
|
|
2000
|
+
};
|
|
2001
|
+
visit(details);
|
|
2002
|
+
return result;
|
|
2003
|
+
}
|
|
2004
|
+
function requiredErrors(fields, values) {
|
|
2005
|
+
const errors = {};
|
|
2006
|
+
fields.forEach((field) => {
|
|
2007
|
+
if (field.required && !(values[field.field] ?? "").trim()) {
|
|
2008
|
+
errors[field.field] = `${fieldLabel({ name: field.field, label: field.label })} \xE9 obrigat\xF3rio.`;
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
return errors;
|
|
2012
|
+
}
|
|
2013
|
+
function resolveReference2(field, values) {
|
|
2014
|
+
const filters = { ...field.referenceFilters ?? {} };
|
|
2015
|
+
const missing = [];
|
|
2016
|
+
Object.entries(field.referenceFilterFrom ?? {}).forEach(([queryField, formField]) => {
|
|
2017
|
+
const value = values[formField];
|
|
2018
|
+
if (value) filters[queryField] = value;
|
|
2019
|
+
else missing.push(formField);
|
|
2020
|
+
});
|
|
2021
|
+
return { filters, disabled: missing.length > 0 };
|
|
2022
|
+
}
|
|
1908
2023
|
function FieldLabel({ field, htmlFor }) {
|
|
1909
2024
|
const label = fieldLabel({ name: field.field, label: field.label });
|
|
1910
2025
|
return /* @__PURE__ */ jsx14("label", { htmlFor, children: /* @__PURE__ */ jsxs10(Text9, { as: "span", display: "block", mb: "5px", color: "#475467", fontSize: "11px", fontWeight: "600", children: [
|
|
@@ -1912,48 +2027,68 @@ function FieldLabel({ field, htmlFor }) {
|
|
|
1912
2027
|
field.required ? /* @__PURE__ */ jsx14(Text9, { as: "span", color: "#DC2626", children: " *" }) : null
|
|
1913
2028
|
] }) });
|
|
1914
2029
|
}
|
|
2030
|
+
function ErrorText2({ id, message }) {
|
|
2031
|
+
return message ? /* @__PURE__ */ jsx14(Text9, { id, role: "alert", mt: "5px", color: "#DC2626", fontSize: "10px", fontWeight: "500", children: message }) : null;
|
|
2032
|
+
}
|
|
1915
2033
|
function FieldControl({
|
|
1916
2034
|
field,
|
|
1917
2035
|
value,
|
|
2036
|
+
values,
|
|
2037
|
+
initialValue,
|
|
2038
|
+
error,
|
|
1918
2039
|
onChange
|
|
1919
2040
|
}) {
|
|
1920
2041
|
const label = fieldLabel({ name: field.field, label: field.label });
|
|
1921
2042
|
const inputId = `oon-detail-field-${field.field.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
|
|
2043
|
+
const errorId = `${inputId}-error`;
|
|
2044
|
+
const invalidProps = {
|
|
2045
|
+
"aria-invalid": error ? true : void 0,
|
|
2046
|
+
"aria-describedby": error ? errorId : void 0,
|
|
2047
|
+
borderColor: error ? "#DC2626" : void 0,
|
|
2048
|
+
boxShadow: error ? "0 0 0 3px rgba(220,38,38,.08)" : void 0
|
|
2049
|
+
};
|
|
1922
2050
|
if (field.widget === "checkbox") {
|
|
1923
2051
|
const checkedValue = String(field.checkedValue ?? true);
|
|
1924
2052
|
const uncheckedValue = String(field.uncheckedValue ?? false);
|
|
1925
2053
|
const checked = (value || uncheckedValue) === checkedValue;
|
|
1926
|
-
return /* @__PURE__ */ jsxs10(
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
2054
|
+
return /* @__PURE__ */ jsxs10(Box7, { children: [
|
|
2055
|
+
/* @__PURE__ */ jsxs10(
|
|
2056
|
+
Box7,
|
|
2057
|
+
{
|
|
2058
|
+
as: "label",
|
|
2059
|
+
display: "flex",
|
|
2060
|
+
minH: "38px",
|
|
2061
|
+
px: "11px",
|
|
2062
|
+
alignItems: "center",
|
|
2063
|
+
gap: "8px",
|
|
2064
|
+
color: "#344054",
|
|
2065
|
+
bg: checked ? "#F0F7FF" : "white",
|
|
2066
|
+
borderWidth: "1px",
|
|
2067
|
+
borderColor: error ? "#DC2626" : checked ? "#8FC9E7" : "#D5DDE3",
|
|
2068
|
+
borderRadius: "7px",
|
|
2069
|
+
cursor: "pointer",
|
|
2070
|
+
children: [
|
|
2071
|
+
/* @__PURE__ */ jsx14(
|
|
2072
|
+
"input",
|
|
2073
|
+
{
|
|
2074
|
+
id: inputId,
|
|
2075
|
+
type: "checkbox",
|
|
2076
|
+
checked,
|
|
2077
|
+
"aria-invalid": error ? true : void 0,
|
|
2078
|
+
"aria-describedby": error ? errorId : void 0,
|
|
2079
|
+
style: { width: 16, height: 16, accentColor: "#0474AF", cursor: "pointer" },
|
|
2080
|
+
onChange: (event) => onChange(event.currentTarget.checked ? checkedValue : uncheckedValue)
|
|
2081
|
+
}
|
|
2082
|
+
),
|
|
2083
|
+
/* @__PURE__ */ jsx14(Text9, { as: "span", fontSize: "11px", fontWeight: "600", children: label })
|
|
2084
|
+
]
|
|
2085
|
+
}
|
|
2086
|
+
),
|
|
2087
|
+
/* @__PURE__ */ jsx14(ErrorText2, { id: errorId, message: error })
|
|
2088
|
+
] });
|
|
1955
2089
|
}
|
|
1956
2090
|
if (field.kind === "ref" && field.ref) {
|
|
2091
|
+
const reference = resolveReference2(field, values);
|
|
1957
2092
|
return /* @__PURE__ */ jsxs10(Box7, { children: [
|
|
1958
2093
|
/* @__PURE__ */ jsx14(FieldLabel, { field, htmlFor: inputId }),
|
|
1959
2094
|
/* @__PURE__ */ jsx14(
|
|
@@ -1961,48 +2096,59 @@ function FieldControl({
|
|
|
1961
2096
|
{
|
|
1962
2097
|
field: field.field,
|
|
1963
2098
|
inputId,
|
|
2099
|
+
errorId,
|
|
1964
2100
|
label,
|
|
1965
2101
|
refModel: field.ref,
|
|
1966
2102
|
value,
|
|
1967
|
-
initialValue
|
|
2103
|
+
initialValue,
|
|
1968
2104
|
required: field.required,
|
|
2105
|
+
invalid: !!error,
|
|
2106
|
+
error,
|
|
2107
|
+
filters: reference.filters,
|
|
2108
|
+
emptyFields: field.referenceEmptyFields,
|
|
2109
|
+
disabled: reference.disabled,
|
|
2110
|
+
disabledMessage: field.referenceDisabledMessage,
|
|
1969
2111
|
onChange
|
|
1970
2112
|
}
|
|
1971
2113
|
)
|
|
1972
2114
|
] });
|
|
1973
2115
|
}
|
|
1974
2116
|
const control = field.kind === "enum" && field.options?.length ? /* @__PURE__ */ jsxs10(NativeSelect4.Root, { size: "sm", children: [
|
|
1975
|
-
/* @__PURE__ */ jsxs10(NativeSelect4.Field, { id: inputId, value, onChange: (event) => onChange(event.currentTarget.value), children: [
|
|
2117
|
+
/* @__PURE__ */ jsxs10(NativeSelect4.Field, { id: inputId, value, ...invalidProps, onChange: (event) => onChange(event.currentTarget.value), children: [
|
|
1976
2118
|
/* @__PURE__ */ jsx14("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
1977
2119
|
field.options.map((option) => /* @__PURE__ */ jsx14("option", { value: option, children: option }, option))
|
|
1978
2120
|
] }),
|
|
1979
2121
|
/* @__PURE__ */ jsx14(NativeSelect4.Indicator, {})
|
|
1980
2122
|
] }) : field.kind === "boolean" ? /* @__PURE__ */ jsxs10(NativeSelect4.Root, { size: "sm", children: [
|
|
1981
|
-
/* @__PURE__ */ jsxs10(NativeSelect4.Field, { id: inputId, value, onChange: (event) => onChange(event.currentTarget.value), children: [
|
|
2123
|
+
/* @__PURE__ */ jsxs10(NativeSelect4.Field, { id: inputId, value, ...invalidProps, onChange: (event) => onChange(event.currentTarget.value), children: [
|
|
1982
2124
|
/* @__PURE__ */ jsx14("option", { value: "", children: "\u2014 Selecione \u2014" }),
|
|
1983
2125
|
/* @__PURE__ */ jsx14("option", { value: "true", children: "Sim" }),
|
|
1984
2126
|
/* @__PURE__ */ jsx14("option", { value: "false", children: "N\xE3o" })
|
|
1985
2127
|
] }),
|
|
1986
2128
|
/* @__PURE__ */ jsx14(NativeSelect4.Indicator, {})
|
|
1987
|
-
] }) : isMultiline2(field) ? /* @__PURE__ */ jsx14(Textarea3, { id: inputId, rows: 4, resize: "vertical", value, onChange: (event) => onChange(event.currentTarget.value) }) : /* @__PURE__ */ jsx14(
|
|
2129
|
+
] }) : isMultiline2(field) ? /* @__PURE__ */ jsx14(Textarea3, { id: inputId, rows: 4, resize: "vertical", value, ...invalidProps, onChange: (event) => onChange(event.currentTarget.value) }) : /* @__PURE__ */ jsx14(
|
|
1988
2130
|
Input5,
|
|
1989
2131
|
{
|
|
1990
2132
|
id: inputId,
|
|
1991
2133
|
size: "sm",
|
|
1992
2134
|
type: field.kind === "date" ? "date" : ["number", "currency", "currencyConverted"].includes(field.kind ?? "") ? "number" : "text",
|
|
1993
2135
|
value,
|
|
2136
|
+
...invalidProps,
|
|
1994
2137
|
onChange: (event) => onChange(event.currentTarget.value)
|
|
1995
2138
|
}
|
|
1996
2139
|
);
|
|
1997
2140
|
return /* @__PURE__ */ jsxs10(Box7, { children: [
|
|
1998
2141
|
/* @__PURE__ */ jsx14(FieldLabel, { field, htmlFor: inputId }),
|
|
1999
|
-
control
|
|
2142
|
+
control,
|
|
2143
|
+
/* @__PURE__ */ jsx14(ErrorText2, { id: errorId, message: error })
|
|
2000
2144
|
] });
|
|
2001
2145
|
}
|
|
2002
2146
|
function GroupSection({
|
|
2003
2147
|
group,
|
|
2004
2148
|
fields,
|
|
2005
2149
|
values,
|
|
2150
|
+
initialValues,
|
|
2151
|
+
errors,
|
|
2006
2152
|
onChange
|
|
2007
2153
|
}) {
|
|
2008
2154
|
if (!fields.length) return null;
|
|
@@ -2015,6 +2161,9 @@ function GroupSection({
|
|
|
2015
2161
|
{
|
|
2016
2162
|
field,
|
|
2017
2163
|
value: values[field.field] ?? "",
|
|
2164
|
+
values,
|
|
2165
|
+
initialValue: initialValues[field.field],
|
|
2166
|
+
error: errors[field.field],
|
|
2018
2167
|
onChange: (value) => onChange(field.field, value)
|
|
2019
2168
|
},
|
|
2020
2169
|
field.field
|
|
@@ -2022,21 +2171,41 @@ function GroupSection({
|
|
|
2022
2171
|
] });
|
|
2023
2172
|
}
|
|
2024
2173
|
function InlineParentForm({
|
|
2025
|
-
fields,
|
|
2174
|
+
fields: rawFields,
|
|
2026
2175
|
groups,
|
|
2027
2176
|
parent,
|
|
2028
2177
|
resource,
|
|
2029
2178
|
onSaved
|
|
2030
2179
|
}) {
|
|
2180
|
+
const fields = rawFields;
|
|
2031
2181
|
const [values, setValues] = useState8({});
|
|
2032
2182
|
const [saving, setSaving] = useState8(false);
|
|
2033
2183
|
const [error, setError] = useState8(null);
|
|
2184
|
+
const [fieldErrors, setFieldErrors] = useState8({});
|
|
2034
2185
|
useEffect5(() => {
|
|
2035
2186
|
setValues(Object.fromEntries(fields.map((field) => [field.field, toValue2(parent[field.field], field.kind)])));
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2187
|
+
setError(null);
|
|
2188
|
+
setFieldErrors({});
|
|
2189
|
+
}, [parent, rawFields]);
|
|
2190
|
+
const fieldsByName = useMemo6(() => new Map(fields.map((field) => [field.field, field])), [rawFields]);
|
|
2191
|
+
const change = (fieldName, value) => {
|
|
2192
|
+
const dependentFields = fields.filter(
|
|
2193
|
+
(candidate) => Object.values(candidate.referenceFilterFrom ?? {}).includes(fieldName)
|
|
2194
|
+
);
|
|
2195
|
+
setValues((current) => {
|
|
2196
|
+
const changed = current[fieldName] !== value;
|
|
2197
|
+
const next = { ...current, [fieldName]: value };
|
|
2198
|
+
if (changed) dependentFields.forEach((candidate) => {
|
|
2199
|
+
next[candidate.field] = "";
|
|
2200
|
+
});
|
|
2201
|
+
return next;
|
|
2202
|
+
});
|
|
2203
|
+
setFieldErrors((current) => {
|
|
2204
|
+
const next = { ...current };
|
|
2205
|
+
delete next[fieldName];
|
|
2206
|
+
dependentFields.forEach((candidate) => delete next[candidate.field]);
|
|
2207
|
+
return next;
|
|
2208
|
+
});
|
|
2040
2209
|
setError(null);
|
|
2041
2210
|
};
|
|
2042
2211
|
const renderFields = () => {
|
|
@@ -2047,6 +2216,8 @@ function InlineParentForm({
|
|
|
2047
2216
|
group,
|
|
2048
2217
|
fields: group.fields.map((field) => fieldsByName.get(field)).filter(Boolean),
|
|
2049
2218
|
values,
|
|
2219
|
+
initialValues: parent,
|
|
2220
|
+
errors: fieldErrors,
|
|
2050
2221
|
onChange: change
|
|
2051
2222
|
},
|
|
2052
2223
|
`${group.label}-${group.fields.join("-")}`
|
|
@@ -2057,6 +2228,9 @@ function InlineParentForm({
|
|
|
2057
2228
|
{
|
|
2058
2229
|
field,
|
|
2059
2230
|
value: values[field.field] ?? "",
|
|
2231
|
+
values,
|
|
2232
|
+
initialValue: parent[field.field],
|
|
2233
|
+
error: fieldErrors[field.field],
|
|
2060
2234
|
onChange: (value) => change(field.field, value)
|
|
2061
2235
|
},
|
|
2062
2236
|
field.field
|
|
@@ -2065,10 +2239,18 @@ function InlineParentForm({
|
|
|
2065
2239
|
return /* @__PURE__ */ jsx14(
|
|
2066
2240
|
"form",
|
|
2067
2241
|
{
|
|
2242
|
+
noValidate: true,
|
|
2068
2243
|
onSubmit: async (event) => {
|
|
2069
2244
|
event.preventDefault();
|
|
2245
|
+
const validation = requiredErrors(fields, values);
|
|
2246
|
+
if (Object.keys(validation).length) {
|
|
2247
|
+
setFieldErrors(validation);
|
|
2248
|
+
setError({ message: "Preencha os campos obrigat\xF3rios destacados." });
|
|
2249
|
+
return;
|
|
2250
|
+
}
|
|
2070
2251
|
setSaving(true);
|
|
2071
2252
|
setError(null);
|
|
2253
|
+
setFieldErrors({});
|
|
2072
2254
|
try {
|
|
2073
2255
|
const payload = Object.fromEntries(
|
|
2074
2256
|
fields.map((field) => [field.field, coerce2(values[field.field] ?? "", field.kind)]).filter(([, value]) => value !== void 0)
|
|
@@ -2077,12 +2259,13 @@ function InlineParentForm({
|
|
|
2077
2259
|
onSaved(saved);
|
|
2078
2260
|
} catch (requestError) {
|
|
2079
2261
|
setError(requestError);
|
|
2262
|
+
setFieldErrors(fieldErrorsOf(requestError));
|
|
2080
2263
|
} finally {
|
|
2081
2264
|
setSaving(false);
|
|
2082
2265
|
}
|
|
2083
2266
|
},
|
|
2084
2267
|
children: /* @__PURE__ */ jsxs10(Stack3, { gap: "16px", children: [
|
|
2085
|
-
error ? /* @__PURE__ */ jsx14(
|
|
2268
|
+
error ? /* @__PURE__ */ jsx14(Box7, { role: "alert", p: "10px 12px", color: "#B42318", bg: "#FEF3F2", borderWidth: "1px", borderColor: "#FECDCA", borderRadius: "7px", fontSize: "11px", children: messageOf3(error) }) : null,
|
|
2086
2269
|
renderFields(),
|
|
2087
2270
|
/* @__PURE__ */ jsx14(Flex6, { justify: "flex-end", children: /* @__PURE__ */ jsx14(Button7, { type: "submit", colorPalette: "brand", loading: saving, children: "Salvar dados principais" }) })
|
|
2088
2271
|
] })
|
|
@@ -2378,7 +2561,27 @@ function ticketId(row) {
|
|
|
2378
2561
|
const id = row._id ?? row.id;
|
|
2379
2562
|
return id == null ? void 0 : String(id);
|
|
2380
2563
|
}
|
|
2381
|
-
function
|
|
2564
|
+
function mergeFormFields2(metadataFields, overrides) {
|
|
2565
|
+
if (!overrides?.length) return metadataFields;
|
|
2566
|
+
const byField = new Map(overrides.map((field) => [field.field, field]));
|
|
2567
|
+
const merged = metadataFields.map((field) => ({ ...field, ...byField.get(field.field) }));
|
|
2568
|
+
const known = new Set(metadataFields.map((field) => field.field));
|
|
2569
|
+
overrides.forEach((field) => {
|
|
2570
|
+
if (!known.has(field.field)) merged.push(field);
|
|
2571
|
+
});
|
|
2572
|
+
return merged;
|
|
2573
|
+
}
|
|
2574
|
+
function CorePipeline({
|
|
2575
|
+
model,
|
|
2576
|
+
label,
|
|
2577
|
+
endpoint,
|
|
2578
|
+
stageField = "status",
|
|
2579
|
+
stages,
|
|
2580
|
+
titleField,
|
|
2581
|
+
form,
|
|
2582
|
+
relations,
|
|
2583
|
+
ticketModal
|
|
2584
|
+
}) {
|
|
2382
2585
|
const schemaQuery = useModelSchema(model);
|
|
2383
2586
|
const schema = schemaQuery.data;
|
|
2384
2587
|
const basePath = endpoint ?? schema?.basePath ?? `/${model.toLowerCase()}s`;
|
|
@@ -2391,6 +2594,7 @@ function CorePipeline({ model, label, endpoint, stageField = "status", stages, t
|
|
|
2391
2594
|
queryFn: () => resource.list({ pageSize: 200 }),
|
|
2392
2595
|
enabled: !!schema
|
|
2393
2596
|
});
|
|
2597
|
+
const invalidate = () => queryClient.invalidateQueries({ queryKey: ["oon", "pipeline", basePath] });
|
|
2394
2598
|
const saveMutation = useMutation3({
|
|
2395
2599
|
mutationFn: (values) => {
|
|
2396
2600
|
const id = selectedTicket ? ticketId(selectedTicket) : void 0;
|
|
@@ -2398,7 +2602,7 @@ function CorePipeline({ model, label, endpoint, stageField = "status", stages, t
|
|
|
2398
2602
|
return resource.update(id, values);
|
|
2399
2603
|
},
|
|
2400
2604
|
onSuccess: async () => {
|
|
2401
|
-
await
|
|
2605
|
+
await invalidate();
|
|
2402
2606
|
setSelectedTicket(null);
|
|
2403
2607
|
setFormError(null);
|
|
2404
2608
|
},
|
|
@@ -2409,9 +2613,9 @@ function CorePipeline({ model, label, endpoint, stageField = "status", stages, t
|
|
|
2409
2613
|
if (listQuery.isError) return /* @__PURE__ */ jsx18(ErrorState, { error: listQuery.error });
|
|
2410
2614
|
const stageFieldMeta = schema?.fields.find((field) => field.name === stageField);
|
|
2411
2615
|
const resolvedStages = stages ?? (stageFieldMeta?.options ?? []).map((option) => ({ id: option, label: option }));
|
|
2412
|
-
const
|
|
2413
|
-
const detailFields = (schema?.fields ?? []).filter((field) => field.name !== stageField && field.name !==
|
|
2414
|
-
const formFields = formFieldsFromMeta(schema?.fields ?? []);
|
|
2616
|
+
const resolvedTitleField = titleField ?? ticketModal?.titleField ?? schema?.fields.find((field) => field.kind === "string")?.name ?? schema?.searchable[0] ?? "_id";
|
|
2617
|
+
const detailFields = (schema?.fields ?? []).filter((field) => field.name !== stageField && field.name !== resolvedTitleField && !["raw"].includes(field.kind)).slice(0, 3);
|
|
2618
|
+
const formFields = mergeFormFields2(formFieldsFromMeta(schema?.fields ?? []), form);
|
|
2415
2619
|
const rows = listQuery.data?.results ?? [];
|
|
2416
2620
|
const byStage = /* @__PURE__ */ new Map();
|
|
2417
2621
|
for (const stage of resolvedStages) byStage.set(stage.id, []);
|
|
@@ -2445,7 +2649,7 @@ function CorePipeline({ model, label, endpoint, stageField = "status", stages, t
|
|
|
2445
2649
|
/* @__PURE__ */ jsx18(Badge4, { colorPalette: "brand", variant: "solid", borderRadius: "full", minW: "24px", justifyContent: "center", children: items.length })
|
|
2446
2650
|
] }),
|
|
2447
2651
|
/* @__PURE__ */ jsx18(Stack5, { gap: 2, children: items.length === 0 ? /* @__PURE__ */ jsx18(Box10, { borderWidth: "1px", borderStyle: "dashed", borderColor: "#C8D0D5", borderRadius: "10px", p: 5, textAlign: "center", children: /* @__PURE__ */ jsx18(Text12, { fontSize: "12px", color: "gray.500", children: "Nenhum ticket nesta etapa." }) }) : items.map((row, index) => {
|
|
2448
|
-
const ticketTitle = formatCell(row[
|
|
2652
|
+
const ticketTitle = formatCell(row[resolvedTitleField], "string");
|
|
2449
2653
|
return /* @__PURE__ */ jsxs13(
|
|
2450
2654
|
Button9,
|
|
2451
2655
|
{
|
|
@@ -2487,7 +2691,23 @@ function CorePipeline({ model, label, endpoint, stageField = "status", stages, t
|
|
|
2487
2691
|
stageId
|
|
2488
2692
|
);
|
|
2489
2693
|
}) }),
|
|
2490
|
-
selectedTicket ? /* @__PURE__ */ jsx18(
|
|
2694
|
+
selectedTicket && ticketModal && ticketModal.enabled !== false ? /* @__PURE__ */ jsx18(
|
|
2695
|
+
CoreDetailModal,
|
|
2696
|
+
{
|
|
2697
|
+
model,
|
|
2698
|
+
title: schema?.singular ?? label ?? model,
|
|
2699
|
+
config: { ...ticketModal, titleField: ticketModal.titleField ?? resolvedTitleField },
|
|
2700
|
+
formFields,
|
|
2701
|
+
recordId: ticketId(selectedTicket),
|
|
2702
|
+
initialRecord: selectedTicket,
|
|
2703
|
+
relations,
|
|
2704
|
+
onClose: () => {
|
|
2705
|
+
setSelectedTicket(null);
|
|
2706
|
+
setFormError(null);
|
|
2707
|
+
},
|
|
2708
|
+
onSaved: invalidate
|
|
2709
|
+
}
|
|
2710
|
+
) : selectedTicket ? /* @__PURE__ */ jsx18(
|
|
2491
2711
|
DynamicForm,
|
|
2492
2712
|
{
|
|
2493
2713
|
title: `Editar ${schema?.singular ?? label ?? model}`,
|
|
@@ -2756,7 +2976,11 @@ function renderView(view, registry) {
|
|
|
2756
2976
|
model: v.model,
|
|
2757
2977
|
label: viewLabel(v),
|
|
2758
2978
|
stageField: v.stageField,
|
|
2759
|
-
stages: v.stages
|
|
2979
|
+
stages: v.stages,
|
|
2980
|
+
titleField: v.titleField,
|
|
2981
|
+
form: v.form,
|
|
2982
|
+
relations: v.relations,
|
|
2983
|
+
ticketModal: v.ticketModal
|
|
2760
2984
|
}
|
|
2761
2985
|
);
|
|
2762
2986
|
}
|
|
@@ -3883,7 +4107,12 @@ function manifestToConfig(manifest, runtime) {
|
|
|
3883
4107
|
label: p.label ?? p.name,
|
|
3884
4108
|
path: p.path,
|
|
3885
4109
|
stageField: p.stageField,
|
|
3886
|
-
|
|
4110
|
+
stages: p.stages,
|
|
4111
|
+
titleField: p.titleField,
|
|
4112
|
+
section: p.section,
|
|
4113
|
+
form: p.form,
|
|
4114
|
+
relations: p.relations,
|
|
4115
|
+
ticketModal: p.ticketModal
|
|
3887
4116
|
};
|
|
3888
4117
|
views.push(view);
|
|
3889
4118
|
}
|