pixelon 0.3.77 → 0.3.78
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/components/atoms/lumi/FieldValue/FieldValue.d.ts +15 -0
- package/dist/components/atoms/lumi/FieldValue/index.d.ts +2 -0
- package/dist/components/atoms/lumi/FieldValue/types.d.ts +10 -0
- package/dist/components/molecules/chat/StructuredContent/components/ReactiveCrud/ChatLinkCell.d.ts +20 -0
- package/dist/components/molecules/chat/StructuredContent/components/ReactiveCrud/optionsLoader.d.ts +2 -1
- package/dist/components/molecules/chat/StructuredContent/components/ReactiveCrud/types.d.ts +6 -0
- package/dist/components/molecules/lumi/Drawer/Drawer.d.ts +8 -0
- package/dist/components/molecules/lumi/RecordCard/RecordCard.d.ts +14 -0
- package/dist/components/molecules/lumi/RecordCard/index.d.ts +2 -0
- package/dist/components/molecules/lumi/RecordCard/types.d.ts +16 -0
- package/dist/components/molecules/lumi/ScrollToEnd/ScrollToEnd.d.ts +21 -0
- package/dist/components/molecules/lumi/ScrollToEnd/index.d.ts +2 -0
- package/dist/components/templates/lumi/Crud/CardList.d.ts +34 -0
- package/dist/components/templates/lumi/Crud/Crud.d.ts +1 -1
- package/dist/components/templates/lumi/Crud/ScrollToEnd.d.ts +18 -0
- package/dist/components/templates/lumi/Crud/helpers/fieldValue.d.ts +12 -0
- package/dist/components/templates/lumi/Crud/types.d.ts +25 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +545 -276
- package/dist/index.js +546 -275
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
- package/src/styles/index.scss +4 -0
package/dist/index.js
CHANGED
|
@@ -4008,13 +4008,13 @@ function resolveVariable(template, formValues, fieldStates) {
|
|
|
4008
4008
|
}
|
|
4009
4009
|
return "";
|
|
4010
4010
|
}
|
|
4011
|
-
function resolveBody(obj, formValues, fieldStates) {
|
|
4011
|
+
function resolveBody$1(obj, formValues, fieldStates) {
|
|
4012
4012
|
if (typeof obj === "string") return resolveVariable(obj, formValues, fieldStates);
|
|
4013
|
-
if (Array.isArray(obj)) return obj.map((item) => resolveBody(item, formValues, fieldStates));
|
|
4013
|
+
if (Array.isArray(obj)) return obj.map((item) => resolveBody$1(item, formValues, fieldStates));
|
|
4014
4014
|
if (obj !== null && typeof obj === "object") {
|
|
4015
4015
|
const resolved = {};
|
|
4016
4016
|
for (const [key, value] of Object.entries(obj)) {
|
|
4017
|
-
resolved[key] = resolveBody(value, formValues, fieldStates);
|
|
4017
|
+
resolved[key] = resolveBody$1(value, formValues, fieldStates);
|
|
4018
4018
|
}
|
|
4019
4019
|
return resolved;
|
|
4020
4020
|
}
|
|
@@ -4064,7 +4064,7 @@ const CostSummaryField = ({
|
|
|
4064
4064
|
return;
|
|
4065
4065
|
}
|
|
4066
4066
|
fetchedRef.current = true;
|
|
4067
|
-
const body = resolveBody(field.endpoint.body || {}, values, fieldStates);
|
|
4067
|
+
const body = resolveBody$1(field.endpoint.body || {}, values, fieldStates);
|
|
4068
4068
|
setLoading(true);
|
|
4069
4069
|
setError("");
|
|
4070
4070
|
fetchViaEventBus(eventBus, field.endpoint.service, field.endpoint.url, field.endpoint.method, body).then((data) => {
|
|
@@ -4518,7 +4518,7 @@ function useReactiveEndpoints({ fields, fieldStates, setFieldState, eventBus, ti
|
|
|
4518
4518
|
setFieldState(field.name, { loading: true, error: null });
|
|
4519
4519
|
const startTime = Date.now();
|
|
4520
4520
|
try {
|
|
4521
|
-
const resolvedBody = field.endpoint.body ? resolveBody(field.endpoint.body, formValues, fieldStates) : void 0;
|
|
4521
|
+
const resolvedBody = field.endpoint.body ? resolveBody$1(field.endpoint.body, formValues, fieldStates) : void 0;
|
|
4522
4522
|
const params = field.endpoint.params ? resolveParams(field.endpoint.params, formValues, fieldStates) : {};
|
|
4523
4523
|
const requestBody = resolvedBody ?? (Object.keys(params).length > 0 ? params : void 0);
|
|
4524
4524
|
if (eventBus) {
|
|
@@ -4793,7 +4793,7 @@ function useReactiveForm(props) {
|
|
|
4793
4793
|
const handleSubmit = async () => {
|
|
4794
4794
|
if (isSubmitting) return;
|
|
4795
4795
|
setIsSubmitting(true);
|
|
4796
|
-
const resolvedPayload = resolveBody(submit.payload_map, values, fieldStates);
|
|
4796
|
+
const resolvedPayload = resolveBody$1(submit.payload_map, values, fieldStates);
|
|
4797
4797
|
if (eventBus) {
|
|
4798
4798
|
try {
|
|
4799
4799
|
const data = await fetchViaEventBus(
|
|
@@ -10886,6 +10886,7 @@ const Drawer = ({
|
|
|
10886
10886
|
size = DRAWER_SIZES.RESPONSIVE,
|
|
10887
10887
|
fixedSize = 400,
|
|
10888
10888
|
responsivePercentage = 80,
|
|
10889
|
+
mobileSheet = false,
|
|
10889
10890
|
title,
|
|
10890
10891
|
headerExtra,
|
|
10891
10892
|
showCloseButton = true,
|
|
@@ -10968,11 +10969,13 @@ const Drawer = ({
|
|
|
10968
10969
|
`${COMPONENT_PREFIX}drawer--${size}`,
|
|
10969
10970
|
isOpen && `${COMPONENT_PREFIX}drawer--open`,
|
|
10970
10971
|
isMobile && `${COMPONENT_PREFIX}drawer--mobile`,
|
|
10972
|
+
mobileSheet && `${COMPONENT_PREFIX}drawer--sheet`,
|
|
10971
10973
|
className
|
|
10972
10974
|
].filter(Boolean).join(" ");
|
|
10973
10975
|
const overlayClasses = [
|
|
10974
10976
|
`${COMPONENT_PREFIX}drawer-overlay`,
|
|
10975
|
-
isOpen && showOverlay && `${COMPONENT_PREFIX}drawer-overlay--visible
|
|
10977
|
+
isOpen && showOverlay && `${COMPONENT_PREFIX}drawer-overlay--visible`,
|
|
10978
|
+
mobileSheet && `${COMPONENT_PREFIX}drawer-overlay--sheet`
|
|
10976
10979
|
].filter(Boolean).join(" ");
|
|
10977
10980
|
const getDrawerStyles = () => {
|
|
10978
10981
|
if (isMobile) {
|
|
@@ -13079,36 +13082,45 @@ const Badge = ({
|
|
|
13079
13082
|
};
|
|
13080
13083
|
Badge.displayName = "LumiBadge";
|
|
13081
13084
|
|
|
13085
|
+
function fieldOptions(field) {
|
|
13086
|
+
return field.uiProps?.options;
|
|
13087
|
+
}
|
|
13088
|
+
function renderFieldValue(field, row) {
|
|
13089
|
+
const value = row[field.key];
|
|
13090
|
+
const options = fieldOptions(field);
|
|
13091
|
+
const opt = options?.find((o) => String(o.value) === String(value));
|
|
13092
|
+
if (field.moleculeType === "BADGE") {
|
|
13093
|
+
if (value == null || value === "") return null;
|
|
13094
|
+
return React.createElement(Badge, { color: opt?.color, children: opt?.label ?? String(value) });
|
|
13095
|
+
}
|
|
13096
|
+
if (field.moleculeType === "INPUT_CURRENCY") {
|
|
13097
|
+
if (value == null || value === "") return null;
|
|
13098
|
+
const cp = field.uiProps ?? {};
|
|
13099
|
+
return React.createElement(CurrencyDisplay, {
|
|
13100
|
+
value,
|
|
13101
|
+
showCode: cp.showCode ?? true,
|
|
13102
|
+
showSymbol: cp.showSymbol ?? true,
|
|
13103
|
+
currency: cp.currency ?? { decimalPlaces: 0 },
|
|
13104
|
+
align: field.align ?? "right",
|
|
13105
|
+
size: cp.size ?? "md"
|
|
13106
|
+
});
|
|
13107
|
+
}
|
|
13108
|
+
if (field.formatValue) return field.formatValue(value, row);
|
|
13109
|
+
if (opt) return opt.label;
|
|
13110
|
+
return value;
|
|
13111
|
+
}
|
|
13112
|
+
function hasFieldValue(field, row) {
|
|
13113
|
+
const value = row[field.key];
|
|
13114
|
+
return value != null && value !== "";
|
|
13115
|
+
}
|
|
13116
|
+
|
|
13082
13117
|
function mapFieldsToTableColumns(fields) {
|
|
13083
13118
|
return fields.filter((field) => field.showInTable !== false).map((field) => {
|
|
13084
13119
|
let width = field.columnWidth;
|
|
13085
13120
|
if (field.fixed && typeof field.columnWidth === "number") {
|
|
13086
13121
|
width = `${field.columnWidth}px`;
|
|
13087
13122
|
}
|
|
13088
|
-
const
|
|
13089
|
-
const build = (row) => {
|
|
13090
|
-
const value = row[field.key];
|
|
13091
|
-
const opt = options?.find((o) => String(o.value) === String(value));
|
|
13092
|
-
if (field.moleculeType === "BADGE") {
|
|
13093
|
-
if (value == null || value === "") return null;
|
|
13094
|
-
return React.createElement(Badge, { color: opt?.color, children: opt?.label ?? String(value) });
|
|
13095
|
-
}
|
|
13096
|
-
if (field.moleculeType === "INPUT_CURRENCY") {
|
|
13097
|
-
if (value == null || value === "") return null;
|
|
13098
|
-
const cp = field.uiProps ?? {};
|
|
13099
|
-
return React.createElement(CurrencyDisplay, {
|
|
13100
|
-
value,
|
|
13101
|
-
showCode: cp.showCode ?? true,
|
|
13102
|
-
showSymbol: cp.showSymbol ?? true,
|
|
13103
|
-
currency: cp.currency ?? { decimalPlaces: 0 },
|
|
13104
|
-
align: field.align ?? "right",
|
|
13105
|
-
size: cp.size ?? "md"
|
|
13106
|
-
});
|
|
13107
|
-
}
|
|
13108
|
-
if (field.formatValue) return field.formatValue(value, row);
|
|
13109
|
-
if (opt) return opt.label;
|
|
13110
|
-
return value;
|
|
13111
|
-
};
|
|
13123
|
+
const build = (row) => renderFieldValue(field, row);
|
|
13112
13124
|
return {
|
|
13113
13125
|
key: field.key,
|
|
13114
13126
|
title: field.label,
|
|
@@ -13139,10 +13151,201 @@ function mapFieldsToFormFields(fields, mode) {
|
|
|
13139
13151
|
}));
|
|
13140
13152
|
}
|
|
13141
13153
|
|
|
13154
|
+
const CLASS$e = `${COMPONENT_PREFIX}field-value`;
|
|
13155
|
+
const FieldValue = ({
|
|
13156
|
+
label,
|
|
13157
|
+
children,
|
|
13158
|
+
layout = "inline",
|
|
13159
|
+
className
|
|
13160
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [CLASS$e, `${CLASS$e}--${layout}`, className].filter(Boolean).join(" "), children: [
|
|
13161
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$e}__label`, children: label }),
|
|
13162
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$e}__value`, children })
|
|
13163
|
+
] });
|
|
13164
|
+
FieldValue.displayName = "FieldValue";
|
|
13165
|
+
|
|
13166
|
+
const CLASS$d = `${COMPONENT_PREFIX}record-card`;
|
|
13167
|
+
const RecordCard = ({
|
|
13168
|
+
title,
|
|
13169
|
+
summary,
|
|
13170
|
+
children,
|
|
13171
|
+
actions,
|
|
13172
|
+
open = false,
|
|
13173
|
+
onToggle,
|
|
13174
|
+
ariaLabel,
|
|
13175
|
+
className
|
|
13176
|
+
}) => {
|
|
13177
|
+
const cuerpoId = React.useId();
|
|
13178
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [CLASS$d, open ? `${CLASS$d}--open` : "", className].filter(Boolean).join(" "), children: [
|
|
13179
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
13180
|
+
"button",
|
|
13181
|
+
{
|
|
13182
|
+
type: "button",
|
|
13183
|
+
className: `${CLASS$d}__header`,
|
|
13184
|
+
"aria-expanded": open,
|
|
13185
|
+
"aria-controls": cuerpoId,
|
|
13186
|
+
"aria-label": ariaLabel,
|
|
13187
|
+
onClick: onToggle,
|
|
13188
|
+
children: [
|
|
13189
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${CLASS$d}__heading`, children: [
|
|
13190
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$d}__title`, children: title }),
|
|
13191
|
+
summary && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$d}__summary`, children: summary })
|
|
13192
|
+
] }),
|
|
13193
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13194
|
+
Icon,
|
|
13195
|
+
{
|
|
13196
|
+
type: open ? "chevron-up" : "chevron-down",
|
|
13197
|
+
width: 18,
|
|
13198
|
+
height: 18,
|
|
13199
|
+
className: `${CLASS$d}__chevron`,
|
|
13200
|
+
"aria-hidden": true
|
|
13201
|
+
}
|
|
13202
|
+
)
|
|
13203
|
+
]
|
|
13204
|
+
}
|
|
13205
|
+
),
|
|
13206
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${CLASS$d}__body`, id: cuerpoId, children: [
|
|
13207
|
+
children,
|
|
13208
|
+
actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$d}__actions`, children: actions })
|
|
13209
|
+
] })
|
|
13210
|
+
] });
|
|
13211
|
+
};
|
|
13212
|
+
RecordCard.displayName = "RecordCard";
|
|
13213
|
+
|
|
13214
|
+
const CLASS$c = `${COMPONENT_PREFIX}crud-cards`;
|
|
13215
|
+
function summaryFields(fields) {
|
|
13216
|
+
const visibles = fields.filter((f) => f.showInTable !== false);
|
|
13217
|
+
const marcados = visibles.filter((f) => f.summary);
|
|
13218
|
+
return marcados.length > 0 ? marcados : visibles.slice(0, 3);
|
|
13219
|
+
}
|
|
13220
|
+
function CardList({
|
|
13221
|
+
fields,
|
|
13222
|
+
rows,
|
|
13223
|
+
rowKey,
|
|
13224
|
+
buildOptions,
|
|
13225
|
+
loading = false,
|
|
13226
|
+
emptyText = "No hay registros"
|
|
13227
|
+
}) {
|
|
13228
|
+
const [abierta, setAbierta] = React.useState(null);
|
|
13229
|
+
const resumen = summaryFields(fields);
|
|
13230
|
+
const claveResumen = new Set(resumen.map((f) => f.key));
|
|
13231
|
+
const cuerpo = fields.filter((f) => f.showInTable !== false && !claveResumen.has(f.key));
|
|
13232
|
+
if (loading && rows.length === 0) {
|
|
13233
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$c}__estado`, children: "Cargando..." });
|
|
13234
|
+
}
|
|
13235
|
+
if (rows.length === 0) {
|
|
13236
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${CLASS$c}__estado`, children: emptyText });
|
|
13237
|
+
}
|
|
13238
|
+
const [principal, ...secundarios] = resumen;
|
|
13239
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: CLASS$c, children: rows.map((row) => {
|
|
13240
|
+
const key = rowKey(row);
|
|
13241
|
+
const opciones = buildOptions?.(row) ?? [];
|
|
13242
|
+
const titulo = principal ? renderFieldValue(principal, row) : key;
|
|
13243
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13244
|
+
RecordCard,
|
|
13245
|
+
{
|
|
13246
|
+
open: abierta === key,
|
|
13247
|
+
onToggle: () => setAbierta((actual) => actual === key ? null : key),
|
|
13248
|
+
ariaLabel: principal ? `${principal.label}: ${String(row[principal.key] ?? "")}` : void 0,
|
|
13249
|
+
title: titulo,
|
|
13250
|
+
summary: secundarios.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: secundarios.map((f) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: renderFieldValue(f, row) }, f.key)) }) : void 0,
|
|
13251
|
+
actions: opciones.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: opciones.map((o) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13252
|
+
"button",
|
|
13253
|
+
{
|
|
13254
|
+
type: "button",
|
|
13255
|
+
className: [
|
|
13256
|
+
`${CLASS$c}__accion`,
|
|
13257
|
+
o.disabled && o.disabledReason ? "is-con-motivo" : ""
|
|
13258
|
+
].filter(Boolean).join(" "),
|
|
13259
|
+
disabled: o.disabled,
|
|
13260
|
+
onClick: () => void o.onClick(),
|
|
13261
|
+
children: [
|
|
13262
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: o.label }),
|
|
13263
|
+
o.disabled && o.disabledReason && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${CLASS$c}__motivo`, children: o.disabledReason })
|
|
13264
|
+
]
|
|
13265
|
+
},
|
|
13266
|
+
o.label
|
|
13267
|
+
)) }) : void 0,
|
|
13268
|
+
children: cuerpo.map(
|
|
13269
|
+
(f) => hasFieldValue(f, row) ? /* @__PURE__ */ jsxRuntime.jsx(FieldValue, { label: f.label, children: renderFieldValue(f, row) }, f.key) : null
|
|
13270
|
+
)
|
|
13271
|
+
},
|
|
13272
|
+
key
|
|
13273
|
+
);
|
|
13274
|
+
}) });
|
|
13275
|
+
}
|
|
13276
|
+
CardList.displayName = "CardList";
|
|
13277
|
+
|
|
13278
|
+
const CLASS$b = `${COMPONENT_PREFIX}crud-scroll-end`;
|
|
13279
|
+
const MARGEN = 24;
|
|
13280
|
+
const SELECTOR_CRUD = `.${COMPONENT_PREFIX}table-container, .${COMPONENT_PREFIX}crud-cards`;
|
|
13281
|
+
const ScrollToEnd = ({
|
|
13282
|
+
hostRef,
|
|
13283
|
+
selector = SELECTOR_CRUD,
|
|
13284
|
+
dep,
|
|
13285
|
+
label = "Ir al final de la lista"
|
|
13286
|
+
}) => {
|
|
13287
|
+
const [visible, setVisible] = React.useState(false);
|
|
13288
|
+
const scrollerRef = React.useRef(null);
|
|
13289
|
+
React.useEffect(() => {
|
|
13290
|
+
const host = hostRef.current;
|
|
13291
|
+
if (!host) return;
|
|
13292
|
+
const scroller = host.querySelector(selector) ?? host;
|
|
13293
|
+
scrollerRef.current = scroller;
|
|
13294
|
+
if (!scroller) {
|
|
13295
|
+
setVisible(false);
|
|
13296
|
+
return;
|
|
13297
|
+
}
|
|
13298
|
+
const revisar = () => {
|
|
13299
|
+
const s = scrollerRef.current;
|
|
13300
|
+
if (!s) return;
|
|
13301
|
+
setVisible(s.scrollHeight - s.clientHeight - s.scrollTop > MARGEN);
|
|
13302
|
+
};
|
|
13303
|
+
revisar();
|
|
13304
|
+
scroller.addEventListener("scroll", revisar, { passive: true });
|
|
13305
|
+
let observador;
|
|
13306
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
13307
|
+
observador = new ResizeObserver(revisar);
|
|
13308
|
+
observador.observe(scroller);
|
|
13309
|
+
if (scroller.firstElementChild) observador.observe(scroller.firstElementChild);
|
|
13310
|
+
}
|
|
13311
|
+
return () => {
|
|
13312
|
+
scroller.removeEventListener("scroll", revisar);
|
|
13313
|
+
observador?.disconnect();
|
|
13314
|
+
};
|
|
13315
|
+
}, [hostRef, selector, dep]);
|
|
13316
|
+
const alFinal = React.useCallback(() => {
|
|
13317
|
+
const s = scrollerRef.current;
|
|
13318
|
+
if (!s) return;
|
|
13319
|
+
s.scrollTo({ top: s.scrollHeight, behavior: "smooth" });
|
|
13320
|
+
}, []);
|
|
13321
|
+
if (!visible) return null;
|
|
13322
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: CLASS$b, onClick: alFinal, "aria-label": label, title: label, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "chevron-down", width: 18, height: 18, "aria-hidden": true }) });
|
|
13323
|
+
};
|
|
13324
|
+
ScrollToEnd.displayName = "ScrollToEnd";
|
|
13325
|
+
|
|
13142
13326
|
function calculateTotalPages(totalRecords, limit) {
|
|
13143
13327
|
return Math.ceil(totalRecords / limit);
|
|
13144
13328
|
}
|
|
13145
13329
|
|
|
13330
|
+
const useAnchoPropio = () => {
|
|
13331
|
+
const ref = React.useRef(null);
|
|
13332
|
+
const [ancho, setAncho] = React.useState(null);
|
|
13333
|
+
React.useEffect(() => {
|
|
13334
|
+
const nodo = ref.current;
|
|
13335
|
+
if (!nodo) return;
|
|
13336
|
+
if (typeof ResizeObserver === "undefined") {
|
|
13337
|
+
setAncho(nodo.getBoundingClientRect().width);
|
|
13338
|
+
return;
|
|
13339
|
+
}
|
|
13340
|
+
const observador = new ResizeObserver((entradas) => {
|
|
13341
|
+
const w = entradas[0]?.contentRect.width;
|
|
13342
|
+
if (typeof w === "number") setAncho(w);
|
|
13343
|
+
});
|
|
13344
|
+
observador.observe(nodo);
|
|
13345
|
+
return () => observador.disconnect();
|
|
13346
|
+
}, []);
|
|
13347
|
+
return [ref, ancho];
|
|
13348
|
+
};
|
|
13146
13349
|
const useIsMobile = () => {
|
|
13147
13350
|
const [isMobile, setIsMobile] = React.useState(false);
|
|
13148
13351
|
React.useEffect(() => {
|
|
@@ -13182,6 +13385,8 @@ function Crud({
|
|
|
13182
13385
|
defaultFilters,
|
|
13183
13386
|
tableHeight,
|
|
13184
13387
|
tableScroll,
|
|
13388
|
+
layout = "auto",
|
|
13389
|
+
cardsBelow = 768,
|
|
13185
13390
|
hidePagination = false,
|
|
13186
13391
|
formDrawerWidth = "80%",
|
|
13187
13392
|
formColumns = 2,
|
|
@@ -13286,6 +13491,69 @@ function Crud({
|
|
|
13286
13491
|
}
|
|
13287
13492
|
return columns;
|
|
13288
13493
|
}, [renderByFields, isMobile, tableScroll?.x]);
|
|
13494
|
+
const buildRowOptions = React.useCallback((row) => {
|
|
13495
|
+
const menuOptions = [];
|
|
13496
|
+
if (rowActionTypes.includes("edit") && !disabledActions?.edit && onEdit) {
|
|
13497
|
+
menuOptions.push({
|
|
13498
|
+
label: labels?.editButton || "Editar",
|
|
13499
|
+
icon: "edit",
|
|
13500
|
+
onClick: () => {
|
|
13501
|
+
openFormDrawer("edit", row);
|
|
13502
|
+
}
|
|
13503
|
+
});
|
|
13504
|
+
}
|
|
13505
|
+
if (rowActionTypes.includes("delete") && !disabledActions?.delete && onDelete) {
|
|
13506
|
+
menuOptions.push({
|
|
13507
|
+
label: labels?.deleteButton || "Eliminar",
|
|
13508
|
+
icon: "trash",
|
|
13509
|
+
onClick: () => {
|
|
13510
|
+
openConfirmDrawer("delete", void 0, [row]);
|
|
13511
|
+
}
|
|
13512
|
+
});
|
|
13513
|
+
}
|
|
13514
|
+
if (rowActionTypes.includes("view") && !disabledActions?.view) {
|
|
13515
|
+
menuOptions.push({
|
|
13516
|
+
label: labels?.viewButton || "Ver",
|
|
13517
|
+
icon: "eye",
|
|
13518
|
+
onClick: async () => {
|
|
13519
|
+
if (onView) {
|
|
13520
|
+
await onView([row]);
|
|
13521
|
+
}
|
|
13522
|
+
openFormDrawer("view", row);
|
|
13523
|
+
}
|
|
13524
|
+
});
|
|
13525
|
+
}
|
|
13526
|
+
rowActions?.forEach((action) => {
|
|
13527
|
+
if (action.show && !action.show(row)) return;
|
|
13528
|
+
menuOptions.push({
|
|
13529
|
+
label: action.label,
|
|
13530
|
+
icon: action.icon,
|
|
13531
|
+
onClick: () => {
|
|
13532
|
+
if (action.drawerId) {
|
|
13533
|
+
openCustomDrawer(action.drawerId, row);
|
|
13534
|
+
}
|
|
13535
|
+
if (action.onClick) {
|
|
13536
|
+
action.onClick(row);
|
|
13537
|
+
}
|
|
13538
|
+
},
|
|
13539
|
+
disabled: action.disabled ? action.disabled(row) : false,
|
|
13540
|
+
// SPEC-090 T3 — una acción apagada sin motivo es indistinguible de una rota.
|
|
13541
|
+
disabledReason: action.disabledReason?.(row)
|
|
13542
|
+
});
|
|
13543
|
+
});
|
|
13544
|
+
return menuOptions;
|
|
13545
|
+
}, [
|
|
13546
|
+
rowActionTypes,
|
|
13547
|
+
disabledActions,
|
|
13548
|
+
onEdit,
|
|
13549
|
+
onDelete,
|
|
13550
|
+
onView,
|
|
13551
|
+
labels,
|
|
13552
|
+
openFormDrawer,
|
|
13553
|
+
openConfirmDrawer,
|
|
13554
|
+
openCustomDrawer,
|
|
13555
|
+
rowActions
|
|
13556
|
+
]);
|
|
13289
13557
|
const tableColumns = React.useMemo(() => {
|
|
13290
13558
|
if (!showRowActions) return baseTableColumns;
|
|
13291
13559
|
const actionsColumn = {
|
|
@@ -13297,55 +13565,7 @@ function Crud({
|
|
|
13297
13565
|
cellType: "CHILDREN",
|
|
13298
13566
|
dataSource: {
|
|
13299
13567
|
build: (row) => {
|
|
13300
|
-
const menuOptions =
|
|
13301
|
-
if (rowActionTypes.includes("edit") && !disabledActions?.edit && onEdit) {
|
|
13302
|
-
menuOptions.push({
|
|
13303
|
-
label: labels?.editButton || "Editar",
|
|
13304
|
-
icon: "edit",
|
|
13305
|
-
onClick: () => {
|
|
13306
|
-
openFormDrawer("edit", row);
|
|
13307
|
-
}
|
|
13308
|
-
});
|
|
13309
|
-
}
|
|
13310
|
-
if (rowActionTypes.includes("delete") && !disabledActions?.delete && onDelete) {
|
|
13311
|
-
menuOptions.push({
|
|
13312
|
-
label: labels?.deleteButton || "Eliminar",
|
|
13313
|
-
icon: "trash",
|
|
13314
|
-
onClick: () => {
|
|
13315
|
-
openConfirmDrawer("delete", void 0, [row]);
|
|
13316
|
-
}
|
|
13317
|
-
});
|
|
13318
|
-
}
|
|
13319
|
-
if (rowActionTypes.includes("view") && !disabledActions?.view) {
|
|
13320
|
-
menuOptions.push({
|
|
13321
|
-
label: labels?.viewButton || "Ver",
|
|
13322
|
-
icon: "eye",
|
|
13323
|
-
onClick: async () => {
|
|
13324
|
-
if (onView) {
|
|
13325
|
-
await onView([row]);
|
|
13326
|
-
}
|
|
13327
|
-
openFormDrawer("view", row);
|
|
13328
|
-
}
|
|
13329
|
-
});
|
|
13330
|
-
}
|
|
13331
|
-
rowActions?.forEach((action) => {
|
|
13332
|
-
if (action.show && !action.show(row)) return;
|
|
13333
|
-
menuOptions.push({
|
|
13334
|
-
label: action.label,
|
|
13335
|
-
icon: action.icon,
|
|
13336
|
-
onClick: () => {
|
|
13337
|
-
if (action.drawerId) {
|
|
13338
|
-
openCustomDrawer(action.drawerId, row);
|
|
13339
|
-
}
|
|
13340
|
-
if (action.onClick) {
|
|
13341
|
-
action.onClick(row);
|
|
13342
|
-
}
|
|
13343
|
-
},
|
|
13344
|
-
disabled: action.disabled ? action.disabled(row) : false,
|
|
13345
|
-
// SPEC-090 T3 — una acción apagada sin motivo es indistinguible de una rota.
|
|
13346
|
-
disabledReason: action.disabledReason?.(row)
|
|
13347
|
-
});
|
|
13348
|
-
});
|
|
13568
|
+
const menuOptions = buildRowOptions(row);
|
|
13349
13569
|
if (menuOptions.length === 0) return null;
|
|
13350
13570
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", width: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13351
13571
|
DropdownMenu,
|
|
@@ -13368,20 +13588,7 @@ function Crud({
|
|
|
13368
13588
|
}
|
|
13369
13589
|
};
|
|
13370
13590
|
return [...baseTableColumns, actionsColumn];
|
|
13371
|
-
}, [
|
|
13372
|
-
baseTableColumns,
|
|
13373
|
-
showRowActions,
|
|
13374
|
-
rowActionTypes,
|
|
13375
|
-
disabledActions,
|
|
13376
|
-
labels,
|
|
13377
|
-
onEdit,
|
|
13378
|
-
onDelete,
|
|
13379
|
-
onView,
|
|
13380
|
-
rowActions,
|
|
13381
|
-
openFormDrawer,
|
|
13382
|
-
openConfirmDrawer,
|
|
13383
|
-
openCustomDrawer
|
|
13384
|
-
]);
|
|
13591
|
+
}, [baseTableColumns, showRowActions, buildRowOptions]);
|
|
13385
13592
|
const formFields = React.useMemo(() => {
|
|
13386
13593
|
return mapFieldsToFormFields(renderByFields, formMode);
|
|
13387
13594
|
}, [renderByFields, formMode]);
|
|
@@ -13578,6 +13785,10 @@ function Crud({
|
|
|
13578
13785
|
return "\xBFEst\xE1 seguro que desea realizar esta acci\xF3n?";
|
|
13579
13786
|
}
|
|
13580
13787
|
};
|
|
13788
|
+
const [refContenedor, anchoPropio] = useAnchoPropio();
|
|
13789
|
+
const enTarjetas = layout === "cards" || // Mientras no se ha medido (`null`) se mantiene la tabla: pintar tarjetas y saltar a tabla un
|
|
13790
|
+
// instante después es el parpadeo que se acaba de quitar en otro sitio.
|
|
13791
|
+
layout === "auto" && anchoPropio !== null && anchoPropio < cardsBelow;
|
|
13581
13792
|
const crudClasses = [
|
|
13582
13793
|
`${COMPONENT_PREFIX}crud`,
|
|
13583
13794
|
loading && `${COMPONENT_PREFIX}crud--loading`,
|
|
@@ -13594,24 +13805,43 @@ function Crud({
|
|
|
13594
13805
|
showLabels: false
|
|
13595
13806
|
}
|
|
13596
13807
|
) }),
|
|
13597
|
-
!formOnly && /* @__PURE__ */ jsxRuntime.
|
|
13598
|
-
|
|
13808
|
+
!formOnly && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13809
|
+
"div",
|
|
13599
13810
|
{
|
|
13600
|
-
|
|
13601
|
-
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13811
|
+
className: `${COMPONENT_PREFIX}crud__data${enTarjetas ? ` ${COMPONENT_PREFIX}crud__data--cards` : ""}`,
|
|
13812
|
+
children: [
|
|
13813
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${COMPONENT_PREFIX}crud__table`, ref: refContenedor, children: enTarjetas ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
13814
|
+
CardList,
|
|
13815
|
+
{
|
|
13816
|
+
fields: renderByFields,
|
|
13817
|
+
rows: dataSource,
|
|
13818
|
+
rowKey: getRowKey,
|
|
13819
|
+
buildOptions: showRowActions ? buildRowOptions : void 0,
|
|
13820
|
+
loading,
|
|
13821
|
+
emptyText: labels?.emptyText
|
|
13822
|
+
}
|
|
13823
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
13824
|
+
Table$1,
|
|
13825
|
+
{
|
|
13826
|
+
dataSource,
|
|
13827
|
+
columns: tableColumns,
|
|
13828
|
+
selectable: showActionBar && actionBarMode === "full",
|
|
13829
|
+
selectedRowKeys: selectedKeys,
|
|
13830
|
+
onSelectionChange: handleSelectionChange,
|
|
13831
|
+
rowKey: getRowKey,
|
|
13832
|
+
loading,
|
|
13833
|
+
height: tableHeight,
|
|
13834
|
+
scroll: tableScroll,
|
|
13835
|
+
compact: size === "small",
|
|
13836
|
+
bordered: true,
|
|
13837
|
+
hoverable: true,
|
|
13838
|
+
emptyText: labels?.emptyText
|
|
13839
|
+
}
|
|
13840
|
+
) }),
|
|
13841
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollToEnd, { hostRef: refContenedor, dep: `${enTarjetas}:${dataSource.length}:${loading}` })
|
|
13842
|
+
]
|
|
13613
13843
|
}
|
|
13614
|
-
)
|
|
13844
|
+
),
|
|
13615
13845
|
!formOnly && !filters.all_data && !hidePagination && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${COMPONENT_PREFIX}crud__pagination`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13616
13846
|
Pagination,
|
|
13617
13847
|
{
|
|
@@ -13676,6 +13906,7 @@ function Crud({
|
|
|
13676
13906
|
position: "right",
|
|
13677
13907
|
size: "responsive",
|
|
13678
13908
|
responsivePercentage: 30,
|
|
13909
|
+
mobileSheet: true,
|
|
13679
13910
|
className: `${COMPONENT_PREFIX}crud__confirm-drawer`,
|
|
13680
13911
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${COMPONENT_PREFIX}crud__confirm-content`, children: [
|
|
13681
13912
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `${COMPONENT_PREFIX}crud__confirm-message`, children: getConfirmMessage() }),
|
|
@@ -13724,6 +13955,60 @@ function Crud({
|
|
|
13724
13955
|
}
|
|
13725
13956
|
Crud.displayName = "Crud";
|
|
13726
13957
|
|
|
13958
|
+
const CLASS$a = "px-chat-reactive-crud__chat-link";
|
|
13959
|
+
function Burbuja() {
|
|
13960
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13961
|
+
"svg",
|
|
13962
|
+
{
|
|
13963
|
+
width: 18,
|
|
13964
|
+
height: 18,
|
|
13965
|
+
viewBox: "0 0 24 24",
|
|
13966
|
+
fill: "none",
|
|
13967
|
+
stroke: "currentColor",
|
|
13968
|
+
strokeWidth: 2,
|
|
13969
|
+
strokeLinecap: "round",
|
|
13970
|
+
strokeLinejoin: "round",
|
|
13971
|
+
"aria-hidden": true,
|
|
13972
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
|
|
13973
|
+
}
|
|
13974
|
+
);
|
|
13975
|
+
}
|
|
13976
|
+
const ChatLinkCell = ({
|
|
13977
|
+
targets,
|
|
13978
|
+
eventBus
|
|
13979
|
+
}) => {
|
|
13980
|
+
if (targets.length === 0) return null;
|
|
13981
|
+
const abrir = (id) => eventBus?.emit(CHAT_EVENT.OPEN_CHAT, { chatId: id, closed: false });
|
|
13982
|
+
if (targets.length === 1) {
|
|
13983
|
+
const t = targets[0];
|
|
13984
|
+
const texto = t.label ? `Abrir chat ${t.label}` : "Abrir chat";
|
|
13985
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: CLASS$a, "aria-label": texto, title: texto, onClick: () => abrir(t.id), children: /* @__PURE__ */ jsxRuntime.jsx(Burbuja, {}) });
|
|
13986
|
+
}
|
|
13987
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13988
|
+
DropdownMenu,
|
|
13989
|
+
{
|
|
13990
|
+
options: targets.map((t) => ({
|
|
13991
|
+
label: t.label ?? "Chat",
|
|
13992
|
+
icon: "message-square",
|
|
13993
|
+
onClick: () => abrir(t.id)
|
|
13994
|
+
})),
|
|
13995
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13996
|
+
"button",
|
|
13997
|
+
{
|
|
13998
|
+
type: "button",
|
|
13999
|
+
className: CLASS$a,
|
|
14000
|
+
"aria-label": `Abrir chat (${targets.length} conversaciones)`,
|
|
14001
|
+
title: "Abrir chat",
|
|
14002
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Burbuja, {})
|
|
14003
|
+
}
|
|
14004
|
+
),
|
|
14005
|
+
position: "bottom-left",
|
|
14006
|
+
usePortal: true
|
|
14007
|
+
}
|
|
14008
|
+
);
|
|
14009
|
+
};
|
|
14010
|
+
ChatLinkCell.displayName = "ChatLinkCell";
|
|
14011
|
+
|
|
13727
14012
|
function buildCrudYupSchema(fields) {
|
|
13728
14013
|
const shape = {};
|
|
13729
14014
|
for (const f of fields) {
|
|
@@ -13804,8 +14089,21 @@ function unwrap$3(raw) {
|
|
|
13804
14089
|
}
|
|
13805
14090
|
return raw;
|
|
13806
14091
|
}
|
|
13807
|
-
|
|
13808
|
-
|
|
14092
|
+
function resolveBody(body, ctx) {
|
|
14093
|
+
if (!body) return {};
|
|
14094
|
+
if (!ctx) return body;
|
|
14095
|
+
return Object.fromEntries(
|
|
14096
|
+
Object.entries(body).map(([k, v]) => {
|
|
14097
|
+
if (typeof v === "string" && v.startsWith("$")) {
|
|
14098
|
+
const key = v.slice(1);
|
|
14099
|
+
return [k, key in ctx ? ctx[key] : v];
|
|
14100
|
+
}
|
|
14101
|
+
return [k, v];
|
|
14102
|
+
})
|
|
14103
|
+
);
|
|
14104
|
+
}
|
|
14105
|
+
async function loadOptions(eventBus, ep, ctx) {
|
|
14106
|
+
const raw = await fetchViaEventBus(eventBus, ep.service, ep.url, ep.method, resolveBody(ep.body, ctx));
|
|
13809
14107
|
let data = unwrap$3(raw);
|
|
13810
14108
|
if (ep.response_path && data && typeof data === "object" && !Array.isArray(data)) {
|
|
13811
14109
|
data = data[ep.response_path];
|
|
@@ -13881,7 +14179,7 @@ function useReactiveCrud(config, eventBus) {
|
|
|
13881
14179
|
const loadList = React.useCallback(async () => {
|
|
13882
14180
|
if (!eventBus) return;
|
|
13883
14181
|
const myReq = ++reqIdRef.current;
|
|
13884
|
-
setState((s) =>
|
|
14182
|
+
setState((s) => s.rows.length === 0 ? { ...s, loading: true, error: null } : { ...s, error: null });
|
|
13885
14183
|
try {
|
|
13886
14184
|
const { service, url, method } = config.data.list;
|
|
13887
14185
|
const raw = await fetchViaEventBus(eventBus, service, url, method, {
|
|
@@ -14132,7 +14430,7 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
|
|
|
14132
14430
|
void Promise.all(
|
|
14133
14431
|
toLoad.map(async (f) => {
|
|
14134
14432
|
try {
|
|
14135
|
-
const opts = await loadOptions(eventBus, f.optionsEndpoint);
|
|
14433
|
+
const opts = await loadOptions(eventBus, f.optionsEndpoint, { ...row, id: row[idField] });
|
|
14136
14434
|
return [f.name, opts];
|
|
14137
14435
|
} catch {
|
|
14138
14436
|
return [f.name, []];
|
|
@@ -14821,6 +15119,7 @@ function unwrap$1(raw) {
|
|
|
14821
15119
|
}
|
|
14822
15120
|
return raw;
|
|
14823
15121
|
}
|
|
15122
|
+
const DETALLE_OCULTOS = /* @__PURE__ */ new Set(["LOCATION", "CHAT_LINK", "FILE"]);
|
|
14824
15123
|
function DetailDrawer({ row, config, eventBus, onClose, loadedOptions }) {
|
|
14825
15124
|
const detail = config.detail;
|
|
14826
15125
|
const [files, setFiles] = React.useState([]);
|
|
@@ -14919,7 +15218,7 @@ function DetailDrawer({ row, config, eventBus, onClose, loadedOptions }) {
|
|
|
14919
15218
|
}
|
|
14920
15219
|
};
|
|
14921
15220
|
return /* @__PURE__ */ jsxRuntime.jsx(Drawer$1, { isOpen: true, onClose, title, placement: "right", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-reactive-crud-detail", children: [
|
|
14922
|
-
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: "px-chat-reactive-crud-detail__fields", children: config.fields.map((f) => {
|
|
15221
|
+
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: "px-chat-reactive-crud-detail__fields", children: config.fields.filter((f) => !DETALLE_OCULTOS.has(f.moleculeType)).map((f) => {
|
|
14923
15222
|
const { node, copyText } = renderField(f);
|
|
14924
15223
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-reactive-crud-detail__row", children: [
|
|
14925
15224
|
/* @__PURE__ */ jsxRuntime.jsx("dt", { className: "px-chat-reactive-crud-detail__label", children: f.label }),
|
|
@@ -15581,35 +15880,13 @@ const LocationField = ({
|
|
|
15581
15880
|
};
|
|
15582
15881
|
LocationField.displayName = "LocationField";
|
|
15583
15882
|
|
|
15584
|
-
function chatLinkButton(id, eventBus, label) {
|
|
15585
|
-
return React.createElement(
|
|
15586
|
-
"button",
|
|
15587
|
-
{
|
|
15588
|
-
key: label ?? id,
|
|
15589
|
-
type: "button",
|
|
15590
|
-
className: "px-chat-reactive-crud__chat-link",
|
|
15591
|
-
"aria-label": label ? `Abrir chat ${label}` : "Abrir chat",
|
|
15592
|
-
title: label ?? "Abrir chat",
|
|
15593
|
-
onClick: () => eventBus?.emit(CHAT_EVENT.OPEN_CHAT, { chatId: id, closed: false })
|
|
15594
|
-
},
|
|
15595
|
-
React.createElement(
|
|
15596
|
-
"svg",
|
|
15597
|
-
{ width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" },
|
|
15598
|
-
React.createElement("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
|
|
15599
|
-
),
|
|
15600
|
-
label ? React.createElement("span", { className: "px-chat-reactive-crud__chat-link-label" }, label) : null
|
|
15601
|
-
);
|
|
15602
|
-
}
|
|
15603
15883
|
function chatLinkFormatter(field, eventBus) {
|
|
15604
15884
|
const sources = field.chats;
|
|
15605
15885
|
return (value, row) => {
|
|
15606
15886
|
const r = row;
|
|
15607
|
-
|
|
15608
|
-
|
|
15609
|
-
|
|
15610
|
-
}
|
|
15611
|
-
const id = value != null && value !== "" ? String(value) : "";
|
|
15612
|
-
return id ? chatLinkButton(id, eventBus) : null;
|
|
15887
|
+
const targets = sources?.length ? sources.map((s) => ({ id: r ? r[s.field] : void 0, label: s.label })).filter((s) => s.id != null && s.id !== "").map((s) => ({ id: String(s.id), label: s.label })) : value != null && value !== "" ? [{ id: String(value) }] : [];
|
|
15888
|
+
if (!targets.length) return null;
|
|
15889
|
+
return React.createElement(ChatLinkCell, { targets, eventBus });
|
|
15613
15890
|
};
|
|
15614
15891
|
}
|
|
15615
15892
|
function toRenderField(f, loaded, eventBus, mapsApiKey) {
|
|
@@ -15648,6 +15925,8 @@ function toRenderField(f, loaded, eventBus, mapsApiKey) {
|
|
|
15648
15925
|
// FILE/CHAT_LINK solo son columnas → INPUT (el render lo define formatValue/build).
|
|
15649
15926
|
moleculeType: f.moleculeType === "FILE" || isChatLink ? "INPUT" : f.moleculeType,
|
|
15650
15927
|
showInTable: f.showInTable,
|
|
15928
|
+
summary: f.summary,
|
|
15929
|
+
// SPEC-093
|
|
15651
15930
|
showInForm: f.showInForm,
|
|
15652
15931
|
showInModes: f.showInModes,
|
|
15653
15932
|
required: f.required,
|
|
@@ -15777,6 +16056,8 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
|
|
|
15777
16056
|
loading: crud.loading,
|
|
15778
16057
|
filters: { skip: crud.skip, limit: crud.pageSize, all_data: false, filters: crud.filters },
|
|
15779
16058
|
tableScroll: config.tableScroll,
|
|
16059
|
+
layout: config.layout,
|
|
16060
|
+
cardsBelow: config.cardsBelow,
|
|
15780
16061
|
validationSchema,
|
|
15781
16062
|
getRowKey: (row) => String(row[config.idField]),
|
|
15782
16063
|
onCreate: config.data.create ? async (rows) => {
|
|
@@ -16046,12 +16327,18 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16046
16327
|
"button",
|
|
16047
16328
|
{
|
|
16048
16329
|
type: "button",
|
|
16049
|
-
className:
|
|
16330
|
+
className: [
|
|
16331
|
+
"px-chat-crud-item__action",
|
|
16332
|
+
a.intent === "danger" ? "is-danger" : "",
|
|
16333
|
+
disabled && a.disabledReason ? "is-con-motivo" : ""
|
|
16334
|
+
].filter(Boolean).join(" "),
|
|
16050
16335
|
disabled,
|
|
16051
|
-
title: disabled ? a.disabledReason : void 0,
|
|
16052
16336
|
onClick: () => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] }),
|
|
16053
16337
|
children: [
|
|
16054
|
-
/* @__PURE__ */ jsxRuntime.
|
|
16338
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-crud-item__action-texts", children: [
|
|
16339
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: a.label }),
|
|
16340
|
+
disabled && a.disabledReason && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-crud-item__action-reason", children: a.disabledReason })
|
|
16341
|
+
] }),
|
|
16055
16342
|
done && /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: "check-circle", width: 18, height: 18, className: "px-chat-crud-item__done", "aria-label": "Hecho" })
|
|
16056
16343
|
]
|
|
16057
16344
|
},
|
|
@@ -16686,6 +16973,7 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
16686
16973
|
React.useEffect(() => {
|
|
16687
16974
|
void load();
|
|
16688
16975
|
}, [load]);
|
|
16976
|
+
const listaRef = React.useRef(null);
|
|
16689
16977
|
const loadRef = React.useRef(load);
|
|
16690
16978
|
loadRef.current = load;
|
|
16691
16979
|
React.useEffect(() => {
|
|
@@ -16733,8 +17021,6 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
16733
17021
|
};
|
|
16734
17022
|
const page = Math.floor(skip / pageSize) + 1;
|
|
16735
17023
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
16736
|
-
const canPrev = skip > 0;
|
|
16737
|
-
const canNext = skip + pageSize < total;
|
|
16738
17024
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator", children: [
|
|
16739
17025
|
config.search && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator__search", children: [
|
|
16740
17026
|
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "px-chat-chat-navigator__search-icon", children: [
|
|
@@ -16814,143 +17100,126 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
16814
17100
|
loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-chat-navigator__state", children: "Cargando conversaciones\u2026" }),
|
|
16815
17101
|
error && !loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-chat-navigator__state px-chat-chat-navigator__state--error", children: error }),
|
|
16816
17102
|
!loading && !error && items.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-chat-navigator__state", children: labels.emptyText ?? "Sin conversaciones" }),
|
|
16817
|
-
/* @__PURE__ */ jsxRuntime.
|
|
16818
|
-
|
|
16819
|
-
|
|
16820
|
-
|
|
16821
|
-
|
|
16822
|
-
|
|
16823
|
-
|
|
16824
|
-
|
|
16825
|
-
|
|
16826
|
-
e
|
|
16827
|
-
|
|
16828
|
-
|
|
16829
|
-
|
|
16830
|
-
|
|
16831
|
-
|
|
16832
|
-
autoFocus: true,
|
|
16833
|
-
className: "px-chat-chat-navigator__rename-input",
|
|
16834
|
-
value: renameValue,
|
|
16835
|
-
onChange: (e) => setRenameValue(e.target.value),
|
|
16836
|
-
onBlur: () => void submitRename(item.id),
|
|
16837
|
-
"aria-label": labels.renameTitle ?? "Nuevo t\xEDtulo"
|
|
16838
|
-
}
|
|
16839
|
-
)
|
|
16840
|
-
}
|
|
16841
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "px-chat-chat-navigator__open", onClick: () => open(item), children: [
|
|
16842
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-chat-navigator__title", children: [
|
|
16843
|
-
displayTitle,
|
|
16844
|
-
item.unread_proactive_count && item.unread_proactive_count >= 1 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
16845
|
-
"span",
|
|
16846
|
-
{
|
|
16847
|
-
className: "px-chat-chat-navigator__badge-count",
|
|
16848
|
-
"aria-label": `${item.unread_proactive_count} mensajes nuevos sin leer`,
|
|
16849
|
-
title: `${item.unread_proactive_count} sin leer`,
|
|
16850
|
-
children: item.unread_proactive_count >= 100 ? "100+" : item.unread_proactive_count
|
|
16851
|
-
}
|
|
16852
|
-
) : null
|
|
16853
|
-
] }),
|
|
16854
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-chat-navigator__meta", children: [
|
|
16855
|
-
item.agent_name ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__agent", children: item.agent_name }) : null,
|
|
16856
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__time", children: relativeTime(item.updated_date) }),
|
|
16857
|
-
(() => {
|
|
16858
|
-
const opt = item.rol_code ? (config.originActorOptions ?? []).find((o) => o.value === item.rol_code) : void 0;
|
|
16859
|
-
if (!opt) return null;
|
|
16860
|
-
const c = opt.color;
|
|
16861
|
-
const nameField = config.originActorNameField;
|
|
16862
|
-
const allyName = nameField ? item[nameField] : void 0;
|
|
16863
|
-
const label = allyName ? String(allyName) : opt.label;
|
|
16864
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16865
|
-
"span",
|
|
16866
|
-
{
|
|
16867
|
-
className: "px-chat-chat-navigator__origin-badge",
|
|
16868
|
-
style: c ? { color: c, background: `${c}22`, borderColor: `${c}55` } : void 0,
|
|
16869
|
-
title: label,
|
|
16870
|
-
children: label
|
|
16871
|
-
}
|
|
16872
|
-
);
|
|
16873
|
-
})(),
|
|
16874
|
-
(() => {
|
|
16875
|
-
const field = config.tagField;
|
|
16876
|
-
if (!field) return null;
|
|
16877
|
-
const value = item[field];
|
|
16878
|
-
if (!value) return null;
|
|
16879
|
-
const opt = (config.tagOptions ?? []).find((o) => o.value === String(value));
|
|
16880
|
-
if (!opt) return null;
|
|
16881
|
-
const c = opt.color;
|
|
16882
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16883
|
-
"span",
|
|
17103
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator__list-wrap", ref: listaRef, children: [
|
|
17104
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "px-chat-chat-navigator__list", children: items.map((item) => {
|
|
17105
|
+
const isRenaming = renamingId === item.id;
|
|
17106
|
+
const displayTitle = item.title?.trim() || fallbackTitle(item);
|
|
17107
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "px-chat-chat-navigator__item", children: [
|
|
17108
|
+
isRenaming ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
17109
|
+
"form",
|
|
17110
|
+
{
|
|
17111
|
+
className: "px-chat-chat-navigator__rename",
|
|
17112
|
+
onSubmit: (e) => {
|
|
17113
|
+
e.preventDefault();
|
|
17114
|
+
void submitRename(item.id);
|
|
17115
|
+
},
|
|
17116
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17117
|
+
"input",
|
|
16884
17118
|
{
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16888
|
-
|
|
17119
|
+
autoFocus: true,
|
|
17120
|
+
className: "px-chat-chat-navigator__rename-input",
|
|
17121
|
+
value: renameValue,
|
|
17122
|
+
onChange: (e) => setRenameValue(e.target.value),
|
|
17123
|
+
onBlur: () => void submitRename(item.id),
|
|
17124
|
+
"aria-label": labels.renameTitle ?? "Nuevo t\xEDtulo"
|
|
16889
17125
|
}
|
|
16890
|
-
)
|
|
16891
|
-
}
|
|
16892
|
-
|
|
16893
|
-
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
const c = opt?.color;
|
|
16897
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17126
|
+
)
|
|
17127
|
+
}
|
|
17128
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "px-chat-chat-navigator__open", onClick: () => open(item), children: [
|
|
17129
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-chat-navigator__title", children: [
|
|
17130
|
+
displayTitle,
|
|
17131
|
+
item.unread_proactive_count && item.unread_proactive_count >= 1 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
16898
17132
|
"span",
|
|
16899
17133
|
{
|
|
16900
|
-
className: "px-chat-chat-
|
|
16901
|
-
|
|
16902
|
-
|
|
17134
|
+
className: "px-chat-chat-navigator__badge-count",
|
|
17135
|
+
"aria-label": `${item.unread_proactive_count} mensajes nuevos sin leer`,
|
|
17136
|
+
title: `${item.unread_proactive_count} sin leer`,
|
|
17137
|
+
children: item.unread_proactive_count >= 100 ? "100+" : item.unread_proactive_count
|
|
16903
17138
|
}
|
|
16904
|
-
)
|
|
16905
|
-
})
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
|
|
16914
|
-
|
|
16915
|
-
|
|
16916
|
-
|
|
16917
|
-
|
|
16918
|
-
|
|
16919
|
-
|
|
17139
|
+
) : null
|
|
17140
|
+
] }),
|
|
17141
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-chat-navigator__meta", children: [
|
|
17142
|
+
item.agent_name ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__agent", children: item.agent_name }) : null,
|
|
17143
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__time", children: relativeTime(item.updated_date) }),
|
|
17144
|
+
(() => {
|
|
17145
|
+
const opt = item.rol_code ? (config.originActorOptions ?? []).find((o) => o.value === item.rol_code) : void 0;
|
|
17146
|
+
if (!opt) return null;
|
|
17147
|
+
const c = opt.color;
|
|
17148
|
+
const nameField = config.originActorNameField;
|
|
17149
|
+
const allyName = nameField ? item[nameField] : void 0;
|
|
17150
|
+
const label = allyName ? String(allyName) : opt.label;
|
|
17151
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17152
|
+
"span",
|
|
17153
|
+
{
|
|
17154
|
+
className: "px-chat-chat-navigator__origin-badge",
|
|
17155
|
+
style: c ? { color: c, background: `${c}22`, borderColor: `${c}55` } : void 0,
|
|
17156
|
+
title: label,
|
|
17157
|
+
children: label
|
|
17158
|
+
}
|
|
17159
|
+
);
|
|
17160
|
+
})(),
|
|
17161
|
+
(() => {
|
|
17162
|
+
const field = config.tagField;
|
|
17163
|
+
if (!field) return null;
|
|
17164
|
+
const value = item[field];
|
|
17165
|
+
if (!value) return null;
|
|
17166
|
+
const opt = (config.tagOptions ?? []).find((o) => o.value === String(value));
|
|
17167
|
+
if (!opt) return null;
|
|
17168
|
+
const c = opt.color;
|
|
17169
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17170
|
+
"span",
|
|
17171
|
+
{
|
|
17172
|
+
className: "px-chat-chat-navigator__origin-badge",
|
|
17173
|
+
style: c ? { color: c, background: `${c}22`, borderColor: `${c}55` } : void 0,
|
|
17174
|
+
title: opt.label,
|
|
17175
|
+
children: opt.label
|
|
17176
|
+
}
|
|
17177
|
+
);
|
|
17178
|
+
})(),
|
|
17179
|
+
item.service_status ? (() => {
|
|
17180
|
+
const opt = (config.serviceStatusOptions ?? []).find(
|
|
17181
|
+
(o) => o.value === item.service_status
|
|
17182
|
+
);
|
|
17183
|
+
const c = opt?.color;
|
|
17184
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17185
|
+
"span",
|
|
17186
|
+
{
|
|
17187
|
+
className: "px-chat-chat-navigator__service-badge",
|
|
17188
|
+
style: c ? { color: c, background: `${c}22`, borderColor: `${c}55` } : void 0,
|
|
17189
|
+
children: opt?.label ?? item.service_status
|
|
17190
|
+
}
|
|
17191
|
+
);
|
|
17192
|
+
})() : null,
|
|
17193
|
+
item.closed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__badge", children: labels.closedBadge ?? "Cerrado" }) : null
|
|
16920
17194
|
] })
|
|
16921
|
-
}
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
|
|
16926
|
-
|
|
16927
|
-
|
|
16928
|
-
|
|
16929
|
-
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
" / ",
|
|
16940
|
-
totalPages
|
|
16941
|
-
] }),
|
|
16942
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16943
|
-
"button",
|
|
16944
|
-
{
|
|
16945
|
-
type: "button",
|
|
16946
|
-
className: "px-chat-chat-navigator__pager-btn",
|
|
16947
|
-
disabled: !canNext,
|
|
16948
|
-
onClick: () => setSkip(skip + pageSize),
|
|
16949
|
-
"aria-label": "P\xE1gina siguiente",
|
|
16950
|
-
children: "\u203A"
|
|
16951
|
-
}
|
|
16952
|
-
)
|
|
17195
|
+
] }),
|
|
17196
|
+
config.data.rename && !isRenaming && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17197
|
+
"button",
|
|
17198
|
+
{
|
|
17199
|
+
type: "button",
|
|
17200
|
+
className: "px-chat-chat-navigator__rename-btn",
|
|
17201
|
+
"aria-label": "Renombrar",
|
|
17202
|
+
title: "Renombrar",
|
|
17203
|
+
onClick: () => startRename(item),
|
|
17204
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
17205
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 20h9" }),
|
|
17206
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z" })
|
|
17207
|
+
] })
|
|
17208
|
+
}
|
|
17209
|
+
)
|
|
17210
|
+
] }, item.id);
|
|
17211
|
+
}) }),
|
|
17212
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScrollToEnd, { hostRef: listaRef, selector: ".px-chat-chat-navigator__list", dep: `${items.length}:${loading}` })
|
|
16953
17213
|
] }),
|
|
17214
|
+
total > pageSize && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-chat-navigator__pager", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17215
|
+
Pagination,
|
|
17216
|
+
{
|
|
17217
|
+
current: page,
|
|
17218
|
+
total: totalPages,
|
|
17219
|
+
onChange: (p) => setSkip((p - 1) * pageSize),
|
|
17220
|
+
showTotal: false
|
|
17221
|
+
}
|
|
17222
|
+
) }),
|
|
16954
17223
|
config.advancedFilters?.length ? /* @__PURE__ */ jsxRuntime.jsx(Drawer$1, { isOpen: advOpen, onClose: () => setAdvOpen(false), title: "Filtros avanzados", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
16955
17224
|
Filter,
|
|
16956
17225
|
{
|
|
@@ -24355,6 +24624,7 @@ exports.LumiDateInput = DateInput$1;
|
|
|
24355
24624
|
exports.LumiDrawer = Drawer;
|
|
24356
24625
|
exports.LumiDropdownMenu = DropdownMenu;
|
|
24357
24626
|
exports.LumiDynamicForm = DynamicForm;
|
|
24627
|
+
exports.LumiFieldValue = FieldValue;
|
|
24358
24628
|
exports.LumiFilter = Filter;
|
|
24359
24629
|
exports.LumiFilterRow = FilterRow;
|
|
24360
24630
|
exports.LumiFormCheckbox = Checkbox;
|
|
@@ -24373,6 +24643,7 @@ exports.LumiNotification = Notification;
|
|
|
24373
24643
|
exports.LumiPagination = Pagination;
|
|
24374
24644
|
exports.LumiPopover = Popover;
|
|
24375
24645
|
exports.LumiQRCode = QRCode;
|
|
24646
|
+
exports.LumiRecordCard = RecordCard;
|
|
24376
24647
|
exports.LumiSelect = Select$1;
|
|
24377
24648
|
exports.LumiStepIndicator = StepIndicator;
|
|
24378
24649
|
exports.LumiStepper = Stepper;
|