pixelon 0.3.81 → 0.3.83

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.
@@ -15,6 +15,7 @@ export interface ReactiveCrudProps {
15
15
  }
16
16
  export declare function matchesVisibleWhen(a: RowActionDef, row: Record<string, unknown>): boolean;
17
17
  export declare function matchesDisabledWhen(a: RowActionDef, row: Record<string, unknown>): boolean;
18
+ export declare function disabledReasonFor(a: RowActionDef, row: Record<string, unknown>): string | undefined;
18
19
  export declare function matchesDoneWhen(a: RowActionDef, row: Record<string, unknown>): boolean;
19
20
  export declare function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, onCreateClose, googleMapsApiKey: apiKeyProp }: ReactiveCrudProps): import("react/jsx-runtime").JSX.Element;
20
21
  export default ReactiveCrud;
@@ -1,6 +1,7 @@
1
1
  import type { SelectOption } from '../../../../../organisms/lumi/DynamicForm/types';
2
2
  import type { ChatEventBus } from '../../../../../../core/eventBus/chatEventBus';
3
3
  import type { CrudFieldOptionsEndpoint } from './types';
4
+ export declare const OPTIONS_LOAD_ERROR = "No se pudieron cargar las opciones. Int\u00E9ntalo de nuevo.";
4
5
  export declare function unwrap(raw: unknown): unknown;
5
6
  export declare function resolveBody(body: Record<string, unknown> | undefined, ctx?: Record<string, unknown>): Record<string, unknown>;
6
7
  export declare function loadOptions(eventBus: ChatEventBus, ep: CrudFieldOptionsEndpoint, ctx?: Record<string, unknown>): Promise<SelectOption[]>;
@@ -84,6 +84,14 @@ export interface RowActionVisibleWhen {
84
84
  field: string;
85
85
  in: string[];
86
86
  }
87
+ /** SPEC-113 — una condición que apaga la acción, con SU motivo.
88
+ *
89
+ * Un botón deshabilitado que no dice cuál de dos motivos lo apaga enseña a ignorarlo. Fundir dos
90
+ * situaciones opuestas —«falta el comprobante del cliente» y «todavía no has llegado»— en un
91
+ * «no puedes todavía» es la validación muda de SPEC-074 con otra cara. */
92
+ export interface RowActionDisabledWhen extends RowActionVisibleWhen {
93
+ reason?: string;
94
+ }
87
95
  export interface RowActionDef {
88
96
  key: string;
89
97
  label: string;
@@ -97,9 +105,13 @@ export interface RowActionDef {
97
105
  * aceptado el precio—, que con condiciones unidas por «y» no se pueden escribir. */
98
106
  hiddenWhen?: RowActionVisibleWhen | RowActionVisibleWhen[];
99
107
  /** SPEC-007: la acción se muestra pero queda DESHABILITADA cuando `String(row[field])` está en
100
- * `in` (ej. "Iniciar" deshabilitado hasta que `has_inspection` sea true). */
101
- disabledWhen?: RowActionVisibleWhen;
102
- /** SPEC-007: tooltip cuando la acción está deshabilitada (ej. "Registra la inspección primero"). */
108
+ * `in` (ej. "Iniciar" deshabilitado hasta que `has_inspection` sea true).
109
+ *
110
+ * SPEC-113: admite VARIAS, cada una con su motivo. Se apaga con la primera que se cumple, y esa
111
+ * es la que habla. Una sola condición sigue valiendo igual que siempre. */
112
+ disabledWhen?: RowActionDisabledWhen | RowActionDisabledWhen[];
113
+ /** SPEC-007: tooltip cuando la acción está deshabilitada (ej. "Registra la inspección primero").
114
+ * SPEC-113: es el respaldo — una condición con `reason` propio manda sobre este. */
103
115
  disabledReason?: string;
104
116
  /** SPEC-007: muestra un ✓ al final cuando `String(row[field])` está en `in` (ej. inspección ya
105
117
  * registrada). Indicador de "hecho"; no bloquea reejecutar la acción. */
package/dist/index.esm.js CHANGED
@@ -14111,6 +14111,7 @@ function getFormatter(key) {
14111
14111
  return key ? CRUD_FORMATTERS[key] : void 0;
14112
14112
  }
14113
14113
 
14114
+ const OPTIONS_LOAD_ERROR = "No se pudieron cargar las opciones. Int\xE9ntalo de nuevo.";
14114
14115
  function unwrap$3(raw) {
14115
14116
  if (raw && typeof raw === "object" && "response" in raw) {
14116
14117
  return raw.response;
@@ -14448,6 +14449,7 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
14448
14449
  const fileFields = useMemo(() => formFields.filter((f) => f.moleculeType === "FILE"), [formFields]);
14449
14450
  const normalFields = useMemo(() => formFields.filter((f) => f.moleculeType !== "FILE"), [formFields]);
14450
14451
  const [optionsByField, setOptionsByField] = useState({});
14452
+ const [optionsErrorByField, setOptionsErrorByField] = useState({});
14451
14453
  const [loadingOptions, setLoadingOptions] = useState(false);
14452
14454
  const [submitting, setSubmitting] = useState(false);
14453
14455
  const [fileEntries, setFileEntries] = useState({});
@@ -14461,14 +14463,17 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
14461
14463
  toLoad.map(async (f) => {
14462
14464
  try {
14463
14465
  const opts = await loadOptions(eventBus, f.optionsEndpoint, { ...row, id: row[idField] });
14464
- return [f.name, opts];
14466
+ return [f.name, opts, null];
14465
14467
  } catch {
14466
- return [f.name, []];
14468
+ return [f.name, [], OPTIONS_LOAD_ERROR];
14467
14469
  }
14468
14470
  })
14469
14471
  ).then((entries) => {
14470
14472
  if (!alive) return;
14471
- setOptionsByField(Object.fromEntries(entries));
14473
+ setOptionsByField(Object.fromEntries(entries.map(([n, o]) => [n, o])));
14474
+ setOptionsErrorByField(
14475
+ Object.fromEntries(entries.filter(([, , e]) => e).map(([n, , e]) => [n, e]))
14476
+ );
14472
14477
  setLoadingOptions(false);
14473
14478
  });
14474
14479
  return () => {
@@ -14482,9 +14487,12 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
14482
14487
  moleculeType: CRUD_TO_FORM_MOLECULE[f.moleculeType] ?? "INPUT",
14483
14488
  required: f.required,
14484
14489
  placeholder: f.placeholder,
14485
- options: f.options ?? optionsByField[f.name]
14490
+ options: f.options ?? optionsByField[f.name],
14491
+ // SPEC-106 T8 — `uiProps` llega tal cual a la molécula, así que el desplegable dice lo
14492
+ // que pasó de verdad en vez del «no hay» de siempre. Sin error, se queda el de siempre.
14493
+ ...optionsErrorByField[f.name] ? { uiProps: { notFoundContent: optionsErrorByField[f.name] } } : {}
14486
14494
  })),
14487
- [normalFields, optionsByField]
14495
+ [normalFields, optionsByField, optionsErrorByField]
14488
14496
  );
14489
14497
  const validationSchema = useMemo(() => buildCrudYupSchema(normalFields), [normalFields]);
14490
14498
  const uploadOne = async (f, file, idx) => {
@@ -15919,7 +15927,7 @@ function chatLinkFormatter(field, eventBus) {
15919
15927
  return createElement(ChatLinkCell, { targets, eventBus });
15920
15928
  };
15921
15929
  }
15922
- function toRenderField(f, loaded, eventBus, mapsApiKey) {
15930
+ function toRenderField(f, loaded, eventBus, mapsApiKey, loadError) {
15923
15931
  const fmt = getFormatter(f.format);
15924
15932
  const options = f.options ?? loaded[f.name];
15925
15933
  if (f.moleculeType === "LOCATION") {
@@ -15964,7 +15972,9 @@ function toRenderField(f, loaded, eventBus, mapsApiKey) {
15964
15972
  columnWidth: f.columnWidth,
15965
15973
  fixed: f.fixed,
15966
15974
  align: f.align,
15967
- uiProps: options ? { options } : void 0,
15975
+ // SPEC-106 T8 — con un fallo de carga, el desplegable dice que no se pudo preguntar en vez
15976
+ // de «no hay opciones disponibles», que es una respuesta y no la tenemos.
15977
+ uiProps: loadError ? { options: options ?? [], notFoundContent: loadError } : options ? { options } : void 0,
15968
15978
  formatValue
15969
15979
  };
15970
15980
  }
@@ -15975,9 +15985,20 @@ function matchesVisibleWhen(a, row) {
15975
15985
  if (!a.visibleWhen) return true;
15976
15986
  return cumplenTodas(a.visibleWhen, row);
15977
15987
  }
15988
+ function condicionesDeshabilitado(a) {
15989
+ if (!a.disabledWhen) return [];
15990
+ return Array.isArray(a.disabledWhen) ? a.disabledWhen : [a.disabledWhen];
15991
+ }
15992
+ function primeraQueApaga(a, row) {
15993
+ return condicionesDeshabilitado(a).find((c) => c.in.includes(String(row[c.field])));
15994
+ }
15978
15995
  function matchesDisabledWhen(a, row) {
15979
- if (!a.disabledWhen) return false;
15980
- return a.disabledWhen.in.includes(String(row[a.disabledWhen.field]));
15996
+ return primeraQueApaga(a, row) !== void 0;
15997
+ }
15998
+ function disabledReasonFor(a, row) {
15999
+ const c = primeraQueApaga(a, row);
16000
+ if (!c) return void 0;
16001
+ return c.reason ?? a.disabledReason;
15981
16002
  }
15982
16003
  function matchesDoneWhen(a, row) {
15983
16004
  if (!a.doneWhen) return false;
@@ -16014,6 +16035,7 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
16014
16035
  const [activeAction, setActiveAction] = useState(null);
16015
16036
  const [detailRow, setDetailRow] = useState(null);
16016
16037
  const [optionsByField, setOptionsByField] = useState({});
16038
+ const [optionsErrorByField, setOptionsErrorByField] = useState({});
16017
16039
  useEffect(() => {
16018
16040
  let alive = true;
16019
16041
  const toLoad = config.fields.filter((f) => f.optionsEndpoint);
@@ -16021,21 +16043,25 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
16021
16043
  void Promise.all(
16022
16044
  toLoad.map(async (f) => {
16023
16045
  try {
16024
- return [f.name, await loadOptions(eventBus, f.optionsEndpoint)];
16046
+ return [f.name, await loadOptions(eventBus, f.optionsEndpoint), null];
16025
16047
  } catch {
16026
- return [f.name, []];
16048
+ return [f.name, [], OPTIONS_LOAD_ERROR];
16027
16049
  }
16028
16050
  })
16029
16051
  ).then((entries) => {
16030
- if (alive) setOptionsByField(Object.fromEntries(entries));
16052
+ if (!alive) return;
16053
+ setOptionsByField(Object.fromEntries(entries.map(([n, o]) => [n, o])));
16054
+ setOptionsErrorByField(
16055
+ Object.fromEntries(entries.filter(([, , e]) => e).map(([n, , e]) => [n, e]))
16056
+ );
16031
16057
  });
16032
16058
  return () => {
16033
16059
  alive = false;
16034
16060
  };
16035
16061
  }, [eventBus, config.fields]);
16036
16062
  const renderByFields = useMemo(
16037
- () => config.fields.map((f) => toRenderField(f, optionsByField, eventBus, googleMapsApiKey)),
16038
- [config.fields, optionsByField, eventBus]
16063
+ () => config.fields.map((f) => toRenderField(f, optionsByField, eventBus, googleMapsApiKey, optionsErrorByField[f.name])),
16064
+ [config.fields, optionsByField, optionsErrorByField, eventBus]
16039
16065
  );
16040
16066
  const validationSchema = useMemo(() => buildCrudYupSchema(config.fields), [config.fields]);
16041
16067
  const rowActions = useMemo(() => {
@@ -16047,7 +16073,8 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
16047
16073
  // SPEC-090 T3 — el `disabledReason` de la config ya existía, pero solo lo pintaba el panel
16048
16074
  // del chat; en la tabla el botón se apagaba mudo. Afecta también al de la inspección
16049
16075
  // («Falta el comprobante de pago del cliente», SPEC-066 T7), que tampoco se veía aquí.
16050
- disabledReason: (row) => matchesDisabledWhen(a, row) ? a.disabledReason : void 0,
16076
+ // SPEC-113 — el motivo sale de la condición que apagó el botón, no de la acción entera.
16077
+ disabledReason: (row) => disabledReasonFor(a, row),
16051
16078
  onClick: (row) => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] })
16052
16079
  }));
16053
16080
  if (config.detail) {
@@ -16371,6 +16398,7 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
16371
16398
  config.detail && /* @__PURE__ */ jsx("button", { type: "button", className: "px-chat-crud-item__action", onClick: () => setDetailRow(row), children: "Ver" }),
16372
16399
  actions.map((a) => {
16373
16400
  const disabled = matchesDisabledWhen(a, row);
16401
+ const motivo = disabledReasonFor(a, row);
16374
16402
  const done = matchesDoneWhen(a, row);
16375
16403
  return /* @__PURE__ */ jsxs(
16376
16404
  "button",
@@ -16379,14 +16407,14 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
16379
16407
  className: [
16380
16408
  "px-chat-crud-item__action",
16381
16409
  a.intent === "danger" ? "is-danger" : "",
16382
- disabled && a.disabledReason ? "is-con-motivo" : ""
16410
+ disabled && motivo ? "is-con-motivo" : ""
16383
16411
  ].filter(Boolean).join(" "),
16384
16412
  disabled,
16385
16413
  onClick: () => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] }),
16386
16414
  children: [
16387
16415
  /* @__PURE__ */ jsxs("span", { className: "px-chat-crud-item__action-texts", children: [
16388
16416
  /* @__PURE__ */ jsx("span", { children: a.label }),
16389
- disabled && a.disabledReason && /* @__PURE__ */ jsx("span", { className: "px-chat-crud-item__action-reason", children: a.disabledReason })
16417
+ disabled && motivo && /* @__PURE__ */ jsx("span", { className: "px-chat-crud-item__action-reason", children: motivo })
16390
16418
  ] }),
16391
16419
  done && /* @__PURE__ */ jsx(Icon$1, { type: "check-circle", width: 18, height: 18, className: "px-chat-crud-item__done", "aria-label": "Hecho" })
16392
16420
  ]
package/dist/index.js CHANGED
@@ -14132,6 +14132,7 @@ function getFormatter(key) {
14132
14132
  return key ? CRUD_FORMATTERS[key] : void 0;
14133
14133
  }
14134
14134
 
14135
+ const OPTIONS_LOAD_ERROR = "No se pudieron cargar las opciones. Int\xE9ntalo de nuevo.";
14135
14136
  function unwrap$3(raw) {
14136
14137
  if (raw && typeof raw === "object" && "response" in raw) {
14137
14138
  return raw.response;
@@ -14469,6 +14470,7 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
14469
14470
  const fileFields = React.useMemo(() => formFields.filter((f) => f.moleculeType === "FILE"), [formFields]);
14470
14471
  const normalFields = React.useMemo(() => formFields.filter((f) => f.moleculeType !== "FILE"), [formFields]);
14471
14472
  const [optionsByField, setOptionsByField] = React.useState({});
14473
+ const [optionsErrorByField, setOptionsErrorByField] = React.useState({});
14472
14474
  const [loadingOptions, setLoadingOptions] = React.useState(false);
14473
14475
  const [submitting, setSubmitting] = React.useState(false);
14474
14476
  const [fileEntries, setFileEntries] = React.useState({});
@@ -14482,14 +14484,17 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
14482
14484
  toLoad.map(async (f) => {
14483
14485
  try {
14484
14486
  const opts = await loadOptions(eventBus, f.optionsEndpoint, { ...row, id: row[idField] });
14485
- return [f.name, opts];
14487
+ return [f.name, opts, null];
14486
14488
  } catch {
14487
- return [f.name, []];
14489
+ return [f.name, [], OPTIONS_LOAD_ERROR];
14488
14490
  }
14489
14491
  })
14490
14492
  ).then((entries) => {
14491
14493
  if (!alive) return;
14492
- setOptionsByField(Object.fromEntries(entries));
14494
+ setOptionsByField(Object.fromEntries(entries.map(([n, o]) => [n, o])));
14495
+ setOptionsErrorByField(
14496
+ Object.fromEntries(entries.filter(([, , e]) => e).map(([n, , e]) => [n, e]))
14497
+ );
14493
14498
  setLoadingOptions(false);
14494
14499
  });
14495
14500
  return () => {
@@ -14503,9 +14508,12 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
14503
14508
  moleculeType: CRUD_TO_FORM_MOLECULE[f.moleculeType] ?? "INPUT",
14504
14509
  required: f.required,
14505
14510
  placeholder: f.placeholder,
14506
- options: f.options ?? optionsByField[f.name]
14511
+ options: f.options ?? optionsByField[f.name],
14512
+ // SPEC-106 T8 — `uiProps` llega tal cual a la molécula, así que el desplegable dice lo
14513
+ // 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] } } : {}
14507
14515
  })),
14508
- [normalFields, optionsByField]
14516
+ [normalFields, optionsByField, optionsErrorByField]
14509
14517
  );
14510
14518
  const validationSchema = React.useMemo(() => buildCrudYupSchema(normalFields), [normalFields]);
14511
14519
  const uploadOne = async (f, file, idx) => {
@@ -15940,7 +15948,7 @@ function chatLinkFormatter(field, eventBus) {
15940
15948
  return React.createElement(ChatLinkCell, { targets, eventBus });
15941
15949
  };
15942
15950
  }
15943
- function toRenderField(f, loaded, eventBus, mapsApiKey) {
15951
+ function toRenderField(f, loaded, eventBus, mapsApiKey, loadError) {
15944
15952
  const fmt = getFormatter(f.format);
15945
15953
  const options = f.options ?? loaded[f.name];
15946
15954
  if (f.moleculeType === "LOCATION") {
@@ -15985,7 +15993,9 @@ function toRenderField(f, loaded, eventBus, mapsApiKey) {
15985
15993
  columnWidth: f.columnWidth,
15986
15994
  fixed: f.fixed,
15987
15995
  align: f.align,
15988
- uiProps: options ? { options } : void 0,
15996
+ // SPEC-106 T8 — con un fallo de carga, el desplegable dice que no se pudo preguntar en vez
15997
+ // de «no hay opciones disponibles», que es una respuesta y no la tenemos.
15998
+ uiProps: loadError ? { options: options ?? [], notFoundContent: loadError } : options ? { options } : void 0,
15989
15999
  formatValue
15990
16000
  };
15991
16001
  }
@@ -15996,9 +16006,20 @@ function matchesVisibleWhen(a, row) {
15996
16006
  if (!a.visibleWhen) return true;
15997
16007
  return cumplenTodas(a.visibleWhen, row);
15998
16008
  }
16009
+ function condicionesDeshabilitado(a) {
16010
+ if (!a.disabledWhen) return [];
16011
+ return Array.isArray(a.disabledWhen) ? a.disabledWhen : [a.disabledWhen];
16012
+ }
16013
+ function primeraQueApaga(a, row) {
16014
+ return condicionesDeshabilitado(a).find((c) => c.in.includes(String(row[c.field])));
16015
+ }
15999
16016
  function matchesDisabledWhen(a, row) {
16000
- if (!a.disabledWhen) return false;
16001
- return a.disabledWhen.in.includes(String(row[a.disabledWhen.field]));
16017
+ return primeraQueApaga(a, row) !== void 0;
16018
+ }
16019
+ function disabledReasonFor(a, row) {
16020
+ const c = primeraQueApaga(a, row);
16021
+ if (!c) return void 0;
16022
+ return c.reason ?? a.disabledReason;
16002
16023
  }
16003
16024
  function matchesDoneWhen(a, row) {
16004
16025
  if (!a.doneWhen) return false;
@@ -16035,6 +16056,7 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
16035
16056
  const [activeAction, setActiveAction] = React.useState(null);
16036
16057
  const [detailRow, setDetailRow] = React.useState(null);
16037
16058
  const [optionsByField, setOptionsByField] = React.useState({});
16059
+ const [optionsErrorByField, setOptionsErrorByField] = React.useState({});
16038
16060
  React.useEffect(() => {
16039
16061
  let alive = true;
16040
16062
  const toLoad = config.fields.filter((f) => f.optionsEndpoint);
@@ -16042,21 +16064,25 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
16042
16064
  void Promise.all(
16043
16065
  toLoad.map(async (f) => {
16044
16066
  try {
16045
- return [f.name, await loadOptions(eventBus, f.optionsEndpoint)];
16067
+ return [f.name, await loadOptions(eventBus, f.optionsEndpoint), null];
16046
16068
  } catch {
16047
- return [f.name, []];
16069
+ return [f.name, [], OPTIONS_LOAD_ERROR];
16048
16070
  }
16049
16071
  })
16050
16072
  ).then((entries) => {
16051
- if (alive) setOptionsByField(Object.fromEntries(entries));
16073
+ if (!alive) return;
16074
+ setOptionsByField(Object.fromEntries(entries.map(([n, o]) => [n, o])));
16075
+ setOptionsErrorByField(
16076
+ Object.fromEntries(entries.filter(([, , e]) => e).map(([n, , e]) => [n, e]))
16077
+ );
16052
16078
  });
16053
16079
  return () => {
16054
16080
  alive = false;
16055
16081
  };
16056
16082
  }, [eventBus, config.fields]);
16057
16083
  const renderByFields = React.useMemo(
16058
- () => config.fields.map((f) => toRenderField(f, optionsByField, eventBus, googleMapsApiKey)),
16059
- [config.fields, optionsByField, eventBus]
16084
+ () => config.fields.map((f) => toRenderField(f, optionsByField, eventBus, googleMapsApiKey, optionsErrorByField[f.name])),
16085
+ [config.fields, optionsByField, optionsErrorByField, eventBus]
16060
16086
  );
16061
16087
  const validationSchema = React.useMemo(() => buildCrudYupSchema(config.fields), [config.fields]);
16062
16088
  const rowActions = React.useMemo(() => {
@@ -16068,7 +16094,8 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
16068
16094
  // SPEC-090 T3 — el `disabledReason` de la config ya existía, pero solo lo pintaba el panel
16069
16095
  // del chat; en la tabla el botón se apagaba mudo. Afecta también al de la inspección
16070
16096
  // («Falta el comprobante de pago del cliente», SPEC-066 T7), que tampoco se veía aquí.
16071
- disabledReason: (row) => matchesDisabledWhen(a, row) ? a.disabledReason : void 0,
16097
+ // SPEC-113 — el motivo sale de la condición que apagó el botón, no de la acción entera.
16098
+ disabledReason: (row) => disabledReasonFor(a, row),
16072
16099
  onClick: (row) => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] })
16073
16100
  }));
16074
16101
  if (config.detail) {
@@ -16392,6 +16419,7 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
16392
16419
  config.detail && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "px-chat-crud-item__action", onClick: () => setDetailRow(row), children: "Ver" }),
16393
16420
  actions.map((a) => {
16394
16421
  const disabled = matchesDisabledWhen(a, row);
16422
+ const motivo = disabledReasonFor(a, row);
16395
16423
  const done = matchesDoneWhen(a, row);
16396
16424
  return /* @__PURE__ */ jsxRuntime.jsxs(
16397
16425
  "button",
@@ -16400,14 +16428,14 @@ function ServiceActionsPanel({ config, recordId, recordLabel, allowed, eventBus
16400
16428
  className: [
16401
16429
  "px-chat-crud-item__action",
16402
16430
  a.intent === "danger" ? "is-danger" : "",
16403
- disabled && a.disabledReason ? "is-con-motivo" : ""
16431
+ disabled && motivo ? "is-con-motivo" : ""
16404
16432
  ].filter(Boolean).join(" "),
16405
16433
  disabled,
16406
16434
  onClick: () => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] }),
16407
16435
  children: [
16408
16436
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-chat-crud-item__action-texts", children: [
16409
16437
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: a.label }),
16410
- disabled && a.disabledReason && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-crud-item__action-reason", children: a.disabledReason })
16438
+ disabled && motivo && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-chat-crud-item__action-reason", children: motivo })
16411
16439
  ] }),
16412
16440
  done && /* @__PURE__ */ jsxRuntime.jsx(Icon$1, { type: "check-circle", width: 18, height: 18, className: "px-chat-crud-item__done", "aria-label": "Hecho" })
16413
16441
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelon",
3
- "version": "0.3.81",
3
+ "version": "0.3.83",
4
4
  "description": "Design system de la marca goluti",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",