pixelon 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/molecules/chat/StructuredContent/components/ReactiveCrud/ReactiveCrud.d.ts +1 -0
- package/dist/components/molecules/chat/StructuredContent/components/ReactiveCrud/TranscriptSection.d.ts +10 -0
- package/dist/components/molecules/chat/StructuredContent/components/ReactiveCrud/types.d.ts +40 -1
- package/dist/components/molecules/chat/StructuredContent/components/ServicesMap/types.d.ts +3 -0
- package/dist/components/molecules/chat/StructuredContent/components/index.d.ts +0 -1
- package/dist/core/chat/ChatConfigContext.d.ts +25 -0
- package/dist/core/i18n/separadores.d.ts +12 -0
- package/dist/index.esm.js +171 -32
- package/dist/index.js +171 -32
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
- package/src/styles/index.scss +1 -0
package/dist/index.js
CHANGED
|
@@ -12838,29 +12838,22 @@ const FormDrawer = ({
|
|
|
12838
12838
|
onClose();
|
|
12839
12839
|
methods.reset();
|
|
12840
12840
|
}, [onClose, onBeforeClose, methods]);
|
|
12841
|
-
const [invalidMsg, setInvalidMsg] = React.useState(null);
|
|
12842
|
-
React.useEffect(() => {
|
|
12843
|
-
if (!isOpen) setInvalidMsg(null);
|
|
12844
|
-
}, [isOpen]);
|
|
12845
|
-
React.useEffect(() => {
|
|
12846
|
-
const sub = methods.watch(() => setInvalidMsg(null));
|
|
12847
|
-
return () => sub.unsubscribe();
|
|
12848
|
-
}, [methods.watch]);
|
|
12849
12841
|
const handleFormSubmit = React.useCallback(
|
|
12850
12842
|
async (data) => {
|
|
12851
|
-
setInvalidMsg(null);
|
|
12852
12843
|
await onSubmit(data);
|
|
12853
12844
|
},
|
|
12854
12845
|
[onSubmit]
|
|
12855
12846
|
);
|
|
12856
12847
|
const handleInvalid = React.useCallback(
|
|
12857
12848
|
(formErrors) => {
|
|
12858
|
-
const
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
);
|
|
12849
|
+
const primero = Object.keys(formErrors)[0];
|
|
12850
|
+
if (!primero) return;
|
|
12851
|
+
const nodo = document.querySelector(`[name="${CSS.escape(primero)}"]`);
|
|
12852
|
+
if (!nodo) return;
|
|
12853
|
+
nodo.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
12854
|
+
window.setTimeout(() => nodo.focus({ preventScroll: true }), 300);
|
|
12862
12855
|
},
|
|
12863
|
-
[
|
|
12856
|
+
[]
|
|
12864
12857
|
);
|
|
12865
12858
|
const handleSubmitClick = methods.handleSubmit(handleFormSubmit, handleInvalid);
|
|
12866
12859
|
const drawerTitle = title || DEFAULT_TITLES[mode];
|
|
@@ -12918,7 +12911,6 @@ const FormDrawer = ({
|
|
|
12918
12911
|
) }) }),
|
|
12919
12912
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${baseClass}__footer`, children: [
|
|
12920
12913
|
footerExtra && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${baseClass}__footer-extra`, children: footerExtra }),
|
|
12921
|
-
invalidMsg && mode !== "view" && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${baseClass}__invalid`, role: "alert", children: invalidMsg }),
|
|
12922
12914
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${baseClass}__actions`, children: [
|
|
12923
12915
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12924
12916
|
Button,
|
|
@@ -14133,7 +14125,7 @@ function getFormatter(key) {
|
|
|
14133
14125
|
}
|
|
14134
14126
|
|
|
14135
14127
|
const OPTIONS_LOAD_ERROR = "No se pudieron cargar las opciones. Int\xE9ntalo de nuevo.";
|
|
14136
|
-
function unwrap$
|
|
14128
|
+
function unwrap$4(raw) {
|
|
14137
14129
|
if (raw && typeof raw === "object" && "response" in raw) {
|
|
14138
14130
|
return raw.response;
|
|
14139
14131
|
}
|
|
@@ -14154,7 +14146,7 @@ function resolveBody(body, ctx) {
|
|
|
14154
14146
|
}
|
|
14155
14147
|
async function loadOptions(eventBus, ep, ctx) {
|
|
14156
14148
|
const raw = await fetchViaEventBus(eventBus, ep.service, ep.url, ep.method, resolveBody(ep.body, ctx));
|
|
14157
|
-
let data = unwrap$
|
|
14149
|
+
let data = unwrap$4(raw);
|
|
14158
14150
|
if (ep.response_path && data && typeof data === "object" && !Array.isArray(data)) {
|
|
14159
14151
|
data = data[ep.response_path];
|
|
14160
14152
|
}
|
|
@@ -14192,7 +14184,7 @@ const mensajeDeError = (e, respaldo) => {
|
|
|
14192
14184
|
};
|
|
14193
14185
|
|
|
14194
14186
|
const REFRESH_INTERVAL_MS = 2e4;
|
|
14195
|
-
function unwrap$
|
|
14187
|
+
function unwrap$3(raw) {
|
|
14196
14188
|
if (raw && typeof raw === "object" && "response" in raw) {
|
|
14197
14189
|
return raw.response;
|
|
14198
14190
|
}
|
|
@@ -14241,7 +14233,7 @@ function useReactiveCrud(config, eventBus) {
|
|
|
14241
14233
|
filters
|
|
14242
14234
|
});
|
|
14243
14235
|
assertOk(raw);
|
|
14244
|
-
const data = unwrap$
|
|
14236
|
+
const data = unwrap$3(raw);
|
|
14245
14237
|
let rows = [];
|
|
14246
14238
|
let total = 0;
|
|
14247
14239
|
if (Array.isArray(data)) {
|
|
@@ -14445,6 +14437,20 @@ const FileField = ({
|
|
|
14445
14437
|
] });
|
|
14446
14438
|
};
|
|
14447
14439
|
|
|
14440
|
+
const RESPALDO = { miles: ".", decimal: "," };
|
|
14441
|
+
function separadoresDelLocale(locale) {
|
|
14442
|
+
if (!locale) return RESPALDO;
|
|
14443
|
+
try {
|
|
14444
|
+
const partes = new Intl.NumberFormat(locale).formatToParts(123456789e-2);
|
|
14445
|
+
const miles = partes.find((p) => p.type === "group")?.value;
|
|
14446
|
+
const decimal = partes.find((p) => p.type === "decimal")?.value;
|
|
14447
|
+
if (!miles || !decimal) return RESPALDO;
|
|
14448
|
+
return { miles, decimal };
|
|
14449
|
+
} catch {
|
|
14450
|
+
return RESPALDO;
|
|
14451
|
+
}
|
|
14452
|
+
}
|
|
14453
|
+
|
|
14448
14454
|
const CRUD_TO_FORM_MOLECULE = {
|
|
14449
14455
|
INPUT: "INPUT",
|
|
14450
14456
|
INPUT_NUMBER: "INPUT_NUMBER",
|
|
@@ -14501,6 +14507,8 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
|
|
|
14501
14507
|
alive = false;
|
|
14502
14508
|
};
|
|
14503
14509
|
}, [eventBus, action.key, normalFields]);
|
|
14510
|
+
const { locale } = useChatConfig();
|
|
14511
|
+
const separadores = React.useMemo(() => separadoresDelLocale(locale), [locale]);
|
|
14504
14512
|
const fields = React.useMemo(
|
|
14505
14513
|
() => normalFields.map((f) => ({
|
|
14506
14514
|
name: f.name,
|
|
@@ -14511,9 +14519,19 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
|
|
|
14511
14519
|
options: f.options ?? optionsByField[f.name],
|
|
14512
14520
|
// SPEC-106 T8 — `uiProps` llega tal cual a la molécula, así que el desplegable dice lo
|
|
14513
14521
|
// que pasó de verdad en vez del «no hay» de siempre. Sin error, se queda el de siempre.
|
|
14514
|
-
...optionsErrorByField[f.name] ? { uiProps: { notFoundContent: optionsErrorByField[f.name] } } : {}
|
|
14522
|
+
...optionsErrorByField[f.name] ? { uiProps: { notFoundContent: optionsErrorByField[f.name] } } : {},
|
|
14523
|
+
// SPEC-128 — el dinero se escribe como se escribe AQUÍ.
|
|
14524
|
+
//
|
|
14525
|
+
// Los campos de moneda caían a `thousandSeparator ?? ','`, un valor por defecto en formato
|
|
14526
|
+
// inglés: al teclear 180000 el campo mostraba «180,000» mientras la tarjeta que recibe el
|
|
14527
|
+
// cliente decía «$ 180.000,00 COP». El mismo importe escrito de una manera y leído de otra.
|
|
14528
|
+
//
|
|
14529
|
+
// Se deriva del locale que el host ya declara en la config del chat, no de un valor fijo ni
|
|
14530
|
+
// del navegador: `navigator.language` puede ser `es-419` —español, pero con coma para los
|
|
14531
|
+
// miles— y entonces el resultado dependería del portátil de cada quien.
|
|
14532
|
+
...f.moleculeType === "INPUT_CURRENCY" ? { uiProps: { thousandSeparator: separadores.miles, decimalSeparator: separadores.decimal } } : {}
|
|
14515
14533
|
})),
|
|
14516
|
-
[normalFields, optionsByField, optionsErrorByField]
|
|
14534
|
+
[normalFields, optionsByField, optionsErrorByField, separadores]
|
|
14517
14535
|
);
|
|
14518
14536
|
const validationSchema = React.useMemo(() => buildCrudYupSchema(normalFields), [normalFields]);
|
|
14519
14537
|
const uploadOne = async (f, file, idx) => {
|
|
@@ -15172,6 +15190,95 @@ const FileViewer = ({
|
|
|
15172
15190
|
] });
|
|
15173
15191
|
};
|
|
15174
15192
|
|
|
15193
|
+
function unwrap$2(raw) {
|
|
15194
|
+
if (raw && typeof raw === "object" && "response" in raw) {
|
|
15195
|
+
return raw.response;
|
|
15196
|
+
}
|
|
15197
|
+
return raw;
|
|
15198
|
+
}
|
|
15199
|
+
function hora(iso) {
|
|
15200
|
+
if (!iso) return "";
|
|
15201
|
+
const d = new Date(iso);
|
|
15202
|
+
if (Number.isNaN(d.getTime())) return "";
|
|
15203
|
+
return d.toLocaleString(void 0, { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" });
|
|
15204
|
+
}
|
|
15205
|
+
function TranscriptSection({ transcript, values, eventBus }) {
|
|
15206
|
+
const chatId = values[transcript.chatIdField];
|
|
15207
|
+
const id = chatId == null || chatId === "" ? "" : String(chatId);
|
|
15208
|
+
const [datos, setDatos] = React.useState(null);
|
|
15209
|
+
const [cargando, setCargando] = React.useState(true);
|
|
15210
|
+
const [fallo, setFallo] = React.useState(false);
|
|
15211
|
+
React.useEffect(() => {
|
|
15212
|
+
if (!eventBus || !id) {
|
|
15213
|
+
setCargando(false);
|
|
15214
|
+
return;
|
|
15215
|
+
}
|
|
15216
|
+
let vivo = true;
|
|
15217
|
+
setCargando(true);
|
|
15218
|
+
setFallo(false);
|
|
15219
|
+
void (async () => {
|
|
15220
|
+
try {
|
|
15221
|
+
const raw = await fetchViaEventBus(
|
|
15222
|
+
eventBus,
|
|
15223
|
+
transcript.get.service,
|
|
15224
|
+
transcript.get.url,
|
|
15225
|
+
transcript.get.method ?? "POST",
|
|
15226
|
+
{ [transcript.param ?? "chat_id"]: id }
|
|
15227
|
+
);
|
|
15228
|
+
if (vivo) {
|
|
15229
|
+
setDatos(unwrap$2(raw) ?? {});
|
|
15230
|
+
setCargando(false);
|
|
15231
|
+
}
|
|
15232
|
+
} catch {
|
|
15233
|
+
if (vivo) {
|
|
15234
|
+
setFallo(true);
|
|
15235
|
+
setCargando(false);
|
|
15236
|
+
}
|
|
15237
|
+
}
|
|
15238
|
+
})();
|
|
15239
|
+
return () => {
|
|
15240
|
+
vivo = false;
|
|
15241
|
+
};
|
|
15242
|
+
}, [eventBus, id, transcript]);
|
|
15243
|
+
if (!id) return null;
|
|
15244
|
+
const lineas = datos?.lines ?? [];
|
|
15245
|
+
const dijoAlgo = (datos?.from_user ?? 0) > 0;
|
|
15246
|
+
const nombres = {
|
|
15247
|
+
user: transcript.labels?.user ?? "Cliente",
|
|
15248
|
+
assistant: transcript.labels?.assistant ?? "Asistente"
|
|
15249
|
+
};
|
|
15250
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-crud-transcript", children: [
|
|
15251
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "px-chat-crud-transcript__title", children: transcript.title ?? "Conversaci\xF3n" }),
|
|
15252
|
+
cargando && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-transcript__note", children: "Cargando\u2026" }),
|
|
15253
|
+
!cargando && fallo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-transcript__note", children: "No se pudo cargar la conversaci\xF3n." }),
|
|
15254
|
+
!cargando && !fallo && !dijoAlgo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-transcript__note", children: transcript.silentText ?? "Todav\xEDa no ha escrito nada." }),
|
|
15255
|
+
!cargando && !fallo && lineas.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "px-chat-crud-transcript__lines", children: lineas.map((l, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15256
|
+
"li",
|
|
15257
|
+
{
|
|
15258
|
+
className: [
|
|
15259
|
+
"px-chat-crud-transcript__line",
|
|
15260
|
+
l.rol === "user" ? "is-user" : "is-assistant"
|
|
15261
|
+
].join(" "),
|
|
15262
|
+
children: [
|
|
15263
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-crud-transcript__who", children: [
|
|
15264
|
+
l.rol === "user" ? nombres.user : nombres.assistant,
|
|
15265
|
+
hora(l.created_date) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-crud-transcript__when", children: hora(l.created_date) })
|
|
15266
|
+
] }),
|
|
15267
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-crud-transcript__text", children: l.text })
|
|
15268
|
+
]
|
|
15269
|
+
},
|
|
15270
|
+
`${i}-${l.created_date ?? ""}`
|
|
15271
|
+
)) }),
|
|
15272
|
+
!cargando && !fallo && (datos?.total ?? 0) > lineas.length && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-crud-transcript__note", children: [
|
|
15273
|
+
"Se muestran los \xFAltimos ",
|
|
15274
|
+
lineas.length,
|
|
15275
|
+
" de ",
|
|
15276
|
+
datos?.total,
|
|
15277
|
+
" mensajes."
|
|
15278
|
+
] })
|
|
15279
|
+
] });
|
|
15280
|
+
}
|
|
15281
|
+
|
|
15175
15282
|
function unwrap$1(raw) {
|
|
15176
15283
|
if (raw && typeof raw === "object" && "response" in raw) {
|
|
15177
15284
|
return raw.response;
|
|
@@ -15300,6 +15407,7 @@ function DetailDrawer({ row, config, eventBus, onClose, loadedOptions }) {
|
|
|
15300
15407
|
] })
|
|
15301
15408
|
] }, f.name);
|
|
15302
15409
|
}) }),
|
|
15410
|
+
config.transcript && /* @__PURE__ */ jsxRuntime.jsx(TranscriptSection, { transcript: config.transcript, values, eventBus }),
|
|
15303
15411
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-reactive-crud-detail__photos", children: [
|
|
15304
15412
|
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "px-chat-reactive-crud-detail__photos-title", children: "Fotos y documentos" }),
|
|
15305
15413
|
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-reactive-crud-detail__empty", children: "Cargando\u2026" }) : files.length ? /* @__PURE__ */ jsxRuntime.jsx(FileViewer, { files }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-reactive-crud-detail__empty", children: "Este servicio no tiene archivos." })
|
|
@@ -16006,6 +16114,10 @@ function matchesVisibleWhen(a, row) {
|
|
|
16006
16114
|
if (!a.visibleWhen) return true;
|
|
16007
16115
|
return cumplenTodas(a.visibleWhen, row);
|
|
16008
16116
|
}
|
|
16117
|
+
function laQueTocaAhora(actions, row) {
|
|
16118
|
+
const candidatas = actions.filter((a) => a.ahoraToca && cumplenTodas(a.ahoraToca, row));
|
|
16119
|
+
return candidatas.length === 1 ? candidatas[0] : void 0;
|
|
16120
|
+
}
|
|
16009
16121
|
function condicionesDeshabilitado(a) {
|
|
16010
16122
|
if (!a.disabledWhen) return [];
|
|
16011
16123
|
return Array.isArray(a.disabledWhen) ? a.disabledWhen : [a.disabledWhen];
|
|
@@ -16326,7 +16438,7 @@ function DeadlineCountdown({ deadline, label, expiredLabel }) {
|
|
|
16326
16438
|
}
|
|
16327
16439
|
|
|
16328
16440
|
function ReactiveCrudItemChat({ component, eventBus }) {
|
|
16329
|
-
const { resolveModuleConfig } = useChatConfig();
|
|
16441
|
+
const { resolveModuleConfig, resolveMomento } = useChatConfig();
|
|
16330
16442
|
const props = component.props ?? {};
|
|
16331
16443
|
const top = component;
|
|
16332
16444
|
const pick = (key) => props[key] !== void 0 ? props[key] : top[key];
|
|
@@ -16334,7 +16446,11 @@ function ReactiveCrudItemChat({ component, eventBus }) {
|
|
|
16334
16446
|
const recordId = pick("record_id") ?? pick("recordId") ?? pick("id") ?? pick("service_id");
|
|
16335
16447
|
const recordLabel = pick("record_label") ?? pick("label");
|
|
16336
16448
|
const allowedRaw = pick("actions");
|
|
16337
|
-
const
|
|
16449
|
+
const allowedLegacy = Array.isArray(allowedRaw) && allowedRaw.length > 0 ? allowedRaw : void 0;
|
|
16450
|
+
const momento = pick("momento");
|
|
16451
|
+
const delMomento = momento && resolveMomento ? resolveMomento(momento) : void 0;
|
|
16452
|
+
const allowed = delMomento ?? allowedLegacy;
|
|
16453
|
+
const sinAcciones = delMomento?.length === 0;
|
|
16338
16454
|
const config = typeof moduleKey === "string" && resolveModuleConfig ? resolveModuleConfig(moduleKey) : void 0;
|
|
16339
16455
|
if (!config || recordId == null || recordId === "") return null;
|
|
16340
16456
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -16344,11 +16460,12 @@ function ReactiveCrudItemChat({ component, eventBus }) {
|
|
|
16344
16460
|
recordId: String(recordId),
|
|
16345
16461
|
recordLabel,
|
|
16346
16462
|
allowed: Array.isArray(allowed) ? allowed.map(String) : void 0,
|
|
16463
|
+
sinAcciones,
|
|
16347
16464
|
eventBus
|
|
16348
16465
|
}
|
|
16349
16466
|
);
|
|
16350
16467
|
}
|
|
16351
|
-
function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus }) {
|
|
16468
|
+
function ServiceActionsPanel({ config, recordId, recordLabel, allowed, sinAcciones, eventBus }) {
|
|
16352
16469
|
const { chatIsForeign } = useChatConfig();
|
|
16353
16470
|
const crud = useReactiveCrud(config, eventBus);
|
|
16354
16471
|
const [activeAction, setActiveAction] = React.useState(null);
|
|
@@ -16397,9 +16514,26 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16397
16514
|
}, [recordId]);
|
|
16398
16515
|
const gastada = !esUltima;
|
|
16399
16516
|
const actions = React.useMemo(() => {
|
|
16400
|
-
if (!row
|
|
16401
|
-
|
|
16517
|
+
if (!row) return [];
|
|
16518
|
+
if (gastada) {
|
|
16519
|
+
const hechas = (config.rowActions ?? []).filter((a) => !allowed || allowed.includes(a.key)).filter((a) => matchesDoneWhen(a, row));
|
|
16520
|
+
const vistas = /* @__PURE__ */ new Set();
|
|
16521
|
+
return hechas.filter((a) => {
|
|
16522
|
+
const linea = a.doneLabel ?? a.label;
|
|
16523
|
+
if (vistas.has(linea)) return false;
|
|
16524
|
+
vistas.add(linea);
|
|
16525
|
+
return true;
|
|
16526
|
+
});
|
|
16527
|
+
}
|
|
16528
|
+
const visibles = (config.rowActions ?? []).filter((a) => !allowed || allowed.includes(a.key)).filter((a) => matchesVisibleWhen(a, row));
|
|
16529
|
+
const toca = laQueTocaAhora(visibles, row);
|
|
16530
|
+
if (!toca) return visibles;
|
|
16531
|
+
return [toca, ...visibles.filter((a) => a.key !== toca.key)];
|
|
16402
16532
|
}, [config.rowActions, row, allowed, gastada]);
|
|
16533
|
+
const claveQueToca = React.useMemo(
|
|
16534
|
+
() => row && !gastada ? laQueTocaAhora(actions, row)?.key : void 0,
|
|
16535
|
+
[actions, row, gastada]
|
|
16536
|
+
);
|
|
16403
16537
|
const title = recordLabel ?? config.title ?? "Servicio";
|
|
16404
16538
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-crud-item", ref: raiz, "data-panel-record": recordId, children: [
|
|
16405
16539
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__header", children: title }),
|
|
@@ -16410,7 +16544,7 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16410
16544
|
crud.loading && !row && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__hint", children: "Cargando\u2026" }),
|
|
16411
16545
|
!crud.loading && !row && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__hint", children: "No se encontr\xF3 el servicio." }),
|
|
16412
16546
|
gastada && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__hint", children: "Este paso ya se gestion\xF3. Contin\xFAa en el mensaje m\xE1s reciente." }),
|
|
16413
|
-
row && config.deadline && typeof row[config.deadline.field] === "string" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16547
|
+
row && !gastada && config.deadline && typeof row[config.deadline.field] === "string" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16414
16548
|
DeadlineCountdown,
|
|
16415
16549
|
{
|
|
16416
16550
|
deadline: row[config.deadline.field],
|
|
@@ -16421,7 +16555,7 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16421
16555
|
row && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-crud-item__actions", children: [
|
|
16422
16556
|
config.detail && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "px-chat-crud-item__action", onClick: () => setDetailRow(row), children: "Ver" }),
|
|
16423
16557
|
actions.map((a) => {
|
|
16424
|
-
const disabled = Boolean(chatIsForeign) || matchesDisabledWhen(a, row);
|
|
16558
|
+
const disabled = gastada || Boolean(chatIsForeign) || matchesDisabledWhen(a, row);
|
|
16425
16559
|
const motivo = chatIsForeign ? "Esta conversaci\xF3n es de otra persona" : disabledReasonFor(a, row);
|
|
16426
16560
|
const done = matchesDoneWhen(a, row);
|
|
16427
16561
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -16431,13 +16565,18 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16431
16565
|
className: [
|
|
16432
16566
|
"px-chat-crud-item__action",
|
|
16433
16567
|
a.intent === "danger" ? "is-danger" : "",
|
|
16434
|
-
disabled && motivo ? "is-con-motivo" : ""
|
|
16568
|
+
disabled && motivo ? "is-con-motivo" : "",
|
|
16569
|
+
// SPEC-129 T6 — lo hecho se pinta como un acta, no como un botón apagado.
|
|
16570
|
+
gastada ? "is-hecho" : "",
|
|
16571
|
+
// SPEC-127 T4 — señalada, pero solo si de verdad se puede pulsar: destacar una
|
|
16572
|
+
// acción apagada sería dirigir a alguien a una puerta cerrada.
|
|
16573
|
+
a.key === claveQueToca && !disabled ? "is-ahora" : ""
|
|
16435
16574
|
].filter(Boolean).join(" "),
|
|
16436
16575
|
disabled,
|
|
16437
16576
|
onClick: () => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] }),
|
|
16438
16577
|
children: [
|
|
16439
16578
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-crud-item__action-texts", children: [
|
|
16440
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: a.label }),
|
|
16579
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: gastada && a.doneLabel ? a.doneLabel : a.label }),
|
|
16441
16580
|
disabled && motivo && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-crud-item__action-reason", children: motivo })
|
|
16442
16581
|
] }),
|
|
16443
16582
|
done && /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: "check-circle", width: 18, height: 18, className: "px-chat-crud-item__done", "aria-label": "Hecho" })
|
|
@@ -16446,7 +16585,7 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16446
16585
|
a.key
|
|
16447
16586
|
);
|
|
16448
16587
|
}),
|
|
16449
|
-
actions.length === 0 && !config.detail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__hint", children: "Sin acciones disponibles." })
|
|
16588
|
+
actions.length === 0 && !config.detail && !sinAcciones && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__hint", children: "Sin acciones disponibles." })
|
|
16450
16589
|
] }),
|
|
16451
16590
|
activeAction && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16452
16591
|
ActionFormDrawer,
|
|
@@ -16666,7 +16805,7 @@ const ServicesMap = ({ config, eventBus, apiKey, filter, fill }) => {
|
|
|
16666
16805
|
),
|
|
16667
16806
|
simulated > 0 && ` \xB7 ${config.live?.labels?.simulatedText ?? "incluye posiciones simuladas"}`
|
|
16668
16807
|
] }),
|
|
16669
|
-
missing > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__note`, children: (labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", String(missing)) }),
|
|
16808
|
+
missing > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__note`, children: ((missing === 1 ? labels.missingTextOne : void 0) ?? labels.missingText ?? "{n} sin ubicaci\xF3n registrada").replace("{n}", String(missing)) }),
|
|
16670
16809
|
outside > 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `${CLASS$6}__note`, children: (labels.outsideText ?? "{n} fuera de la zona (aleja el mapa para verlos)").replace(
|
|
16671
16810
|
"{n}",
|
|
16672
16811
|
String(outside)
|