pixelon 0.3.76 → 0.3.77
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/helpers/errorMessage.d.ts +5 -0
- package/dist/components/molecules/lumi/DropdownMenu/types.d.ts +6 -0
- package/dist/components/templates/lumi/Crud/types.d.ts +2 -0
- package/dist/index.esm.js +41 -6
- package/dist/index.js +41 -6
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
|
@@ -11,6 +11,12 @@ export interface DropdownMenuOption {
|
|
|
11
11
|
icon?: LumiIconType;
|
|
12
12
|
/** Si la opción está deshabilitada */
|
|
13
13
|
disabled?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* SPEC-090 T3 — por qué está deshabilitada. Se muestra bajo la etiqueta, no como tooltip:
|
|
16
|
+
* este menú se usa sobre todo desde el teléfono, y ahí un `title` no se lee nunca.
|
|
17
|
+
* Sin esto, una opción apagada es indistinguible de una rota.
|
|
18
|
+
*/
|
|
19
|
+
disabledReason?: string;
|
|
14
20
|
}
|
|
15
21
|
/**
|
|
16
22
|
* Props del componente DropdownMenu
|
|
@@ -239,6 +239,8 @@ export interface CrudProps<T extends Record<string, unknown>> {
|
|
|
239
239
|
drawerId?: string;
|
|
240
240
|
/** Función para determinar si la acción está deshabilitada */
|
|
241
241
|
disabled?: (row: T) => boolean;
|
|
242
|
+
/** SPEC-090 T3 — por qué está deshabilitada, para esa fila. Se muestra bajo la etiqueta. */
|
|
243
|
+
disabledReason?: (row: T) => string | undefined;
|
|
242
244
|
/** Función para determinar si la acción debe mostrarse */
|
|
243
245
|
show?: (row: T) => boolean;
|
|
244
246
|
}>;
|
package/dist/index.esm.js
CHANGED
|
@@ -11686,11 +11686,12 @@ const DropdownMenu = ({
|
|
|
11686
11686
|
children: options.map((option, index) => /* @__PURE__ */ jsxs(
|
|
11687
11687
|
"button",
|
|
11688
11688
|
{
|
|
11689
|
-
className: `${baseClass}__option ${option.disabled ? `${baseClass}__option--disabled` : ""}`,
|
|
11689
|
+
className: `${baseClass}__option ${option.disabled ? `${baseClass}__option--disabled` : ""} ${option.disabled && option.disabledReason ? `${baseClass}__option--con-motivo` : ""}`,
|
|
11690
11690
|
onClick: () => !option.disabled && handleOptionClick(option.onClick),
|
|
11691
11691
|
disabled: option.disabled,
|
|
11692
11692
|
role: "menuitem",
|
|
11693
11693
|
type: "button",
|
|
11694
|
+
title: option.disabled && option.disabledReason ? option.disabledReason : void 0,
|
|
11694
11695
|
children: [
|
|
11695
11696
|
option.icon && /* @__PURE__ */ jsx(
|
|
11696
11697
|
Icon,
|
|
@@ -11700,7 +11701,10 @@ const DropdownMenu = ({
|
|
|
11700
11701
|
className: `${baseClass}__option-icon`
|
|
11701
11702
|
}
|
|
11702
11703
|
),
|
|
11703
|
-
/* @__PURE__ */
|
|
11704
|
+
option.disabled && option.disabledReason ? /* @__PURE__ */ jsxs("span", { className: `${baseClass}__option-texts`, children: [
|
|
11705
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__option-label`, children: option.label }),
|
|
11706
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__option-reason`, children: option.disabledReason })
|
|
11707
|
+
] }) : /* @__PURE__ */ jsx("span", { className: `${baseClass}__option-label`, children: option.label })
|
|
11704
11708
|
]
|
|
11705
11709
|
},
|
|
11706
11710
|
index
|
|
@@ -13316,7 +13320,9 @@ function Crud({
|
|
|
13316
13320
|
action.onClick(row);
|
|
13317
13321
|
}
|
|
13318
13322
|
},
|
|
13319
|
-
disabled: action.disabled ? action.disabled(row) : false
|
|
13323
|
+
disabled: action.disabled ? action.disabled(row) : false,
|
|
13324
|
+
// SPEC-090 T3 — una acción apagada sin motivo es indistinguible de una rota.
|
|
13325
|
+
disabledReason: action.disabledReason?.(row)
|
|
13320
13326
|
});
|
|
13321
13327
|
});
|
|
13322
13328
|
if (menuOptions.length === 0) return null;
|
|
@@ -13790,6 +13796,30 @@ async function loadOptions(eventBus, ep) {
|
|
|
13790
13796
|
}));
|
|
13791
13797
|
}
|
|
13792
13798
|
|
|
13799
|
+
const esTextoUtil = (v) => typeof v === "string" && v.trim().length > 0;
|
|
13800
|
+
const buscarEnCuerpo = (cuerpo) => {
|
|
13801
|
+
if (!cuerpo || typeof cuerpo !== "object") return null;
|
|
13802
|
+
const c = cuerpo;
|
|
13803
|
+
const detalle = c.detail;
|
|
13804
|
+
if (esTextoUtil(detalle)) return detalle;
|
|
13805
|
+
if (detalle && typeof detalle === "object") {
|
|
13806
|
+
const d = detalle;
|
|
13807
|
+
if (esTextoUtil(d.message)) return d.message;
|
|
13808
|
+
}
|
|
13809
|
+
if (esTextoUtil(c.message)) return c.message;
|
|
13810
|
+
return null;
|
|
13811
|
+
};
|
|
13812
|
+
const ES_JERGA_HTTP = /^Request failed with status code \d+$/i;
|
|
13813
|
+
const mensajeDeError = (e, respaldo) => {
|
|
13814
|
+
const err = e;
|
|
13815
|
+
const delServidor = buscarEnCuerpo(err?.response?.data);
|
|
13816
|
+
if (delServidor) return delServidor;
|
|
13817
|
+
if (esTextoUtil(err?.message) && !ES_JERGA_HTTP.test(err.message.trim())) {
|
|
13818
|
+
return err.message;
|
|
13819
|
+
}
|
|
13820
|
+
return respaldo;
|
|
13821
|
+
};
|
|
13822
|
+
|
|
13793
13823
|
const REFRESH_INTERVAL_MS = 2e4;
|
|
13794
13824
|
function unwrap$2(raw) {
|
|
13795
13825
|
if (raw && typeof raw === "object" && "response" in raw) {
|
|
@@ -13854,7 +13884,7 @@ function useReactiveCrud(config, eventBus) {
|
|
|
13854
13884
|
if (myReq === reqIdRef.current) setState({ rows, total, loading: false, error: null });
|
|
13855
13885
|
} catch (e) {
|
|
13856
13886
|
if (myReq === reqIdRef.current) {
|
|
13857
|
-
setState((s) => ({ ...s, loading: false, error: e
|
|
13887
|
+
setState((s) => ({ ...s, loading: false, error: mensajeDeError(e, "Error al cargar") }));
|
|
13858
13888
|
}
|
|
13859
13889
|
}
|
|
13860
13890
|
}, [eventBus, config.data.list, skip, pageSize, filters]);
|
|
@@ -13898,7 +13928,7 @@ function useReactiveCrud(config, eventBus) {
|
|
|
13898
13928
|
}
|
|
13899
13929
|
await loadList();
|
|
13900
13930
|
} catch (e) {
|
|
13901
|
-
setActionError(e
|
|
13931
|
+
setActionError(mensajeDeError(e, "La acci\xF3n no se pudo completar"));
|
|
13902
13932
|
throw e;
|
|
13903
13933
|
}
|
|
13904
13934
|
},
|
|
@@ -14159,7 +14189,7 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
|
|
|
14159
14189
|
await onExecute(ctx);
|
|
14160
14190
|
onClose();
|
|
14161
14191
|
} catch (e) {
|
|
14162
|
-
setFormError(e
|
|
14192
|
+
setFormError(mensajeDeError(e, "La acci\xF3n no se pudo completar"));
|
|
14163
14193
|
} finally {
|
|
14164
14194
|
setSubmitting(false);
|
|
14165
14195
|
}
|
|
@@ -15681,6 +15711,10 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
|
|
|
15681
15711
|
icon: a.icon,
|
|
15682
15712
|
show: (row) => matchesVisibleWhen(a, row),
|
|
15683
15713
|
disabled: (row) => matchesDisabledWhen(a, row),
|
|
15714
|
+
// SPEC-090 T3 — el `disabledReason` de la config ya existía, pero solo lo pintaba el panel
|
|
15715
|
+
// del chat; en la tabla el botón se apagaba mudo. Afecta también al de la inspección
|
|
15716
|
+
// («Falta el comprobante de pago del cliente», SPEC-066 T7), que tampoco se veía aquí.
|
|
15717
|
+
disabledReason: (row) => matchesDisabledWhen(a, row) ? a.disabledReason : void 0,
|
|
15684
15718
|
onClick: (row) => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] })
|
|
15685
15719
|
}));
|
|
15686
15720
|
if (config.detail) {
|
|
@@ -15689,6 +15723,7 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
|
|
|
15689
15723
|
icon: "eye",
|
|
15690
15724
|
show: () => true,
|
|
15691
15725
|
disabled: () => false,
|
|
15726
|
+
disabledReason: () => void 0,
|
|
15692
15727
|
onClick: (row) => setDetailRow(row)
|
|
15693
15728
|
});
|
|
15694
15729
|
}
|
package/dist/index.js
CHANGED
|
@@ -11707,11 +11707,12 @@ const DropdownMenu = ({
|
|
|
11707
11707
|
children: options.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11708
11708
|
"button",
|
|
11709
11709
|
{
|
|
11710
|
-
className: `${baseClass}__option ${option.disabled ? `${baseClass}__option--disabled` : ""}`,
|
|
11710
|
+
className: `${baseClass}__option ${option.disabled ? `${baseClass}__option--disabled` : ""} ${option.disabled && option.disabledReason ? `${baseClass}__option--con-motivo` : ""}`,
|
|
11711
11711
|
onClick: () => !option.disabled && handleOptionClick(option.onClick),
|
|
11712
11712
|
disabled: option.disabled,
|
|
11713
11713
|
role: "menuitem",
|
|
11714
11714
|
type: "button",
|
|
11715
|
+
title: option.disabled && option.disabledReason ? option.disabledReason : void 0,
|
|
11715
11716
|
children: [
|
|
11716
11717
|
option.icon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
11717
11718
|
Icon,
|
|
@@ -11721,7 +11722,10 @@ const DropdownMenu = ({
|
|
|
11721
11722
|
className: `${baseClass}__option-icon`
|
|
11722
11723
|
}
|
|
11723
11724
|
),
|
|
11724
|
-
/* @__PURE__ */ jsxRuntime.
|
|
11725
|
+
option.disabled && option.disabledReason ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${baseClass}__option-texts`, children: [
|
|
11726
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${baseClass}__option-label`, children: option.label }),
|
|
11727
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${baseClass}__option-reason`, children: option.disabledReason })
|
|
11728
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${baseClass}__option-label`, children: option.label })
|
|
11725
11729
|
]
|
|
11726
11730
|
},
|
|
11727
11731
|
index
|
|
@@ -13337,7 +13341,9 @@ function Crud({
|
|
|
13337
13341
|
action.onClick(row);
|
|
13338
13342
|
}
|
|
13339
13343
|
},
|
|
13340
|
-
disabled: action.disabled ? action.disabled(row) : false
|
|
13344
|
+
disabled: action.disabled ? action.disabled(row) : false,
|
|
13345
|
+
// SPEC-090 T3 — una acción apagada sin motivo es indistinguible de una rota.
|
|
13346
|
+
disabledReason: action.disabledReason?.(row)
|
|
13341
13347
|
});
|
|
13342
13348
|
});
|
|
13343
13349
|
if (menuOptions.length === 0) return null;
|
|
@@ -13811,6 +13817,30 @@ async function loadOptions(eventBus, ep) {
|
|
|
13811
13817
|
}));
|
|
13812
13818
|
}
|
|
13813
13819
|
|
|
13820
|
+
const esTextoUtil = (v) => typeof v === "string" && v.trim().length > 0;
|
|
13821
|
+
const buscarEnCuerpo = (cuerpo) => {
|
|
13822
|
+
if (!cuerpo || typeof cuerpo !== "object") return null;
|
|
13823
|
+
const c = cuerpo;
|
|
13824
|
+
const detalle = c.detail;
|
|
13825
|
+
if (esTextoUtil(detalle)) return detalle;
|
|
13826
|
+
if (detalle && typeof detalle === "object") {
|
|
13827
|
+
const d = detalle;
|
|
13828
|
+
if (esTextoUtil(d.message)) return d.message;
|
|
13829
|
+
}
|
|
13830
|
+
if (esTextoUtil(c.message)) return c.message;
|
|
13831
|
+
return null;
|
|
13832
|
+
};
|
|
13833
|
+
const ES_JERGA_HTTP = /^Request failed with status code \d+$/i;
|
|
13834
|
+
const mensajeDeError = (e, respaldo) => {
|
|
13835
|
+
const err = e;
|
|
13836
|
+
const delServidor = buscarEnCuerpo(err?.response?.data);
|
|
13837
|
+
if (delServidor) return delServidor;
|
|
13838
|
+
if (esTextoUtil(err?.message) && !ES_JERGA_HTTP.test(err.message.trim())) {
|
|
13839
|
+
return err.message;
|
|
13840
|
+
}
|
|
13841
|
+
return respaldo;
|
|
13842
|
+
};
|
|
13843
|
+
|
|
13814
13844
|
const REFRESH_INTERVAL_MS = 2e4;
|
|
13815
13845
|
function unwrap$2(raw) {
|
|
13816
13846
|
if (raw && typeof raw === "object" && "response" in raw) {
|
|
@@ -13875,7 +13905,7 @@ function useReactiveCrud(config, eventBus) {
|
|
|
13875
13905
|
if (myReq === reqIdRef.current) setState({ rows, total, loading: false, error: null });
|
|
13876
13906
|
} catch (e) {
|
|
13877
13907
|
if (myReq === reqIdRef.current) {
|
|
13878
|
-
setState((s) => ({ ...s, loading: false, error: e
|
|
13908
|
+
setState((s) => ({ ...s, loading: false, error: mensajeDeError(e, "Error al cargar") }));
|
|
13879
13909
|
}
|
|
13880
13910
|
}
|
|
13881
13911
|
}, [eventBus, config.data.list, skip, pageSize, filters]);
|
|
@@ -13919,7 +13949,7 @@ function useReactiveCrud(config, eventBus) {
|
|
|
13919
13949
|
}
|
|
13920
13950
|
await loadList();
|
|
13921
13951
|
} catch (e) {
|
|
13922
|
-
setActionError(e
|
|
13952
|
+
setActionError(mensajeDeError(e, "La acci\xF3n no se pudo completar"));
|
|
13923
13953
|
throw e;
|
|
13924
13954
|
}
|
|
13925
13955
|
},
|
|
@@ -14180,7 +14210,7 @@ function ActionFormDrawer({ action, row, idField, eventBus, onExecute, onClose }
|
|
|
14180
14210
|
await onExecute(ctx);
|
|
14181
14211
|
onClose();
|
|
14182
14212
|
} catch (e) {
|
|
14183
|
-
setFormError(e
|
|
14213
|
+
setFormError(mensajeDeError(e, "La acci\xF3n no se pudo completar"));
|
|
14184
14214
|
} finally {
|
|
14185
14215
|
setSubmitting(false);
|
|
14186
14216
|
}
|
|
@@ -15702,6 +15732,10 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
|
|
|
15702
15732
|
icon: a.icon,
|
|
15703
15733
|
show: (row) => matchesVisibleWhen(a, row),
|
|
15704
15734
|
disabled: (row) => matchesDisabledWhen(a, row),
|
|
15735
|
+
// SPEC-090 T3 — el `disabledReason` de la config ya existía, pero solo lo pintaba el panel
|
|
15736
|
+
// del chat; en la tabla el botón se apagaba mudo. Afecta también al de la inspección
|
|
15737
|
+
// («Falta el comprobante de pago del cliente», SPEC-066 T7), que tampoco se veía aquí.
|
|
15738
|
+
disabledReason: (row) => matchesDisabledWhen(a, row) ? a.disabledReason : void 0,
|
|
15705
15739
|
onClick: (row) => a.form ? setActiveAction({ action: a, row }) : crud.runEndpoints(a.endpoints ?? [a.endpoint], { ...row, id: row[config.idField] })
|
|
15706
15740
|
}));
|
|
15707
15741
|
if (config.detail) {
|
|
@@ -15710,6 +15744,7 @@ function ReactiveCrud({ config, eventBus, autoOpenCreate, prefill, onCreated, on
|
|
|
15710
15744
|
icon: "eye",
|
|
15711
15745
|
show: () => true,
|
|
15712
15746
|
disabled: () => false,
|
|
15747
|
+
disabledReason: () => void 0,
|
|
15713
15748
|
onClick: (row) => setDetailRow(row)
|
|
15714
15749
|
});
|
|
15715
15750
|
}
|