contentoh-components-library 21.6.44 → 21.6.45
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/organisms/VariantGroupModal/index.js +361 -0
- package/dist/components/organisms/VariantGroupModal/styles.js +55 -0
- package/dist/components/pages/ProviderProductEdition/index.js +385 -145
- package/dist/components/pages/RetailerProductEdition/index.js +467 -230
- package/dist/index.js +25 -12
- package/package.json +1 -1
- package/src/components/organisms/VariantGroupModal/index.js +252 -0
- package/src/components/organisms/VariantGroupModal/styles.js +228 -0
- package/src/components/pages/ProviderProductEdition/index.js +164 -0
- package/src/components/pages/RetailerProductEdition/index.js +156 -0
- package/src/index.js +1 -0
|
@@ -40,6 +40,7 @@ import { ImagePreviewer } from "../../organisms/ImagePreviewer";
|
|
|
40
40
|
import { InputGroup } from "../../organisms/InputGroup";
|
|
41
41
|
import { LinkVariantsModal } from "../../organisms/LinkVariantsModal";
|
|
42
42
|
import { UnlinkVariantModal } from "../../organisms/UnlinkVariantModal";
|
|
43
|
+
import { VariantGroupModal } from "../../organisms/VariantGroupModal";
|
|
43
44
|
import { PropagateChangesModal } from "../../organisms/PropagateChangesModal";
|
|
44
45
|
import { readPayload } from "../../organisms/LinkVariantsModal/api";
|
|
45
46
|
import { ProductImageModal } from "../../organisms/ProductImageModal";
|
|
@@ -85,6 +86,15 @@ const ProviderProductEditionView = ({
|
|
|
85
86
|
const [family, setFamily] = useState(null);
|
|
86
87
|
const [showFamily, setShowFamily] = useState(false);
|
|
87
88
|
const [loadingVariant, setLoadingVariant] = useState(null);
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
Agrupación de variantes. Vive aparte del padre/hijo de arriba a propósito:
|
|
92
|
+
son mecanismos independientes y un producto puede tener los dos. Padre/hijo
|
|
93
|
+
es herencia; esto es solo una agrupación por un código compartido.
|
|
94
|
+
*/
|
|
95
|
+
const [variantGroup, setVariantGroup] = useState(null);
|
|
96
|
+
const [showGroup, setShowGroup] = useState(false);
|
|
97
|
+
const [showGroupModal, setShowGroupModal] = useState(false);
|
|
88
98
|
const [pendingPropagation, setPendingPropagation] = useState(null);
|
|
89
99
|
const [preparandoPropagacion, setPreparandoPropagacion] = useState(false);
|
|
90
100
|
const [preparandoEdicionMultiple, setPreparandoEdicionMultiple] =
|
|
@@ -941,6 +951,72 @@ const ProviderProductEditionView = ({
|
|
|
941
951
|
setLinkNonce((n) => n + 1);
|
|
942
952
|
};
|
|
943
953
|
|
|
954
|
+
/*
|
|
955
|
+
Trae el grupo de variantes del producto y sus miembros.
|
|
956
|
+
|
|
957
|
+
Se pide al montar y no al abrir el desplegable —al contrario que la familia
|
|
958
|
+
padre/hijo— porque aquí el conteo no viene en el producto: `variant_group`
|
|
959
|
+
no lo devuelven los endpoints del listado, así que sin esta llamada la ficha
|
|
960
|
+
no sabría ni si el producto está agrupado.
|
|
961
|
+
*/
|
|
962
|
+
const loadVariantGroup = async (forzar = false) => {
|
|
963
|
+
if (variantGroup && !forzar) return variantGroup;
|
|
964
|
+
try {
|
|
965
|
+
const res = await axios.post(
|
|
966
|
+
`${process.env.REACT_APP_VARIANTS_ENDPOINT}/group`,
|
|
967
|
+
{ articleId: state.product?.id_article },
|
|
968
|
+
{ headers: { Authorization: token } }
|
|
969
|
+
);
|
|
970
|
+
const data = readPayload(res);
|
|
971
|
+
setVariantGroup(data);
|
|
972
|
+
return data;
|
|
973
|
+
} catch (error) {
|
|
974
|
+
console.error("loadVariantGroup: ", error);
|
|
975
|
+
setVariantGroup({ group: null, members: [], error: true });
|
|
976
|
+
return null;
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
useEffect(() => {
|
|
981
|
+
if (!state.product?.id_article) return;
|
|
982
|
+
loadVariantGroup(true);
|
|
983
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
984
|
+
}, [state.product?.id_article]);
|
|
985
|
+
|
|
986
|
+
// Saca el producto del grupo. Los demás miembros siguen agrupados entre ellos;
|
|
987
|
+
// si era el último, el grupo deja de existir, porque no vive en ninguna tabla.
|
|
988
|
+
const handleOnLeaveGroup = async () => {
|
|
989
|
+
try {
|
|
990
|
+
const res = await axios.post(
|
|
991
|
+
`${process.env.REACT_APP_VARIANTS_ENDPOINT}/leave`,
|
|
992
|
+
{ articleId: state.product?.id_article },
|
|
993
|
+
{ headers: { Authorization: token } }
|
|
994
|
+
);
|
|
995
|
+
setVariantGroup(readPayload(res));
|
|
996
|
+
setShowGroup(false);
|
|
997
|
+
} catch (error) {
|
|
998
|
+
console.error("leaveVariantGroup: ", error);
|
|
999
|
+
dispatch({
|
|
1000
|
+
type: "SET_MODAL",
|
|
1001
|
+
payload: {
|
|
1002
|
+
show: true,
|
|
1003
|
+
title: "Variantes",
|
|
1004
|
+
message: "No se pudo quitar el producto del grupo. Intenta de nuevo.",
|
|
1005
|
+
image: warningIcon,
|
|
1006
|
+
// Con `buttons` vacío el modal se queda sin forma de cerrarse.
|
|
1007
|
+
buttons: [
|
|
1008
|
+
{
|
|
1009
|
+
text: "Entendido",
|
|
1010
|
+
buttonType: "general-white-button",
|
|
1011
|
+
action: () =>
|
|
1012
|
+
dispatch({ type: "SET_MODAL", payload: { show: false } }),
|
|
1013
|
+
},
|
|
1014
|
+
],
|
|
1015
|
+
},
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
|
|
944
1020
|
const openVariant = async (articleId) => {
|
|
945
1021
|
setLoadingVariant(articleId);
|
|
946
1022
|
try {
|
|
@@ -1585,6 +1661,20 @@ const ProviderProductEditionView = ({
|
|
|
1585
1661
|
onLinked={handleOnLinkedVariants}
|
|
1586
1662
|
/>
|
|
1587
1663
|
)}
|
|
1664
|
+
{showGroupModal && (
|
|
1665
|
+
<VariantGroupModal
|
|
1666
|
+
articleId={state.product?.id_article}
|
|
1667
|
+
articleName={state.product?.name}
|
|
1668
|
+
articleUpc={state.product?.upc}
|
|
1669
|
+
currentGroup={variantGroup?.group ?? null}
|
|
1670
|
+
token={token}
|
|
1671
|
+
onClose={() => setShowGroupModal(false)}
|
|
1672
|
+
onSaved={(result) => {
|
|
1673
|
+
setVariantGroup(result);
|
|
1674
|
+
setShowGroup(true);
|
|
1675
|
+
}}
|
|
1676
|
+
/>
|
|
1677
|
+
)}
|
|
1588
1678
|
{porDesvincular && (
|
|
1589
1679
|
<UnlinkVariantModal
|
|
1590
1680
|
{...porDesvincular}
|
|
@@ -1947,6 +2037,80 @@ const ProviderProductEditionView = ({
|
|
|
1947
2037
|
)}
|
|
1948
2038
|
</div>
|
|
1949
2039
|
)}
|
|
2040
|
+
{/* AGRUPACIÓN DE VARIANTES.
|
|
2041
|
+
|
|
2042
|
+
Bloque aparte del de padre/hijo, y a propósito: son
|
|
2043
|
+
mecanismos independientes y un producto puede tener los dos.
|
|
2044
|
+
Padre/hijo es herencia y tiene jerarquía; esto es solo un
|
|
2045
|
+
código compartido que dice "estos son el mismo producto en
|
|
2046
|
+
otra presentación". Mezclarlos en una sola caja haría creer
|
|
2047
|
+
que agrupar hereda algo, que es justo lo que no pasa. */}
|
|
2048
|
+
<div className="variants-actions">
|
|
2049
|
+
<button
|
|
2050
|
+
type="button"
|
|
2051
|
+
className="link-variants"
|
|
2052
|
+
onClick={() => setShowGroupModal(true)}
|
|
2053
|
+
>
|
|
2054
|
+
{variantGroup?.group ? "Cambiar de grupo" : "Agrupar variantes"}
|
|
2055
|
+
</button>
|
|
2056
|
+
|
|
2057
|
+
{variantGroup?.group && (
|
|
2058
|
+
<button
|
|
2059
|
+
type="button"
|
|
2060
|
+
className="variants-count"
|
|
2061
|
+
aria-expanded={showGroup}
|
|
2062
|
+
onClick={() => setShowGroup((abierto) => !abierto)}
|
|
2063
|
+
>
|
|
2064
|
+
Variante {variantGroup.group}
|
|
2065
|
+
<span aria-hidden="true">{showGroup ? " ▴" : " ▾"}</span>
|
|
2066
|
+
</button>
|
|
2067
|
+
)}
|
|
2068
|
+
</div>
|
|
2069
|
+
|
|
2070
|
+
{showGroup && variantGroup?.group && (
|
|
2071
|
+
<div className="variants-family">
|
|
2072
|
+
{/* Los hermanos de grupo NO se listan como padre/hijo: aquí
|
|
2073
|
+
nadie hereda de nadie, así que no hay rol que mostrar,
|
|
2074
|
+
solo de qué productos se trata. */}
|
|
2075
|
+
{(variantGroup.members ?? [])
|
|
2076
|
+
.filter((miembro) => !miembro.isCurrent)
|
|
2077
|
+
.map((miembro) => (
|
|
2078
|
+
<div className="family-item" key={miembro.articleId}>
|
|
2079
|
+
<button
|
|
2080
|
+
type="button"
|
|
2081
|
+
className="family-row"
|
|
2082
|
+
disabled={loadingVariant !== null}
|
|
2083
|
+
onClick={() => openVariant(miembro.articleId)}
|
|
2084
|
+
>
|
|
2085
|
+
<span className="role">
|
|
2086
|
+
{loadingVariant === miembro.articleId
|
|
2087
|
+
? "Abriendo…"
|
|
2088
|
+
: "Variante"}
|
|
2089
|
+
</span>
|
|
2090
|
+
<span className="name">{miembro.name}</span>
|
|
2091
|
+
<span className="upc">{miembro.upc}</span>
|
|
2092
|
+
</button>
|
|
2093
|
+
</div>
|
|
2094
|
+
))}
|
|
2095
|
+
|
|
2096
|
+
{(variantGroup.members ?? []).filter((m) => !m.isCurrent)
|
|
2097
|
+
.length === 0 && (
|
|
2098
|
+
<p className="loading">
|
|
2099
|
+
Este producto es el único en el grupo {variantGroup.group}.
|
|
2100
|
+
</p>
|
|
2101
|
+
)}
|
|
2102
|
+
|
|
2103
|
+
<button
|
|
2104
|
+
type="button"
|
|
2105
|
+
className="desvincular"
|
|
2106
|
+
title="Quitar este producto del grupo"
|
|
2107
|
+
onClick={handleOnLeaveGroup}
|
|
2108
|
+
>
|
|
2109
|
+
Quitar del grupo
|
|
2110
|
+
</button>
|
|
2111
|
+
</div>
|
|
2112
|
+
)}
|
|
2113
|
+
|
|
1950
2114
|
<FullProductNameHeader
|
|
1951
2115
|
headerData={state.product}
|
|
1952
2116
|
percent={state.active_percentage?.percentagesGeneral?.required}
|
|
@@ -52,6 +52,7 @@ import { VersionSelector } from "../../organisms/VersionSelector";
|
|
|
52
52
|
import { Modal } from "../../organisms/Modal";
|
|
53
53
|
import { LinkVariantsModal } from "../../organisms/LinkVariantsModal";
|
|
54
54
|
import { UnlinkVariantModal } from "../../organisms/UnlinkVariantModal";
|
|
55
|
+
import { VariantGroupModal } from "../../organisms/VariantGroupModal";
|
|
55
56
|
import { PropagateChangesModal } from "../../organisms/PropagateChangesModal";
|
|
56
57
|
import { readPayload } from "../../organisms/LinkVariantsModal/api";
|
|
57
58
|
|
|
@@ -186,6 +187,15 @@ const RetailerProductEditionView = ({
|
|
|
186
187
|
const [family, setFamily] = useState(null);
|
|
187
188
|
const [showFamily, setShowFamily] = useState(false);
|
|
188
189
|
const [loadingVariant, setLoadingVariant] = useState(null);
|
|
190
|
+
|
|
191
|
+
/*
|
|
192
|
+
Agrupación de variantes. Aparte del padre/hijo a propósito: son mecanismos
|
|
193
|
+
independientes y un producto puede tener los dos. Padre/hijo es herencia;
|
|
194
|
+
esto es solo un código compartido.
|
|
195
|
+
*/
|
|
196
|
+
const [variantGroup, setVariantGroup] = useState(null);
|
|
197
|
+
const [showGroup, setShowGroup] = useState(false);
|
|
198
|
+
const [showGroupModal, setShowGroupModal] = useState(false);
|
|
189
199
|
// Qué vínculo se está por romper, o null si no hay diálogo abierto. Guarda al
|
|
190
200
|
// HIJO, que es quien lleva la relación y lo que pide la acción `unlink`.
|
|
191
201
|
const [porDesvincular, setPorDesvincular] = useState(null);
|
|
@@ -975,6 +985,68 @@ const RetailerProductEditionView = ({
|
|
|
975
985
|
loadData(false);
|
|
976
986
|
};
|
|
977
987
|
|
|
988
|
+
/*
|
|
989
|
+
Trae el grupo de variantes y sus miembros.
|
|
990
|
+
|
|
991
|
+
Al montar, no al abrir el desplegable: `variant_group` no lo devuelve el
|
|
992
|
+
endpoint del listado, así que sin esta llamada la ficha no sabe si el
|
|
993
|
+
producto está agrupado.
|
|
994
|
+
*/
|
|
995
|
+
const loadVariantGroup = async (forzar = false) => {
|
|
996
|
+
if (variantGroup && !forzar) return variantGroup;
|
|
997
|
+
try {
|
|
998
|
+
const res = await axios.post(
|
|
999
|
+
`${process.env.REACT_APP_VARIANTS_ENDPOINT}/group`,
|
|
1000
|
+
{ articleId: state.product?.id_article },
|
|
1001
|
+
{ headers: { Authorization: token } }
|
|
1002
|
+
);
|
|
1003
|
+
const data = readPayload(res);
|
|
1004
|
+
setVariantGroup(data);
|
|
1005
|
+
return data;
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
console.error("loadVariantGroup: ", error);
|
|
1008
|
+
setVariantGroup({ group: null, members: [], error: true });
|
|
1009
|
+
return null;
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
|
|
1013
|
+
useEffect(() => {
|
|
1014
|
+
if (!state.product?.id_article) return;
|
|
1015
|
+
loadVariantGroup(true);
|
|
1016
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1017
|
+
}, [state.product?.id_article]);
|
|
1018
|
+
|
|
1019
|
+
const handleOnLeaveGroup = async () => {
|
|
1020
|
+
try {
|
|
1021
|
+
const res = await axios.post(
|
|
1022
|
+
`${process.env.REACT_APP_VARIANTS_ENDPOINT}/leave`,
|
|
1023
|
+
{ articleId: state.product?.id_article },
|
|
1024
|
+
{ headers: { Authorization: token } }
|
|
1025
|
+
);
|
|
1026
|
+
setVariantGroup(readPayload(res));
|
|
1027
|
+
setShowGroup(false);
|
|
1028
|
+
} catch (error) {
|
|
1029
|
+
console.error("leaveVariantGroup: ", error);
|
|
1030
|
+
dispatch({
|
|
1031
|
+
type: "SET_MODAL",
|
|
1032
|
+
payload: {
|
|
1033
|
+
show: true,
|
|
1034
|
+
title: "Variantes",
|
|
1035
|
+
message: "No se pudo quitar el producto del grupo. Intenta de nuevo.",
|
|
1036
|
+
image: warningIcon,
|
|
1037
|
+
buttons: [
|
|
1038
|
+
{
|
|
1039
|
+
text: "Entendido",
|
|
1040
|
+
buttonType: "general-white-button",
|
|
1041
|
+
action: () =>
|
|
1042
|
+
dispatch({ type: "SET_MODAL", payload: { show: false } }),
|
|
1043
|
+
},
|
|
1044
|
+
],
|
|
1045
|
+
},
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
|
|
978
1050
|
const openFamilyMember = async (articleId) => {
|
|
979
1051
|
setLoadingVariant(articleId);
|
|
980
1052
|
setAvisoFamilia(null);
|
|
@@ -2030,6 +2102,20 @@ const RetailerProductEditionView = ({
|
|
|
2030
2102
|
onLinked={handleOnLinkedVariants}
|
|
2031
2103
|
/>
|
|
2032
2104
|
)}
|
|
2105
|
+
{showGroupModal && (
|
|
2106
|
+
<VariantGroupModal
|
|
2107
|
+
articleId={state.product?.id_article}
|
|
2108
|
+
articleName={state.product?.name}
|
|
2109
|
+
articleUpc={state.product?.upc}
|
|
2110
|
+
currentGroup={variantGroup?.group ?? null}
|
|
2111
|
+
token={token}
|
|
2112
|
+
onClose={() => setShowGroupModal(false)}
|
|
2113
|
+
onSaved={(result) => {
|
|
2114
|
+
setVariantGroup(result);
|
|
2115
|
+
setShowGroup(true);
|
|
2116
|
+
}}
|
|
2117
|
+
/>
|
|
2118
|
+
)}
|
|
2033
2119
|
{porDesvincular && (
|
|
2034
2120
|
<UnlinkVariantModal
|
|
2035
2121
|
{...porDesvincular}
|
|
@@ -2392,6 +2478,76 @@ const RetailerProductEditionView = ({
|
|
|
2392
2478
|
</div>
|
|
2393
2479
|
)}
|
|
2394
2480
|
|
|
2481
|
+
{/* AGRUPACIÓN DE VARIANTES.
|
|
2482
|
+
|
|
2483
|
+
Bloque aparte del de padre/hijo a propósito: son mecanismos
|
|
2484
|
+
independientes y un producto puede tener los dos. Padre/hijo es
|
|
2485
|
+
herencia y tiene jerarquía; esto es solo un código compartido
|
|
2486
|
+
que dice "estos son el mismo producto en otra presentación".
|
|
2487
|
+
Juntarlos haría creer que agrupar hereda algo, que no pasa. */}
|
|
2488
|
+
<div className="variants-actions">
|
|
2489
|
+
<button
|
|
2490
|
+
type="button"
|
|
2491
|
+
className="link-variants"
|
|
2492
|
+
onClick={() => setShowGroupModal(true)}
|
|
2493
|
+
>
|
|
2494
|
+
{variantGroup?.group ? "Cambiar de grupo" : "Agrupar variantes"}
|
|
2495
|
+
</button>
|
|
2496
|
+
|
|
2497
|
+
{variantGroup?.group && (
|
|
2498
|
+
<button
|
|
2499
|
+
type="button"
|
|
2500
|
+
className="variants-count"
|
|
2501
|
+
aria-expanded={showGroup}
|
|
2502
|
+
onClick={() => setShowGroup((abierto) => !abierto)}
|
|
2503
|
+
>
|
|
2504
|
+
Variante {variantGroup.group}
|
|
2505
|
+
<span aria-hidden="true">{showGroup ? " ▴" : " ▾"}</span>
|
|
2506
|
+
</button>
|
|
2507
|
+
)}
|
|
2508
|
+
</div>
|
|
2509
|
+
|
|
2510
|
+
{showGroup && variantGroup?.group && (
|
|
2511
|
+
<div className="variants-family">
|
|
2512
|
+
{(variantGroup.members ?? [])
|
|
2513
|
+
.filter((miembro) => !miembro.isCurrent)
|
|
2514
|
+
.map((miembro) => (
|
|
2515
|
+
<div className="family-item" key={miembro.articleId}>
|
|
2516
|
+
<button
|
|
2517
|
+
type="button"
|
|
2518
|
+
className="family-row"
|
|
2519
|
+
disabled={loadingVariant !== null}
|
|
2520
|
+
onClick={() => openFamilyMember(miembro.articleId)}
|
|
2521
|
+
>
|
|
2522
|
+
<span className="role">
|
|
2523
|
+
{loadingVariant === miembro.articleId
|
|
2524
|
+
? "Abriendo…"
|
|
2525
|
+
: "Variante"}
|
|
2526
|
+
</span>
|
|
2527
|
+
<span className="name">{miembro.name}</span>
|
|
2528
|
+
<span className="upc">{miembro.upc}</span>
|
|
2529
|
+
</button>
|
|
2530
|
+
</div>
|
|
2531
|
+
))}
|
|
2532
|
+
|
|
2533
|
+
{(variantGroup.members ?? []).filter((m) => !m.isCurrent)
|
|
2534
|
+
.length === 0 && (
|
|
2535
|
+
<p className="loading">
|
|
2536
|
+
Este producto es el único en el grupo {variantGroup.group}.
|
|
2537
|
+
</p>
|
|
2538
|
+
)}
|
|
2539
|
+
|
|
2540
|
+
<button
|
|
2541
|
+
type="button"
|
|
2542
|
+
className="desvincular"
|
|
2543
|
+
title="Quitar este producto del grupo"
|
|
2544
|
+
onClick={handleOnLeaveGroup}
|
|
2545
|
+
>
|
|
2546
|
+
Quitar del grupo
|
|
2547
|
+
</button>
|
|
2548
|
+
</div>
|
|
2549
|
+
)}
|
|
2550
|
+
|
|
2395
2551
|
<FullProductNameHeader
|
|
2396
2552
|
// states
|
|
2397
2553
|
headerData={state.product}
|
package/src/index.js
CHANGED
|
@@ -90,6 +90,7 @@ export * from "./components/organisms/InputGroup/index";
|
|
|
90
90
|
export * from "./components/organisms/LinkVariantsModal/index";
|
|
91
91
|
export * from "./components/organisms/PropagateChangesModal/index";
|
|
92
92
|
export * from "./components/organisms/UnlinkVariantModal/index";
|
|
93
|
+
export * from "./components/organisms/VariantGroupModal/index";
|
|
93
94
|
export * from "./components/organisms/ProductImageModal/index";
|
|
94
95
|
export * from "./components/organisms/Chat/index";
|
|
95
96
|
export * from "./components/organisms/Modal/index";
|