pixelon 0.3.83 → 0.4.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/index.d.ts +0 -1
- package/dist/components/molecules/chat/StructuredContent/helpers/componentRegistry.d.ts +13 -0
- package/dist/core/chat/ChatConfigContext.d.ts +13 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.esm.js +40 -196
- package/dist/index.js +47 -195
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
- package/src/styles/index.scss +0 -1
|
@@ -13,7 +13,6 @@ export { ActionMenu } from './ActionMenu/ActionMenu';
|
|
|
13
13
|
export { ReactiveCrud } from './ReactiveCrud/ReactiveCrud';
|
|
14
14
|
export { ReactiveCrudChat } from './ReactiveCrud/ReactiveCrudChat';
|
|
15
15
|
export { ReactiveCrudItemChat } from './ReactiveCrud/ReactiveCrudItemChat';
|
|
16
|
-
export { PriceNegotiationChat } from './ReactiveCrud/PriceNegotiationChat';
|
|
17
16
|
export { MapView } from './MapView/MapView';
|
|
18
17
|
export { MapViewChat } from './MapView/MapViewChat';
|
|
19
18
|
export type { MapPoint, MapViewProps, MapViewLabels } from './MapView/types';
|
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ChatComponentProps } from './types';
|
|
3
|
+
export interface HostChatComponent {
|
|
4
|
+
render: React.FC<ChatComponentProps>;
|
|
5
|
+
/** No se oculta al llegar a un estado terminal (paneles y navegación, no acciones de un uso). */
|
|
6
|
+
persistent?: boolean;
|
|
7
|
+
/** Contenido del autor, sin interacción: nunca se oculta al re-hidratar el historial. */
|
|
8
|
+
pureDisplay?: boolean;
|
|
9
|
+
}
|
|
10
|
+
type EntradaHost = React.FC<ChatComponentProps> | HostChatComponent;
|
|
11
|
+
/** Registra componentes del consumidor. Se llama una vez, al arrancar la app. */
|
|
12
|
+
export declare function registerChatComponents(comps: Record<string, EntradaHost>): void;
|
|
13
|
+
/** Vacía el registro del host. Para tests: sin esto un caso contamina al siguiente. */
|
|
14
|
+
export declare function clearChatComponents(): void;
|
|
3
15
|
export declare function renderComponent(props: ChatComponentProps): React.ReactNode;
|
|
16
|
+
export {};
|
|
@@ -6,6 +6,19 @@ export interface ChatCurrency {
|
|
|
6
6
|
symbol?: string;
|
|
7
7
|
}
|
|
8
8
|
export interface ChatConfig {
|
|
9
|
+
/** SPEC-107 — esta conversación es de OTRO: se lee, no se opera.
|
|
10
|
+
*
|
|
11
|
+
* Las cards del chat llevan acciones que ejecutan de verdad —aceptar una cotización, confirmar
|
|
12
|
+
* un pago, asignar—. Estando dentro de la conversación de otro rol, pulsarlas es actuar en su
|
|
13
|
+
* nombre. `readOnly` no sirve para decidirlo: mezcla «cerrado», «del sistema» y «de otro», y los
|
|
14
|
+
* chats de servicio pertenecen a un usuario sintético, así que hasta el propio panel de la
|
|
15
|
+
* operadora sale como solo lectura.
|
|
16
|
+
*
|
|
17
|
+
* Viaja por config y no por evento porque el bus no guarda el último valor y estas cards nacen
|
|
18
|
+
* después de que se emita: no llegarían a oírlo. Por omisión, operable — una guarda que se cae
|
|
19
|
+
* sola es preferible a un panel que se apaga por una conexión mala; el backend sigue rechazando
|
|
20
|
+
* lo que no toca. */
|
|
21
|
+
chatIsForeign?: boolean;
|
|
9
22
|
/** IANA timezone identifier (e.g. "America/Bogota") */
|
|
10
23
|
timezone: string;
|
|
11
24
|
/** BCP 47 locale string (e.g. "es-CO") */
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export { default as ChatModal } from './components/molecules/chat/Modal/Modal';
|
|
|
25
25
|
export { default as ChatUserAttachments } from './components/molecules/chat/UserAttachments/UserAttachments';
|
|
26
26
|
export { default as ChatUserMessage } from './components/molecules/chat/UserMessage/UserMessage';
|
|
27
27
|
export { StructuredContent as ChatStructuredContent, type StructuredContentProps as ChatStructuredContentProps } from './components/molecules/chat/StructuredContent';
|
|
28
|
+
export { useReactiveCrud } from './components/molecules/chat/StructuredContent/components/ReactiveCrud/useReactiveCrud';
|
|
29
|
+
export { ActionFormDrawer } from './components/molecules/chat/StructuredContent/components/ReactiveCrud/ActionFormDrawer';
|
|
30
|
+
export { matchesVisibleWhen, matchesDisabledWhen, matchesDoneWhen, disabledReasonFor, } from './components/molecules/chat/StructuredContent/components/ReactiveCrud/ReactiveCrud';
|
|
31
|
+
export { registerChatComponents, clearChatComponents, type HostChatComponent, } from './components/molecules/chat/StructuredContent/helpers/componentRegistry';
|
|
32
|
+
export type { ChatComponentProps as ChatHostComponentProps } from './components/molecules/chat/StructuredContent/helpers/types';
|
|
28
33
|
export { ServiceShortcuts } from './components/molecules/chat/StructuredContent/components/ServiceShortcuts/ServiceShortcuts';
|
|
29
34
|
export type { ServiceShortcut, ServiceShortcutsProps } from './components/molecules/chat/StructuredContent/components/ServiceShortcuts/ServiceShortcuts';
|
|
30
35
|
export { ServicesMap } from './components/molecules/chat/StructuredContent/components/ServicesMap/ServicesMap';
|
package/dist/index.esm.js
CHANGED
|
@@ -1651,7 +1651,7 @@ function getSubmitActionId(component) {
|
|
|
1651
1651
|
}
|
|
1652
1652
|
const TERMINAL_STATUS = /* @__PURE__ */ new Set(["answered", "cancelled", "expired"]);
|
|
1653
1653
|
const DISPLAY_COMPONENTS = /* @__PURE__ */ new Set(["card", "badge", "reactive_form", "carousel"]);
|
|
1654
|
-
const PERSISTENT_COMPONENTS = /* @__PURE__ */ new Set(["reactive_crud", "reactive_crud_item", "
|
|
1654
|
+
const PERSISTENT_COMPONENTS = /* @__PURE__ */ new Set(["reactive_crud", "reactive_crud_item", "chat_navigator", "map_view", "user_tools"]);
|
|
1655
1655
|
const PURE_DISPLAY_COMPONENTS = /* @__PURE__ */ new Set(["card", "badge"]);
|
|
1656
1656
|
|
|
1657
1657
|
const AnsweredSummary = ({ component }) => {
|
|
@@ -16167,7 +16167,7 @@ function readCreated(messageId) {
|
|
|
16167
16167
|
}
|
|
16168
16168
|
}
|
|
16169
16169
|
function ReactiveCrudChat({ component, eventBus, assistantMessageId }) {
|
|
16170
|
-
const { resolveModuleConfig } = useChatConfig();
|
|
16170
|
+
const { resolveModuleConfig, chatIsForeign } = useChatConfig();
|
|
16171
16171
|
const [open, setOpen] = useState(false);
|
|
16172
16172
|
const [created, setCreated] = useState(() => readCreated(assistantMessageId));
|
|
16173
16173
|
const props = component.props ?? {};
|
|
@@ -16206,8 +16206,8 @@ function ReactiveCrudChat({ component, eventBus, assistantMessageId }) {
|
|
|
16206
16206
|
type: "button",
|
|
16207
16207
|
className: `px-chat-reactive-crud-trigger${done ? " px-chat-reactive-crud-trigger--done" : ""}`,
|
|
16208
16208
|
onClick: () => setOpen(true),
|
|
16209
|
-
disabled: done,
|
|
16210
|
-
"aria-disabled": done,
|
|
16209
|
+
disabled: done || Boolean(chatIsForeign),
|
|
16210
|
+
"aria-disabled": done || Boolean(chatIsForeign),
|
|
16211
16211
|
children: [
|
|
16212
16212
|
/* @__PURE__ */ jsx("span", { className: "px-chat-reactive-crud-trigger__icon", children: done ? /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
16213
16213
|
/* @__PURE__ */ jsx("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
|
|
@@ -16311,7 +16311,8 @@ function ReactiveCrudItemChat({ component, eventBus }) {
|
|
|
16311
16311
|
const moduleKey = pick("module");
|
|
16312
16312
|
const recordId = pick("record_id") ?? pick("recordId") ?? pick("id") ?? pick("service_id");
|
|
16313
16313
|
const recordLabel = pick("record_label") ?? pick("label");
|
|
16314
|
-
const
|
|
16314
|
+
const allowedRaw = pick("actions");
|
|
16315
|
+
const allowed = Array.isArray(allowedRaw) && allowedRaw.length > 0 ? allowedRaw : void 0;
|
|
16315
16316
|
const config = typeof moduleKey === "string" && resolveModuleConfig ? resolveModuleConfig(moduleKey) : void 0;
|
|
16316
16317
|
if (!config || recordId == null || recordId === "") return null;
|
|
16317
16318
|
return /* @__PURE__ */ jsx(
|
|
@@ -16326,6 +16327,7 @@ function ReactiveCrudItemChat({ component, eventBus }) {
|
|
|
16326
16327
|
);
|
|
16327
16328
|
}
|
|
16328
16329
|
function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus }) {
|
|
16330
|
+
const { chatIsForeign } = useChatConfig();
|
|
16329
16331
|
const crud = useReactiveCrud(config, eventBus);
|
|
16330
16332
|
const [activeAction, setActiveAction] = useState(null);
|
|
16331
16333
|
const [detailRow, setDetailRow] = useState(null);
|
|
@@ -16397,8 +16399,8 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16397
16399
|
row && /* @__PURE__ */ jsxs("div", { className: "px-chat-crud-item__actions", children: [
|
|
16398
16400
|
config.detail && /* @__PURE__ */ jsx("button", { type: "button", className: "px-chat-crud-item__action", onClick: () => setDetailRow(row), children: "Ver" }),
|
|
16399
16401
|
actions.map((a) => {
|
|
16400
|
-
const disabled = matchesDisabledWhen(a, row);
|
|
16401
|
-
const motivo = disabledReasonFor(a, row);
|
|
16402
|
+
const disabled = Boolean(chatIsForeign) || matchesDisabledWhen(a, row);
|
|
16403
|
+
const motivo = chatIsForeign ? "Esta conversaci\xF3n es de otra persona" : disabledReasonFor(a, row);
|
|
16402
16404
|
const done = matchesDoneWhen(a, row);
|
|
16403
16405
|
return /* @__PURE__ */ jsxs(
|
|
16404
16406
|
"button",
|
|
@@ -16439,107 +16441,6 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
|
|
|
16439
16441
|
] });
|
|
16440
16442
|
}
|
|
16441
16443
|
|
|
16442
|
-
const ACTOR_LABEL = { COLLA: "la empresa aliada", ADMIN: "la operadora" };
|
|
16443
|
-
const TURN_GATED = /* @__PURE__ */ new Set(["accept_price", "propose_price"]);
|
|
16444
|
-
function PriceNegotiationChat({ component, eventBus }) {
|
|
16445
|
-
const { resolveModuleConfig } = useChatConfig();
|
|
16446
|
-
const props = component.props ?? {};
|
|
16447
|
-
const top = component;
|
|
16448
|
-
const pick = (key) => props[key] !== void 0 ? props[key] : top[key];
|
|
16449
|
-
const moduleKey = pick("module");
|
|
16450
|
-
const recordId = pick("record_id") ?? pick("service_id") ?? pick("id");
|
|
16451
|
-
const recordLabel = pick("record_label") ?? pick("label");
|
|
16452
|
-
const allowed = pick("actions");
|
|
16453
|
-
const config = typeof moduleKey === "string" && resolveModuleConfig ? resolveModuleConfig(moduleKey) : void 0;
|
|
16454
|
-
if (!config || recordId == null || recordId === "") return null;
|
|
16455
|
-
return /* @__PURE__ */ jsx(
|
|
16456
|
-
NegotiationPanel,
|
|
16457
|
-
{
|
|
16458
|
-
config,
|
|
16459
|
-
recordId: String(recordId),
|
|
16460
|
-
recordLabel,
|
|
16461
|
-
allowed: Array.isArray(allowed) ? allowed.map(String) : void 0,
|
|
16462
|
-
eventBus
|
|
16463
|
-
}
|
|
16464
|
-
);
|
|
16465
|
-
}
|
|
16466
|
-
function NegotiationPanel({ config, recordId, recordLabel, allowed, eventBus }) {
|
|
16467
|
-
const crud = useReactiveCrud(config, eventBus);
|
|
16468
|
-
const [activeAction, setActiveAction] = useState(null);
|
|
16469
|
-
const row = useMemo(
|
|
16470
|
-
() => crud.rows.find((r) => String(r[config.idField]) === recordId),
|
|
16471
|
-
[crud.rows, config.idField, recordId]
|
|
16472
|
-
);
|
|
16473
|
-
const actions = useMemo(() => {
|
|
16474
|
-
if (!row) return [];
|
|
16475
|
-
return (config.rowActions ?? []).filter((a) => !allowed || allowed.includes(a.key)).filter((a) => matchesVisibleWhen(a, row));
|
|
16476
|
-
}, [config.rowActions, row, allowed]);
|
|
16477
|
-
const title = recordLabel ?? config.title ?? "Servicio";
|
|
16478
|
-
const proposed = row?.proposed_price;
|
|
16479
|
-
const proposer = row?.price_proposed_by;
|
|
16480
|
-
const myTurn = row?.my_turn === true || String(row?.my_turn) === "true";
|
|
16481
|
-
const hasOffer = proposed != null && proposed !== "";
|
|
16482
|
-
const canPropose = !allowed || allowed.includes("propose_price");
|
|
16483
|
-
const agreed = row?.price_amount;
|
|
16484
|
-
const esperandoRespuesta = ["QUOTED", "PRE_ASSIGNED"].includes(String(row?.status ?? ""));
|
|
16485
|
-
const cerrada = !esperandoRespuesta && agreed != null && agreed !== "";
|
|
16486
|
-
const ofertaMia = hasOffer && !myTurn;
|
|
16487
|
-
const quienOfrece = ofertaMia ? "tu oferta" : `oferta de ${ACTOR_LABEL[proposer ?? ""] ?? "la otra parte"}`;
|
|
16488
|
-
return /* @__PURE__ */ jsxs("div", { className: "px-chat-price-neg", children: [
|
|
16489
|
-
/* @__PURE__ */ jsxs("div", { className: "px-chat-price-neg__header", children: [
|
|
16490
|
-
/* @__PURE__ */ jsx("span", { className: "px-chat-price-neg__title", children: title }),
|
|
16491
|
-
/* @__PURE__ */ jsx("span", { className: `px-chat-price-neg__badge${cerrada ? " is-closed" : ""}`, children: cerrada ? "Precio acordado" : canPropose ? "Negociaci\xF3n de precio" : "Cotizaci\xF3n" })
|
|
16492
|
-
] }),
|
|
16493
|
-
crud.actionError && /* @__PURE__ */ jsxs("div", { className: "px-chat-price-neg__error", role: "alert", children: [
|
|
16494
|
-
/* @__PURE__ */ jsx("span", { children: crud.actionError }),
|
|
16495
|
-
/* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Cerrar", onClick: crud.clearActionError, children: "\u2715" })
|
|
16496
|
-
] }),
|
|
16497
|
-
crud.loading && !row && /* @__PURE__ */ jsx("div", { className: "px-chat-price-neg__hint", children: "Cargando\u2026" }),
|
|
16498
|
-
!crud.loading && !row && /* @__PURE__ */ jsx("div", { className: "px-chat-price-neg__hint", children: "No se encontr\xF3 el servicio." }),
|
|
16499
|
-
row && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
16500
|
-
/* @__PURE__ */ jsx("div", { className: "px-chat-price-neg__offer", children: cerrada ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
16501
|
-
/* @__PURE__ */ jsx("span", { className: "px-chat-price-neg__amount", children: /* @__PURE__ */ jsx(CurrencyDisplay, { value: agreed }) }),
|
|
16502
|
-
/* @__PURE__ */ jsx("span", { className: "px-chat-price-neg__by", children: "precio acordado" })
|
|
16503
|
-
] }) : hasOffer ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
16504
|
-
/* @__PURE__ */ jsx("span", { className: "px-chat-price-neg__amount", children: /* @__PURE__ */ jsx(CurrencyDisplay, { value: proposed }) }),
|
|
16505
|
-
/* @__PURE__ */ jsx("span", { className: "px-chat-price-neg__by", children: canPropose ? quienOfrece : "costo del servicio" })
|
|
16506
|
-
] }) : /* @__PURE__ */ jsx("span", { className: "px-chat-price-neg__by", children: "A\xFAn no hay una oferta. Prop\xF3n un valor." }) }),
|
|
16507
|
-
!cerrada && /* @__PURE__ */ jsx("div", { className: `px-chat-price-neg__turn${myTurn ? " is-mine" : ""}`, children: myTurn ? canPropose ? "Es tu turno: acepta o contraprop\xF3n." : "Es tu turno: acepta o rechaza." : "Esperando la respuesta de la otra parte\u2026" }),
|
|
16508
|
-
!cerrada && /* @__PURE__ */ jsxs("div", { className: "px-chat-price-neg__actions", children: [
|
|
16509
|
-
actions.map((a) => {
|
|
16510
|
-
const gated = TURN_GATED.has(a.key) && !myTurn;
|
|
16511
|
-
const noOffer = a.key === "accept_price" && !hasOffer;
|
|
16512
|
-
const disabled = gated || noOffer;
|
|
16513
|
-
return /* @__PURE__ */ jsx(
|
|
16514
|
-
"button",
|
|
16515
|
-
{
|
|
16516
|
-
type: "button",
|
|
16517
|
-
className: `px-chat-price-neg__action${a.intent === "danger" ? " is-danger" : a.key === "accept_price" ? " is-primary" : ""}`,
|
|
16518
|
-
disabled,
|
|
16519
|
-
title: gated ? "Esperando la respuesta de la otra parte" : void 0,
|
|
16520
|
-
onClick: () => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] }),
|
|
16521
|
-
children: a.label
|
|
16522
|
-
},
|
|
16523
|
-
a.key
|
|
16524
|
-
);
|
|
16525
|
-
}),
|
|
16526
|
-
actions.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-chat-price-neg__hint", children: "Sin acciones disponibles." })
|
|
16527
|
-
] })
|
|
16528
|
-
] }),
|
|
16529
|
-
activeAction && /* @__PURE__ */ jsx(
|
|
16530
|
-
ActionFormDrawer,
|
|
16531
|
-
{
|
|
16532
|
-
action: activeAction.action,
|
|
16533
|
-
row: activeAction.row,
|
|
16534
|
-
idField: config.idField,
|
|
16535
|
-
eventBus,
|
|
16536
|
-
onExecute: (ctx) => crud.runEndpoints(activeAction.action.endpoints ?? [activeAction.action.endpoint], ctx),
|
|
16537
|
-
onClose: () => setActiveAction(null)
|
|
16538
|
-
}
|
|
16539
|
-
)
|
|
16540
|
-
] });
|
|
16541
|
-
}
|
|
16542
|
-
|
|
16543
16444
|
function MapViewChat({ component, eventBus }) {
|
|
16544
16445
|
const { googleMapsApiKey } = useChatConfig();
|
|
16545
16446
|
const props = component.props ?? {};
|
|
@@ -16754,30 +16655,6 @@ const ServicesMap = ({ config, eventBus, apiKey, filter, fill }) => {
|
|
|
16754
16655
|
};
|
|
16755
16656
|
ServicesMap.displayName = "ServicesMap";
|
|
16756
16657
|
|
|
16757
|
-
function ServicesMapChat({ component, eventBus }) {
|
|
16758
|
-
const { resolveModuleConfig, googleMapsApiKey } = useChatConfig();
|
|
16759
|
-
const props = component.props ?? {};
|
|
16760
|
-
const top = component;
|
|
16761
|
-
const pick = (key) => props[key] !== void 0 ? props[key] : top[key];
|
|
16762
|
-
const moduleKey = pick("module");
|
|
16763
|
-
let config;
|
|
16764
|
-
if (typeof moduleKey === "string" && resolveModuleConfig) {
|
|
16765
|
-
config = resolveModuleConfig(moduleKey);
|
|
16766
|
-
} else if (pick("data")) {
|
|
16767
|
-
config = component.props ? props : top;
|
|
16768
|
-
}
|
|
16769
|
-
if (!config?.data?.list) return null;
|
|
16770
|
-
return /* @__PURE__ */ jsx(
|
|
16771
|
-
ServicesMap,
|
|
16772
|
-
{
|
|
16773
|
-
config,
|
|
16774
|
-
eventBus,
|
|
16775
|
-
apiKey: googleMapsApiKey,
|
|
16776
|
-
filter: pick("filter")
|
|
16777
|
-
}
|
|
16778
|
-
);
|
|
16779
|
-
}
|
|
16780
|
-
|
|
16781
16658
|
const CLASS$5 = `${COMPONENT_PREFIX$1}service-shortcuts`;
|
|
16782
16659
|
const ICONS = {
|
|
16783
16660
|
map: /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
@@ -16854,62 +16731,6 @@ const ServiceShortcuts = ({
|
|
|
16854
16731
|
};
|
|
16855
16732
|
ServiceShortcuts.displayName = "ServiceShortcuts";
|
|
16856
16733
|
|
|
16857
|
-
const USED_KEY = (messageId) => `px:service_shortcuts:used:${messageId}`;
|
|
16858
|
-
function readUsed(messageId) {
|
|
16859
|
-
if (!messageId) return void 0;
|
|
16860
|
-
try {
|
|
16861
|
-
return localStorage.getItem(USED_KEY(messageId)) ?? void 0;
|
|
16862
|
-
} catch {
|
|
16863
|
-
return void 0;
|
|
16864
|
-
}
|
|
16865
|
-
}
|
|
16866
|
-
const DEFAULTS = {
|
|
16867
|
-
map: { id: "map", label: "Ver en el mapa", hint: "D\xF3nde est\xE1n ubicados", route: "/mapa", icon: "map" },
|
|
16868
|
-
list: { id: "list", label: "Ver la lista", hint: "Gestionar y filtrar", route: "/servicios", icon: "list" },
|
|
16869
|
-
// SPEC-030 — las dos puertas de quien llega por el enlace público y no sabe qué escribir.
|
|
16870
|
-
// No navegan: dicen por él lo que tendría que teclear, y el agente responde con el formulario
|
|
16871
|
-
// que toque. Así el componente no necesita saber qué formulario es cada cosa.
|
|
16872
|
-
request: {
|
|
16873
|
-
id: "request",
|
|
16874
|
-
label: "Solicitar una gr\xFAa",
|
|
16875
|
-
hint: "Pedir el servicio ahora",
|
|
16876
|
-
prompt: "Quiero solicitar una gr\xFAa",
|
|
16877
|
-
icon: "tow"
|
|
16878
|
-
},
|
|
16879
|
-
check: {
|
|
16880
|
-
id: "check",
|
|
16881
|
-
label: "Consultar mi servicio",
|
|
16882
|
-
hint: "Ya ped\xED una gr\xFAa antes",
|
|
16883
|
-
prompt: "Quiero consultar el servicio que ya ped\xED",
|
|
16884
|
-
icon: "search"
|
|
16885
|
-
}
|
|
16886
|
-
};
|
|
16887
|
-
function ServiceShortcutsChat({ component, eventBus, assistantMessageId }) {
|
|
16888
|
-
const [elegido, setElegido] = useState(() => readUsed(assistantMessageId));
|
|
16889
|
-
const props = component.props ?? {};
|
|
16890
|
-
const top = component;
|
|
16891
|
-
const pick = (key) => props[key] !== void 0 ? props[key] : top[key];
|
|
16892
|
-
const recordar = (id) => {
|
|
16893
|
-
setElegido(id);
|
|
16894
|
-
if (!assistantMessageId) return;
|
|
16895
|
-
try {
|
|
16896
|
-
localStorage.setItem(USED_KEY(assistantMessageId), id);
|
|
16897
|
-
} catch {
|
|
16898
|
-
}
|
|
16899
|
-
};
|
|
16900
|
-
const custom = pick("options");
|
|
16901
|
-
const options = custom?.length ? custom : (pick("show") ?? ["map", "list"]).map((k) => DEFAULTS[k]).filter(Boolean);
|
|
16902
|
-
return /* @__PURE__ */ jsx(
|
|
16903
|
-
ServiceShortcuts,
|
|
16904
|
-
{
|
|
16905
|
-
options,
|
|
16906
|
-
eventBus,
|
|
16907
|
-
selectedId: elegido,
|
|
16908
|
-
onSelect: recordar
|
|
16909
|
-
}
|
|
16910
|
-
);
|
|
16911
|
-
}
|
|
16912
|
-
|
|
16913
16734
|
const DATE_CHIPS = [
|
|
16914
16735
|
{ key: "todo", label: "Todo" },
|
|
16915
16736
|
{ key: "hoy", label: "Hoy" },
|
|
@@ -17573,16 +17394,39 @@ const COMPONENT_MAP = {
|
|
|
17573
17394
|
action_menu: ActionMenu,
|
|
17574
17395
|
reactive_crud: ReactiveCrudChat,
|
|
17575
17396
|
reactive_crud_item: ReactiveCrudItemChat,
|
|
17576
|
-
price_negotiation: PriceNegotiationChat,
|
|
17577
17397
|
chat_navigator: ChatNavigatorChat,
|
|
17578
17398
|
user_tools: UserToolsChat,
|
|
17579
|
-
map_view: MapViewChat
|
|
17580
|
-
services_map
|
|
17581
|
-
|
|
17582
|
-
|
|
17399
|
+
map_view: MapViewChat
|
|
17400
|
+
// SPEC-115 — `price_negotiation`, `services_map` y `service_shortcuts` salieron de aquí: son del flujo del
|
|
17401
|
+
// solicitante de grúas, no primitivos de diseño. Los registra el host (towing-web) con
|
|
17402
|
+
// `registerChatComponents`. Los componentes de presentación (ServicesMap, ServiceShortcuts)
|
|
17403
|
+
// SÍ se quedan y siguen exportándose: lo que se fue es su adaptador al chat.
|
|
17404
|
+
};
|
|
17405
|
+
const HOST_COMPONENTS = {};
|
|
17406
|
+
function normalizar(e) {
|
|
17407
|
+
return typeof e === "function" ? { render: e } : e;
|
|
17408
|
+
}
|
|
17409
|
+
function registerChatComponents(comps) {
|
|
17410
|
+
for (const [tipo, entrada] of Object.entries(comps)) {
|
|
17411
|
+
HOST_COMPONENTS[tipo] = normalizar(entrada);
|
|
17412
|
+
}
|
|
17413
|
+
}
|
|
17414
|
+
function clearChatComponents() {
|
|
17415
|
+
for (const tipo of Object.keys(HOST_COMPONENTS)) delete HOST_COMPONENTS[tipo];
|
|
17416
|
+
}
|
|
17417
|
+
function esPersistente(tipo) {
|
|
17418
|
+
const h = HOST_COMPONENTS[tipo];
|
|
17419
|
+
if (h) return h.persistent === true;
|
|
17420
|
+
return PERSISTENT_COMPONENTS.has(tipo);
|
|
17421
|
+
}
|
|
17422
|
+
function esDisplayPuro(tipo) {
|
|
17423
|
+
const h = HOST_COMPONENTS[tipo];
|
|
17424
|
+
if (h) return h.pureDisplay === true;
|
|
17425
|
+
return PURE_DISPLAY_COMPONENTS.has(tipo);
|
|
17426
|
+
}
|
|
17583
17427
|
function renderComponent(props) {
|
|
17584
17428
|
const { component } = props;
|
|
17585
|
-
if (!
|
|
17429
|
+
if (!esPersistente(component.type) && !esDisplayPuro(component.type)) {
|
|
17586
17430
|
if (component.status) {
|
|
17587
17431
|
if (TERMINAL_STATUS.has(component.status)) {
|
|
17588
17432
|
const policy = component.visibility_policy ?? "hide_on_terminal";
|
|
@@ -17595,7 +17439,7 @@ function renderComponent(props) {
|
|
|
17595
17439
|
return null;
|
|
17596
17440
|
}
|
|
17597
17441
|
}
|
|
17598
|
-
const Component = COMPONENT_MAP[component.type];
|
|
17442
|
+
const Component = HOST_COMPONENTS[component.type]?.render ?? COMPONENT_MAP[component.type];
|
|
17599
17443
|
if (!Component) return null;
|
|
17600
17444
|
return /* @__PURE__ */ jsx(Component, { ...props });
|
|
17601
17445
|
}
|
|
@@ -24733,4 +24577,4 @@ function buildBreadcrumbPath(items, targetKey, currentPath = []) {
|
|
|
24733
24577
|
return [];
|
|
24734
24578
|
}
|
|
24735
24579
|
|
|
24736
|
-
export { BottomSheet, CHAT_CONFIG_DEFAULTS, CHAT_EVENT, ICON_TYPES as CHAT_ICON_TYPES, Chat, AssistantMessage as ChatAssistantMessage, AssistantThinkingIndicator as ChatAssistantThinkingIndicator, AttachmentPreview as ChatAttachmentPreview, Avatar as ChatAvatar, Button$1 as ChatButton, ChatConfigProvider, DateDivider as ChatDateDivider, FileViewer as ChatFileViewer, ChatFloatingActions, FullscreenViewer as ChatFullscreenViewer, ChatHeader as ChatHeaderComponent, Icon$1 as ChatIcon, Input$2 as ChatInput, ChatInput as ChatInputComponent, Link as ChatLink, Loader$1 as ChatLoader, Logo as ChatLogo, MessageStatus as ChatMessageStatus, Modal as ChatModal, ChatNavigator, Select$2 as ChatSelect, SelectMenu as ChatSelectMenu, StructuredContent as ChatStructuredContent, Text as ChatText, Textarea as ChatTextarea, UserAttachments as ChatUserAttachments, UserMessage as ChatUserMessage, ChatWidget, FileField, BADGE_VARIANTS as LUMI_BADGE_VARIANTS, DEFAULT_TITLES as LUMI_DEFAULT_TITLES, LUMI_ICON_TYPES, LiveIndicator, LocationField, ActionBar as LumiActionBar, Badge as LumiBadge, Base as LumiBase, BaseNavbar as LumiBaseNavbar, BaseWorkspace as LumiBaseWorkspace, Breadcrumb as LumiBreadcrumb, BreadcrumbItem as LumiBreadcrumbItem, BreadcrumbSeparator as LumiBreadcrumbSeparator, Button as LumiButton, Calendar as LumiCalendar, Card as LumiCard, Checkbox$1 as LumiCheckbox, Crud as LumiCrud, CurrencyDisplay as LumiCurrencyDisplay, Dashboard as LumiDashboard, DashboardNavbar as LumiDashboardNavbar, DashboardSidebar as LumiDashboardSidebar, DashboardWorkspace as LumiDashboardWorkspace, DateDisplay as LumiDateDisplay, DateInput$1 as LumiDateInput, Drawer as LumiDrawer, DropdownMenu as LumiDropdownMenu, DynamicForm as LumiDynamicForm, FieldValue as LumiFieldValue, Filter as LumiFilter, FilterRow as LumiFilterRow, Checkbox as LumiFormCheckbox, DateInput as LumiFormDateInput, FormDrawer as LumiFormDrawer, Input as LumiFormInput, Select as LumiFormSelect, TimeInput as LumiFormTimeInput, Icon as LumiIcon, Input$1 as LumiInput, Loader as LumiLoader, Menu as LumiMenu, MenuItem as LumiMenuItem, MenuItemGroup as LumiMenuItemGroup, Notification as LumiNotification, Pagination as LumiPagination, Popover as LumiPopover, QRCode as LumiQRCode, RecordCard as LumiRecordCard, Select$1 as LumiSelect, StepIndicator as LumiStepIndicator, Stepper as LumiStepper, SubMenu as LumiSubMenu, Table as LumiTable, Tabs as LumiTabs, TextArea as LumiTextArea, TimeInput$1 as LumiTimeInput, Tooltip as LumiTooltip, MapView, ReactiveCrud, ServiceShortcuts, ServicesMap, SessionExpiryPrompt, UserTools, chatEventBus, createDeepPropertySubscriber, createEventBus, createStore, createStoreMerger, deepMerge, getLastFleetSnapshot, setLastFleetSnapshot, useChatConfig };
|
|
24580
|
+
export { ActionFormDrawer, BottomSheet, CHAT_CONFIG_DEFAULTS, CHAT_EVENT, ICON_TYPES as CHAT_ICON_TYPES, Chat, AssistantMessage as ChatAssistantMessage, AssistantThinkingIndicator as ChatAssistantThinkingIndicator, AttachmentPreview as ChatAttachmentPreview, Avatar as ChatAvatar, Button$1 as ChatButton, ChatConfigProvider, DateDivider as ChatDateDivider, FileViewer as ChatFileViewer, ChatFloatingActions, FullscreenViewer as ChatFullscreenViewer, ChatHeader as ChatHeaderComponent, Icon$1 as ChatIcon, Input$2 as ChatInput, ChatInput as ChatInputComponent, Link as ChatLink, Loader$1 as ChatLoader, Logo as ChatLogo, MessageStatus as ChatMessageStatus, Modal as ChatModal, ChatNavigator, Select$2 as ChatSelect, SelectMenu as ChatSelectMenu, StructuredContent as ChatStructuredContent, Text as ChatText, Textarea as ChatTextarea, UserAttachments as ChatUserAttachments, UserMessage as ChatUserMessage, ChatWidget, FileField, BADGE_VARIANTS as LUMI_BADGE_VARIANTS, DEFAULT_TITLES as LUMI_DEFAULT_TITLES, LUMI_ICON_TYPES, LiveIndicator, LocationField, ActionBar as LumiActionBar, Badge as LumiBadge, Base as LumiBase, BaseNavbar as LumiBaseNavbar, BaseWorkspace as LumiBaseWorkspace, Breadcrumb as LumiBreadcrumb, BreadcrumbItem as LumiBreadcrumbItem, BreadcrumbSeparator as LumiBreadcrumbSeparator, Button as LumiButton, Calendar as LumiCalendar, Card as LumiCard, Checkbox$1 as LumiCheckbox, Crud as LumiCrud, CurrencyDisplay as LumiCurrencyDisplay, Dashboard as LumiDashboard, DashboardNavbar as LumiDashboardNavbar, DashboardSidebar as LumiDashboardSidebar, DashboardWorkspace as LumiDashboardWorkspace, DateDisplay as LumiDateDisplay, DateInput$1 as LumiDateInput, Drawer as LumiDrawer, DropdownMenu as LumiDropdownMenu, DynamicForm as LumiDynamicForm, FieldValue as LumiFieldValue, Filter as LumiFilter, FilterRow as LumiFilterRow, Checkbox as LumiFormCheckbox, DateInput as LumiFormDateInput, FormDrawer as LumiFormDrawer, Input as LumiFormInput, Select as LumiFormSelect, TimeInput as LumiFormTimeInput, Icon as LumiIcon, Input$1 as LumiInput, Loader as LumiLoader, Menu as LumiMenu, MenuItem as LumiMenuItem, MenuItemGroup as LumiMenuItemGroup, Notification as LumiNotification, Pagination as LumiPagination, Popover as LumiPopover, QRCode as LumiQRCode, RecordCard as LumiRecordCard, Select$1 as LumiSelect, StepIndicator as LumiStepIndicator, Stepper as LumiStepper, SubMenu as LumiSubMenu, Table as LumiTable, Tabs as LumiTabs, TextArea as LumiTextArea, TimeInput$1 as LumiTimeInput, Tooltip as LumiTooltip, MapView, ReactiveCrud, ServiceShortcuts, ServicesMap, SessionExpiryPrompt, UserTools, chatEventBus, clearChatComponents, createDeepPropertySubscriber, createEventBus, createStore, createStoreMerger, deepMerge, disabledReasonFor, getLastFleetSnapshot, matchesDisabledWhen, matchesDoneWhen, matchesVisibleWhen, registerChatComponents, setLastFleetSnapshot, useChatConfig, useReactiveCrud };
|