pixelon 0.3.79 → 0.3.81
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/Icon/Icon.d.ts +1 -0
- package/dist/components/atoms/lumi/Select/Select.d.ts +6 -0
- package/dist/components/molecules/chat/StructuredContent/components/ChatNavigator/types.d.ts +21 -0
- package/dist/components/molecules/chat/StructuredContent/components/ReactiveCrud/types.d.ts +7 -1
- package/dist/components/organisms/lumi/DynamicForm/types.d.ts +4 -0
- package/dist/index.esm.js +161 -18
- package/dist/index.js +161 -18
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
- package/dist/styles(1).css +0 -1
|
@@ -42,6 +42,7 @@ export declare const LUMI_ICON_TYPES: {
|
|
|
42
42
|
readonly MAP_PIN: "map-pin";
|
|
43
43
|
readonly USER_X: "user-x";
|
|
44
44
|
readonly REFRESH: "refresh";
|
|
45
|
+
readonly TRUCK: "truck";
|
|
45
46
|
readonly MESSAGE_SQUARE: "message-square";
|
|
46
47
|
readonly MESSAGE_CIRCLE: "message-circle";
|
|
47
48
|
readonly MAP: "map";
|
|
@@ -5,6 +5,12 @@ export interface SelectOption {
|
|
|
5
5
|
label: string;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
icon?: ReactNode;
|
|
8
|
+
/** SPEC-104: segunda línea, en gris y más pequeña. Para el PORQUÉ de la opción —quién la lleva,
|
|
9
|
+
* a qué distancia, si hay algún aviso— sin que compita con su nombre. */
|
|
10
|
+
sublabel?: string;
|
|
11
|
+
/** SPEC-104: icono por nombre del set de lumi. Existe además de `icon` porque las opciones que
|
|
12
|
+
* llegan de un endpoint son JSON y no pueden traer un nodo de React. */
|
|
13
|
+
iconName?: string;
|
|
8
14
|
}
|
|
9
15
|
/** Tipo de valor según el modo */
|
|
10
16
|
export type SelectValue = string | number | (string | number)[];
|
package/dist/components/molecules/chat/StructuredContent/components/ChatNavigator/types.d.ts
CHANGED
|
@@ -69,6 +69,27 @@ export interface ChatNavigatorConfig {
|
|
|
69
69
|
label: string;
|
|
70
70
|
color?: string;
|
|
71
71
|
}>;
|
|
72
|
+
/** SPEC-098 — agrupa varios chats en UNA tarjeta con varias puertas.
|
|
73
|
+
*
|
|
74
|
+
* Genérico a propósito: este componente no sabe qué agrupa el consumidor ni por qué. Lo único
|
|
75
|
+
* que exige es que la lista llegue con los items de un grupo JUNTOS y COMPLETOS —el que pagina
|
|
76
|
+
* es quien sabe qué forma un grupo, y partir un grupo entre dos páginas lo rompería—. La
|
|
77
|
+
* etiqueta de cada puerta sale de `tagField`/`tagOptions`, el mismo catálogo que sin agrupar
|
|
78
|
+
* pinta un pill.
|
|
79
|
+
*
|
|
80
|
+
* Un item sin valor en `field` se pinta como una fila normal. */
|
|
81
|
+
group?: {
|
|
82
|
+
/** Campo cuyo valor comparten los items de una tarjeta (items CONSECUTIVOS). */
|
|
83
|
+
field: string;
|
|
84
|
+
/** Campo con el título de la tarjeta; sin él se usa el título del primer chat. */
|
|
85
|
+
titleField?: string;
|
|
86
|
+
/** Campos que, unidos por «·», forman el subtítulo. Los vacíos se omiten. */
|
|
87
|
+
subtitleFields?: string[];
|
|
88
|
+
/** Campo de estado de la tarjeta (se pinta con `serviceStatusOptions`). */
|
|
89
|
+
statusField?: string;
|
|
90
|
+
};
|
|
91
|
+
/** SPEC-098 — `agent_name` es el nombre técnico del agente; en un producto no se enseña. */
|
|
92
|
+
showAgent?: boolean;
|
|
72
93
|
}
|
|
73
94
|
export interface ChatNavigatorItem {
|
|
74
95
|
id: string;
|
|
@@ -89,7 +89,13 @@ export interface RowActionDef {
|
|
|
89
89
|
label: string;
|
|
90
90
|
icon?: string;
|
|
91
91
|
intent?: 'primary' | 'secondary' | 'danger';
|
|
92
|
-
|
|
92
|
+
/** SPEC-103: una condición, o VARIAS unidas por «y». */
|
|
93
|
+
visibleWhen?: RowActionVisibleWhen | RowActionVisibleWhen[];
|
|
94
|
+
/** SPEC-103: la excepción. Si se cumplen TODAS, la acción no se muestra aunque `visibleWhen` dé
|
|
95
|
+
* por buena la fila. Es para las reglas con forma de «se ve en estos estados, salvo este caso»
|
|
96
|
+
* —p.ej. asignar grúa en PENDING_APPROVAL, salvo si quien pide es un invitado que todavía no ha
|
|
97
|
+
* aceptado el precio—, que con condiciones unidas por «y» no se pueden escribir. */
|
|
98
|
+
hiddenWhen?: RowActionVisibleWhen | RowActionVisibleWhen[];
|
|
93
99
|
/** SPEC-007: la acción se muestra pero queda DESHABILITADA cuando `String(row[field])` está en
|
|
94
100
|
* `in` (ej. "Iniciar" deshabilitado hasta que `has_inspection` sea true). */
|
|
95
101
|
disabledWhen?: RowActionVisibleWhen;
|
|
@@ -10,6 +10,10 @@ export interface SelectOption {
|
|
|
10
10
|
value: string | number;
|
|
11
11
|
label: string;
|
|
12
12
|
disabled?: boolean;
|
|
13
|
+
/** SPEC-104: segunda línea en gris — el porqué de la opción, sin competir con su nombre. */
|
|
14
|
+
sublabel?: string;
|
|
15
|
+
/** SPEC-104: nombre de icono del set de lumi (no un nodo: esto viaja como JSON desde el backend). */
|
|
16
|
+
iconName?: string;
|
|
13
17
|
}
|
|
14
18
|
/**
|
|
15
19
|
* Configuración de un campo del formulario
|
package/dist/index.esm.js
CHANGED
|
@@ -5739,6 +5739,9 @@ const LUMI_ICON_TYPES = {
|
|
|
5739
5739
|
// Iconos para Agenda
|
|
5740
5740
|
USER_X: "user-x",
|
|
5741
5741
|
REFRESH: "refresh",
|
|
5742
|
+
// SPEC-104 — grúas: el selector de despacho necesitaba distinguir de un vistazo qué es cada
|
|
5743
|
+
// opción, y no había ningún icono de vehículo en el set.
|
|
5744
|
+
TRUCK: "truck",
|
|
5742
5745
|
// Iconos para Chat
|
|
5743
5746
|
MESSAGE_SQUARE: "message-square",
|
|
5744
5747
|
MESSAGE_CIRCLE: "message-circle",
|
|
@@ -6449,6 +6452,27 @@ const BuildingIcon = (props) => /* @__PURE__ */ jsxs(
|
|
|
6449
6452
|
]
|
|
6450
6453
|
}
|
|
6451
6454
|
);
|
|
6455
|
+
const TruckIcon = (props) => /* @__PURE__ */ jsxs(
|
|
6456
|
+
"svg",
|
|
6457
|
+
{
|
|
6458
|
+
width: "16",
|
|
6459
|
+
height: "16",
|
|
6460
|
+
viewBox: "0 0 24 24",
|
|
6461
|
+
fill: "none",
|
|
6462
|
+
stroke: "currentColor",
|
|
6463
|
+
strokeWidth: "2",
|
|
6464
|
+
strokeLinecap: "round",
|
|
6465
|
+
strokeLinejoin: "round",
|
|
6466
|
+
...props,
|
|
6467
|
+
children: [
|
|
6468
|
+
/* @__PURE__ */ jsx("path", { d: "M2 17V8h10v9" }),
|
|
6469
|
+
/* @__PURE__ */ jsx("path", { d: "M12 11h4l3 3v3" }),
|
|
6470
|
+
/* @__PURE__ */ jsx("circle", { cx: "7", cy: "18", r: "2" }),
|
|
6471
|
+
/* @__PURE__ */ jsx("circle", { cx: "17", cy: "18", r: "2" }),
|
|
6472
|
+
/* @__PURE__ */ jsx("path", { d: "M9 18h6" })
|
|
6473
|
+
]
|
|
6474
|
+
}
|
|
6475
|
+
);
|
|
6452
6476
|
const MapPinIcon = (props) => /* @__PURE__ */ jsxs(
|
|
6453
6477
|
"svg",
|
|
6454
6478
|
{
|
|
@@ -6567,6 +6591,7 @@ const lumiIconMap = {
|
|
|
6567
6591
|
// Iconos para Servicios
|
|
6568
6592
|
[LUMI_ICON_TYPES.BUILDING]: BuildingIcon,
|
|
6569
6593
|
[LUMI_ICON_TYPES.MAP_PIN]: MapPinIcon,
|
|
6594
|
+
[LUMI_ICON_TYPES.TRUCK]: TruckIcon,
|
|
6570
6595
|
// Iconos para Agenda
|
|
6571
6596
|
[LUMI_ICON_TYPES.USER_X]: UserXIcon,
|
|
6572
6597
|
[LUMI_ICON_TYPES.REFRESH]: RefreshIcon,
|
|
@@ -7738,8 +7763,11 @@ const Select$1 = forwardRef(
|
|
|
7738
7763
|
`${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__checkbox`,
|
|
7739
7764
|
isSelected && `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__checkbox--checked`
|
|
7740
7765
|
].filter(Boolean).join(" "), children: isSelected && /* @__PURE__ */ jsx(Icon, { type: LUMI_ICON_TYPES.CHECK, size: "small" }) }) }),
|
|
7741
|
-
option.icon && /* @__PURE__ */ jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-icon`, children: option.icon }),
|
|
7742
|
-
/* @__PURE__ */
|
|
7766
|
+
(option.icon || option.iconName) && /* @__PURE__ */ jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-icon`, children: option.icon ?? /* @__PURE__ */ jsx(Icon, { type: option.iconName }) }),
|
|
7767
|
+
/* @__PURE__ */ jsxs("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-texts`, children: [
|
|
7768
|
+
/* @__PURE__ */ jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-label`, children: option.label }),
|
|
7769
|
+
option.sublabel && /* @__PURE__ */ jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-sublabel`, children: option.sublabel })
|
|
7770
|
+
] }),
|
|
7743
7771
|
mode === "single" && isSelected && /* @__PURE__ */ jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-check`, children: /* @__PURE__ */ jsx(Icon, { type: LUMI_ICON_TYPES.CHECK, size: "small" }) })
|
|
7744
7772
|
]
|
|
7745
7773
|
},
|
|
@@ -14111,7 +14139,9 @@ async function loadOptions(eventBus, ep, ctx) {
|
|
|
14111
14139
|
const arr = Array.isArray(data) ? data : [];
|
|
14112
14140
|
return arr.map((item) => ({
|
|
14113
14141
|
value: String(item[ep.value_field] ?? ""),
|
|
14114
|
-
label: String(item[ep.label_field] ?? "")
|
|
14142
|
+
label: String(item[ep.label_field] ?? ""),
|
|
14143
|
+
...item.sublabel ? { sublabel: String(item.sublabel) } : {},
|
|
14144
|
+
...item.icon ? { iconName: String(item.icon) } : {}
|
|
14115
14145
|
}));
|
|
14116
14146
|
}
|
|
14117
14147
|
|
|
@@ -15938,9 +15968,12 @@ function toRenderField(f, loaded, eventBus, mapsApiKey) {
|
|
|
15938
15968
|
formatValue
|
|
15939
15969
|
};
|
|
15940
15970
|
}
|
|
15971
|
+
const cumpleCondicion = (c, row) => c.in.includes(String(row[c.field]));
|
|
15972
|
+
const cumplenTodas = (c, row) => (Array.isArray(c) ? c : [c]).every((x) => cumpleCondicion(x, row));
|
|
15941
15973
|
function matchesVisibleWhen(a, row) {
|
|
15974
|
+
if (a.hiddenWhen && cumplenTodas(a.hiddenWhen, row)) return false;
|
|
15942
15975
|
if (!a.visibleWhen) return true;
|
|
15943
|
-
return a.visibleWhen
|
|
15976
|
+
return cumplenTodas(a.visibleWhen, row);
|
|
15944
15977
|
}
|
|
15945
15978
|
function matchesDisabledWhen(a, row) {
|
|
15946
15979
|
if (!a.disabledWhen) return false;
|
|
@@ -16297,12 +16330,27 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16297
16330
|
() => crud.rows.find((r) => String(r[config.idField]) === recordId),
|
|
16298
16331
|
[crud.rows, config.idField, recordId]
|
|
16299
16332
|
);
|
|
16333
|
+
const raiz = useRef(null);
|
|
16334
|
+
const [esUltima, setEsUltima] = useState(true);
|
|
16335
|
+
useEffect(() => {
|
|
16336
|
+
const calcular = () => {
|
|
16337
|
+
const el = raiz.current;
|
|
16338
|
+
if (!el) return;
|
|
16339
|
+
const hermanas = document.querySelectorAll(`[data-panel-record="${recordId}"]`);
|
|
16340
|
+
setEsUltima(hermanas.length === 0 || hermanas[hermanas.length - 1] === el);
|
|
16341
|
+
};
|
|
16342
|
+
calcular();
|
|
16343
|
+
const observador = new MutationObserver(calcular);
|
|
16344
|
+
observador.observe(document.body, { childList: true, subtree: true });
|
|
16345
|
+
return () => observador.disconnect();
|
|
16346
|
+
}, [recordId]);
|
|
16347
|
+
const gastada = !esUltima;
|
|
16300
16348
|
const actions = useMemo(() => {
|
|
16301
|
-
if (!row) return [];
|
|
16349
|
+
if (!row || gastada) return [];
|
|
16302
16350
|
return (config.rowActions ?? []).filter((a) => !allowed || allowed.includes(a.key)).filter((a) => matchesVisibleWhen(a, row));
|
|
16303
|
-
}, [config.rowActions, row, allowed]);
|
|
16351
|
+
}, [config.rowActions, row, allowed, gastada]);
|
|
16304
16352
|
const title = recordLabel ?? config.title ?? "Servicio";
|
|
16305
|
-
return /* @__PURE__ */ jsxs("div", { className: "px-chat-crud-item", children: [
|
|
16353
|
+
return /* @__PURE__ */ jsxs("div", { className: "px-chat-crud-item", ref: raiz, "data-panel-record": recordId, children: [
|
|
16306
16354
|
/* @__PURE__ */ jsx("div", { className: "px-chat-crud-item__header", children: title }),
|
|
16307
16355
|
crud.actionError && /* @__PURE__ */ jsxs("div", { className: "px-chat-crud-item__error", role: "alert", children: [
|
|
16308
16356
|
/* @__PURE__ */ jsx("span", { children: crud.actionError }),
|
|
@@ -16310,6 +16358,7 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16310
16358
|
] }),
|
|
16311
16359
|
crud.loading && !row && /* @__PURE__ */ jsx("div", { className: "px-chat-crud-item__hint", children: "Cargando\u2026" }),
|
|
16312
16360
|
!crud.loading && !row && /* @__PURE__ */ jsx("div", { className: "px-chat-crud-item__hint", children: "No se encontr\xF3 el servicio." }),
|
|
16361
|
+
gastada && /* @__PURE__ */ jsx("div", { className: "px-chat-crud-item__hint", children: "Este paso ya se gestion\xF3. Contin\xFAa en el mensaje m\xE1s reciente." }),
|
|
16313
16362
|
row && config.deadline && typeof row[config.deadline.field] === "string" && /* @__PURE__ */ jsx(
|
|
16314
16363
|
DeadlineCountdown,
|
|
16315
16364
|
{
|
|
@@ -16878,6 +16927,11 @@ function fallbackTitle(item) {
|
|
|
16878
16927
|
if (Number.isNaN(d.getTime())) return "Chat";
|
|
16879
16928
|
return `Chat del ${String(d.getDate()).padStart(2, "0")}/${String(d.getMonth() + 1).padStart(2, "0")}`;
|
|
16880
16929
|
}
|
|
16930
|
+
function campo(item, field) {
|
|
16931
|
+
if (!field) return "";
|
|
16932
|
+
const v = item[field];
|
|
16933
|
+
return v == null || v === "" ? "" : String(v);
|
|
16934
|
+
}
|
|
16881
16935
|
function relativeTime(raw) {
|
|
16882
16936
|
if (!raw) return "";
|
|
16883
16937
|
const d = new Date(raw);
|
|
@@ -16976,6 +17030,25 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
16976
17030
|
const listaRef = useRef(null);
|
|
16977
17031
|
const loadRef = useRef(load);
|
|
16978
17032
|
loadRef.current = load;
|
|
17033
|
+
useEffect(() => {
|
|
17034
|
+
const host = listaRef.current;
|
|
17035
|
+
const scroller = host?.querySelector(".px-chat-chat-navigator__list");
|
|
17036
|
+
if (!scroller) return;
|
|
17037
|
+
const MARGEN = 8;
|
|
17038
|
+
const revisar = () => {
|
|
17039
|
+
scroller.dataset.desvaneceArriba = scroller.scrollTop > MARGEN ? "1" : "";
|
|
17040
|
+
const abajo = scroller.scrollHeight - scroller.clientHeight - scroller.scrollTop;
|
|
17041
|
+
scroller.dataset.desvaneceAbajo = abajo > MARGEN ? "1" : "";
|
|
17042
|
+
};
|
|
17043
|
+
revisar();
|
|
17044
|
+
scroller.addEventListener("scroll", revisar, { passive: true });
|
|
17045
|
+
const ro = new ResizeObserver(revisar);
|
|
17046
|
+
ro.observe(scroller);
|
|
17047
|
+
return () => {
|
|
17048
|
+
scroller.removeEventListener("scroll", revisar);
|
|
17049
|
+
ro.disconnect();
|
|
17050
|
+
};
|
|
17051
|
+
}, [items, loading]);
|
|
16979
17052
|
useEffect(() => {
|
|
16980
17053
|
if (!eventBus) return;
|
|
16981
17054
|
let t = null;
|
|
@@ -17021,6 +17094,82 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
17021
17094
|
};
|
|
17022
17095
|
const page = Math.floor(skip / pageSize) + 1;
|
|
17023
17096
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
17097
|
+
const bloques = useMemo(() => {
|
|
17098
|
+
const field = config.group?.field;
|
|
17099
|
+
const out = [];
|
|
17100
|
+
items.forEach((item) => {
|
|
17101
|
+
const clave = campo(item, field);
|
|
17102
|
+
const ultimo = out[out.length - 1];
|
|
17103
|
+
if (clave && ultimo && ultimo.agrupado && ultimo.clave === clave) {
|
|
17104
|
+
ultimo.chats.push(item);
|
|
17105
|
+
return;
|
|
17106
|
+
}
|
|
17107
|
+
out.push({ clave: clave || item.id, agrupado: !!clave, chats: [item] });
|
|
17108
|
+
});
|
|
17109
|
+
return out;
|
|
17110
|
+
}, [items, config.group?.field]);
|
|
17111
|
+
const insigniaEstado = (valor) => {
|
|
17112
|
+
if (!valor) return null;
|
|
17113
|
+
const opt = (config.serviceStatusOptions ?? []).find((o) => o.value === valor);
|
|
17114
|
+
const c = opt?.color;
|
|
17115
|
+
return /* @__PURE__ */ jsx(
|
|
17116
|
+
"span",
|
|
17117
|
+
{
|
|
17118
|
+
className: "px-chat-chat-navigator__service-badge",
|
|
17119
|
+
style: c ? { color: c, background: `${c}22`, borderColor: `${c}55` } : void 0,
|
|
17120
|
+
children: opt?.label ?? valor
|
|
17121
|
+
}
|
|
17122
|
+
);
|
|
17123
|
+
};
|
|
17124
|
+
const contador = (item) => item.unread_proactive_count && item.unread_proactive_count >= 1 ? /* @__PURE__ */ jsx(
|
|
17125
|
+
"span",
|
|
17126
|
+
{
|
|
17127
|
+
className: "px-chat-chat-navigator__badge-count",
|
|
17128
|
+
"aria-label": `${item.unread_proactive_count} mensajes nuevos sin leer`,
|
|
17129
|
+
title: `${item.unread_proactive_count} sin leer`,
|
|
17130
|
+
children: item.unread_proactive_count >= 100 ? "100+" : item.unread_proactive_count
|
|
17131
|
+
}
|
|
17132
|
+
) : null;
|
|
17133
|
+
const tarjeta = (bloque) => {
|
|
17134
|
+
const g = config.group;
|
|
17135
|
+
const primero = bloque.chats[0];
|
|
17136
|
+
const titulo = campo(primero, g.titleField) || primero.title?.trim() || fallbackTitle(primero);
|
|
17137
|
+
const subtitulo = (g.subtitleFields ?? []).map((f) => campo(primero, f)).filter(Boolean).join(" \xB7 ");
|
|
17138
|
+
const reciente = bloque.chats.reduce(
|
|
17139
|
+
(max, c) => !max || c.updated_date && c.updated_date > max ? c.updated_date : max,
|
|
17140
|
+
null
|
|
17141
|
+
);
|
|
17142
|
+
return /* @__PURE__ */ jsxs("li", { className: "px-chat-chat-navigator__item px-chat-chat-navigator__item--card", children: [
|
|
17143
|
+
/* @__PURE__ */ jsxs("div", { className: "px-chat-chat-navigator__card-head", children: [
|
|
17144
|
+
/* @__PURE__ */ jsx("span", { className: "px-chat-chat-navigator__title", children: titulo }),
|
|
17145
|
+
insigniaEstado(campo(primero, g.statusField))
|
|
17146
|
+
] }),
|
|
17147
|
+
/* @__PURE__ */ jsxs("div", { className: "px-chat-chat-navigator__card-sub", children: [
|
|
17148
|
+
subtitulo ? /* @__PURE__ */ jsx("span", { className: "px-chat-chat-navigator__card-detail", children: subtitulo }) : null,
|
|
17149
|
+
/* @__PURE__ */ jsx("span", { className: "px-chat-chat-navigator__time", children: relativeTime(reciente) })
|
|
17150
|
+
] }),
|
|
17151
|
+
/* @__PURE__ */ jsx("div", { className: "px-chat-chat-navigator__doors", children: bloque.chats.map((chat) => {
|
|
17152
|
+
const opt = (config.tagOptions ?? []).find(
|
|
17153
|
+
(o) => o.value === campo(chat, config.tagField)
|
|
17154
|
+
);
|
|
17155
|
+
return /* @__PURE__ */ jsxs(
|
|
17156
|
+
"button",
|
|
17157
|
+
{
|
|
17158
|
+
type: "button",
|
|
17159
|
+
className: "px-chat-chat-navigator__door",
|
|
17160
|
+
style: opt?.color ? { "--px-door-color": opt.color } : void 0,
|
|
17161
|
+
onClick: () => open(chat),
|
|
17162
|
+
children: [
|
|
17163
|
+
opt?.label ?? chat.title?.trim() ?? "Abrir",
|
|
17164
|
+
contador(chat),
|
|
17165
|
+
chat.closed ? /* @__PURE__ */ jsx("span", { className: "px-chat-chat-navigator__door-closed", "aria-hidden": "true" }) : null
|
|
17166
|
+
]
|
|
17167
|
+
},
|
|
17168
|
+
chat.id
|
|
17169
|
+
);
|
|
17170
|
+
}) })
|
|
17171
|
+
] }, bloque.clave);
|
|
17172
|
+
};
|
|
17024
17173
|
return /* @__PURE__ */ jsxs("div", { className: "px-chat-chat-navigator", children: [
|
|
17025
17174
|
config.search && /* @__PURE__ */ jsxs("div", { className: "px-chat-chat-navigator__search", children: [
|
|
17026
17175
|
/* @__PURE__ */ 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: [
|
|
@@ -17101,7 +17250,9 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
17101
17250
|
error && !loading && /* @__PURE__ */ jsx("div", { className: "px-chat-chat-navigator__state px-chat-chat-navigator__state--error", children: error }),
|
|
17102
17251
|
!loading && !error && items.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-chat-chat-navigator__state", children: labels.emptyText ?? "Sin conversaciones" }),
|
|
17103
17252
|
/* @__PURE__ */ jsxs("div", { className: "px-chat-chat-navigator__list-wrap", ref: listaRef, children: [
|
|
17104
|
-
/* @__PURE__ */ jsx("ul", { className: "px-chat-chat-navigator__list", children:
|
|
17253
|
+
/* @__PURE__ */ jsx("ul", { className: "px-chat-chat-navigator__list", children: bloques.map((bloque) => {
|
|
17254
|
+
if (bloque.agrupado) return tarjeta(bloque);
|
|
17255
|
+
const item = bloque.chats[0];
|
|
17105
17256
|
const isRenaming = renamingId === item.id;
|
|
17106
17257
|
const displayTitle = item.title?.trim() || fallbackTitle(item);
|
|
17107
17258
|
return /* @__PURE__ */ jsxs("li", { className: "px-chat-chat-navigator__item", children: [
|
|
@@ -17128,18 +17279,10 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
17128
17279
|
) : /* @__PURE__ */ jsxs("button", { type: "button", className: "px-chat-chat-navigator__open", onClick: () => open(item), children: [
|
|
17129
17280
|
/* @__PURE__ */ jsxs("span", { className: "px-chat-chat-navigator__title", children: [
|
|
17130
17281
|
displayTitle,
|
|
17131
|
-
item
|
|
17132
|
-
"span",
|
|
17133
|
-
{
|
|
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
|
|
17138
|
-
}
|
|
17139
|
-
) : null
|
|
17282
|
+
contador(item)
|
|
17140
17283
|
] }),
|
|
17141
17284
|
/* @__PURE__ */ jsxs("span", { className: "px-chat-chat-navigator__meta", children: [
|
|
17142
|
-
item.agent_name ? /* @__PURE__ */ jsx("span", { className: "px-chat-chat-navigator__agent", children: item.agent_name }) : null,
|
|
17285
|
+
item.agent_name && config.showAgent !== false ? /* @__PURE__ */ jsx("span", { className: "px-chat-chat-navigator__agent", children: item.agent_name }) : null,
|
|
17143
17286
|
/* @__PURE__ */ jsx("span", { className: "px-chat-chat-navigator__time", children: relativeTime(item.updated_date) }),
|
|
17144
17287
|
(() => {
|
|
17145
17288
|
const opt = item.rol_code ? (config.originActorOptions ?? []).find((o) => o.value === item.rol_code) : void 0;
|
package/dist/index.js
CHANGED
|
@@ -5760,6 +5760,9 @@ const LUMI_ICON_TYPES = {
|
|
|
5760
5760
|
// Iconos para Agenda
|
|
5761
5761
|
USER_X: "user-x",
|
|
5762
5762
|
REFRESH: "refresh",
|
|
5763
|
+
// SPEC-104 — grúas: el selector de despacho necesitaba distinguir de un vistazo qué es cada
|
|
5764
|
+
// opción, y no había ningún icono de vehículo en el set.
|
|
5765
|
+
TRUCK: "truck",
|
|
5763
5766
|
// Iconos para Chat
|
|
5764
5767
|
MESSAGE_SQUARE: "message-square",
|
|
5765
5768
|
MESSAGE_CIRCLE: "message-circle",
|
|
@@ -6470,6 +6473,27 @@ const BuildingIcon = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
|
6470
6473
|
]
|
|
6471
6474
|
}
|
|
6472
6475
|
);
|
|
6476
|
+
const TruckIcon = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6477
|
+
"svg",
|
|
6478
|
+
{
|
|
6479
|
+
width: "16",
|
|
6480
|
+
height: "16",
|
|
6481
|
+
viewBox: "0 0 24 24",
|
|
6482
|
+
fill: "none",
|
|
6483
|
+
stroke: "currentColor",
|
|
6484
|
+
strokeWidth: "2",
|
|
6485
|
+
strokeLinecap: "round",
|
|
6486
|
+
strokeLinejoin: "round",
|
|
6487
|
+
...props,
|
|
6488
|
+
children: [
|
|
6489
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 17V8h10v9" }),
|
|
6490
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 11h4l3 3v3" }),
|
|
6491
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "18", r: "2" }),
|
|
6492
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "17", cy: "18", r: "2" }),
|
|
6493
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 18h6" })
|
|
6494
|
+
]
|
|
6495
|
+
}
|
|
6496
|
+
);
|
|
6473
6497
|
const MapPinIcon = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6474
6498
|
"svg",
|
|
6475
6499
|
{
|
|
@@ -6588,6 +6612,7 @@ const lumiIconMap = {
|
|
|
6588
6612
|
// Iconos para Servicios
|
|
6589
6613
|
[LUMI_ICON_TYPES.BUILDING]: BuildingIcon,
|
|
6590
6614
|
[LUMI_ICON_TYPES.MAP_PIN]: MapPinIcon,
|
|
6615
|
+
[LUMI_ICON_TYPES.TRUCK]: TruckIcon,
|
|
6591
6616
|
// Iconos para Agenda
|
|
6592
6617
|
[LUMI_ICON_TYPES.USER_X]: UserXIcon,
|
|
6593
6618
|
[LUMI_ICON_TYPES.REFRESH]: RefreshIcon,
|
|
@@ -7759,8 +7784,11 @@ const Select$1 = React.forwardRef(
|
|
|
7759
7784
|
`${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__checkbox`,
|
|
7760
7785
|
isSelected && `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__checkbox--checked`
|
|
7761
7786
|
].filter(Boolean).join(" "), children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: LUMI_ICON_TYPES.CHECK, size: "small" }) }) }),
|
|
7762
|
-
option.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-icon`, children: option.icon }),
|
|
7763
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7787
|
+
(option.icon || option.iconName) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-icon`, children: option.icon ?? /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: option.iconName }) }),
|
|
7788
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-texts`, children: [
|
|
7789
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-label`, children: option.label }),
|
|
7790
|
+
option.sublabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-sublabel`, children: option.sublabel })
|
|
7791
|
+
] }),
|
|
7764
7792
|
mode === "single" && isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${COMPONENT_PREFIX}${COMPONENT_TYPES.SELECT}__option-check`, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: LUMI_ICON_TYPES.CHECK, size: "small" }) })
|
|
7765
7793
|
]
|
|
7766
7794
|
},
|
|
@@ -14132,7 +14160,9 @@ async function loadOptions(eventBus, ep, ctx) {
|
|
|
14132
14160
|
const arr = Array.isArray(data) ? data : [];
|
|
14133
14161
|
return arr.map((item) => ({
|
|
14134
14162
|
value: String(item[ep.value_field] ?? ""),
|
|
14135
|
-
label: String(item[ep.label_field] ?? "")
|
|
14163
|
+
label: String(item[ep.label_field] ?? ""),
|
|
14164
|
+
...item.sublabel ? { sublabel: String(item.sublabel) } : {},
|
|
14165
|
+
...item.icon ? { iconName: String(item.icon) } : {}
|
|
14136
14166
|
}));
|
|
14137
14167
|
}
|
|
14138
14168
|
|
|
@@ -15959,9 +15989,12 @@ function toRenderField(f, loaded, eventBus, mapsApiKey) {
|
|
|
15959
15989
|
formatValue
|
|
15960
15990
|
};
|
|
15961
15991
|
}
|
|
15992
|
+
const cumpleCondicion = (c, row) => c.in.includes(String(row[c.field]));
|
|
15993
|
+
const cumplenTodas = (c, row) => (Array.isArray(c) ? c : [c]).every((x) => cumpleCondicion(x, row));
|
|
15962
15994
|
function matchesVisibleWhen(a, row) {
|
|
15995
|
+
if (a.hiddenWhen && cumplenTodas(a.hiddenWhen, row)) return false;
|
|
15963
15996
|
if (!a.visibleWhen) return true;
|
|
15964
|
-
return a.visibleWhen
|
|
15997
|
+
return cumplenTodas(a.visibleWhen, row);
|
|
15965
15998
|
}
|
|
15966
15999
|
function matchesDisabledWhen(a, row) {
|
|
15967
16000
|
if (!a.disabledWhen) return false;
|
|
@@ -16318,12 +16351,27 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16318
16351
|
() => crud.rows.find((r) => String(r[config.idField]) === recordId),
|
|
16319
16352
|
[crud.rows, config.idField, recordId]
|
|
16320
16353
|
);
|
|
16354
|
+
const raiz = React.useRef(null);
|
|
16355
|
+
const [esUltima, setEsUltima] = React.useState(true);
|
|
16356
|
+
React.useEffect(() => {
|
|
16357
|
+
const calcular = () => {
|
|
16358
|
+
const el = raiz.current;
|
|
16359
|
+
if (!el) return;
|
|
16360
|
+
const hermanas = document.querySelectorAll(`[data-panel-record="${recordId}"]`);
|
|
16361
|
+
setEsUltima(hermanas.length === 0 || hermanas[hermanas.length - 1] === el);
|
|
16362
|
+
};
|
|
16363
|
+
calcular();
|
|
16364
|
+
const observador = new MutationObserver(calcular);
|
|
16365
|
+
observador.observe(document.body, { childList: true, subtree: true });
|
|
16366
|
+
return () => observador.disconnect();
|
|
16367
|
+
}, [recordId]);
|
|
16368
|
+
const gastada = !esUltima;
|
|
16321
16369
|
const actions = React.useMemo(() => {
|
|
16322
|
-
if (!row) return [];
|
|
16370
|
+
if (!row || gastada) return [];
|
|
16323
16371
|
return (config.rowActions ?? []).filter((a) => !allowed || allowed.includes(a.key)).filter((a) => matchesVisibleWhen(a, row));
|
|
16324
|
-
}, [config.rowActions, row, allowed]);
|
|
16372
|
+
}, [config.rowActions, row, allowed, gastada]);
|
|
16325
16373
|
const title = recordLabel ?? config.title ?? "Servicio";
|
|
16326
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-crud-item", children: [
|
|
16374
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-crud-item", ref: raiz, "data-panel-record": recordId, children: [
|
|
16327
16375
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__header", children: title }),
|
|
16328
16376
|
crud.actionError && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-crud-item__error", role: "alert", children: [
|
|
16329
16377
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: crud.actionError }),
|
|
@@ -16331,6 +16379,7 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16331
16379
|
] }),
|
|
16332
16380
|
crud.loading && !row && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__hint", children: "Cargando\u2026" }),
|
|
16333
16381
|
!crud.loading && !row && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-crud-item__hint", children: "No se encontr\xF3 el servicio." }),
|
|
16382
|
+
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." }),
|
|
16334
16383
|
row && config.deadline && typeof row[config.deadline.field] === "string" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
16335
16384
|
DeadlineCountdown,
|
|
16336
16385
|
{
|
|
@@ -16899,6 +16948,11 @@ function fallbackTitle(item) {
|
|
|
16899
16948
|
if (Number.isNaN(d.getTime())) return "Chat";
|
|
16900
16949
|
return `Chat del ${String(d.getDate()).padStart(2, "0")}/${String(d.getMonth() + 1).padStart(2, "0")}`;
|
|
16901
16950
|
}
|
|
16951
|
+
function campo(item, field) {
|
|
16952
|
+
if (!field) return "";
|
|
16953
|
+
const v = item[field];
|
|
16954
|
+
return v == null || v === "" ? "" : String(v);
|
|
16955
|
+
}
|
|
16902
16956
|
function relativeTime(raw) {
|
|
16903
16957
|
if (!raw) return "";
|
|
16904
16958
|
const d = new Date(raw);
|
|
@@ -16997,6 +17051,25 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
16997
17051
|
const listaRef = React.useRef(null);
|
|
16998
17052
|
const loadRef = React.useRef(load);
|
|
16999
17053
|
loadRef.current = load;
|
|
17054
|
+
React.useEffect(() => {
|
|
17055
|
+
const host = listaRef.current;
|
|
17056
|
+
const scroller = host?.querySelector(".px-chat-chat-navigator__list");
|
|
17057
|
+
if (!scroller) return;
|
|
17058
|
+
const MARGEN = 8;
|
|
17059
|
+
const revisar = () => {
|
|
17060
|
+
scroller.dataset.desvaneceArriba = scroller.scrollTop > MARGEN ? "1" : "";
|
|
17061
|
+
const abajo = scroller.scrollHeight - scroller.clientHeight - scroller.scrollTop;
|
|
17062
|
+
scroller.dataset.desvaneceAbajo = abajo > MARGEN ? "1" : "";
|
|
17063
|
+
};
|
|
17064
|
+
revisar();
|
|
17065
|
+
scroller.addEventListener("scroll", revisar, { passive: true });
|
|
17066
|
+
const ro = new ResizeObserver(revisar);
|
|
17067
|
+
ro.observe(scroller);
|
|
17068
|
+
return () => {
|
|
17069
|
+
scroller.removeEventListener("scroll", revisar);
|
|
17070
|
+
ro.disconnect();
|
|
17071
|
+
};
|
|
17072
|
+
}, [items, loading]);
|
|
17000
17073
|
React.useEffect(() => {
|
|
17001
17074
|
if (!eventBus) return;
|
|
17002
17075
|
let t = null;
|
|
@@ -17042,6 +17115,82 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
17042
17115
|
};
|
|
17043
17116
|
const page = Math.floor(skip / pageSize) + 1;
|
|
17044
17117
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
17118
|
+
const bloques = React.useMemo(() => {
|
|
17119
|
+
const field = config.group?.field;
|
|
17120
|
+
const out = [];
|
|
17121
|
+
items.forEach((item) => {
|
|
17122
|
+
const clave = campo(item, field);
|
|
17123
|
+
const ultimo = out[out.length - 1];
|
|
17124
|
+
if (clave && ultimo && ultimo.agrupado && ultimo.clave === clave) {
|
|
17125
|
+
ultimo.chats.push(item);
|
|
17126
|
+
return;
|
|
17127
|
+
}
|
|
17128
|
+
out.push({ clave: clave || item.id, agrupado: !!clave, chats: [item] });
|
|
17129
|
+
});
|
|
17130
|
+
return out;
|
|
17131
|
+
}, [items, config.group?.field]);
|
|
17132
|
+
const insigniaEstado = (valor) => {
|
|
17133
|
+
if (!valor) return null;
|
|
17134
|
+
const opt = (config.serviceStatusOptions ?? []).find((o) => o.value === valor);
|
|
17135
|
+
const c = opt?.color;
|
|
17136
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17137
|
+
"span",
|
|
17138
|
+
{
|
|
17139
|
+
className: "px-chat-chat-navigator__service-badge",
|
|
17140
|
+
style: c ? { color: c, background: `${c}22`, borderColor: `${c}55` } : void 0,
|
|
17141
|
+
children: opt?.label ?? valor
|
|
17142
|
+
}
|
|
17143
|
+
);
|
|
17144
|
+
};
|
|
17145
|
+
const contador = (item) => item.unread_proactive_count && item.unread_proactive_count >= 1 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
17146
|
+
"span",
|
|
17147
|
+
{
|
|
17148
|
+
className: "px-chat-chat-navigator__badge-count",
|
|
17149
|
+
"aria-label": `${item.unread_proactive_count} mensajes nuevos sin leer`,
|
|
17150
|
+
title: `${item.unread_proactive_count} sin leer`,
|
|
17151
|
+
children: item.unread_proactive_count >= 100 ? "100+" : item.unread_proactive_count
|
|
17152
|
+
}
|
|
17153
|
+
) : null;
|
|
17154
|
+
const tarjeta = (bloque) => {
|
|
17155
|
+
const g = config.group;
|
|
17156
|
+
const primero = bloque.chats[0];
|
|
17157
|
+
const titulo = campo(primero, g.titleField) || primero.title?.trim() || fallbackTitle(primero);
|
|
17158
|
+
const subtitulo = (g.subtitleFields ?? []).map((f) => campo(primero, f)).filter(Boolean).join(" \xB7 ");
|
|
17159
|
+
const reciente = bloque.chats.reduce(
|
|
17160
|
+
(max, c) => !max || c.updated_date && c.updated_date > max ? c.updated_date : max,
|
|
17161
|
+
null
|
|
17162
|
+
);
|
|
17163
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "px-chat-chat-navigator__item px-chat-chat-navigator__item--card", children: [
|
|
17164
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator__card-head", children: [
|
|
17165
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__title", children: titulo }),
|
|
17166
|
+
insigniaEstado(campo(primero, g.statusField))
|
|
17167
|
+
] }),
|
|
17168
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator__card-sub", children: [
|
|
17169
|
+
subtitulo ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__card-detail", children: subtitulo }) : null,
|
|
17170
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__time", children: relativeTime(reciente) })
|
|
17171
|
+
] }),
|
|
17172
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-chat-navigator__doors", children: bloque.chats.map((chat) => {
|
|
17173
|
+
const opt = (config.tagOptions ?? []).find(
|
|
17174
|
+
(o) => o.value === campo(chat, config.tagField)
|
|
17175
|
+
);
|
|
17176
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17177
|
+
"button",
|
|
17178
|
+
{
|
|
17179
|
+
type: "button",
|
|
17180
|
+
className: "px-chat-chat-navigator__door",
|
|
17181
|
+
style: opt?.color ? { "--px-door-color": opt.color } : void 0,
|
|
17182
|
+
onClick: () => open(chat),
|
|
17183
|
+
children: [
|
|
17184
|
+
opt?.label ?? chat.title?.trim() ?? "Abrir",
|
|
17185
|
+
contador(chat),
|
|
17186
|
+
chat.closed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__door-closed", "aria-hidden": "true" }) : null
|
|
17187
|
+
]
|
|
17188
|
+
},
|
|
17189
|
+
chat.id
|
|
17190
|
+
);
|
|
17191
|
+
}) })
|
|
17192
|
+
] }, bloque.clave);
|
|
17193
|
+
};
|
|
17045
17194
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator", children: [
|
|
17046
17195
|
config.search && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator__search", children: [
|
|
17047
17196
|
/* @__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: [
|
|
@@ -17122,7 +17271,9 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
17122
17271
|
error && !loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-chat-navigator__state px-chat-chat-navigator__state--error", children: error }),
|
|
17123
17272
|
!loading && !error && items.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-chat-chat-navigator__state", children: labels.emptyText ?? "Sin conversaciones" }),
|
|
17124
17273
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-chat-chat-navigator__list-wrap", ref: listaRef, children: [
|
|
17125
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "px-chat-chat-navigator__list", children:
|
|
17274
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "px-chat-chat-navigator__list", children: bloques.map((bloque) => {
|
|
17275
|
+
if (bloque.agrupado) return tarjeta(bloque);
|
|
17276
|
+
const item = bloque.chats[0];
|
|
17126
17277
|
const isRenaming = renamingId === item.id;
|
|
17127
17278
|
const displayTitle = item.title?.trim() || fallbackTitle(item);
|
|
17128
17279
|
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "px-chat-chat-navigator__item", children: [
|
|
@@ -17149,18 +17300,10 @@ function ChatNavigator({ config, eventBus }) {
|
|
|
17149
17300
|
) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: "px-chat-chat-navigator__open", onClick: () => open(item), children: [
|
|
17150
17301
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-chat-navigator__title", children: [
|
|
17151
17302
|
displayTitle,
|
|
17152
|
-
item
|
|
17153
|
-
"span",
|
|
17154
|
-
{
|
|
17155
|
-
className: "px-chat-chat-navigator__badge-count",
|
|
17156
|
-
"aria-label": `${item.unread_proactive_count} mensajes nuevos sin leer`,
|
|
17157
|
-
title: `${item.unread_proactive_count} sin leer`,
|
|
17158
|
-
children: item.unread_proactive_count >= 100 ? "100+" : item.unread_proactive_count
|
|
17159
|
-
}
|
|
17160
|
-
) : null
|
|
17303
|
+
contador(item)
|
|
17161
17304
|
] }),
|
|
17162
17305
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-chat-navigator__meta", children: [
|
|
17163
|
-
item.agent_name ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__agent", children: item.agent_name }) : null,
|
|
17306
|
+
item.agent_name && config.showAgent !== false ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__agent", children: item.agent_name }) : null,
|
|
17164
17307
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-chat-navigator__time", children: relativeTime(item.updated_date) }),
|
|
17165
17308
|
(() => {
|
|
17166
17309
|
const opt = item.rol_code ? (config.originActorOptions ?? []).find((o) => o.value === item.rol_code) : void 0;
|