contentoh-components-library 21.5.99 → 21.6.1
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/GeneralButton/styles.js +1 -1
- package/dist/components/atoms/GeneralInput/index.js +249 -54
- package/dist/components/atoms/GeneralInput/styles.js +7 -3
- package/dist/components/atoms/InputFormatter/index.js +223 -68
- package/dist/components/atoms/InputFormatter/styles.js +20 -4
- package/dist/components/molecules/StatusAsignationInfo/index.js +11 -1
- package/dist/components/molecules/TabsMenu/index.js +13 -1
- package/dist/components/molecules/TagAndInput/index.js +364 -24
- package/dist/components/molecules/TagAndInput/styles.js +2 -2
- package/dist/components/organisms/FullProductNameHeader/index.js +6 -22
- package/dist/components/organisms/InputGroup/index.js +22 -18
- package/dist/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +150 -337
- package/dist/components/pages/ProviderProductEdition/context/provider-product-edition.context.js +15 -15
- package/dist/components/pages/ProviderProductEdition/index.js +393 -352
- package/dist/components/pages/ProviderProductEdition/utils.js +1 -0
- package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +125 -211
- package/dist/components/pages/RetailerProductEdition/index.js +1743 -2239
- package/dist/components/pages/RetailerProductEdition/styles.js +4 -2
- package/dist/components/pages/RetailerProductEdition/utils.js +251 -2
- package/dist/contexts/AiProductEdition.js +34 -22
- package/package.json +4 -2
- package/src/ai/utils/compare-strings.js +45 -0
- package/src/assets/images/Icons/arrow.png +0 -0
- package/src/assets/images/Icons/cancel.png +0 -0
- package/src/assets/images/Icons/ia-icon.png +0 -0
- package/src/assets/images/Icons/loading.svg +5 -0
- package/src/assets/images/Icons/reload.png +0 -0
- package/src/components/atoms/GeneralButton/styles.js +4 -0
- package/src/components/atoms/GeneralInput/index.js +241 -60
- package/src/components/atoms/GeneralInput/styles.js +81 -0
- package/src/components/atoms/InputFormatter/index.js +200 -51
- package/src/components/atoms/InputFormatter/styles.js +284 -0
- package/src/components/atoms/RetailerSelector/RetailerSelector.stories.js +10 -0
- package/src/components/atoms/RetailerSelector/index.js +3 -0
- package/src/components/atoms/RetailerSelector/styles.js +0 -0
- package/src/components/molecules/StatusAsignationInfo/index.js +9 -1
- package/src/components/molecules/TabsMenu/index.js +12 -0
- package/src/components/molecules/TagAndInput/index.js +294 -21
- package/src/components/molecules/TagAndInput/styles.js +59 -17
- package/src/components/organisms/ChangeStatusModal/index.jsx +488 -0
- package/src/components/organisms/ChangeStatusModal/styles.js +333 -0
- package/src/components/organisms/FullProductNameHeader/index.js +4 -28
- package/src/components/organisms/FullTabsMenu/index.js +1 -1
- package/src/components/organisms/InputGroup/index.js +12 -4
- package/src/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +174 -202
- package/src/components/pages/ProviderProductEdition/context/provider-product-edition.context.jsx +14 -14
- package/src/components/pages/ProviderProductEdition/index.js +486 -417
- package/src/components/pages/ProviderProductEdition/utils.js +2 -2
- package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +136 -243
- package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +575 -0
- package/src/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +62 -0
- package/src/components/pages/RetailerProductEdition/context/reducers/active-state.js +344 -0
- package/src/components/pages/RetailerProductEdition/context/reducers/inputs.js +155 -0
- package/src/components/pages/RetailerProductEdition/context/reducers/product.js +114 -0
- package/src/components/pages/RetailerProductEdition/context/reducers/system.js +60 -0
- package/src/components/pages/RetailerProductEdition/index.js +1580 -1719
- package/src/components/pages/RetailerProductEdition/index_old.js +1979 -0
- package/src/components/pages/RetailerProductEdition/stories/Auditor.stories.js +101 -0
- package/src/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +115 -0
- package/src/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +174 -0
- package/src/components/pages/RetailerProductEdition/styles.js +67 -2
- package/src/components/pages/RetailerProductEdition/utils.js +240 -0
- package/src/contexts/AiProductEdition.jsx +356 -0
- package/src/global-files/statusDictionary.js +103 -0
|
@@ -1,392 +1,297 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { FullProductNameHeader } from "../../organisms/FullProductNameHeader";
|
|
6
|
-
import { FullTabsMenu } from "../../organisms/FullTabsMenu";
|
|
7
|
-
import { InputGroup } from "../../organisms/InputGroup";
|
|
8
|
-
import { useEffect, useReducer, useState, useCallback } from "react";
|
|
9
|
-
import { GalleryElement } from "../../molecules/GalleryElement";
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import { useDropzone } from "react-dropzone";
|
|
10
5
|
import { saveAs } from "file-saver";
|
|
11
|
-
|
|
6
|
+
|
|
12
7
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "../../../global-files/data";
|
|
17
|
-
import { GalleryHeader } from "../../molecules/GalleryHeader";
|
|
18
|
-
import { ProductImageModal } from "../../organisms/ProductImageModal";
|
|
19
|
-
import { useDropzone } from "react-dropzone";
|
|
20
|
-
import axios from "axios";
|
|
21
|
-
import { v4 as uuidv4 } from "uuid";
|
|
22
|
-
import AWS from "aws-sdk";
|
|
23
|
-
import attributesSent from "../../../assets/images/modalsSVGs/attributesSent.svg";
|
|
24
|
-
import descriptionSent from "../../../assets/images/modalsSVGs/descriptionSent.svg";
|
|
25
|
-
import imagesSent from "../../../assets/images/modalsSVGs/uploadingImages.svg";
|
|
26
|
-
import { TagAndInput } from "../../molecules/TagAndInput/index";
|
|
27
|
-
import { Button } from "../../atoms/GeneralButton";
|
|
28
|
-
import { GenericModal } from "../../atoms/GenericModal";
|
|
29
|
-
import { ScreenHeader } from "../../atoms/ScreenHeader";
|
|
30
|
-
import { Loading } from "../../atoms/Loading";
|
|
31
|
-
import succes from "../../../assets/images/genericModal/genericModalCheck.svg";
|
|
32
|
-
import { VersionSelector } from "../../organisms/VersionSelector";
|
|
33
|
-
import { useCloseModal } from "../../../global-files/customHooks";
|
|
8
|
+
ProviderProductEditionProvider,
|
|
9
|
+
useProviderProductEdition,
|
|
10
|
+
} from "./context/provider-product-edition.context";
|
|
34
11
|
import {
|
|
12
|
+
normalizeProduct,
|
|
13
|
+
getConceptByTab,
|
|
35
14
|
getAuditVersion,
|
|
36
15
|
getInputsData,
|
|
37
16
|
createMessage,
|
|
38
17
|
sendMessage,
|
|
18
|
+
translateConcept,
|
|
19
|
+
getStatusArrayByRole,
|
|
20
|
+
getConceptsByRole,
|
|
21
|
+
buildCollaboratorAssignations,
|
|
22
|
+
calculateRequiredNull,
|
|
39
23
|
} from "./utils";
|
|
40
|
-
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
fetchUsers,
|
|
27
|
+
getPercentage,
|
|
28
|
+
getRetailerServices,
|
|
29
|
+
getServicesData,
|
|
30
|
+
} from "../../../global-files/data";
|
|
31
|
+
import { useCloseModal } from "../../../global-files/customHooks";
|
|
32
|
+
|
|
33
|
+
import { Button } from "../../atoms/GeneralButton";
|
|
34
|
+
import { GenericModal } from "../../atoms/GenericModal";
|
|
35
|
+
import { Loading } from "../../atoms/Loading";
|
|
36
|
+
import { ScreenHeader } from "../../atoms/ScreenHeader";
|
|
41
37
|
import { ButtonV2 } from "../../atoms/ButtonV2";
|
|
42
|
-
import generateThumbnail from "./generateThumnail";
|
|
43
|
-
|
|
44
|
-
const reducerImages = (state, action) => {
|
|
45
|
-
let { values, attrForImgs, inputsByRetailer } = state;
|
|
46
|
-
switch (action.action) {
|
|
47
|
-
case "init":
|
|
48
|
-
const newInputsByRetailer = {};
|
|
49
|
-
action?.init?.inputsByRetailer?.forEach((inputs) => {
|
|
50
|
-
inputs?.forEach((input) => {
|
|
51
|
-
if (!newInputsByRetailer[`${input.id_retailer}`])
|
|
52
|
-
newInputsByRetailer[`${input.id_retailer}`] = [];
|
|
53
|
-
newInputsByRetailer[`${input.id_retailer}`].push(input);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
inputsByRetailer = newInputsByRetailer;
|
|
57
|
-
return {
|
|
58
|
-
...action.init,
|
|
59
|
-
inputsByRetailer,
|
|
60
|
-
valuesInitial: action.init.values,
|
|
61
|
-
inputsInitial: action.init.inputs,
|
|
62
|
-
};
|
|
63
|
-
case "addImg":
|
|
64
|
-
values = [...values, action.img];
|
|
65
|
-
return { ...state, values };
|
|
66
|
-
case "changeImageInfo":
|
|
67
|
-
values[action.index][action.attribute] = action.value;
|
|
68
|
-
return { ...state, values };
|
|
69
|
-
case "changeShotType":
|
|
70
|
-
values[action.index][action.attribute] = action.value;
|
|
71
|
-
return { ...state, values };
|
|
72
|
-
|
|
73
|
-
case "changeAttrValue":
|
|
74
|
-
const index = attrForImgs.general.findIndex((f) => f.id === action.id);
|
|
75
|
-
if (index !== -1) {
|
|
76
|
-
attrForImgs.general[index].value = action.value;
|
|
77
|
-
}
|
|
78
38
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
84
|
-
return { ...state, values };
|
|
85
|
-
case "orderImages": {
|
|
86
|
-
let { inputsByRetailer, valuesInitial, inputsInitial, inputs } = state;
|
|
87
|
-
try {
|
|
88
|
-
const orderedImages = [];
|
|
89
|
-
const imageIdArray = [];
|
|
90
|
-
if (action?.retailerId && !inputsByRetailer[action.retailerId]) {
|
|
91
|
-
inputsByRetailer[action.retailerId] = [];
|
|
92
|
-
}
|
|
93
|
-
action.retailerId &&
|
|
94
|
-
inputsByRetailer[action.retailerId]?.filter((input) => {
|
|
95
|
-
imageIdArray.push(input.id_image);
|
|
96
|
-
valuesInitial.forEach(async (value) => {
|
|
97
|
-
if (value.ext == "mp4") {
|
|
98
|
-
convertirVideoABase64(
|
|
99
|
-
"https://" +
|
|
100
|
-
process.env.REACT_APP_IMAGES_BUCKET +
|
|
101
|
-
".s3.amazonaws.com/" +
|
|
102
|
-
value.srcDB
|
|
103
|
-
)
|
|
104
|
-
.then(async (base64) => {
|
|
105
|
-
const videoSrc =
|
|
106
|
-
"data:video/mp4;base64," + base64.split(",")[1]; // Añade el tipo MIME adecuado
|
|
107
|
-
value.src = await generateThumbnail(videoSrc, 2);
|
|
108
|
-
})
|
|
109
|
-
.catch((error) => {
|
|
110
|
-
console.error("Error:", error);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
if (value.image_id === input.id_image) orderedImages.push(value);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
inputs = inputsInitial?.filter((input) =>
|
|
117
|
-
imageIdArray.includes(input.id)
|
|
118
|
-
);
|
|
39
|
+
import { GalleryElement } from "../../molecules/GalleryElement";
|
|
40
|
+
import { GalleryHeader } from "../../molecules/GalleryHeader";
|
|
41
|
+
import { HeaderTop } from "../../molecules/HeaderTop";
|
|
42
|
+
import { TagAndInput } from "../../molecules/TagAndInput/index";
|
|
119
43
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
};
|
|
44
|
+
import { FullProductNameHeader } from "../../organisms/FullProductNameHeader";
|
|
45
|
+
import { FullTabsMenu } from "../../organisms/FullTabsMenu";
|
|
46
|
+
import { ImageDataTable } from "../../organisms/ImageDataTable";
|
|
47
|
+
import { ImagePreviewer } from "../../organisms/ImagePreviewer";
|
|
48
|
+
import { InputGroup } from "../../organisms/InputGroup";
|
|
49
|
+
import { ProductImageModal } from "../../organisms/ProductImageModal";
|
|
50
|
+
import { VersionSelector } from "../../organisms/VersionSelector";
|
|
51
|
+
import { Modal } from "../../organisms/Modal";
|
|
130
52
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (xhr.status === 200) {
|
|
141
|
-
const blob = xhr.response;
|
|
142
|
-
const reader = new FileReader();
|
|
143
|
-
reader.onloadend = function () {
|
|
144
|
-
resolve(reader.result);
|
|
145
|
-
};
|
|
146
|
-
reader.readAsDataURL(blob);
|
|
147
|
-
} else {
|
|
148
|
-
reject(new Error("Error al cargar el video"));
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
xhr.onerror = function () {
|
|
152
|
-
reject(new Error("Error de red al cargar el video"));
|
|
153
|
-
};
|
|
154
|
-
xhr.send();
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function obtenerDuracionVideoBase64(base64Data) {
|
|
159
|
-
return new Promise((resolve, reject) => {
|
|
160
|
-
const video = document.createElement("video");
|
|
161
|
-
video.src = base64Data;
|
|
162
|
-
video.addEventListener("loadedmetadata", () => {
|
|
163
|
-
resolve(video.duration);
|
|
164
|
-
});
|
|
165
|
-
video.addEventListener("error", reject);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
53
|
+
import successIcon from "../../../assets/images/genericModal/genericModalCheck.svg";
|
|
54
|
+
import errorIcon from "../../../assets/images/genericModal/errorModal.svg";
|
|
55
|
+
import warningIcon from "../../../assets/images/genericModal/genericModalWarning.svg";
|
|
56
|
+
import attributesSent from "../../../assets/images/modalsSVGs/attributesSent.svg";
|
|
57
|
+
import descriptionSent from "../../../assets/images/modalsSVGs/descriptionSent.svg";
|
|
58
|
+
import imagesSent from "../../../assets/images/modalsSVGs/uploadingImages.svg";
|
|
59
|
+
|
|
60
|
+
import { Container } from "./styles";
|
|
61
|
+
import { Commentary } from "../../atoms/Commentary";
|
|
168
62
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
secretAccessKey: process.env.REACT_APP_AKUTS3,
|
|
172
|
-
});
|
|
63
|
+
import { AiProductEditionProvider } from "../../../contexts/AiProductEdition";
|
|
64
|
+
import ChangeStatusModal from "../../organisms/ChangeStatusModal";
|
|
173
65
|
|
|
174
|
-
|
|
175
|
-
params: { Bucket: S3_BUCKET },
|
|
176
|
-
region: REGION,
|
|
177
|
-
});
|
|
66
|
+
import { Skeleton, Box, Stack } from "@mui/material";
|
|
178
67
|
|
|
179
|
-
|
|
68
|
+
const allowedAccountsToViewChangeStatus = [
|
|
69
|
+
"mperez@contentoh.com",
|
|
70
|
+
"gmorales@contentoh.com",
|
|
71
|
+
"rvega@contentoh.com",
|
|
72
|
+
"amora@contentoh.com",
|
|
73
|
+
"oparra@contentoh.com",
|
|
74
|
+
"zsegura@contentoh.com",
|
|
75
|
+
"oserna@contentoh.com",
|
|
76
|
+
"jalvarado@contentoh.com"
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
const RetailerProductEditionView = ({
|
|
180
80
|
tabsSections,
|
|
181
81
|
productSelected = {},
|
|
182
82
|
user = {},
|
|
183
83
|
token,
|
|
184
84
|
location,
|
|
185
85
|
}) => {
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
86
|
+
const {
|
|
87
|
+
state,
|
|
88
|
+
dispatch,
|
|
89
|
+
saveDatasheets,
|
|
90
|
+
saveDescriptions,
|
|
91
|
+
updateImages,
|
|
92
|
+
saveImageAttrs,
|
|
93
|
+
deleteImages,
|
|
94
|
+
handleOnDownloadImages,
|
|
95
|
+
createComment,
|
|
96
|
+
} = useProviderProductEdition();
|
|
97
|
+
|
|
98
|
+
const isRetailer = user?.is_retailer;
|
|
99
|
+
|
|
100
|
+
const [showVersionSelector, setShowVersionSelector] =
|
|
101
|
+
useCloseModal("version-selector");
|
|
102
|
+
const [auditableVersion, setAuditableVersion] = useState(null);
|
|
189
103
|
const [headerTop, setHeaderTop] = useState(0);
|
|
190
|
-
const [
|
|
191
|
-
const [
|
|
192
|
-
const [images, setImages] = useReducer(reducerImages, {});
|
|
193
|
-
const [showModal, setShowModal] = useState(false);
|
|
104
|
+
const [shotThd, setShotThd] = useState(false);
|
|
105
|
+
const [observation, setObservation] = useState();
|
|
194
106
|
const [showRejectModal, setShowRejectModal] = useState(false);
|
|
195
|
-
const
|
|
196
|
-
|
|
107
|
+
const [isObservationVisible, setObservationVisible] = useState(false);
|
|
108
|
+
const [imageLayout, setImageLayout] = useState(false);
|
|
109
|
+
const [crossComment, setCrossComment] = useState(false);
|
|
110
|
+
const [statusArray, setStatusArray] = useState([]);
|
|
111
|
+
const [rejectAll, setRejectAll] = useState(false);
|
|
112
|
+
|
|
113
|
+
const [auditServices, setAuditServices] = useState([]);
|
|
114
|
+
const [auditDatasheets, setAuditDatasheets] = useState([]);
|
|
115
|
+
const [auditDescriptions, setAuditDescriptions] = useState([]);
|
|
116
|
+
const [showModal, setShowModal] = useState(false);
|
|
117
|
+
|
|
118
|
+
const [compare, setCompare] = useState(false);
|
|
119
|
+
const { getRootProps, getInputProps, isDragActive, open } = useDropzone({
|
|
120
|
+
accept: "image/*",
|
|
197
121
|
noKeyboard: true,
|
|
198
122
|
multiple: true,
|
|
199
123
|
noClick: true,
|
|
200
124
|
onDrop: (acceptedFiles) => {
|
|
201
|
-
const newImages = [];
|
|
202
125
|
acceptedFiles.map((file) => {
|
|
203
126
|
const reader = new FileReader();
|
|
204
127
|
reader.fileName = file.name;
|
|
128
|
+
|
|
205
129
|
reader.onload = async function (e) {
|
|
206
|
-
const
|
|
130
|
+
const fileName = e.target.fileName;
|
|
131
|
+
const fileExtension = fileName.split(".").pop();
|
|
132
|
+
const fileDataURL = e.target.result;
|
|
133
|
+
|
|
207
134
|
const img = new Image();
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
};
|
|
228
|
-
setImages(newImg);
|
|
229
|
-
}, 500);
|
|
230
|
-
} else {
|
|
231
|
-
setModalAlert({
|
|
232
|
-
show: true,
|
|
233
|
-
title: "Hubo un error al subir el video",
|
|
234
|
-
message:
|
|
235
|
-
"Los videos deben durar entre 15 segundos y 10 minutos",
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
})
|
|
239
|
-
.catch((error) => {
|
|
240
|
-
console.error("Error al obtener la duración del video:", error);
|
|
241
|
-
});
|
|
242
|
-
} else {
|
|
243
|
-
img.src = e.target.result;
|
|
244
|
-
setTimeout(() => {
|
|
245
|
-
const width = img.width;
|
|
246
|
-
const height = img.height;
|
|
247
|
-
const newImg = {
|
|
248
|
-
action: "addImg",
|
|
249
|
-
img: {
|
|
250
|
-
src: img.src, //e.target.result,
|
|
251
|
-
name: e.target.fileName,
|
|
252
|
-
ext: ext[ext.length - 1],
|
|
253
|
-
width: width,
|
|
254
|
-
height: height,
|
|
255
|
-
video_src:
|
|
256
|
-
ext[ext.length - 1] == "mp4" ? e.target.result : "",
|
|
257
|
-
},
|
|
258
|
-
};
|
|
259
|
-
setImages(newImg);
|
|
260
|
-
}, 500);
|
|
261
|
-
}
|
|
135
|
+
img.src = fileDataURL;
|
|
136
|
+
|
|
137
|
+
img.onload = function () {
|
|
138
|
+
const width = img.width;
|
|
139
|
+
const height = img.height;
|
|
140
|
+
const newImg = {
|
|
141
|
+
src: fileDataURL,
|
|
142
|
+
name: fileName,
|
|
143
|
+
ext: fileExtension,
|
|
144
|
+
width: width,
|
|
145
|
+
height: height,
|
|
146
|
+
isApproved: true, // VALIDAR QUE SOLO SEA PARA RADIOSHACK
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
dispatch({
|
|
150
|
+
type: "ADD_IMAGE_VALUE",
|
|
151
|
+
payload: newImg,
|
|
152
|
+
});
|
|
153
|
+
};
|
|
262
154
|
};
|
|
155
|
+
|
|
263
156
|
reader.onerror = function (error) {
|
|
264
157
|
console.log("dropzoneError: ", error);
|
|
265
158
|
};
|
|
159
|
+
|
|
266
160
|
reader.readAsDataURL(file);
|
|
267
161
|
return file;
|
|
268
162
|
});
|
|
269
163
|
},
|
|
270
164
|
});
|
|
271
|
-
const [updatedDatasheets, setUpdatedDatasheets] = useState([]);
|
|
272
|
-
const [updatedDescriptions, setUpdatedDescriptions] = useState([]);
|
|
273
|
-
const [imagesUploaded, setImagesUploaded] = useState(false);
|
|
274
|
-
const [dataImages, setDataImages] = useState();
|
|
275
|
-
const [percentages, setPercentages] = useState(
|
|
276
|
-
new Array(product?.retailers?.length).fill({ percentage: 0 })
|
|
277
|
-
);
|
|
278
|
-
// const [percentages, setPercentages] = useState([{ retailers: {} }]);
|
|
279
|
-
const [activePercentage, setActivePercentage] = useState(0);
|
|
280
|
-
const [activeRetailer, setActiveRetailer] = useState({});
|
|
281
|
-
const [services, setServices] = useState([]);
|
|
282
|
-
const [servicesData, setServicesData] = useState([]);
|
|
283
|
-
const [message, setMessage] = useState("");
|
|
284
|
-
const [product, setProduct] = useState(
|
|
285
|
-
JSON.parse(sessionStorage.getItem("productSelected"))
|
|
286
|
-
? JSON.parse(sessionStorage.getItem("productSelected"))
|
|
287
|
-
: productSelected
|
|
288
|
-
);
|
|
289
|
-
const [icon, setIcon] = useState(null);
|
|
290
|
-
const [version, setVersion] = useState(product?.version);
|
|
291
|
-
const [comments, setComments] = useState({});
|
|
292
|
-
const [comment, setComment] = useState("");
|
|
293
|
-
const [requiredNull, setRequiredNull] = useState({
|
|
294
|
-
"Ficha técnica": 0,
|
|
295
|
-
Descripción: 0,
|
|
296
|
-
Imágenes: 0,
|
|
297
|
-
});
|
|
298
|
-
const [crossComment, setCrossComment] = useState(false);
|
|
299
|
-
const [userGroups, setUserGroups] = useState([]);
|
|
300
|
-
const [assig, setAssig] = useState({});
|
|
301
|
-
const [selectedImages, setSelectedImages] = useState([]);
|
|
302
|
-
const [componentsArray, setComponentsArray] = useState([]);
|
|
303
|
-
const [checkAll, setCheckAll] = useState(false);
|
|
304
|
-
const isRetailer = user?.is_retailer;
|
|
305
|
-
const [loading, setLoading] = useState(true);
|
|
306
|
-
const [retailerStatus, setRetailerStatus] = useState("-");
|
|
307
|
-
const [statusArray, setStatusArray] = useState([]);
|
|
308
|
-
const [socketType, setSocketType] = useState(null);
|
|
309
|
-
const [saving, setSaving] = useState(loading);
|
|
310
|
-
const [showVersionSelector, setShowVersionSelector] =
|
|
311
|
-
useCloseModal("version-selector");
|
|
312
|
-
const shotThd = [58, 59, 60, 61].includes(activeRetailer.id);
|
|
313
|
-
const [auditableVersion, setAuditableVersion] = useState(null);
|
|
314
|
-
const [auditServices, setAuditServices] = useState([]);
|
|
315
|
-
const [auditDatasheets, setAuditDatasheets] = useState([]);
|
|
316
|
-
const [auditDescriptions, setAuditDescriptions] = useState([]);
|
|
317
|
-
const [auditImages, setAuditImages] = useState([]);
|
|
318
|
-
const [compare, setCompare] = useState(false);
|
|
319
|
-
const [observation, setObservation] = useState();
|
|
320
|
-
const [valRejAll, setValRejAll] = useState(false);
|
|
321
|
-
const [modalAlert, setModalAlert] = useState({
|
|
322
|
-
show: false,
|
|
323
|
-
title: "",
|
|
324
|
-
message: "",
|
|
325
|
-
errorInputMessage: false,
|
|
326
|
-
});
|
|
327
165
|
|
|
328
|
-
const [
|
|
329
|
-
const [fich, setFich] = useState([]);
|
|
330
|
-
const [imag, setImag] = useState([]);
|
|
166
|
+
const [openChangeStatusModal, setOpenChangeStatusModal] = useState(false);
|
|
331
167
|
|
|
332
|
-
const
|
|
168
|
+
const thumbs = () => {
|
|
169
|
+
const imageInputs = state.images_values?.inputs?.map((e) => ({
|
|
170
|
+
value: e?.id,
|
|
171
|
+
name: e?.name,
|
|
172
|
+
required: e?.required,
|
|
173
|
+
active: state.images_values?.values?.some(
|
|
174
|
+
(value) => value?.image_id === e?.id,
|
|
175
|
+
),
|
|
176
|
+
}));
|
|
177
|
+
const imageType = state.images_values?.imageType?.map((e) => ({
|
|
178
|
+
value: e?.id,
|
|
179
|
+
name: e?.name,
|
|
180
|
+
}));
|
|
181
|
+
const imagePackagingType = state.images_values?.imagePackagingType?.map(
|
|
182
|
+
(e) => ({
|
|
183
|
+
value: e?.id,
|
|
184
|
+
name: e?.name,
|
|
185
|
+
}),
|
|
186
|
+
);
|
|
333
187
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
188
|
+
return state.images_values?.values?.map((image, index) => (
|
|
189
|
+
<GalleryElement
|
|
190
|
+
id={"gallery-element-" + index}
|
|
191
|
+
index={index + "-" + image.name}
|
|
192
|
+
key={index}
|
|
193
|
+
image={image}
|
|
194
|
+
number={index}
|
|
195
|
+
gridLayout={imageLayout}
|
|
196
|
+
imageType={imageType}
|
|
197
|
+
imagePackagingType={imagePackagingType}
|
|
198
|
+
imageInputs={imageInputs}
|
|
199
|
+
selectedImages={state.selected_images}
|
|
200
|
+
setCheckAll={handleOnSetCheckAll}
|
|
201
|
+
changeImage={(item) => {
|
|
202
|
+
dispatch({ type: "UPDATE_IMAGE_VALUE", payload: item });
|
|
203
|
+
}}
|
|
204
|
+
setSelectedImages={(item) =>
|
|
205
|
+
dispatch({ type: "SET_SELECTED_IMAGE", payload: item })
|
|
206
|
+
}
|
|
207
|
+
updateApprovedInputsImages={(item) =>
|
|
208
|
+
console.log("updateApprovedInputsImages", item)
|
|
209
|
+
}
|
|
210
|
+
/>
|
|
211
|
+
));
|
|
356
212
|
};
|
|
357
213
|
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
214
|
+
const initializeProduct = async () => {
|
|
215
|
+
try {
|
|
216
|
+
const product = productSelected ? productSelected : JSON.parse(sessionStorage.getItem("productSelected"));
|
|
217
|
+
|
|
218
|
+
const productNormalized = normalizeProduct(product);
|
|
219
|
+
|
|
220
|
+
console.log({productNormalized});
|
|
221
|
+
|
|
222
|
+
dispatch({
|
|
223
|
+
type: "SET_PRODUCT",
|
|
224
|
+
payload: productNormalized,
|
|
225
|
+
});
|
|
226
|
+
dispatch({
|
|
227
|
+
type: "SET_ACTIVE_RETAILER",
|
|
228
|
+
payload: productNormalized.categoryRetailerInOrder[0],
|
|
229
|
+
});
|
|
230
|
+
setShotThd(
|
|
231
|
+
[58, 59, 60, 61].includes(
|
|
232
|
+
productNormalized.categoryRetailerInOrder[0].id_retailer,
|
|
233
|
+
),
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
// Configurar statusArray según el rol del usuario
|
|
237
|
+
setStatusArray(getStatusArrayByRole(user.id_role));
|
|
238
|
+
|
|
239
|
+
// Cargar usuarios y asignaciones
|
|
240
|
+
const users = await fetchUsers(token);
|
|
241
|
+
if (users.length > 0) {
|
|
242
|
+
dispatch({
|
|
243
|
+
type: "SET_COLLABORATOR_ASSIGNATIONS",
|
|
244
|
+
payload: buildCollaboratorAssignations(productNormalized, users),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const { id_article } = productNormalized;
|
|
249
|
+
if (id_article) {
|
|
250
|
+
await getAuditVersion(id_article, setAuditableVersion, token);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (id_article && productNormalized.id_order) {
|
|
254
|
+
const response = await axios.get(
|
|
255
|
+
process.env.REACT_APP_READ_OBSERVATION,
|
|
256
|
+
{
|
|
257
|
+
params: {
|
|
258
|
+
articleId: id_article,
|
|
259
|
+
orderId: productNormalized.id_order,
|
|
260
|
+
},
|
|
261
|
+
headers: {
|
|
262
|
+
Authorization: sessionStorage.getItem("jwt"),
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
);
|
|
266
|
+
const parseData = JSON.parse(response.data.body).data[0];
|
|
267
|
+
setObservation(parseData.observations);
|
|
268
|
+
}
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.log("Error setting product data: ", error);
|
|
271
|
+
}
|
|
364
272
|
};
|
|
365
273
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
await getAuditVersion(id_article, setAuditableVersion, token);
|
|
274
|
+
// Setter del producto y carga inicial (optimizado para evitar cascada)
|
|
275
|
+
useEffect(() => {
|
|
276
|
+
initializeProduct();
|
|
370
277
|
}, []);
|
|
371
278
|
|
|
372
279
|
const loadAuditableData = async () => {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
setAuditImages(auditServices[2]);
|
|
389
|
-
}
|
|
280
|
+
const auditServices = await getRetailerServices(
|
|
281
|
+
state.product?.id_article,
|
|
282
|
+
state.product?.categoryName,
|
|
283
|
+
parseInt(state.product?.id_category),
|
|
284
|
+
auditableVersion.version,
|
|
285
|
+
token,
|
|
286
|
+
);
|
|
287
|
+
getInputsData(
|
|
288
|
+
auditServices,
|
|
289
|
+
{ id: state.active_retailer.id_retailer },
|
|
290
|
+
setAuditDatasheets,
|
|
291
|
+
setAuditDescriptions,
|
|
292
|
+
);
|
|
293
|
+
setAuditServices(auditServices);
|
|
294
|
+
setAuditImages(auditServices[2]);
|
|
390
295
|
};
|
|
391
296
|
|
|
392
297
|
useEffect(() => {
|
|
@@ -395,682 +300,438 @@ export const RetailerProductEdition = ({
|
|
|
395
300
|
}
|
|
396
301
|
}, [auditableVersion]);
|
|
397
302
|
|
|
398
|
-
|
|
399
|
-
checkAll && setSelectedImages(images.values);
|
|
400
|
-
}, [checkAll]);
|
|
401
|
-
|
|
402
|
-
const loadData = async () => {
|
|
303
|
+
const loadData = async (enableLoading = true, versionSelected = null) => {
|
|
403
304
|
try {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const ids =
|
|
407
|
-
product?.statusByRetailer?.map((item) => item.retailer_id) ??
|
|
408
|
-
product?.statusByRetailer?.map((item) => item.id_retailer) ??
|
|
409
|
-
[];
|
|
410
|
-
const uniqueIds = [...new Set(ids)];
|
|
411
|
-
|
|
412
|
-
let activeRetailerId = activeRetailer?.id;
|
|
413
|
-
if (!activeRetailerId) {
|
|
414
|
-
const firstValid = product?.article?.categoryRetailer?.find((item) =>
|
|
415
|
-
uniqueIds.includes(item.id_retailer || item.retailer_id)
|
|
416
|
-
);
|
|
417
|
-
if (firstValid) {
|
|
418
|
-
activeRetailerId = firstValid.id_retailer || firstValid.retailer_id;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const categoryRetailer =
|
|
423
|
-
product?.article?.categoryRetailer?.filter(
|
|
424
|
-
(item) =>
|
|
425
|
-
uniqueIds.includes(item.id_retailer) &&
|
|
426
|
-
item.id_retailer === activeRetailerId
|
|
427
|
-
) ??
|
|
428
|
-
product?.article?.categoryRetailer?.filter(
|
|
429
|
-
(item) =>
|
|
430
|
-
uniqueIds.includes(item.retailer_id) &&
|
|
431
|
-
item.retailer_id === activeRetailerId
|
|
432
|
-
) ??
|
|
433
|
-
[];
|
|
434
|
-
|
|
435
|
-
const categoryName = categoryRetailer[0]?.category_name;
|
|
436
|
-
const categoryId = categoryRetailer[0]?.id_category;
|
|
437
|
-
|
|
438
|
-
const category_name =
|
|
439
|
-
categoryName ??
|
|
440
|
-
(product?.article?.company_name || product?.categoryName);
|
|
441
|
-
const category_id =
|
|
442
|
-
categoryId ??
|
|
443
|
-
parseInt(product?.article?.id_category || product?.id_category);
|
|
444
|
-
|
|
445
|
-
const retailer_id = activeRetailerId ?? categoryRetailer?.id_retailer;
|
|
446
|
-
|
|
447
|
-
const services = await getRetailerServices(
|
|
448
|
-
product?.id_article || product?.article?.id_article,
|
|
449
|
-
category_name,
|
|
450
|
-
category_id,
|
|
451
|
-
version,
|
|
452
|
-
token,
|
|
453
|
-
retailer_id
|
|
454
|
-
);
|
|
455
|
-
|
|
456
|
-
if (auditableVersion && retailer_id) {
|
|
457
|
-
loadAuditableData();
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
setServices(services);
|
|
461
|
-
const generalServices = await getServices();
|
|
462
|
-
|
|
463
|
-
setImages({ action: "init", init: services[2] });
|
|
305
|
+
if (enableLoading) dispatch({ type: "SET_LOADING", payload: true });
|
|
464
306
|
|
|
465
|
-
|
|
307
|
+
const { id_article, version, id_order } = state.product;
|
|
308
|
+
const { category, id_category, id_retailer } = state.active_retailer;
|
|
466
309
|
|
|
310
|
+
// Payloads y headers
|
|
467
311
|
const data = [
|
|
468
312
|
{
|
|
469
|
-
id_article
|
|
313
|
+
id_article,
|
|
314
|
+
version: versionSelected ? versionSelected : version,
|
|
470
315
|
relations: [
|
|
471
316
|
{
|
|
472
|
-
id_retailer
|
|
473
|
-
id_category
|
|
317
|
+
id_retailer,
|
|
318
|
+
id_category,
|
|
474
319
|
},
|
|
475
320
|
],
|
|
476
|
-
version: product.version,
|
|
477
321
|
},
|
|
478
322
|
];
|
|
479
323
|
|
|
480
324
|
const headers = { Authorization: token };
|
|
481
|
-
|
|
482
|
-
|
|
325
|
+
|
|
326
|
+
const [services, percentagesRes, servicesDataRes, commentsResponse] =
|
|
327
|
+
await Promise.all([
|
|
328
|
+
getRetailerServices(
|
|
329
|
+
id_article,
|
|
330
|
+
category,
|
|
331
|
+
id_category,
|
|
332
|
+
versionSelected ?? version,
|
|
333
|
+
token,
|
|
334
|
+
id_retailer,
|
|
335
|
+
),
|
|
336
|
+
getPercentage({ data, headers }),
|
|
337
|
+
getServicesData({
|
|
338
|
+
articleId: id_article,
|
|
339
|
+
orderId: id_order,
|
|
340
|
+
end: true,
|
|
341
|
+
token,
|
|
342
|
+
}),
|
|
343
|
+
// Obtener comentarios en paralelo
|
|
344
|
+
Promise.all([
|
|
345
|
+
axios.get(process.env.REACT_APP_COMMENTS_ENDPOINT, {
|
|
346
|
+
params: {
|
|
347
|
+
articleId: id_article,
|
|
348
|
+
concept: "description",
|
|
349
|
+
orderIdColab: id_order,
|
|
350
|
+
version: versionSelected ?? version,
|
|
351
|
+
},
|
|
352
|
+
}),
|
|
353
|
+
axios.get(process.env.REACT_APP_COMMENTS_ENDPOINT, {
|
|
354
|
+
params: {
|
|
355
|
+
articleId: id_article,
|
|
356
|
+
concept: "datasheet",
|
|
357
|
+
orderIdColab: id_order,
|
|
358
|
+
version: versionSelected ?? version,
|
|
359
|
+
},
|
|
360
|
+
}),
|
|
361
|
+
axios.get(process.env.REACT_APP_COMMENTS_ENDPOINT, {
|
|
362
|
+
params: {
|
|
363
|
+
articleId: id_article,
|
|
364
|
+
concept: "images",
|
|
365
|
+
orderIdColab: id_order,
|
|
366
|
+
version: versionSelected ?? version,
|
|
367
|
+
},
|
|
368
|
+
}),
|
|
369
|
+
]),
|
|
370
|
+
]);
|
|
371
|
+
|
|
372
|
+
dispatch({
|
|
373
|
+
type: "SET_RETAILER_STATUS",
|
|
374
|
+
payload: servicesDataRes.map((service) => ({
|
|
375
|
+
retailer_id: service?.id_retailer,
|
|
376
|
+
service: service?.service,
|
|
377
|
+
status: service?.status,
|
|
378
|
+
task_user_group_id: service?.task_user_group_id,
|
|
379
|
+
})),
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// Extraer relaciones del response
|
|
383
|
+
const percentages =
|
|
384
|
+
JSON.parse(percentagesRes?.[0]?.body)?.[0]?.relations ?? [];
|
|
385
|
+
|
|
386
|
+
// Procesar comentarios
|
|
387
|
+
let commentsMap = {};
|
|
388
|
+
commentsResponse.forEach((commentRes) => {
|
|
389
|
+
const commentData = JSON.parse(commentRes?.data?.body).data[0];
|
|
390
|
+
if (commentData) {
|
|
391
|
+
const tab = translateConcept(commentData.concept);
|
|
392
|
+
commentsMap[tab] = commentData;
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
dispatch({ type: "SET_COMMENTS", payload: commentsMap });
|
|
396
|
+
|
|
397
|
+
// Ordenamiento de imágenes
|
|
398
|
+
const orderMap = services[2].inputsByRetailer
|
|
399
|
+
.flat()
|
|
400
|
+
.reduce((acc, item) => {
|
|
401
|
+
acc[item.id_image] = item.order;
|
|
402
|
+
return acc;
|
|
403
|
+
}, {});
|
|
404
|
+
|
|
405
|
+
const orderedValues = [...services[2].values].sort((a, b) => {
|
|
406
|
+
const orderA = orderMap[a.image_id] ?? Number.MAX_SAFE_INTEGER;
|
|
407
|
+
const orderB = orderMap[b.image_id] ?? Number.MAX_SAFE_INTEGER;
|
|
408
|
+
return orderA - orderB;
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// Procesamiento de inputs del retailer activo (evita cascada con state.services)
|
|
412
|
+
const retailerDatasheets = services[0][id_retailer];
|
|
413
|
+
const datasheetsActiveRetailer = {
|
|
414
|
+
...retailerDatasheets,
|
|
415
|
+
data: Object.values(retailerDatasheets.data),
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
const descriptionsActiveRetailer = services[1].filter(
|
|
419
|
+
(item) => item.id === id_retailer,
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const filteredValues = services[2].values.filter((value) => {
|
|
423
|
+
return services[2].inputsByRetailer.some((retailerInput) =>
|
|
424
|
+
retailerInput.some(
|
|
425
|
+
(input) =>
|
|
426
|
+
input.id_retailer === id_retailer &&
|
|
427
|
+
input.id_image === value.image_id,
|
|
428
|
+
),
|
|
429
|
+
);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// Dispatch consolidado
|
|
433
|
+
dispatch({
|
|
434
|
+
type: "SET_SERVICES",
|
|
435
|
+
payload: {
|
|
436
|
+
datasheets: services[0],
|
|
437
|
+
descriptions: services[1],
|
|
438
|
+
images: {
|
|
439
|
+
...services[2],
|
|
440
|
+
values: orderedValues,
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
dispatch({ type: "SET_PERCENTAGES", payload: percentages });
|
|
446
|
+
dispatch({
|
|
447
|
+
type: "SET_ACTIVE_PERCENTAGES",
|
|
448
|
+
payload: percentages.find(
|
|
449
|
+
({ id_retailer: rId }) => rId === id_retailer,
|
|
450
|
+
),
|
|
451
|
+
});
|
|
452
|
+
dispatch({ type: "SET_SERVICES_DATA", payload: servicesDataRes });
|
|
453
|
+
|
|
454
|
+
// Setear inputs del retailer activo directamente (evita cascada)
|
|
455
|
+
dispatch({
|
|
456
|
+
type: "SET_DATASHEETS_INPUTS",
|
|
457
|
+
payload: [datasheetsActiveRetailer, services[0].inputs],
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
dispatch({
|
|
461
|
+
type: "SET_DESCRIPTIONS_INPUTS",
|
|
462
|
+
payload: descriptionsActiveRetailer,
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
dispatch({
|
|
466
|
+
type: "SET_IMAGES_VALUES",
|
|
467
|
+
payload: {
|
|
468
|
+
...services[2],
|
|
469
|
+
values: filteredValues,
|
|
470
|
+
},
|
|
483
471
|
});
|
|
484
472
|
|
|
485
|
-
|
|
473
|
+
// Calcular campos requeridos sin valor
|
|
474
|
+
dispatch({
|
|
475
|
+
type: "SET_MISSING_REQUIRED_FIELDS",
|
|
476
|
+
payload: calculateRequiredNull(services, servicesDataRes, id_retailer),
|
|
477
|
+
});
|
|
486
478
|
|
|
487
|
-
|
|
479
|
+
// Auditable
|
|
480
|
+
if (auditableVersion && id_retailer) {
|
|
481
|
+
loadAuditableData();
|
|
482
|
+
}
|
|
488
483
|
} catch (error) {
|
|
489
|
-
|
|
490
|
-
|
|
484
|
+
console.log("Error loading data: ", error);
|
|
485
|
+
dispatch({ type: "SET_ERRORS", payload: [error.message] });
|
|
486
|
+
} finally {
|
|
487
|
+
dispatch({ type: "SET_LOADING", payload: false });
|
|
491
488
|
}
|
|
492
489
|
};
|
|
493
490
|
|
|
494
491
|
useEffect(() => {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const getServices = async () => {
|
|
500
|
-
const servicesResponse = await axios.get(
|
|
501
|
-
`${process.env.REACT_APP_SERVICES_ENDPOINT}?articleId=${
|
|
502
|
-
product?.article?.id_article
|
|
503
|
-
}&orderId=${product?.article?.id_order || product.orderId}&end=true`
|
|
504
|
-
);
|
|
505
|
-
const parsedResponse = JSON.parse(servicesResponse?.data?.body).data;
|
|
492
|
+
if (state.active_retailer) {
|
|
493
|
+
loadData();
|
|
494
|
+
}
|
|
495
|
+
}, [state.active_retailer]);
|
|
506
496
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
setServicesData(parsedResponse);
|
|
497
|
+
const handleOnChangeCurrentImage = (index) => {
|
|
498
|
+
if (typeof index === "number") {
|
|
499
|
+
dispatch({ type: "SET_CURRENT_IMAGE", payload: index });
|
|
500
|
+
} else if (typeof index === "object") {
|
|
501
|
+
dispatch({ type: "CHANGE_ATTR_VALUE", payload: index });
|
|
502
|
+
}
|
|
514
503
|
};
|
|
515
504
|
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
return translation[concept];
|
|
505
|
+
const handleOnShowModalGallery = () => {
|
|
506
|
+
dispatch({
|
|
507
|
+
type: "SET_ACTIVE_TAB",
|
|
508
|
+
payload: "Imágenes",
|
|
509
|
+
});
|
|
510
|
+
setShowModal(true);
|
|
523
511
|
};
|
|
524
512
|
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
axios.get(
|
|
531
|
-
`${process.env.REACT_APP_COMMENTS_ENDPOINT}?articleId=${product?.article?.id_article}&concept=datasheet&orderIdColab=${product?.orderId}&version=${version}`
|
|
532
|
-
),
|
|
533
|
-
axios.get(
|
|
534
|
-
`${process.env.REACT_APP_COMMENTS_ENDPOINT}?articleId=${product?.article?.id_article}&concept=images&orderIdColab=${product?.orderId}&version=${version}`
|
|
535
|
-
),
|
|
536
|
-
]);
|
|
537
|
-
|
|
538
|
-
let comments = {};
|
|
539
|
-
commentsResponse.forEach(
|
|
540
|
-
(comment) =>
|
|
541
|
-
JSON.parse(comment?.data?.body).data[0] &&
|
|
542
|
-
(comments[
|
|
543
|
-
translateConcept(JSON.parse(comment?.data?.body)?.data[0]?.concept)
|
|
544
|
-
] = JSON.parse(comment?.data?.body).data[0])
|
|
545
|
-
);
|
|
546
|
-
setComment(comments[tab]);
|
|
547
|
-
setComments(comments);
|
|
513
|
+
const handleOnChangeActiveRetailer = (retailer) => {
|
|
514
|
+
dispatch({
|
|
515
|
+
type: "SET_ACTIVE_RETAILER",
|
|
516
|
+
payload: retailer,
|
|
517
|
+
});
|
|
548
518
|
};
|
|
549
519
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
setUserGroups(await fetchUsers(token));
|
|
555
|
-
let arr = [];
|
|
556
|
-
switch (user.id_role) {
|
|
557
|
-
case 7:
|
|
558
|
-
case 8:
|
|
559
|
-
arr = ["PA", "AS", "CA", "RC", "RA", "RP", "RCA"];
|
|
560
|
-
break;
|
|
561
|
-
case 4:
|
|
562
|
-
case 5:
|
|
563
|
-
arr = ["RC", "AC", "AA", "AP", "ACA"];
|
|
564
|
-
break;
|
|
565
|
-
case 6:
|
|
566
|
-
arr = ["RP", "RCA", "AC", "RA"];
|
|
567
|
-
break;
|
|
568
|
-
default:
|
|
569
|
-
arr = [];
|
|
570
|
-
break;
|
|
571
|
-
}
|
|
572
|
-
setStatusArray(arr);
|
|
573
|
-
setLoading(false);
|
|
574
|
-
}, [product, version]);
|
|
575
|
-
|
|
576
|
-
const loadAssignations = (currentProduct) => {
|
|
577
|
-
setAssig({
|
|
578
|
-
Descripción: {
|
|
579
|
-
assignations: [
|
|
580
|
-
{
|
|
581
|
-
collaboratorType: "especialist",
|
|
582
|
-
id: currentProduct?.article?.id_description_especialist,
|
|
583
|
-
},
|
|
584
|
-
{
|
|
585
|
-
collaboratorType: "facilitator",
|
|
586
|
-
id: currentProduct?.article?.id_description_facilitator,
|
|
587
|
-
},
|
|
588
|
-
],
|
|
589
|
-
collaborators: {
|
|
590
|
-
especialist: userGroups[0] || [],
|
|
591
|
-
facilitator: userGroups[2] || [],
|
|
592
|
-
},
|
|
593
|
-
},
|
|
594
|
-
"Ficha técnica": {
|
|
595
|
-
assignations: [
|
|
596
|
-
{
|
|
597
|
-
collaboratorType: "especialist",
|
|
598
|
-
id: currentProduct?.article?.id_datasheet_especialist,
|
|
599
|
-
},
|
|
600
|
-
{
|
|
601
|
-
collaboratorType: "facilitator",
|
|
602
|
-
id: currentProduct?.article?.id_datasheet_facilitator,
|
|
603
|
-
},
|
|
604
|
-
],
|
|
605
|
-
collaborators: {
|
|
606
|
-
especialist: userGroups[0] || [],
|
|
607
|
-
facilitator: userGroups[2] || [],
|
|
608
|
-
},
|
|
609
|
-
},
|
|
610
|
-
Imágenes: {
|
|
611
|
-
assignations: [
|
|
612
|
-
{
|
|
613
|
-
collaboratorType: "especialist",
|
|
614
|
-
id: currentProduct?.article?.id_images_especialist,
|
|
615
|
-
},
|
|
616
|
-
{
|
|
617
|
-
collaboratorType: "facilitator",
|
|
618
|
-
id: currentProduct?.article?.id_images_facilitator,
|
|
619
|
-
},
|
|
620
|
-
],
|
|
621
|
-
collaborators: {
|
|
622
|
-
especialist: userGroups[1] || [],
|
|
623
|
-
facilitator: userGroups[3] || [],
|
|
624
|
-
},
|
|
625
|
-
},
|
|
520
|
+
const handleOnChangeActiveTab = (tab) => {
|
|
521
|
+
dispatch({
|
|
522
|
+
type: "SET_ACTIVE_TAB",
|
|
523
|
+
payload: tab,
|
|
626
524
|
});
|
|
627
525
|
};
|
|
628
526
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
}, [userGroups]);
|
|
632
|
-
|
|
633
|
-
useEffect(() => {
|
|
634
|
-
const retailerPercentages =
|
|
635
|
-
percentages?.[0]?.relations?.[0]?.percentagesGeneral;
|
|
636
|
-
|
|
637
|
-
const requiredPercentage = retailerPercentages?.required;
|
|
638
|
-
|
|
639
|
-
setActivePercentage(requiredPercentage);
|
|
640
|
-
|
|
641
|
-
// const retailers = product?.retailersAvailable || product?.retailers;
|
|
642
|
-
// if (
|
|
643
|
-
// Object.keys(percentages[product.article.id_article] ?? {})?.length > 0
|
|
644
|
-
// ) {
|
|
645
|
-
// retailers?.forEach((retailer, index) => {
|
|
646
|
-
// retailer["percentage"] = Number(
|
|
647
|
-
// percentages[product.article.id_article][retailer.id]
|
|
648
|
-
// ?.percentageRequired
|
|
649
|
-
// );
|
|
650
|
-
// });
|
|
651
|
-
// }
|
|
652
|
-
// setActivePercentage(retailers[0]?.percentage);
|
|
653
|
-
}, [percentages]);
|
|
654
|
-
|
|
655
|
-
useEffect(() => {
|
|
656
|
-
getInputsData(services, activeRetailer, setDatasheets, setDescriptions);
|
|
657
|
-
auditableVersion && loadAuditableData();
|
|
658
|
-
setActivePercentage(Math.round(activeRetailer?.percentage, 0));
|
|
659
|
-
activeRetailer?.id &&
|
|
660
|
-
setImages({ action: "orderImages", retailerId: activeRetailer.id });
|
|
661
|
-
}, [activeRetailer, services]);
|
|
662
|
-
|
|
663
|
-
const thumbs = () => {
|
|
664
|
-
const imageInputs = socketType?.slice();
|
|
665
|
-
const imageType = images?.imageType?.map((e) => ({
|
|
666
|
-
value: e?.id,
|
|
667
|
-
name: e?.name,
|
|
668
|
-
}));
|
|
669
|
-
const imagePackagingType = images?.imagePackagingType?.map((e) => ({
|
|
670
|
-
value: e?.id,
|
|
671
|
-
name: e?.name,
|
|
672
|
-
}));
|
|
673
|
-
const imageShotType = images?.imageShotType?.map((e) => ({
|
|
674
|
-
value: e?.id,
|
|
675
|
-
name: e?.type_shot,
|
|
676
|
-
}));
|
|
677
|
-
return images?.values?.map((image, index) => (
|
|
678
|
-
<GalleryElement
|
|
679
|
-
setCheckAll={setCheckAll}
|
|
680
|
-
key={index + "-" + image.name}
|
|
681
|
-
image={image}
|
|
682
|
-
gridLayout={imageLayout}
|
|
683
|
-
id={"gallery-element-" + index}
|
|
684
|
-
index={index + "-" + image.name + "-" + compare}
|
|
685
|
-
number={index}
|
|
686
|
-
imageType={imageType}
|
|
687
|
-
imagePackagingType={imagePackagingType}
|
|
688
|
-
imageInputs={imageInputs}
|
|
689
|
-
imageShotType={imageShotType}
|
|
690
|
-
setSocketType={setSocketType}
|
|
691
|
-
changeImage={setImages}
|
|
692
|
-
selectedImages={selectedImages}
|
|
693
|
-
setSelectedImages={setSelectedImages}
|
|
694
|
-
auditImages={auditImages}
|
|
695
|
-
compare={compare}
|
|
696
|
-
/>
|
|
697
|
-
));
|
|
527
|
+
const handleOnToggleImageLayout = () => {
|
|
528
|
+
setImageLayout(!imageLayout);
|
|
698
529
|
};
|
|
699
530
|
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
setLoading(true);
|
|
704
|
-
const productTemp = product;
|
|
705
|
-
const articleId = product?.article?.id_article;
|
|
706
|
-
const dataObject = {
|
|
707
|
-
articleId,
|
|
708
|
-
articleData: dataClean,
|
|
709
|
-
};
|
|
710
|
-
if (product?.orderId) dataObject["orderId"] = product?.orderId;
|
|
711
|
-
try {
|
|
712
|
-
const res = await axios.put(
|
|
713
|
-
`${process.env.REACT_APP_ARTICLE_DATA_ENDPOINT}?description=true&version=${version}`,
|
|
714
|
-
dataObject,
|
|
715
|
-
{
|
|
716
|
-
headers: {
|
|
717
|
-
Authorization: token,
|
|
718
|
-
},
|
|
719
|
-
}
|
|
720
|
-
);
|
|
721
|
-
if (res.data.statusCode === 200) {
|
|
722
|
-
const { newStatus, newArticleStatus } = JSON.parse(res.data.body);
|
|
723
|
-
if (newArticleStatus)
|
|
724
|
-
productTemp.status = newArticleStatus[articleId];
|
|
725
|
-
if (newStatus) productTemp.description_status = newStatus;
|
|
726
|
-
setProduct(productTemp);
|
|
727
|
-
sessionStorage.setItem(
|
|
728
|
-
"productSelected",
|
|
729
|
-
JSON.stringify(productTemp)
|
|
730
|
-
);
|
|
531
|
+
const handleOnToggleObservation = () => {
|
|
532
|
+
setObservationVisible(!isObservationVisible);
|
|
533
|
+
};
|
|
731
534
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
await loadData();
|
|
735
|
-
}
|
|
736
|
-
} catch (error) {
|
|
737
|
-
console.log(error);
|
|
738
|
-
} finally {
|
|
739
|
-
setLoading(false);
|
|
740
|
-
}
|
|
741
|
-
}
|
|
535
|
+
const handleOnHideObservation = () => {
|
|
536
|
+
setObservationVisible(false);
|
|
742
537
|
};
|
|
743
538
|
|
|
744
|
-
const
|
|
745
|
-
|
|
746
|
-
if (dataClean.length > 0) {
|
|
747
|
-
setLoading(true);
|
|
748
|
-
const productTemp = product;
|
|
749
|
-
const articleId = product?.article?.id_article;
|
|
750
|
-
const dataObject = {
|
|
751
|
-
articleId,
|
|
752
|
-
articleData: dataClean,
|
|
753
|
-
};
|
|
754
|
-
if (product?.orderId) dataObject["orderId"] = product?.orderId;
|
|
755
|
-
try {
|
|
756
|
-
const res = await axios.put(
|
|
757
|
-
`${process.env.REACT_APP_ARTICLE_DATA_ENDPOINT}?datasheet=true&version=${version}`,
|
|
758
|
-
dataObject,
|
|
759
|
-
{
|
|
760
|
-
headers: {
|
|
761
|
-
Authorization: token,
|
|
762
|
-
},
|
|
763
|
-
}
|
|
764
|
-
);
|
|
765
|
-
if (res.data.statusCode === 200) {
|
|
766
|
-
const { newStatus, newArticleStatus } = JSON.parse(res.data.body);
|
|
767
|
-
if (newArticleStatus)
|
|
768
|
-
productTemp.status = newArticleStatus[articleId];
|
|
769
|
-
if (newStatus) productTemp.datasheet_status = newStatus;
|
|
770
|
-
setProduct(productTemp);
|
|
771
|
-
sessionStorage.setItem(
|
|
772
|
-
"productSelected",
|
|
773
|
-
JSON.stringify(productTemp)
|
|
774
|
-
);
|
|
775
|
-
setUpdatedDatasheets([]);
|
|
776
|
-
setMessage("Fichas técnicas guardadas");
|
|
777
|
-
await loadData();
|
|
778
|
-
}
|
|
779
|
-
} catch (error) {
|
|
780
|
-
console.log(error);
|
|
781
|
-
} finally {
|
|
782
|
-
setLoading(false);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
539
|
+
const isAuditorAssigned = () => {
|
|
540
|
+
return state.product?.id_auditor === user?.id_user;
|
|
785
541
|
};
|
|
786
542
|
|
|
787
|
-
|
|
788
|
-
const
|
|
789
|
-
value: e?.id,
|
|
790
|
-
name: e?.name,
|
|
791
|
-
required: e?.required,
|
|
792
|
-
active: images?.values?.some((value) => value?.image_id === e?.id),
|
|
793
|
-
}));
|
|
794
|
-
setSocketType(imageInputs);
|
|
795
|
-
}, [images]);
|
|
796
|
-
|
|
797
|
-
const updateImages = useCallback(async () => {
|
|
798
|
-
const imagesList = images?.values?.slice();
|
|
799
|
-
const imagesListTemp = imagesList?.reduce((acc, image) => {
|
|
800
|
-
acc[image?.image_id] = ++acc[image?.image_id] || 0;
|
|
801
|
-
return acc;
|
|
802
|
-
}, {});
|
|
803
|
-
|
|
804
|
-
const duplicated = imagesList?.filter((image) => {
|
|
805
|
-
return imagesListTemp[image?.image_id];
|
|
806
|
-
});
|
|
543
|
+
const isUserAssignedToService = (tab, rol) => {
|
|
544
|
+
const concept = getConceptByTab(state.active_tab);
|
|
807
545
|
|
|
808
|
-
const
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
};
|
|
818
|
-
if (product?.orderId) data["orderId"] = product?.orderId;
|
|
819
|
-
let valid =
|
|
820
|
-
data?.articleData?.length === 0
|
|
821
|
-
? true
|
|
822
|
-
: data?.articleData?.every((e, i) => {
|
|
823
|
-
// if (e?.image_id && e?.packing_type && e?.image_type) {
|
|
824
|
-
if (e?.image_id) {
|
|
825
|
-
return true;
|
|
826
|
-
}
|
|
827
|
-
return false;
|
|
828
|
-
});
|
|
829
|
-
if (valid && data?.updateImages?.length > 0 && duplicated?.length === 0) {
|
|
830
|
-
valid = data?.updateImages?.every((e, i) => {
|
|
831
|
-
// if (e?.image_id && e?.packing_type && e?.image_type) {
|
|
832
|
-
if (e?.image_id) {
|
|
833
|
-
return true;
|
|
834
|
-
}
|
|
835
|
-
return false;
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
if (valid && duplicated?.length === 0) {
|
|
839
|
-
setLoading(true);
|
|
840
|
-
try {
|
|
841
|
-
data?.articleData?.forEach((e) => {
|
|
842
|
-
e.uuid = uuidv4();
|
|
843
|
-
});
|
|
844
|
-
setDataImages(data);
|
|
845
|
-
if (data?.articleData?.length > 0) {
|
|
846
|
-
setImagesUploaded(false);
|
|
847
|
-
const promiseArray = [];
|
|
848
|
-
data?.articleData?.forEach((e) => {
|
|
849
|
-
let file;
|
|
850
|
-
if (e.ext == "mp4") {
|
|
851
|
-
file = Buffer.from(
|
|
852
|
-
e.video_src.replace(/^data:video\/\w+;base64,/, ""),
|
|
853
|
-
"base64"
|
|
854
|
-
);
|
|
855
|
-
e.video_src = "";
|
|
856
|
-
} else {
|
|
857
|
-
file = Buffer.from(
|
|
858
|
-
e.src.replace(/^data:image\/\w+;base64,/, ""),
|
|
859
|
-
"base64"
|
|
860
|
-
);
|
|
861
|
-
}
|
|
862
|
-
const params = {
|
|
863
|
-
ACL: "public-read",
|
|
864
|
-
Body: file,
|
|
865
|
-
Bucket: S3_BUCKET,
|
|
866
|
-
Key: `id-${data.articleId}/${version}/${e?.image_id}-${e?.uuid}.${e?.ext}`,
|
|
867
|
-
};
|
|
868
|
-
promiseArray.push(myBucket.putObject(params).promise());
|
|
869
|
-
});
|
|
870
|
-
await Promise.all(promiseArray);
|
|
871
|
-
setImagesUploaded(true);
|
|
872
|
-
} else {
|
|
873
|
-
setImagesUploaded(true);
|
|
874
|
-
}
|
|
875
|
-
} catch (err) {
|
|
876
|
-
console.log(err);
|
|
877
|
-
// setMainLoading(false);
|
|
878
|
-
} finally {
|
|
879
|
-
setLoading(false);
|
|
880
|
-
}
|
|
881
|
-
} else {
|
|
882
|
-
// setMainLoading(false);
|
|
883
|
-
setMessage(
|
|
884
|
-
"Completa los campos que solicita cada una de la imágenes o hay imágenes con el mismo tipo de toma.\nRecuerda hay campos obligatorios y no podras avanzar si no estan completos."
|
|
885
|
-
);
|
|
886
|
-
}
|
|
887
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
888
|
-
}, [images, imagesUploaded]);
|
|
889
|
-
|
|
890
|
-
useEffect(async () => {
|
|
891
|
-
if (imagesUploaded) {
|
|
892
|
-
dataImages.articleData = dataImages?.articleData.map((e) => {
|
|
893
|
-
delete e.src;
|
|
894
|
-
e.imageID = e.image_id;
|
|
895
|
-
// e.packingType = e.packing_type;
|
|
896
|
-
// e.imageType = e.image_type;
|
|
897
|
-
if (product?.orderId) e["orderId"] = product?.orderId;
|
|
898
|
-
return e;
|
|
899
|
-
});
|
|
900
|
-
try {
|
|
901
|
-
const res = await axios.put(
|
|
902
|
-
`${process.env.REACT_APP_ARTICLE_DATA_ENDPOINT}?image=true&version=${version}`,
|
|
903
|
-
dataImages,
|
|
904
|
-
{
|
|
905
|
-
headers: {
|
|
906
|
-
Authorization: token,
|
|
907
|
-
},
|
|
908
|
-
}
|
|
909
|
-
);
|
|
910
|
-
if (res.data.statusCode === 200) {
|
|
911
|
-
let productTemp = product;
|
|
912
|
-
const { newStatus, newArticleStatus } = JSON.parse(res.data.body);
|
|
913
|
-
if (newArticleStatus)
|
|
914
|
-
productTemp.status = newArticleStatus[product?.article?.id_article];
|
|
915
|
-
if (newStatus) productTemp.images_status = newStatus;
|
|
916
|
-
setProduct(productTemp);
|
|
917
|
-
sessionStorage.setItem(
|
|
918
|
-
"productSelected",
|
|
919
|
-
JSON.stringify(productTemp)
|
|
920
|
-
);
|
|
921
|
-
setImages({});
|
|
922
|
-
setMessage("Imágenes guardadas con éxito");
|
|
923
|
-
sessionStorage.removeItem("imagesList");
|
|
924
|
-
}
|
|
925
|
-
await loadData();
|
|
926
|
-
} catch (error) {
|
|
927
|
-
console.log(error);
|
|
546
|
+
const allowedRoles = [1, 4, 5, 6, 7, 8];
|
|
547
|
+
const validUser = allowedRoles.includes(user?.id_role);
|
|
548
|
+
|
|
549
|
+
// Determinar rol por defecto si no se pasa
|
|
550
|
+
if (!rol) {
|
|
551
|
+
if (user.id_role === 4 || user.id_role === 5) {
|
|
552
|
+
rol = "facilitator";
|
|
553
|
+
} else if (user.id_role === 7 || user.id_role === 8) {
|
|
554
|
+
rol = "especialist";
|
|
928
555
|
}
|
|
929
556
|
}
|
|
930
|
-
}, [dataImages, imagesUploaded]);
|
|
931
557
|
|
|
932
|
-
|
|
933
|
-
const
|
|
934
|
-
const
|
|
935
|
-
.find((serv) => serv.id_retailer === activeRetailer?.id)
|
|
936
|
-
?.status?.replace(/.*\//, "");
|
|
937
|
-
const currStatus = product[`${getConcept(tab)}_status`]?.replace(
|
|
938
|
-
/.*\//,
|
|
939
|
-
""
|
|
940
|
-
);
|
|
941
|
-
const unvalidated = ["IE", "CA"].includes(currStatus);
|
|
942
|
-
|
|
943
|
-
const auditorUnvalidated = !["RA", "AA", "ACA", "AP"].includes(currStatus);
|
|
944
|
-
|
|
945
|
-
switch (userId) {
|
|
946
|
-
case 7:
|
|
947
|
-
case 8:
|
|
948
|
-
return (
|
|
949
|
-
(statusArray.includes(srvActive) &&
|
|
950
|
-
statusArray.includes(product?.status)) ||
|
|
951
|
-
srv.filter((serv) =>
|
|
952
|
-
statusArray.includes(serv.status?.replace(/.*\//, ""))
|
|
953
|
-
).length === srv.length
|
|
954
|
-
);
|
|
955
|
-
case 4:
|
|
956
|
-
case 5:
|
|
957
|
-
return (
|
|
958
|
-
unvalidated &&
|
|
959
|
-
["CA", "IE"].includes(product.status) && // "RC", "AC", "AA", "AP", "ACA"
|
|
960
|
-
srv.filter((serv) => statusArray.includes(serv.status)).length ===
|
|
961
|
-
srv.length
|
|
962
|
-
);
|
|
963
|
-
case 6:
|
|
964
|
-
return (
|
|
965
|
-
statusArray.includes(product.status) && // RP, RCA, AC, RA true
|
|
966
|
-
srv.every((serv) =>
|
|
967
|
-
["RA", "AA", "AP", "ACA"].includes(serv.status)
|
|
968
|
-
) &&
|
|
969
|
-
auditorUnvalidated
|
|
970
|
-
);
|
|
971
|
-
default:
|
|
972
|
-
break;
|
|
973
|
-
}
|
|
974
|
-
};
|
|
558
|
+
const isAdmin = user.id_role === 1;
|
|
559
|
+
const idUserAssigned = state.product?.[`id_${concept}_${rol}`];
|
|
560
|
+
const isAssigned = idUserAssigned === user.id_user;
|
|
975
561
|
|
|
976
|
-
|
|
977
|
-
switch (tab) {
|
|
978
|
-
case "Descripción":
|
|
979
|
-
return "description";
|
|
980
|
-
case "Ficha técnica":
|
|
981
|
-
return "datasheet";
|
|
982
|
-
case "Imágenes":
|
|
983
|
-
return "images";
|
|
984
|
-
}
|
|
562
|
+
return isAdmin || (isAssigned && validUser);
|
|
985
563
|
};
|
|
986
564
|
|
|
987
|
-
const
|
|
988
|
-
let concept =
|
|
565
|
+
const canShowSingleEvaluationButtons = (action) => {
|
|
566
|
+
let concept = getConceptByTab(action || state.active_tab);
|
|
989
567
|
|
|
990
|
-
const retailerStatus =
|
|
991
|
-
|
|
568
|
+
const retailerStatus = state.services_data
|
|
569
|
+
?.find(
|
|
992
570
|
(srv) =>
|
|
993
|
-
srv.id_retailer ===
|
|
571
|
+
srv.id_retailer === state.active_retailer?.id_retailer &&
|
|
572
|
+
srv.service === concept,
|
|
994
573
|
)
|
|
995
574
|
?.status?.replace(/.*\//, "");
|
|
996
575
|
|
|
997
|
-
//sessionStorage product
|
|
998
576
|
const adminFacilitatorCanEvaluate =
|
|
999
577
|
retailerStatus === "IE" && [1, 4, 5].includes(user.id_role);
|
|
1000
578
|
const adminAuditorCanEvaluate =
|
|
1001
579
|
["AC", "RP", "RCA", "SAC"].includes(retailerStatus) &&
|
|
1002
580
|
[1, 6].includes(user.id_role);
|
|
581
|
+
|
|
1003
582
|
return adminFacilitatorCanEvaluate || adminAuditorCanEvaluate;
|
|
1004
583
|
};
|
|
1005
584
|
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
switch (user.id_role) {
|
|
1009
|
-
case 4:
|
|
1010
|
-
concepts = ["description", "datasheet"];
|
|
1011
|
-
break;
|
|
1012
|
-
case 5:
|
|
1013
|
-
concepts = ["images"];
|
|
1014
|
-
break;
|
|
1015
|
-
|
|
1016
|
-
default:
|
|
1017
|
-
concepts = ["description", "datasheet", "images"];
|
|
1018
|
-
break;
|
|
1019
|
-
}
|
|
585
|
+
const canShowBulkEvaluationButtons = () => {
|
|
586
|
+
const concepts = getConceptsByRole(user.id_role);
|
|
1020
587
|
|
|
1021
|
-
const services =
|
|
1022
|
-
concepts.includes(service)
|
|
588
|
+
const services = state.services_data.filter(({ service }) =>
|
|
589
|
+
concepts.includes(service),
|
|
1023
590
|
);
|
|
1024
591
|
|
|
1025
592
|
const adminFacilitatorCanEvaluate =
|
|
1026
593
|
services.every((srv) => srv?.status?.replace(/.*\//, "") === "IE") &&
|
|
1027
594
|
[1, 4, 5].includes(user.id_role);
|
|
1028
595
|
|
|
1029
|
-
//sessionStorage product
|
|
1030
596
|
const adminAuditorCanEvaluate =
|
|
1031
|
-
|
|
1032
|
-
["AC", "RP", "RCA"].includes(srv?.status?.replace(/.*\//, ""))
|
|
597
|
+
state.services_data.every((srv) =>
|
|
598
|
+
["AC", "RP", "RCA"].includes(srv?.status?.replace(/.*\//, "")),
|
|
1033
599
|
) && [1, 6].includes(user.id_role);
|
|
1034
600
|
return adminFacilitatorCanEvaluate || adminAuditorCanEvaluate;
|
|
1035
601
|
};
|
|
1036
602
|
|
|
1037
|
-
const
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
603
|
+
const getStatusByCurrentServiceAndRetailer = () => {
|
|
604
|
+
const { statusByRetailer } = state.product;
|
|
605
|
+
if (!statusByRetailer) return "-";
|
|
606
|
+
|
|
607
|
+
const currentService = getConceptByTab(state.active_tab);
|
|
608
|
+
const currentRetailer = state.active_retailer.id_retailer;
|
|
609
|
+
const currentStatus =
|
|
610
|
+
statusByRetailer.filter(
|
|
611
|
+
(item) =>
|
|
612
|
+
item.retailer_id === currentRetailer &&
|
|
613
|
+
item.service === currentService,
|
|
614
|
+
)[0]?.status || "-";
|
|
615
|
+
|
|
616
|
+
return currentStatus;
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
const handleOnClickSaveImages = () => {
|
|
620
|
+
if (state.product?.services?.images === 1) {
|
|
621
|
+
saveImageAttrs(token);
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
const handleOnClickSave = async () => {
|
|
626
|
+
if (state.saving) return;
|
|
627
|
+
|
|
628
|
+
switch (state.active_tab) {
|
|
1042
629
|
case "Descripción":
|
|
1043
|
-
|
|
630
|
+
await saveDescriptions(token);
|
|
631
|
+
break;
|
|
632
|
+
case "Ficha técnica":
|
|
633
|
+
await saveDatasheets(token);
|
|
1044
634
|
break;
|
|
1045
635
|
case "Imágenes":
|
|
1046
|
-
|
|
636
|
+
await updateImages(token);
|
|
1047
637
|
break;
|
|
1048
638
|
default:
|
|
1049
639
|
break;
|
|
1050
640
|
}
|
|
641
|
+
|
|
642
|
+
await loadData(false);
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
const handleOnSetUpdatedDescriptions = (items) => {
|
|
646
|
+
dispatch({
|
|
647
|
+
type: "SET_UPDATED_DESCRIPTIONS_INPUTS",
|
|
648
|
+
payload: items,
|
|
649
|
+
});
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
const handleOnSetUpdatedDatasheets = (items) => {
|
|
653
|
+
dispatch({
|
|
654
|
+
type: "SET_UPDATED_DATASHEETS_INPUTS",
|
|
655
|
+
payload: items,
|
|
656
|
+
});
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
const handleOnAskToDeleteImages = () => {
|
|
660
|
+
if (state.selected_images.length === 0) {
|
|
661
|
+
dispatch({
|
|
662
|
+
type: "SET_MODAL",
|
|
663
|
+
payload: {
|
|
664
|
+
show: true,
|
|
665
|
+
title: "Eliminar imágenes",
|
|
666
|
+
message: "No has seleccionado ninguna imagen para eliminar.",
|
|
667
|
+
image: warningIcon,
|
|
668
|
+
},
|
|
669
|
+
});
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
dispatch({
|
|
674
|
+
type: "SET_MODAL",
|
|
675
|
+
payload: {
|
|
676
|
+
show: true,
|
|
677
|
+
title: "Eliminar imágenes",
|
|
678
|
+
message:
|
|
679
|
+
"¿Estás seguro de que deseas eliminar las imágenes seleccionadas?",
|
|
680
|
+
image: warningIcon,
|
|
681
|
+
buttons: [
|
|
682
|
+
{
|
|
683
|
+
text: "Cancelar",
|
|
684
|
+
buttonType: "general-white-button",
|
|
685
|
+
action: () =>
|
|
686
|
+
dispatch({ type: "SET_MODAL", payload: { show: false } }),
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
text: "Eliminar",
|
|
690
|
+
buttonType: "general-button-default",
|
|
691
|
+
action: () => {
|
|
692
|
+
dispatch({ type: "SET_MODAL", payload: { show: false } });
|
|
693
|
+
deleteImages(token);
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
],
|
|
697
|
+
},
|
|
698
|
+
});
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
const handleOnApproveSingleService = async () => {
|
|
702
|
+
await sendSingleEvaluation("A");
|
|
1051
703
|
};
|
|
1052
704
|
|
|
1053
|
-
const
|
|
1054
|
-
|
|
705
|
+
const handleOnRejectSingleService = () => {
|
|
706
|
+
setShowRejectModal(true);
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
const sendSingleEvaluation = async (result) => {
|
|
710
|
+
if (state.saving) return;
|
|
711
|
+
|
|
712
|
+
dispatch({ type: "SET_SAVING", payload: true });
|
|
713
|
+
|
|
714
|
+
const concept = getConceptByTab(state.active_tab);
|
|
715
|
+
|
|
716
|
+
const articleId = state.product.id_article;
|
|
717
|
+
const orderId = state.product.id_order ?? state.product.orderId;
|
|
718
|
+
const sectionStatusKey = `${concept}_status`;
|
|
719
|
+
const evalStatus = state.product[sectionStatusKey];
|
|
720
|
+
const retailerId = state.active_retailer?.id_retailer;
|
|
721
|
+
|
|
722
|
+
let data = { articleId, orderId, concept, evalStatus, retailerId };
|
|
723
|
+
let res;
|
|
724
|
+
let message;
|
|
725
|
+
let icon;
|
|
726
|
+
|
|
727
|
+
const activeTab = state.active_tab;
|
|
728
|
+
|
|
1055
729
|
try {
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
const productTemp = { ...product };
|
|
1059
|
-
const evalStatus = retailerStatus;
|
|
1060
|
-
const articleId = product.article.id_article;
|
|
1061
|
-
const orderId = product.orderId;
|
|
1062
|
-
|
|
1063
|
-
let data = {
|
|
1064
|
-
articleId,
|
|
1065
|
-
orderId,
|
|
1066
|
-
concept,
|
|
1067
|
-
evalStatus,
|
|
1068
|
-
retailerId: activeRetailer.id,
|
|
1069
|
-
};
|
|
1070
|
-
let res;
|
|
1071
|
-
let message;
|
|
730
|
+
//Esto solo se ejecutará cuando se aprueba o rechaza desde el modal superior derecho
|
|
1072
731
|
if (result) {
|
|
1073
732
|
data.result = result;
|
|
733
|
+
data.retailerId = retailerId;
|
|
734
|
+
|
|
1074
735
|
res = await axios.put(
|
|
1075
736
|
`${process.env.REACT_APP_EVALUATION_ENDPOINT}`,
|
|
1076
737
|
data,
|
|
@@ -1078,254 +739,297 @@ export const RetailerProductEdition = ({
|
|
|
1078
739
|
headers: {
|
|
1079
740
|
Authorization: token,
|
|
1080
741
|
},
|
|
1081
|
-
}
|
|
742
|
+
},
|
|
1082
743
|
);
|
|
1083
|
-
|
|
1084
|
-
|
|
744
|
+
|
|
745
|
+
const newStatuses = JSON.parse(res.data.body);
|
|
746
|
+
const serviceStatus = newStatuses.newServiceStatus[articleId][`${concept}Status`];
|
|
747
|
+
const articleStatus = newStatuses.newArticleStatus[articleId];
|
|
748
|
+
|
|
749
|
+
console.log({newStatuses});
|
|
750
|
+
|
|
751
|
+
// Actualizar el producto con los nuevos estados
|
|
752
|
+
const updatedStatusByRetailer = state.product.statusByRetailer.map(
|
|
753
|
+
(item) =>
|
|
754
|
+
item.retailer_id === retailerId && item.service === concept
|
|
755
|
+
? { ...item, status: serviceStatus }
|
|
756
|
+
: item,
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
const updatedProduct = {
|
|
760
|
+
...state.product,
|
|
761
|
+
statusByRetailer: updatedStatusByRetailer,
|
|
762
|
+
// version_status: articleStatus,
|
|
763
|
+
// status: articleStatus,
|
|
764
|
+
// article_status: articleStatus
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
dispatch({ type: "SET_PRODUCT", payload: updatedProduct });
|
|
768
|
+
|
|
769
|
+
// Mostrar modal de éxito
|
|
770
|
+
dispatch({
|
|
771
|
+
type: "SET_MODAL",
|
|
772
|
+
payload: {
|
|
773
|
+
show: true,
|
|
774
|
+
title: "",
|
|
775
|
+
message:
|
|
776
|
+
result === "A" ? "Aprobado con éxito" : "Rechazado con éxito",
|
|
777
|
+
image: successIcon,
|
|
778
|
+
},
|
|
779
|
+
});
|
|
780
|
+
} else { //Caso del botón "Enviar evaluación"
|
|
781
|
+
|
|
782
|
+
//Se construye el mensaje y se actualiza el estatus
|
|
783
|
+
|
|
1085
784
|
const specialistDone = ["RC", "RA", "CA"].includes(evalStatus);
|
|
1086
785
|
|
|
1087
786
|
if (specialistDone) {
|
|
1088
787
|
message = `${activeTab} enviada a facilitador`;
|
|
1089
|
-
|
|
788
|
+
icon =
|
|
789
|
+
activeTab === "Descripción"
|
|
790
|
+
? descriptionSent
|
|
791
|
+
: activeTab === "Ficha técnica"
|
|
792
|
+
? attributesSent
|
|
793
|
+
: imagesSent;
|
|
1090
794
|
} else if (["IE", "AC", "RP", "RCA"].includes(evalStatus)) {
|
|
1091
795
|
message = "Evaluación enviada";
|
|
1092
|
-
|
|
796
|
+
icon = successIcon;
|
|
1093
797
|
}
|
|
798
|
+
|
|
1094
799
|
res = await axios.put(`${process.env.REACT_APP_SEND_EVAL}`, data, {
|
|
1095
800
|
headers: {
|
|
1096
801
|
Authorization: token,
|
|
1097
802
|
},
|
|
1098
803
|
});
|
|
1099
804
|
}
|
|
805
|
+
|
|
1100
806
|
if (res.data.statusCode === 200) {
|
|
1101
|
-
const { newStatus, newOrderStatus, newArticleStatus } = JSON.parse(
|
|
1102
|
-
res.data.body
|
|
1103
|
-
);
|
|
1104
|
-
const messageToChat = createMessage(
|
|
1105
|
-
product.retailers,
|
|
1106
|
-
activeRetailer.id,
|
|
1107
|
-
evalStatus,
|
|
1108
|
-
newStatus,
|
|
1109
|
-
activeTab
|
|
1110
|
-
);
|
|
1111
807
|
|
|
1112
|
-
const
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
808
|
+
const { newStatus, newOrderStatus, newArticleStatus } = JSON.parse( res.data.body );
|
|
809
|
+
|
|
810
|
+
const articleStatus = newArticleStatus[articleId];
|
|
811
|
+
|
|
812
|
+
console.log({newArticleStatus});
|
|
813
|
+
|
|
814
|
+
// const retailers = state.product.categoryRetailer.map((r) => ({
|
|
815
|
+
// id: r.id_retailer,
|
|
816
|
+
// name: r.retailerName,
|
|
817
|
+
// }));
|
|
818
|
+
// const messageToChat = createMessage(
|
|
819
|
+
// retailers,
|
|
820
|
+
// retailerId,
|
|
821
|
+
// evalStatus,
|
|
822
|
+
// newStatus,
|
|
823
|
+
// activeTab,
|
|
824
|
+
// );
|
|
825
|
+
|
|
826
|
+
// const messageData = {
|
|
827
|
+
// paramsBody: {
|
|
828
|
+
// id: articleId,
|
|
829
|
+
// version: state.product.version,
|
|
830
|
+
// items: [{ type: "status", value: messageToChat }],
|
|
831
|
+
// retailerId: retailerId,
|
|
832
|
+
// status: state.product.status,
|
|
833
|
+
// },
|
|
834
|
+
// paramsHeader: { Authorization: token },
|
|
835
|
+
// };
|
|
836
|
+
// await sendMessage(messageData);
|
|
837
|
+
|
|
838
|
+
const updatedProduct = {
|
|
839
|
+
...state.product,
|
|
840
|
+
[`${concept}_status`]: newStatus,
|
|
841
|
+
// actualizar el status es statusByRetailer
|
|
842
|
+
statusByRetailer: state.product.statusByRetailer.map((item) => {
|
|
843
|
+
if (item.retailer_id === retailerId && item.service === concept) {
|
|
844
|
+
return { ...item, status: newStatus };
|
|
845
|
+
}
|
|
846
|
+
return item;
|
|
847
|
+
}),
|
|
848
|
+
// version_status: articleStatus,
|
|
849
|
+
// status: articleStatus,
|
|
850
|
+
// article_status: articleStatus
|
|
1121
851
|
};
|
|
1122
|
-
await sendMessage(data);
|
|
1123
|
-
if (newOrderStatus) productTemp.status = newArticleStatus[articleId];
|
|
1124
|
-
productTemp[`${concept}_status`] = newStatus;
|
|
1125
|
-
await loadData();
|
|
1126
|
-
if (message) setMessage(message);
|
|
1127
|
-
sessionStorage.setItem("productSelected", JSON.stringify(productTemp));
|
|
1128
|
-
setProduct(productTemp);
|
|
1129
|
-
}
|
|
1130
|
-
} catch (error) {
|
|
1131
|
-
setLoading(false);
|
|
1132
|
-
console.log(error);
|
|
1133
|
-
}
|
|
1134
|
-
};
|
|
1135
852
|
|
|
1136
|
-
|
|
1137
|
-
let concept = getConcept(activeTab);
|
|
853
|
+
//Actualizamos el services_data en el servicio específico del retailer actual
|
|
1138
854
|
|
|
1139
|
-
|
|
1140
|
-
|
|
855
|
+
const updatedServicesData = state.services_data?.map(service => ({
|
|
856
|
+
...service,
|
|
857
|
+
status: service?.id_retailer === retailerId && service?.service === concept ? newStatus : service?.status
|
|
858
|
+
}));
|
|
1141
859
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
860
|
+
const sessionProduct = sessionStorage.getItem("productSelected");
|
|
861
|
+
|
|
862
|
+
if (sessionProduct) {
|
|
863
|
+
const productInSession = JSON.parse(sessionProduct);
|
|
864
|
+
const updatedProductInSession = {
|
|
865
|
+
...productInSession,
|
|
866
|
+
[`${concept}_status`]: newStatus,
|
|
867
|
+
statusByRetailer: state.product.statusByRetailer.map((item) => {
|
|
868
|
+
if (item.retailer_id === retailerId && item.service === concept) {
|
|
869
|
+
return { ...item, status: newStatus };
|
|
870
|
+
}
|
|
871
|
+
return item;
|
|
872
|
+
}),
|
|
873
|
+
};
|
|
874
|
+
sessionStorage.setItem(
|
|
875
|
+
"productSelected",
|
|
876
|
+
JSON.stringify(updatedProductInSession),
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
if (message) {
|
|
881
|
+
dispatch({
|
|
882
|
+
type: "SET_MODAL",
|
|
883
|
+
payload: {
|
|
884
|
+
show: true,
|
|
885
|
+
title: "",
|
|
886
|
+
message: message,
|
|
887
|
+
image: successIcon,
|
|
888
|
+
},
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
dispatch({ type: "SET_PRODUCT", payload: updatedProduct });
|
|
893
|
+
dispatch({ type: "SET_SERVICES_DATA", payload: updatedServicesData });
|
|
1152
894
|
}
|
|
895
|
+
} catch (error) {
|
|
896
|
+
console.error("Error sending evaluation:", error);
|
|
897
|
+
dispatch({
|
|
898
|
+
type: "SET_MODAL",
|
|
899
|
+
payload: {
|
|
900
|
+
show: true,
|
|
901
|
+
title: "Error",
|
|
902
|
+
message: "Hubo un error al procesar la evaluación",
|
|
903
|
+
image: errorIcon,
|
|
904
|
+
},
|
|
905
|
+
});
|
|
906
|
+
} finally {
|
|
907
|
+
dispatch({ type: "SET_SAVING", payload: false });
|
|
1153
908
|
}
|
|
1154
|
-
|
|
1155
|
-
return (
|
|
1156
|
-
user.id_role === 1 ||
|
|
1157
|
-
(product.article[`id_${concept}_${rol}`] === user.id_user && validUser)
|
|
1158
|
-
);
|
|
1159
909
|
};
|
|
1160
910
|
|
|
1161
|
-
const
|
|
1162
|
-
|
|
911
|
+
const handleOnApproveAllServices = async () => {
|
|
912
|
+
await sendBulkEvaluation("A");
|
|
1163
913
|
};
|
|
1164
914
|
|
|
1165
|
-
const
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
case "Ficha técnica":
|
|
1169
|
-
concept = "datasheet";
|
|
1170
|
-
break;
|
|
1171
|
-
case "Imágenes":
|
|
1172
|
-
concept = "images";
|
|
1173
|
-
break;
|
|
1174
|
-
|
|
1175
|
-
default:
|
|
1176
|
-
concept = "description";
|
|
1177
|
-
break;
|
|
1178
|
-
}
|
|
1179
|
-
const data = {
|
|
1180
|
-
articleId: product?.article?.id_article,
|
|
1181
|
-
orderId: product?.orderId,
|
|
1182
|
-
message: body?.replace(/<.*?\/?>/gm, ""),
|
|
1183
|
-
concept: concept,
|
|
1184
|
-
version: version,
|
|
1185
|
-
};
|
|
1186
|
-
await axios.post(`${process.env.REACT_APP_COMMENTS_ENDPOINT}`, data, {
|
|
1187
|
-
headers: {
|
|
1188
|
-
Authorization: token,
|
|
1189
|
-
},
|
|
1190
|
-
});
|
|
1191
|
-
await getComments(tab);
|
|
1192
|
-
setMessage("");
|
|
1193
|
-
setComponentsArray([]);
|
|
915
|
+
const handleOnRejectAllServices = () => {
|
|
916
|
+
setRejectAll(true);
|
|
917
|
+
setShowRejectModal(true);
|
|
1194
918
|
};
|
|
1195
919
|
|
|
1196
|
-
const
|
|
920
|
+
const sendBulkEvaluation = async (result) => {
|
|
921
|
+
dispatch({ type: "SET_SAVING", payload: true });
|
|
1197
922
|
try {
|
|
1198
|
-
const
|
|
1199
|
-
const datasheetServicesArray = Object.values(services[0]);
|
|
1200
|
-
const allDatasheetInputs = datasheetServicesArray.pop();
|
|
1201
|
-
const descriptionsServicesArray = services[1];
|
|
1202
|
-
|
|
1203
|
-
let dsInputsRequired = [];
|
|
1204
|
-
|
|
1205
|
-
let desInputsRequired = 0;
|
|
1206
|
-
datasheetServicesArray?.forEach((datasheet) => {
|
|
1207
|
-
const [requested] = servicesData?.filter(
|
|
1208
|
-
(srv) =>
|
|
1209
|
-
srv.id_retailer === datasheet.retailer.id &&
|
|
1210
|
-
srv.service === getConcept(activeTab)
|
|
1211
|
-
);
|
|
923
|
+
const evaluationArray = [];
|
|
1212
924
|
|
|
1213
|
-
|
|
1214
|
-
datasheet?.data &&
|
|
1215
|
-
Object.values(datasheet?.data).forEach((dataGroup) => {
|
|
1216
|
-
dsInputsRequired.push(
|
|
1217
|
-
...dataGroup.inputs.filter((input) => {
|
|
1218
|
-
return (
|
|
1219
|
-
allDatasheetInputs[input].required &&
|
|
1220
|
-
allDatasheetInputs[input].id_retailer === activeRetailer.id &&
|
|
1221
|
-
(allDatasheetInputs[input].value === undefined ||
|
|
1222
|
-
!allDatasheetInputs[input].value)
|
|
1223
|
-
);
|
|
1224
|
-
})
|
|
1225
|
-
);
|
|
1226
|
-
});
|
|
1227
|
-
});
|
|
925
|
+
const conceptArray = getConceptsByRole(user.id_role);
|
|
1228
926
|
|
|
1229
|
-
|
|
927
|
+
state.services_data?.forEach((ret, idx) => {
|
|
928
|
+
const { service: retailer_service, id_retailer, status: status_retailer_service } = ret;
|
|
1230
929
|
|
|
1231
|
-
|
|
1232
|
-
descriptionsServicesArray.forEach((description) => {
|
|
1233
|
-
if (description.id != activeRetailer.id) return;
|
|
930
|
+
const lastStatusLevel = status_retailer_service.replace(/.*\//, "");
|
|
1234
931
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
932
|
+
if (conceptArray.includes(retailer_service) && statusArray?.includes(lastStatusLevel)) {
|
|
933
|
+
const data = {
|
|
934
|
+
articleId: state.product.id_article,
|
|
935
|
+
orderId: state.product.id_order,
|
|
936
|
+
concept: retailer_service,
|
|
937
|
+
result,
|
|
938
|
+
evalStatus: status_retailer_service,
|
|
939
|
+
retailerId: id_retailer,
|
|
940
|
+
};
|
|
1240
941
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
)
|
|
1247
|
-
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
942
|
+
evaluationArray.push(
|
|
943
|
+
axios.put(`${process.env.REACT_APP_EVALUATION_ENDPOINT}`, data, {
|
|
944
|
+
headers: {
|
|
945
|
+
Authorization: token,
|
|
946
|
+
},
|
|
947
|
+
}),
|
|
948
|
+
);
|
|
1250
949
|
}
|
|
1251
950
|
});
|
|
1252
951
|
|
|
1253
|
-
|
|
952
|
+
await Promise.all(evaluationArray);
|
|
1254
953
|
|
|
1255
|
-
const
|
|
954
|
+
const status = `${result}A`;
|
|
1256
955
|
|
|
1257
|
-
|
|
1258
|
-
|
|
956
|
+
// Actualizar el statusByRetailer para todos los retailers y conceptos
|
|
957
|
+
const updatedStatusByRetailer = state.product.statusByRetailer.map(
|
|
958
|
+
(item) =>
|
|
959
|
+
conceptArray.includes(item.service) ? { ...item, status } : item,
|
|
1259
960
|
);
|
|
1260
961
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
962
|
+
// Actualizar el producto con los nuevos estados
|
|
963
|
+
const updatedProduct = {
|
|
964
|
+
...state.product,
|
|
965
|
+
article_status: status,
|
|
966
|
+
status: status,
|
|
967
|
+
datasheet_status:
|
|
968
|
+
state.product.datasheet_status === "NA" ? "NA" : status,
|
|
969
|
+
description_status:
|
|
970
|
+
state.product.description_status === "NA" ? "NA" : status,
|
|
971
|
+
images_status: state.product.images_status === "NA" ? "NA" : status,
|
|
972
|
+
statusByRetailer: updatedStatusByRetailer,
|
|
973
|
+
};
|
|
1271
974
|
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
services[2].values.filter((img) => img.image_id === req.id).length ===
|
|
1276
|
-
0 && requiredCounter++
|
|
1277
|
-
);
|
|
975
|
+
dispatch({
|
|
976
|
+
type: "SET_PRODUCT",
|
|
977
|
+
payload: updatedProduct,
|
|
1278
978
|
});
|
|
1279
|
-
objetcTemp["Imágenes"] = requiredCounter;
|
|
1280
|
-
setRequiredNull(objetcTemp);
|
|
1281
|
-
} catch (error) {
|
|
1282
|
-
console.log(error);
|
|
1283
|
-
}
|
|
1284
|
-
};
|
|
1285
979
|
|
|
1286
|
-
|
|
1287
|
-
setComment(comments[activeTab]);
|
|
1288
|
-
}, [activeTab]);
|
|
1289
|
-
|
|
1290
|
-
const commentRevised = async () => {
|
|
1291
|
-
const data = {
|
|
1292
|
-
commentId: comment.id,
|
|
1293
|
-
};
|
|
1294
|
-
await axios.put(`${process.env.REACT_APP_COMMENTS_ENDPOINT}`, data, {
|
|
1295
|
-
headers: {
|
|
1296
|
-
Authorization: sessionStorage.getItem("jwt"),
|
|
1297
|
-
},
|
|
1298
|
-
});
|
|
1299
|
-
setCrossComment(false);
|
|
1300
|
-
await getComments();
|
|
1301
|
-
};
|
|
980
|
+
const updatedServicesData = state.services_data.map(service => conceptArray.includes(service.service) ? { ...service, status: status } : service);
|
|
1302
981
|
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
concept = "datasheet";
|
|
1308
|
-
break;
|
|
1309
|
-
case "Imágenes":
|
|
1310
|
-
concept = "images";
|
|
1311
|
-
break;
|
|
982
|
+
dispatch({
|
|
983
|
+
type: "SET_SERVICES_DATA",
|
|
984
|
+
payload: updatedServicesData,
|
|
985
|
+
});
|
|
1312
986
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
987
|
+
// sessionStorage.setItem(
|
|
988
|
+
// "productSelected",
|
|
989
|
+
// JSON.stringify(updatedProduct),
|
|
990
|
+
// );
|
|
991
|
+
// sessionStorage.setItem(
|
|
992
|
+
// "productEdit",
|
|
993
|
+
// JSON.stringify({
|
|
994
|
+
// ArticleId: updatedProduct.id_article,
|
|
995
|
+
// idCategory: updatedProduct.id_category,
|
|
996
|
+
// product: updatedProduct,
|
|
997
|
+
// }),
|
|
998
|
+
// );
|
|
999
|
+
|
|
1000
|
+
// Mostrar modal de éxito
|
|
1001
|
+
dispatch({
|
|
1002
|
+
type: "SET_MODAL",
|
|
1003
|
+
payload: {
|
|
1004
|
+
show: true,
|
|
1005
|
+
title: "",
|
|
1006
|
+
message:
|
|
1007
|
+
result === "A"
|
|
1008
|
+
? "Todos los servicios aprobados con éxito"
|
|
1009
|
+
: "Todos los servicios rechazados con éxito",
|
|
1010
|
+
image: successIcon,
|
|
1011
|
+
},
|
|
1012
|
+
});
|
|
1013
|
+
} catch (error) {
|
|
1014
|
+
console.error("Error in bulk evaluation:", error);
|
|
1015
|
+
} finally {
|
|
1016
|
+
dispatch({ type: "SET_SAVING", payload: false });
|
|
1316
1017
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
const handleOnChangeAssignations = async (assignationType, assignationId) => {
|
|
1021
|
+
const concept = getConceptByTab(state.active_tab);
|
|
1319
1022
|
const data = {
|
|
1320
1023
|
articleList: [
|
|
1321
1024
|
{
|
|
1322
|
-
orderId: product.
|
|
1323
|
-
articleId: product
|
|
1025
|
+
orderId: state.product.id_order,
|
|
1026
|
+
articleId: state.product.id_article,
|
|
1324
1027
|
},
|
|
1325
1028
|
],
|
|
1326
1029
|
concept: concept,
|
|
1327
1030
|
userId: assignationId,
|
|
1328
1031
|
};
|
|
1032
|
+
|
|
1329
1033
|
await axios({
|
|
1330
1034
|
method: "post",
|
|
1331
1035
|
url: process.env.REACT_APP_ASSIGNATIONS_ENDPOINT,
|
|
@@ -1334,646 +1038,803 @@ export const RetailerProductEdition = ({
|
|
|
1334
1038
|
Authorization: token,
|
|
1335
1039
|
},
|
|
1336
1040
|
});
|
|
1337
|
-
loadAssignations(productTemp);
|
|
1338
|
-
sessionStorage.setItem("productSelected", JSON.stringify(productTemp));
|
|
1339
|
-
};
|
|
1340
1041
|
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
`${product.article.upc}_${e.name}.${e.ext}`
|
|
1348
|
-
);
|
|
1349
|
-
}
|
|
1350
|
-
})
|
|
1351
|
-
: images?.values?.forEach((e) => {
|
|
1352
|
-
if (e.id) {
|
|
1353
|
-
saveAs(
|
|
1354
|
-
`https://${process.env.REACT_APP_IMAGES_BUCKET}.s3.amazonaws.com/${e.srcDB}`,
|
|
1355
|
-
`${product.article.upc}_${e.name}.${e.ext}`
|
|
1356
|
-
);
|
|
1357
|
-
}
|
|
1358
|
-
});
|
|
1042
|
+
const updatedProduct = {
|
|
1043
|
+
...state.product,
|
|
1044
|
+
[`id_${concept}_${assignationType}`]: assignationId,
|
|
1045
|
+
};
|
|
1046
|
+
|
|
1047
|
+
dispatch({ type: "SET_PRODUCT", payload: updatedProduct });
|
|
1359
1048
|
};
|
|
1360
1049
|
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
const imgsInBack = [];
|
|
1050
|
+
const handleOnSetAssignation = () => {
|
|
1051
|
+
console.log("handleOnSetAssignation - pendiente de implementar");
|
|
1052
|
+
};
|
|
1365
1053
|
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1054
|
+
const handleOnSetImages = () => {
|
|
1055
|
+
console.log("handleOnSetImages - pendiente de implementar");
|
|
1056
|
+
};
|
|
1369
1057
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1058
|
+
const handleOnSetCheckAll = (isChecked) => {
|
|
1059
|
+
dispatch({ type: "TOGGLE_CHECK_ALL_IMAGES", payload: isChecked });
|
|
1060
|
+
};
|
|
1373
1061
|
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1062
|
+
const handleOnSetSelectedImages = () => {
|
|
1063
|
+
/*
|
|
1064
|
+
Esta función no se utiliza actualmente.
|
|
1065
|
+
|
|
1066
|
+
En la versión anterior se usaban dos funciones distintas para el checkbox
|
|
1067
|
+
"Seleccionar todo":
|
|
1068
|
+
- Una para cambiar el valor booleano del checkbox.
|
|
1069
|
+
- Otra para actualizar el array de imágenes seleccionadas.
|
|
1070
|
+
|
|
1071
|
+
En la versión actual se unificó la lógica en una sola función,
|
|
1072
|
+
`handleOnSetCheckAll`, que recibe el valor `true` o `false` del checkbox
|
|
1073
|
+
"Seleccionar todo" y, a partir de este, agrega o elimina todas las imágenes
|
|
1074
|
+
del array de imágenes seleccionadas.
|
|
1075
|
+
*/
|
|
1076
|
+
console.log("setSelectedImages");
|
|
1077
|
+
};
|
|
1078
|
+
const handleOnSubmitComment = async (e) => {
|
|
1079
|
+
e.preventDefault();
|
|
1080
|
+
const commentText = document.querySelector(
|
|
1081
|
+
"#commentary-box .ql-container .ql-editor > p",
|
|
1082
|
+
).innerHTML;
|
|
1083
|
+
try {
|
|
1084
|
+
await createComment(commentText, token);
|
|
1085
|
+
|
|
1086
|
+
dispatch({
|
|
1087
|
+
type: "SET_MODAL",
|
|
1088
|
+
payload: {
|
|
1089
|
+
show: true,
|
|
1090
|
+
title: "",
|
|
1091
|
+
message: "Comentario guardado con éxito",
|
|
1092
|
+
image: successIcon,
|
|
1093
|
+
},
|
|
1094
|
+
});
|
|
1095
|
+
} catch (error) {
|
|
1096
|
+
console.error("Error saving comment:", error);
|
|
1097
|
+
dispatch({
|
|
1098
|
+
type: "SET_MODAL",
|
|
1099
|
+
payload: {
|
|
1100
|
+
show: true,
|
|
1101
|
+
title: "Error",
|
|
1102
|
+
message: "Hubo un error al guardar el comentario",
|
|
1103
|
+
image: errorIcon,
|
|
1104
|
+
},
|
|
1105
|
+
});
|
|
1391
1106
|
}
|
|
1107
|
+
};
|
|
1392
1108
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
});
|
|
1397
|
-
|
|
1398
|
-
getRequired([
|
|
1399
|
-
services[0],
|
|
1400
|
-
services[1],
|
|
1401
|
-
{ ...services[2], values: imgsLeft },
|
|
1402
|
-
]);
|
|
1109
|
+
const handleOnSendEvaluationToFacilitator = () => {
|
|
1110
|
+
sendSingleEvaluation();
|
|
1111
|
+
};
|
|
1403
1112
|
|
|
1404
|
-
|
|
1113
|
+
const isEvaluationFinished = (id_rol, tab, statusArray) => {
|
|
1114
|
+
const servicesData = state.services_data;
|
|
1115
|
+
const activeRetailer = state.active_retailer;
|
|
1116
|
+
const product = state.product;
|
|
1117
|
+
const concept = getConceptByTab(tab);
|
|
1405
1118
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1119
|
+
const servicesByTab = servicesData?.filter(
|
|
1120
|
+
(serv) => serv.service === concept,
|
|
1121
|
+
);
|
|
1409
1122
|
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
setComponentsArray([
|
|
1414
|
-
<ScreenHeader
|
|
1415
|
-
key={"1"}
|
|
1416
|
-
text={"¿Está seguro de eliminar las imágenes seleccionadas?"}
|
|
1417
|
-
headerType="retailer-name-header"
|
|
1418
|
-
color={"white"}
|
|
1419
|
-
/>,
|
|
1420
|
-
<Button
|
|
1421
|
-
key={"2"}
|
|
1422
|
-
buttonType="general-white-button"
|
|
1423
|
-
label={"Cancelar"}
|
|
1424
|
-
onClick={() => setMessage("")}
|
|
1425
|
-
/>,
|
|
1426
|
-
<Button
|
|
1427
|
-
key={"3"}
|
|
1428
|
-
buttonType="general-button-default"
|
|
1429
|
-
label={"Aceptar"}
|
|
1430
|
-
onClick={() => {
|
|
1431
|
-
setMessage("");
|
|
1432
|
-
deleteImages();
|
|
1433
|
-
}}
|
|
1434
|
-
/>,
|
|
1435
|
-
]);
|
|
1436
|
-
}
|
|
1437
|
-
};
|
|
1123
|
+
const statusBySelectedRetailerService = servicesByTab
|
|
1124
|
+
?.find((serv) => serv.id_retailer === activeRetailer?.id_retailer)
|
|
1125
|
+
?.status?.replace(/.*\//, "");
|
|
1438
1126
|
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1127
|
+
const currentProducStatus = product?.[`${concept}_status`]?.replace(
|
|
1128
|
+
/.*\//,
|
|
1129
|
+
"",
|
|
1130
|
+
);
|
|
1442
1131
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
service.id_retailer === activeRetailer?.id &&
|
|
1447
|
-
service.service === concept
|
|
1132
|
+
const unvalidated = ["IE", "CA"].includes(currentProducStatus);
|
|
1133
|
+
const auditorUnvalidated = !["RA", "AA", "ACA", "AP"].includes(
|
|
1134
|
+
currentProducStatus,
|
|
1448
1135
|
);
|
|
1449
|
-
return retailerService ? retailerService.status : "NS";
|
|
1450
|
-
};
|
|
1451
1136
|
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1137
|
+
let result;
|
|
1138
|
+
switch (id_rol) {
|
|
1139
|
+
case 7:
|
|
1140
|
+
case 8:
|
|
1456
1141
|
|
|
1457
|
-
|
|
1458
|
-
services.length > 0 && getRequired(services);
|
|
1459
|
-
}, [services, servicesData, activeTab]);
|
|
1142
|
+
const canSendEvaluation = statusArray.includes(statusBySelectedRetailerService);
|
|
1460
1143
|
|
|
1461
|
-
|
|
1462
|
-
setSaving(loading);
|
|
1463
|
-
}, [loading]);
|
|
1144
|
+
// const conditionTwo = statusArray.includes(product?.status);
|
|
1464
1145
|
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
let conceptArray = [];
|
|
1470
|
-
switch (user.id_role) {
|
|
1471
|
-
case 4:
|
|
1472
|
-
conceptArray = ["description", "datasheet"];
|
|
1473
|
-
break;
|
|
1474
|
-
case 5:
|
|
1475
|
-
conceptArray = ["images"];
|
|
1476
|
-
break;
|
|
1477
|
-
|
|
1478
|
-
default:
|
|
1479
|
-
conceptArray = ["description", "datasheet", "images"];
|
|
1480
|
-
break;
|
|
1481
|
-
}
|
|
1146
|
+
// const conditionThree =
|
|
1147
|
+
// servicesByTab.filter((service) =>
|
|
1148
|
+
// statusArray.includes(service.status?.replace(/.*\//, "")),
|
|
1149
|
+
// ).length === servicesByTab.length;
|
|
1482
1150
|
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
servicesData?.forEach((ret) => {
|
|
1486
|
-
if (conceptArray.includes(ret.service)) {
|
|
1487
|
-
let data = {
|
|
1488
|
-
articleId: product.article.id_article,
|
|
1489
|
-
orderId: product.id_order ?? product.orderId,
|
|
1490
|
-
concept: ret.service,
|
|
1491
|
-
result: result,
|
|
1492
|
-
evalStatus: ret.status,
|
|
1493
|
-
retailerId: ret.id_retailer,
|
|
1494
|
-
};
|
|
1495
|
-
evaluationArray.push(
|
|
1496
|
-
axios.put(`${process.env.REACT_APP_EVALUATION_ENDPOINT}`, data, {
|
|
1497
|
-
headers: {
|
|
1498
|
-
Authorization: token,
|
|
1499
|
-
},
|
|
1500
|
-
})
|
|
1501
|
-
);
|
|
1502
|
-
}
|
|
1503
|
-
});
|
|
1504
|
-
await Promise.all(evaluationArray);
|
|
1151
|
+
// return (canSendEvaluation && conditionTwo) || conditionThree;
|
|
1505
1152
|
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1153
|
+
return canSendEvaluation;
|
|
1154
|
+
|
|
1155
|
+
case 4:
|
|
1156
|
+
case 5:
|
|
1157
|
+
const filteredSrv45 = servicesByTab?.filter((serv) =>
|
|
1158
|
+
statusArray.includes(serv?.status),
|
|
1159
|
+
);
|
|
1160
|
+
const condition45 =
|
|
1161
|
+
unvalidated &&
|
|
1162
|
+
["CA", "IE"].includes(product?.status) &&
|
|
1163
|
+
filteredSrv45?.length === servicesByTab?.length;
|
|
1164
|
+
return condition45;
|
|
1165
|
+
case 6:
|
|
1166
|
+
const statusInArray = statusArray.includes(product?.status);
|
|
1167
|
+
const allSrvValid = srv?.every((serv) =>
|
|
1168
|
+
["RA", "AA", "AP", "ACA"].includes(serv?.status),
|
|
1169
|
+
);
|
|
1170
|
+
const condition6 = statusInArray && allSrvValid && auditorUnvalidated;
|
|
1171
|
+
return condition6;
|
|
1172
|
+
default:
|
|
1173
|
+
console.log("Default case - returning false");
|
|
1174
|
+
return false;
|
|
1523
1175
|
}
|
|
1524
1176
|
};
|
|
1525
1177
|
|
|
1526
|
-
const
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1178
|
+
const handleOnChangeProductVersion = (version) => {
|
|
1179
|
+
console.log('se cambia la version')
|
|
1180
|
+
dispatch({
|
|
1181
|
+
type: "SET_PRODUCT_VERSION",
|
|
1182
|
+
payload: version,
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
loadData(true, version);
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
const ProductEditionSkeleton = () => {
|
|
1189
|
+
return (
|
|
1190
|
+
<Container headerTop={0}>
|
|
1191
|
+
<Box
|
|
1192
|
+
px={1.5}
|
|
1193
|
+
py={1}
|
|
1194
|
+
pb={0}
|
|
1195
|
+
display="flex"
|
|
1196
|
+
alignItems="center"
|
|
1197
|
+
justifyContent="space-between"
|
|
1198
|
+
>
|
|
1199
|
+
<Skeleton variant="text" width={300} height={40} />
|
|
1200
|
+
<Stack direction="row" spacing={2}>
|
|
1201
|
+
<Skeleton variant="circular" width={32} height={32} />
|
|
1202
|
+
</Stack>
|
|
1203
|
+
</Box>
|
|
1204
|
+
|
|
1205
|
+
<div
|
|
1206
|
+
className="data-container"
|
|
1207
|
+
style={{ display: "flex", gap: "8px", padding: "0 12px 12px" }}
|
|
1208
|
+
>
|
|
1209
|
+
<div
|
|
1210
|
+
className="image-data-panel"
|
|
1211
|
+
style={{
|
|
1212
|
+
flex: "0 0 320px",
|
|
1213
|
+
display: "flex",
|
|
1214
|
+
flexDirection: "column",
|
|
1215
|
+
gap: "20px",
|
|
1216
|
+
}}
|
|
1217
|
+
>
|
|
1218
|
+
<Skeleton variant="rounded" width="100%" height={400} />
|
|
1219
|
+
|
|
1220
|
+
<Stack direction="row" spacing={2} justifyContent="center">
|
|
1221
|
+
{[1, 2, 3, 4].map((item) => (
|
|
1222
|
+
<Skeleton key={item} variant="rounded" width={60} height={80} />
|
|
1223
|
+
))}
|
|
1224
|
+
</Stack>
|
|
1225
|
+
|
|
1226
|
+
<Box mt={2}>
|
|
1227
|
+
{[1, 2, 3, 4].map((item) => (
|
|
1228
|
+
<Box
|
|
1229
|
+
key={item}
|
|
1230
|
+
display="flex"
|
|
1231
|
+
justifyContent="space-between"
|
|
1232
|
+
py={1}
|
|
1233
|
+
borderBottom="1px solid #f0f0f0"
|
|
1234
|
+
>
|
|
1235
|
+
<Skeleton variant="text" width="40%" />
|
|
1236
|
+
<Skeleton variant="text" width="20%" />
|
|
1237
|
+
</Box>
|
|
1238
|
+
))}
|
|
1239
|
+
</Box>
|
|
1240
|
+
</div>
|
|
1241
|
+
|
|
1242
|
+
<div
|
|
1243
|
+
className="product-information"
|
|
1244
|
+
style={{
|
|
1245
|
+
flex: 1,
|
|
1246
|
+
display: "flex",
|
|
1247
|
+
flexDirection: "column",
|
|
1248
|
+
gap: "14px",
|
|
1249
|
+
}}
|
|
1250
|
+
>
|
|
1251
|
+
<Box>
|
|
1252
|
+
<Skeleton variant="text" width="80%" height={50} />
|
|
1253
|
+
<Stack direction="row" spacing={2} alignItems="center">
|
|
1254
|
+
<Skeleton variant="rounded" width={180} height={24} />
|
|
1255
|
+
<Skeleton variant="rounded" width={300} height={24} />
|
|
1256
|
+
</Stack>
|
|
1257
|
+
</Box>
|
|
1258
|
+
|
|
1259
|
+
<Box display="flex" gap={4} pb={1}>
|
|
1260
|
+
<Skeleton variant="text" width={140} height={45} />
|
|
1261
|
+
<Skeleton variant="text" width={140} height={45} />
|
|
1262
|
+
<Skeleton variant="text" width={140} height={45} />
|
|
1263
|
+
</Box>
|
|
1264
|
+
|
|
1265
|
+
<Box display="flex" flexDirection="column" gap={4}>
|
|
1266
|
+
{[1, 2, 3].map((item) => (
|
|
1267
|
+
<Box key={item}>
|
|
1268
|
+
<Box
|
|
1269
|
+
display="flex"
|
|
1270
|
+
justifyContent="space-between"
|
|
1271
|
+
alignItems="center"
|
|
1272
|
+
mb={1}
|
|
1273
|
+
>
|
|
1274
|
+
<Skeleton variant="text" width="30%" height={24} />
|
|
1275
|
+
<Skeleton
|
|
1276
|
+
variant="rounded"
|
|
1277
|
+
width={175}
|
|
1278
|
+
height={25}
|
|
1279
|
+
sx={{ borderRadius: "7.5px" }}
|
|
1280
|
+
/>
|
|
1281
|
+
</Box>
|
|
1282
|
+
<Skeleton variant="rounded" width="100%" height={70} />
|
|
1283
|
+
<Box display="flex" justifyContent="flex-end" mt={0.5}>
|
|
1284
|
+
<Skeleton variant="text" width={60} />
|
|
1285
|
+
</Box>
|
|
1286
|
+
</Box>
|
|
1287
|
+
))}
|
|
1288
|
+
</Box>
|
|
1289
|
+
|
|
1290
|
+
<Box mt="auto" pt={4}>
|
|
1291
|
+
<Skeleton variant="rounded" width="100%" height={120} />
|
|
1292
|
+
<Box display="flex" justifyContent="flex-end" gap={2} mt={2}>
|
|
1293
|
+
<Skeleton
|
|
1294
|
+
variant="rounded"
|
|
1295
|
+
width={180}
|
|
1296
|
+
height={45}
|
|
1297
|
+
sx={{ borderRadius: "24px" }}
|
|
1298
|
+
/>
|
|
1299
|
+
<Skeleton
|
|
1300
|
+
variant="rounded"
|
|
1301
|
+
width={180}
|
|
1302
|
+
height={45}
|
|
1303
|
+
sx={{ borderRadius: "24px" }}
|
|
1304
|
+
/>
|
|
1305
|
+
</Box>
|
|
1306
|
+
</Box>
|
|
1307
|
+
</div>
|
|
1308
|
+
</div>
|
|
1309
|
+
</Container>
|
|
1534
1310
|
);
|
|
1535
|
-
const parseData = JSON.parse(response.data.body).data[0];
|
|
1536
|
-
setObservation(parseData.observations);
|
|
1537
1311
|
};
|
|
1312
|
+
|
|
1538
1313
|
useEffect(() => {
|
|
1539
|
-
|
|
1540
|
-
}, []);
|
|
1314
|
+
console.log({stateProduct: state.product})
|
|
1315
|
+
}, [state.product]);
|
|
1316
|
+
|
|
1317
|
+
if (state.loading || !state.services || !state.product)
|
|
1318
|
+
return (
|
|
1319
|
+
<>
|
|
1320
|
+
<ProductEditionSkeleton />
|
|
1321
|
+
</>
|
|
1322
|
+
);
|
|
1323
|
+
|
|
1541
1324
|
return (
|
|
1542
|
-
<
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
<div className="image-data-panel">
|
|
1556
|
-
<ImagePreviewer
|
|
1557
|
-
activeImage={images?.values ? images?.values[activeImage] : {}}
|
|
1558
|
-
imagesArray={images}
|
|
1559
|
-
setActiveImage={setActiveImage}
|
|
1560
|
-
setShowModal={setShowModal}
|
|
1561
|
-
/>
|
|
1562
|
-
<ImageDataTable
|
|
1563
|
-
lists={images}
|
|
1564
|
-
activeImage={images?.values ? images?.values[activeImage] : {}}
|
|
1565
|
-
retailerSelected={activeRetailer?.id}
|
|
1566
|
-
setImages={setImages}
|
|
1567
|
-
assignationsImages={assig["Imágenes"]}
|
|
1568
|
-
imagesStatus={product?.images_status}
|
|
1569
|
-
setAssignation={setAssignation}
|
|
1570
|
-
isRetailer={isRetailer}
|
|
1571
|
-
onClickSave={() =>
|
|
1572
|
-
product?.services?.images === 1 && updateImages()
|
|
1325
|
+
<AiProductEditionProvider
|
|
1326
|
+
isCreatorsEdition={true}
|
|
1327
|
+
user={user}
|
|
1328
|
+
token={token}
|
|
1329
|
+
state={state}
|
|
1330
|
+
>
|
|
1331
|
+
<Container headerTop={headerTop}>
|
|
1332
|
+
{showRejectModal && (
|
|
1333
|
+
<Modal
|
|
1334
|
+
title={
|
|
1335
|
+
rejectAll
|
|
1336
|
+
? "Agregar mensaje para rechazar todo"
|
|
1337
|
+
: "Agregar mensaje de rechazo"
|
|
1573
1338
|
}
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
headerData={product}
|
|
1583
|
-
productObservation={observation}
|
|
1584
|
-
percent={activePercentage}
|
|
1585
|
-
activeRetailer={activeRetailer}
|
|
1586
|
-
servicesData={servicesData}
|
|
1587
|
-
setActiveRetailer={setActiveRetailer}
|
|
1588
|
-
sendToFacilitator={sendToFacilitator}
|
|
1589
|
-
approve={() => {
|
|
1590
|
-
sendToFacilitator("A");
|
|
1591
|
-
}}
|
|
1592
|
-
reject={() => {
|
|
1593
|
-
setShowRejectModal(true);
|
|
1594
|
-
}}
|
|
1595
|
-
showApproveRejectAll={
|
|
1596
|
-
approveRejectAllButtons() && (auditorAssigned() || userAssigned())
|
|
1339
|
+
show={showRejectModal}
|
|
1340
|
+
customComponent={
|
|
1341
|
+
<TagAndInput
|
|
1342
|
+
inputType={"textarea"}
|
|
1343
|
+
inputId={"modal-message-box"}
|
|
1344
|
+
index={0}
|
|
1345
|
+
color={"white"}
|
|
1346
|
+
/>
|
|
1597
1347
|
}
|
|
1598
|
-
|
|
1599
|
-
|
|
1348
|
+
buttons={[
|
|
1349
|
+
<ButtonV2
|
|
1350
|
+
key={"btn-Cancelar"}
|
|
1351
|
+
type={"white"}
|
|
1352
|
+
label={"Cancelar"}
|
|
1353
|
+
size={12}
|
|
1354
|
+
onClick={() => {
|
|
1355
|
+
setShowRejectModal(false);
|
|
1356
|
+
}}
|
|
1357
|
+
/>,
|
|
1358
|
+
<ButtonV2
|
|
1359
|
+
key={"btn-Aceptar"}
|
|
1360
|
+
type={"pink"}
|
|
1361
|
+
label={"Aceptar"}
|
|
1362
|
+
size={12}
|
|
1363
|
+
onClick={async () => {
|
|
1364
|
+
const elements = document.querySelectorAll(
|
|
1365
|
+
"#modal-message-box .ql-container .ql-editor > p",
|
|
1366
|
+
);
|
|
1367
|
+
|
|
1368
|
+
if (!elements || elements.length === 0) {
|
|
1369
|
+
console.error("Elemento no encontrado");
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
const isMessageEmpty = Array.from(elements).every((el) => {
|
|
1374
|
+
const body = el.innerHTML;
|
|
1375
|
+
return (
|
|
1376
|
+
!body || body.replace(/<.*?\/?>/gm, "").trim() === ""
|
|
1377
|
+
);
|
|
1378
|
+
});
|
|
1379
|
+
|
|
1380
|
+
if (isMessageEmpty) {
|
|
1381
|
+
const container = document.querySelector(
|
|
1382
|
+
".container-customComponent",
|
|
1383
|
+
);
|
|
1384
|
+
const existingAlert =
|
|
1385
|
+
container.querySelector(".alert-error");
|
|
1386
|
+
|
|
1387
|
+
if (!existingAlert) {
|
|
1388
|
+
const alert = document.createElement("div");
|
|
1389
|
+
alert.className = "alert-error";
|
|
1390
|
+
alert.style.cssText = `
|
|
1391
|
+
color: #d32f2f;
|
|
1392
|
+
background-color: #ffebee;
|
|
1393
|
+
border: 1px solid #ef5350;
|
|
1394
|
+
border-radius: 4px;
|
|
1395
|
+
padding: 12px 16px;
|
|
1396
|
+
margin-top: 10px;
|
|
1397
|
+
font-size: 14px;
|
|
1398
|
+
display: flex;
|
|
1399
|
+
align-items: center;
|
|
1400
|
+
gap: 8px;
|
|
1401
|
+
font-family: 'Roboto', sans-serif;
|
|
1402
|
+
text-align: center;
|
|
1403
|
+
`;
|
|
1404
|
+
alert.innerHTML = `<span>El mensaje no puede estar vacío.</span>`;
|
|
1405
|
+
container.appendChild(alert);
|
|
1406
|
+
}
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
const fullMessage = Array.from(elements)
|
|
1411
|
+
.map((element) => element.innerHTML)
|
|
1412
|
+
.join("")
|
|
1413
|
+
.replace(/<br\s*\/?>/gi, "\n");
|
|
1414
|
+
|
|
1415
|
+
await createComment(fullMessage, token);
|
|
1416
|
+
|
|
1417
|
+
rejectAll
|
|
1418
|
+
? sendBulkEvaluation("R")
|
|
1419
|
+
: sendSingleEvaluation("R");
|
|
1420
|
+
setShowRejectModal(false);
|
|
1421
|
+
}}
|
|
1422
|
+
/>,
|
|
1423
|
+
]}
|
|
1424
|
+
/>
|
|
1425
|
+
)}
|
|
1426
|
+
{state.modal.show && (
|
|
1427
|
+
<GenericModal
|
|
1428
|
+
componentsArray={[
|
|
1429
|
+
state.modal.image && (
|
|
1430
|
+
<img key="1" src={state.modal.image} alt="modal icon" />
|
|
1431
|
+
),
|
|
1432
|
+
state.modal.title && (
|
|
1433
|
+
<ScreenHeader
|
|
1434
|
+
key="2"
|
|
1435
|
+
headerType={"retailer-name-header"}
|
|
1436
|
+
text={state.modal.title}
|
|
1437
|
+
color={"white"}
|
|
1438
|
+
/>
|
|
1439
|
+
),
|
|
1440
|
+
state.modal.message && (
|
|
1441
|
+
<ScreenHeader
|
|
1442
|
+
key="3"
|
|
1443
|
+
headerType={"retailer-name-header"}
|
|
1444
|
+
text={state.modal.message}
|
|
1445
|
+
color={"white"}
|
|
1446
|
+
/>
|
|
1447
|
+
),
|
|
1448
|
+
state.modal.buttons && (
|
|
1449
|
+
<div key="4" style={{ marginTop: "16px" }}>
|
|
1450
|
+
{state.modal.buttons.map((button, index) => (
|
|
1451
|
+
<Button
|
|
1452
|
+
key={index}
|
|
1453
|
+
buttonType={button.buttonType}
|
|
1454
|
+
label={button.text}
|
|
1455
|
+
onClick={button.action}
|
|
1456
|
+
/>
|
|
1457
|
+
))}
|
|
1458
|
+
</div>
|
|
1459
|
+
),
|
|
1460
|
+
].filter(Boolean)}
|
|
1461
|
+
onClick={() =>
|
|
1462
|
+
dispatch({
|
|
1463
|
+
type: "SET_MODAL",
|
|
1464
|
+
payload: { show: false, title: "", message: "", image: null },
|
|
1465
|
+
})
|
|
1600
1466
|
}
|
|
1601
|
-
approveAll={() => validateAll("A")}
|
|
1602
|
-
rejectAll={() => {
|
|
1603
|
-
setShowRejectModal(true);
|
|
1604
|
-
setValRejAll(true);
|
|
1605
|
-
}}
|
|
1606
|
-
isObservationVisible={isObservationVisible}
|
|
1607
|
-
toggleObservation={toggleObservation}
|
|
1608
|
-
// handleClickOutside={handleClickOutside}
|
|
1609
|
-
hideObservation={hideObservation}
|
|
1610
1467
|
/>
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
setFich={setFich}
|
|
1628
|
-
imag={imag}
|
|
1629
|
-
setImag={setImag}
|
|
1630
|
-
updatedDescriptions={updatedDescriptions}
|
|
1631
|
-
setUpdatedDescriptions={setUpdatedDescriptions}
|
|
1632
|
-
updatedDatasheets={updatedDatasheets}
|
|
1633
|
-
setUpdatedDatasheets={setUpdatedDatasheets}
|
|
1634
|
-
images={images}
|
|
1635
|
-
setImages={setImages}
|
|
1636
|
-
selectedImages={selectedImages}
|
|
1637
|
-
setSelectedImages={setSelectedImages}
|
|
1468
|
+
)}
|
|
1469
|
+
{showModal && (
|
|
1470
|
+
<ProductImageModal
|
|
1471
|
+
images={state.images_values}
|
|
1472
|
+
setShowModal={setShowModal}
|
|
1473
|
+
approveRejectButtons={canShowSingleEvaluationButtons()}
|
|
1474
|
+
sendToFacilitator={handleOnSendEvaluationToFacilitator}
|
|
1475
|
+
/>
|
|
1476
|
+
)}
|
|
1477
|
+
{showVersionSelector && (
|
|
1478
|
+
<VersionSelector
|
|
1479
|
+
modalId={"version-selector"}
|
|
1480
|
+
articleId={state.product.id_article}
|
|
1481
|
+
setVersion={handleOnChangeProductVersion}
|
|
1482
|
+
companyName={state.product.company}
|
|
1483
|
+
currentVersion={state.product.version}
|
|
1638
1484
|
setShowVersionSelector={setShowVersionSelector}
|
|
1639
|
-
|
|
1640
|
-
switch (activeTab) {
|
|
1641
|
-
case "Descripción":
|
|
1642
|
-
!saving &&
|
|
1643
|
-
product?.description_status !== "NS" &&
|
|
1644
|
-
saveDescriptions();
|
|
1645
|
-
break;
|
|
1646
|
-
case "Ficha técnica":
|
|
1647
|
-
!saving &&
|
|
1648
|
-
product?.datasheet_status !== "NS" &&
|
|
1649
|
-
saveDatasheets();
|
|
1650
|
-
break;
|
|
1651
|
-
case "Imágenes":
|
|
1652
|
-
!saving && product?.images_status !== "NS" && updateImages();
|
|
1653
|
-
break;
|
|
1654
|
-
|
|
1655
|
-
default:
|
|
1656
|
-
break;
|
|
1657
|
-
}
|
|
1658
|
-
}}
|
|
1659
|
-
canAssign={![7, 8].includes(user.id_role)}
|
|
1485
|
+
jwt={token}
|
|
1660
1486
|
/>
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1487
|
+
)}
|
|
1488
|
+
<HeaderTop
|
|
1489
|
+
setHeaderTop={setHeaderTop}
|
|
1490
|
+
auditableVersion={auditableVersion}
|
|
1491
|
+
setCompare={setCompare}
|
|
1492
|
+
isAuditor={[1, 6].includes(user.id_role)}
|
|
1493
|
+
withChat={location?.state?.withChat}
|
|
1494
|
+
chatType={location?.state?.chatType}
|
|
1495
|
+
productSelected={state.product}
|
|
1496
|
+
token={token}
|
|
1497
|
+
activeRetailer={{
|
|
1498
|
+
id: state.active_retailer?.id_retailer,
|
|
1499
|
+
name: state.active_retailer?.retailer,
|
|
1500
|
+
}}
|
|
1501
|
+
/>
|
|
1502
|
+
<div className="data-container">
|
|
1503
|
+
<div className="image-data-panel">
|
|
1504
|
+
<ImagePreviewer
|
|
1505
|
+
activeImage={
|
|
1506
|
+
state.images_values.values[state.current_image] ?? {}
|
|
1507
|
+
}
|
|
1508
|
+
imagesArray={state.images_values || []}
|
|
1509
|
+
setActiveImage={handleOnChangeCurrentImage}
|
|
1510
|
+
setShowModal={handleOnShowModalGallery}
|
|
1511
|
+
/>
|
|
1512
|
+
<ImageDataTable
|
|
1513
|
+
// states
|
|
1514
|
+
lists={state.images_values || []}
|
|
1515
|
+
activeImage={
|
|
1516
|
+
state.images_values?.values
|
|
1517
|
+
? state.images_values?.values[state.current_image]
|
|
1518
|
+
: {}
|
|
1519
|
+
}
|
|
1520
|
+
assignationsImages={state.collaborator_assignations["Imágenes"]}
|
|
1521
|
+
imagesStatus={state.product?.images_status || "-"}
|
|
1522
|
+
retailerSelected={state.active_retailer?.id_retailer}
|
|
1523
|
+
isRetailer={isRetailer}
|
|
1524
|
+
version={state.product.version}
|
|
1525
|
+
shotThd={shotThd}
|
|
1526
|
+
setShowVersionSelector={setShowVersionSelector}
|
|
1527
|
+
// actions
|
|
1528
|
+
setImages={handleOnChangeCurrentImage}
|
|
1529
|
+
setAssignation={handleOnChangeAssignations} // No se usa?
|
|
1530
|
+
onClickSave={handleOnClickSaveImages}
|
|
1531
|
+
showSaveButton={isAuditorAssigned() || isUserAssignedToService()}
|
|
1532
|
+
/>
|
|
1533
|
+
</div>
|
|
1681
1534
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1535
|
+
<div className="product-information">
|
|
1536
|
+
<FullProductNameHeader
|
|
1537
|
+
// states
|
|
1538
|
+
headerData={state.product}
|
|
1539
|
+
productObservation={observation}
|
|
1540
|
+
percent={state.active_percentage.percentagesGeneral.required}
|
|
1541
|
+
activeRetailer={{
|
|
1542
|
+
id: state.active_retailer?.id_retailer,
|
|
1543
|
+
name: state.active_retailer?.retailer,
|
|
1544
|
+
image: state.active_retailer?.image,
|
|
1545
|
+
}}
|
|
1546
|
+
servicesData={state.services_data ? state.services_data : null}
|
|
1547
|
+
isObservationVisible={isObservationVisible}
|
|
1548
|
+
// actions
|
|
1549
|
+
setActiveRetailer={handleOnChangeActiveRetailer}
|
|
1550
|
+
approve={handleOnApproveSingleService}
|
|
1551
|
+
approveAll={handleOnApproveAllServices}
|
|
1552
|
+
reject={handleOnRejectSingleService}
|
|
1553
|
+
rejectAll={handleOnRejectAllServices}
|
|
1554
|
+
toggleObservation={handleOnToggleObservation}
|
|
1555
|
+
hideObservation={handleOnHideObservation}
|
|
1556
|
+
// sendToFacilitator={handleOnSendEvaluationToFacilitator} // No se usa?
|
|
1557
|
+
// validations
|
|
1558
|
+
showApproveRejectAll={
|
|
1559
|
+
canShowBulkEvaluationButtons() ||
|
|
1560
|
+
isAuditorAssigned() ||
|
|
1561
|
+
isUserAssignedToService()
|
|
1562
|
+
}
|
|
1563
|
+
showValidationButtons={
|
|
1564
|
+
canShowSingleEvaluationButtons() &&
|
|
1565
|
+
(isAuditorAssigned() || isUserAssignedToService())
|
|
1566
|
+
}
|
|
1567
|
+
/>
|
|
1568
|
+
<FullTabsMenu
|
|
1569
|
+
tabsSections={tabsSections}
|
|
1570
|
+
status={getStatusByCurrentServiceAndRetailer()}
|
|
1571
|
+
activeTab={state.active_tab}
|
|
1572
|
+
isRetailer={isRetailer}
|
|
1573
|
+
assig={state.collaborator_assignations[state.active_tab]}
|
|
1574
|
+
version={state.product.version}
|
|
1575
|
+
updatedDescriptions={state.updated_descriptions_inputs}
|
|
1576
|
+
updatedDatasheets={state.updated_datasheets_inputs}
|
|
1577
|
+
updatedImages={state.updated_images_values}
|
|
1578
|
+
images={state.services.images}
|
|
1579
|
+
// selectedImages={selectedImages} prop pasada asi: FullTabsMenu -> TabsMenu Pero en TabsMenu no se espera ninguna prop setSelectedImages
|
|
1580
|
+
// setters
|
|
1581
|
+
setActiveTab={handleOnChangeActiveTab}
|
|
1582
|
+
setImageLayout={handleOnToggleImageLayout}
|
|
1583
|
+
setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
|
|
1584
|
+
setUpdatedDatasheets={handleOnSetUpdatedDatasheets}
|
|
1585
|
+
setAssignation={handleOnSetAssignation} // No se usa?
|
|
1586
|
+
setImages={handleOnSetImages} // No se usa?
|
|
1587
|
+
setShowVersionSelector={setShowVersionSelector}
|
|
1588
|
+
// setSelectedImages={setSelectedImages} prop pasada asi: FullTabsMenu -> TabsMenu Pero en TabsMenu no se espera ninguna prop setSelectedImages
|
|
1589
|
+
// actions
|
|
1590
|
+
downloadImages={handleOnDownloadImages}
|
|
1591
|
+
askToDeleteImages={handleOnAskToDeleteImages}
|
|
1592
|
+
showSaveButton={isAuditorAssigned() || isUserAssignedToService()}
|
|
1593
|
+
onClickSave={handleOnClickSave}
|
|
1594
|
+
// validations
|
|
1595
|
+
canAssign={![7, 8].includes(user.id_role)}
|
|
1596
|
+
/>
|
|
1597
|
+
<div
|
|
1598
|
+
className={
|
|
1599
|
+
"services-information-container " +
|
|
1600
|
+
(imageLayout && state.active_tab === "Imágenes"
|
|
1601
|
+
? "image-services"
|
|
1602
|
+
: "")
|
|
1603
|
+
}
|
|
1604
|
+
id="services-information-container"
|
|
1605
|
+
>
|
|
1606
|
+
{state.saving ? (
|
|
1607
|
+
<Loading />
|
|
1608
|
+
) : (
|
|
1609
|
+
<>
|
|
1610
|
+
{state.active_tab === "Descripción" &&
|
|
1611
|
+
(state.product?.description_status !== "NS" ? (
|
|
1685
1612
|
<InputGroup
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
setUpdatedDatasheets={setUpdatedDatasheets}
|
|
1613
|
+
activeSection={state.active_tab}
|
|
1614
|
+
inputGroup={state.descriptions_inputs[0]}
|
|
1615
|
+
updatedDescriptions={state.updated_descriptions_inputs}
|
|
1616
|
+
articleId={state.product?.id_article}
|
|
1617
|
+
version={state.product.version}
|
|
1618
|
+
auditInputGroup={auditDescriptions[0]}
|
|
1619
|
+
setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
|
|
1620
|
+
dinamicHeight={true}
|
|
1695
1621
|
compare={compare}
|
|
1696
1622
|
/>
|
|
1697
|
-
)
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1623
|
+
) : (
|
|
1624
|
+
<ScreenHeader
|
|
1625
|
+
text={"No cuentas con este servicio"}
|
|
1626
|
+
headerType={"input-name-header"}
|
|
1627
|
+
/>
|
|
1628
|
+
))}
|
|
1629
|
+
{state.active_tab === "Ficha técnica" &&
|
|
1630
|
+
(state.product?.datasheet_status !== "NS" ? (
|
|
1631
|
+
<>
|
|
1632
|
+
{state.datasheets_inputs[0]?.data?.map(
|
|
1633
|
+
(dataGroup, index) => (
|
|
1634
|
+
<InputGroup
|
|
1635
|
+
key={index + "-" + state.active_retailer.retailer}
|
|
1636
|
+
articleId={state.product.id_article}
|
|
1637
|
+
version={state.version}
|
|
1638
|
+
activeSection={state.active_tab}
|
|
1639
|
+
inputGroup={dataGroup}
|
|
1640
|
+
dataInputs={state.datasheets_inputs[1]}
|
|
1641
|
+
auditInputs={auditDatasheets[1]}
|
|
1642
|
+
updatedDatasheets={
|
|
1643
|
+
state.updated_datasheets_inputs
|
|
1644
|
+
}
|
|
1645
|
+
setUpdatedDatasheets={
|
|
1646
|
+
handleOnSetUpdatedDatasheets
|
|
1647
|
+
}
|
|
1648
|
+
compare={compare}
|
|
1649
|
+
/>
|
|
1650
|
+
),
|
|
1651
|
+
)}
|
|
1652
|
+
</>
|
|
1653
|
+
) : (
|
|
1654
|
+
<ScreenHeader
|
|
1655
|
+
text={"No cuentas con este servicio"}
|
|
1656
|
+
headerType={"input-name-header"}
|
|
1657
|
+
/>
|
|
1658
|
+
))}
|
|
1659
|
+
{state.active_tab === "Imágenes" &&
|
|
1660
|
+
(state.product?.images_status !== "NS" ? (
|
|
1661
|
+
<>
|
|
1662
|
+
{!imageLayout && (
|
|
1663
|
+
<GalleryHeader
|
|
1664
|
+
checkAll={state.all_image_checked} // Determina si el checkbox "Seleccionar todo" está marcado
|
|
1665
|
+
setCheckAll={handleOnSetCheckAll} // Toggler de true o false para el checkbox "Seleccionar todo"
|
|
1666
|
+
setSelectedImages={handleOnSetSelectedImages}
|
|
1667
|
+
// shotThd={shotThd} // No se usa?
|
|
1668
|
+
/>
|
|
1669
|
+
)}
|
|
1670
|
+
<section
|
|
1671
|
+
className="container"
|
|
1672
|
+
style={{ position: "relative" }}
|
|
1673
|
+
>
|
|
1674
|
+
<div
|
|
1675
|
+
{...getRootProps({
|
|
1676
|
+
className: `dropzone ${
|
|
1677
|
+
isDragActive ? "drag-active" : ""
|
|
1678
|
+
}`,
|
|
1679
|
+
})}
|
|
1680
|
+
>
|
|
1681
|
+
<input {...getInputProps()} />
|
|
1682
|
+
{isDragActive && (
|
|
1683
|
+
<div className="drag-overlay">
|
|
1684
|
+
<p>Suelta las imágenes aquí</p>
|
|
1685
|
+
</div>
|
|
1686
|
+
)}
|
|
1687
|
+
<aside>{thumbs()}</aside>
|
|
1688
|
+
</div>
|
|
1689
|
+
{state.images_values?.values.length === 0 && (
|
|
1690
|
+
<div
|
|
1691
|
+
style={{
|
|
1692
|
+
position: "absolute",
|
|
1693
|
+
top: "50%",
|
|
1694
|
+
left: "50%",
|
|
1695
|
+
transform: "translate(-50%, -50%)",
|
|
1696
|
+
textAlign: "center",
|
|
1697
|
+
padding: "40px",
|
|
1698
|
+
width: "80%",
|
|
1699
|
+
maxWidth: "500px",
|
|
1700
|
+
fontFamily: "Arial, sans-serif",
|
|
1701
|
+
}}
|
|
1702
|
+
>
|
|
1703
|
+
<p
|
|
1704
|
+
style={{
|
|
1705
|
+
fontSize: "18px",
|
|
1706
|
+
color: "#666",
|
|
1707
|
+
marginBottom: "16px",
|
|
1708
|
+
}}
|
|
1709
|
+
>
|
|
1710
|
+
Este producto no tiene imágenes
|
|
1711
|
+
</p>
|
|
1712
|
+
{isAuditorAssigned() ||
|
|
1713
|
+
isUserAssignedToService() ? (
|
|
1714
|
+
<p
|
|
1715
|
+
style={{
|
|
1716
|
+
fontSize: "14px",
|
|
1717
|
+
color: "#999",
|
|
1718
|
+
marginBottom: "20px",
|
|
1719
|
+
}}
|
|
1720
|
+
>
|
|
1721
|
+
Arrastra las imágenes aquí o{" "}
|
|
1722
|
+
<span
|
|
1723
|
+
onClick={open}
|
|
1724
|
+
style={{
|
|
1725
|
+
color: "#007bff",
|
|
1726
|
+
cursor: "pointer",
|
|
1727
|
+
textDecoration: "underline",
|
|
1728
|
+
}}
|
|
1729
|
+
>
|
|
1730
|
+
haz clic para abrir el explorador de
|
|
1731
|
+
archivos
|
|
1732
|
+
</span>
|
|
1733
|
+
</p>
|
|
1734
|
+
) : null}
|
|
1735
|
+
</div>
|
|
1736
|
+
)}
|
|
1737
|
+
</section>
|
|
1738
|
+
</>
|
|
1739
|
+
) : (
|
|
1740
|
+
<ScreenHeader
|
|
1741
|
+
text={"No cuentas con este servicio"}
|
|
1742
|
+
headerType={"input-name-header"}
|
|
1743
|
+
/>
|
|
1744
|
+
))}
|
|
1745
|
+
</>
|
|
1746
|
+
)}
|
|
1747
|
+
</div>
|
|
1748
|
+
{(isUserAssignedToService(state.active_tab) ||
|
|
1749
|
+
isAuditorAssigned()) &&
|
|
1750
|
+
state.product[`${getConceptByTab(state.active_tab)}_status`] !==
|
|
1751
|
+
"NS" && (
|
|
1752
|
+
<div className="commentary-box">
|
|
1753
|
+
{!state.comment ? (
|
|
1754
|
+
<div className="commentary">
|
|
1755
|
+
<TagAndInput
|
|
1756
|
+
label={"Caja de Comentario"}
|
|
1757
|
+
inputType={"textarea"}
|
|
1758
|
+
inputCols={80}
|
|
1759
|
+
inputRows={4}
|
|
1760
|
+
inputId={"commentary-box"}
|
|
1761
|
+
index={0}
|
|
1762
|
+
/>
|
|
1763
|
+
<div className="buttons-box">
|
|
1764
|
+
<Button
|
|
1765
|
+
buttonType={"general-transparent-button"}
|
|
1766
|
+
label={"Enviar comentario"}
|
|
1767
|
+
onClick={handleOnSubmitComment}
|
|
1768
|
+
/>
|
|
1730
1769
|
</div>
|
|
1731
|
-
</
|
|
1770
|
+
</div>
|
|
1732
1771
|
) : (
|
|
1733
|
-
<
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
</>
|
|
1739
|
-
)}
|
|
1740
|
-
</div>
|
|
1741
|
-
{/* {(userAssigned(activeTab) || auditorAssigned()) &&
|
|
1742
|
-
product[`${getConcept(activeTab)}_status`] !== "NS" && (
|
|
1743
|
-
<div className="commentary-box">
|
|
1744
|
-
{[7, 8].includes(user.id_role) && (
|
|
1745
|
-
<Button
|
|
1746
|
-
buttonType={
|
|
1747
|
-
evaluationFinished(
|
|
1748
|
-
user.id_role,
|
|
1749
|
-
activeTab,
|
|
1750
|
-
statusArray
|
|
1751
|
-
) && requiredNull[activeTab] === 0
|
|
1752
|
-
? "general-green-button"
|
|
1753
|
-
: "general-button-disabled"
|
|
1754
|
-
}
|
|
1755
|
-
label={"Enviar evaluación"}
|
|
1756
|
-
onClick={() => sendToFacilitator()}
|
|
1757
|
-
/>
|
|
1758
|
-
)}
|
|
1759
|
-
</div>
|
|
1760
|
-
)} */}
|
|
1761
|
-
|
|
1762
|
-
{(userAssigned(activeTab) || auditorAssigned()) &&
|
|
1763
|
-
product[`${getConcept(activeTab)}_status`] !== "NS" && (
|
|
1764
|
-
<div className="commentary-box">
|
|
1765
|
-
{!comment ? (
|
|
1766
|
-
<div className="commentary">
|
|
1767
|
-
<TagAndInput
|
|
1768
|
-
label={"Caja de Comentario"}
|
|
1769
|
-
inputType={"textarea"}
|
|
1770
|
-
inputCols={80}
|
|
1771
|
-
inputRows={4}
|
|
1772
|
-
inputId={"commentary-box"}
|
|
1773
|
-
index={0}
|
|
1774
|
-
/>
|
|
1775
|
-
<div className="buttons-box">
|
|
1772
|
+
<div className="feedback-box">
|
|
1773
|
+
<Commentary
|
|
1774
|
+
comment={state.comment?.message}
|
|
1775
|
+
reviewed={crossComment}
|
|
1776
|
+
/>
|
|
1776
1777
|
<Button
|
|
1777
|
-
buttonType={"
|
|
1778
|
-
|
|
1779
|
-
|
|
1778
|
+
buttonType={"circular-button accept-button"}
|
|
1779
|
+
onClick={async () => {
|
|
1780
|
+
setCrossComment(true);
|
|
1781
|
+
commentRevised();
|
|
1782
|
+
}}
|
|
1780
1783
|
/>
|
|
1781
1784
|
</div>
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
<div className="
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
}}
|
|
1795
|
-
/>
|
|
1796
|
-
</div>
|
|
1797
|
-
)}
|
|
1798
|
-
{[7, 8].includes(user.id_role) && (
|
|
1799
|
-
<Button
|
|
1800
|
-
buttonType={
|
|
1801
|
-
evaluationFinished(
|
|
1802
|
-
user.id_role,
|
|
1803
|
-
activeTab,
|
|
1804
|
-
statusArray
|
|
1805
|
-
) && requiredNull[activeTab] === 0
|
|
1806
|
-
? "general-green-button"
|
|
1807
|
-
: "general-button-disabled"
|
|
1785
|
+
)}
|
|
1786
|
+
|
|
1787
|
+
<div className="action-buttons">
|
|
1788
|
+
{
|
|
1789
|
+
allowedAccountsToViewChangeStatus.includes(user?.email) && (
|
|
1790
|
+
<Button
|
|
1791
|
+
buttonType={"general-pink-button"}
|
|
1792
|
+
label={"Cambio de Estatus"}
|
|
1793
|
+
onClick={() => setOpenChangeStatusModal(true)}
|
|
1794
|
+
id="button-change-status"
|
|
1795
|
+
/>
|
|
1796
|
+
)
|
|
1808
1797
|
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1798
|
+
{[7, 8].includes(user.id_role) && (
|
|
1799
|
+
<Button
|
|
1800
|
+
buttonType={
|
|
1801
|
+
isEvaluationFinished(
|
|
1802
|
+
user.id_role,
|
|
1803
|
+
state.active_tab,
|
|
1804
|
+
statusArray,
|
|
1805
|
+
) &&
|
|
1806
|
+
state.missing_required_fields[state.active_tab] === 0
|
|
1807
|
+
? "general-green-button"
|
|
1808
|
+
: "general-button-disabled"
|
|
1809
|
+
}
|
|
1810
|
+
label={"Enviar evaluación"}
|
|
1811
|
+
onClick={handleOnSendEvaluationToFacilitator}
|
|
1812
|
+
/>
|
|
1813
|
+
)}
|
|
1814
|
+
</div>
|
|
1815
|
+
</div>
|
|
1816
|
+
)}
|
|
1817
|
+
</div>
|
|
1815
1818
|
</div>
|
|
1816
|
-
</
|
|
1817
|
-
{showModal && (
|
|
1818
|
-
<ProductImageModal
|
|
1819
|
-
images={images}
|
|
1820
|
-
setShowModal={setShowModal}
|
|
1821
|
-
sendToFacilitator={sendToFacilitator}
|
|
1822
|
-
approveRejectButtons={approveRejectButtons()}
|
|
1823
|
-
/>
|
|
1824
|
-
)}
|
|
1825
|
-
{message.length > 0 && (
|
|
1826
|
-
<GenericModal
|
|
1827
|
-
buttonType={componentsArray.length > 0 && "delete-product"}
|
|
1828
|
-
componentsArray={
|
|
1829
|
-
componentsArray.length > 0
|
|
1830
|
-
? componentsArray
|
|
1831
|
-
: [
|
|
1832
|
-
<img key="1" src={succes} alt="success icon" />,
|
|
1833
|
-
<ScreenHeader
|
|
1834
|
-
key="2"
|
|
1835
|
-
headerType={"retailer-name-header"}
|
|
1836
|
-
text={message}
|
|
1837
|
-
color={"white"}
|
|
1838
|
-
/>,
|
|
1839
|
-
]
|
|
1840
|
-
}
|
|
1841
|
-
onClick={() => setMessage("")}
|
|
1842
|
-
/>
|
|
1843
|
-
)}
|
|
1844
|
-
{showVersionSelector && (
|
|
1845
|
-
<VersionSelector
|
|
1846
|
-
modalId={"version-selector"}
|
|
1847
|
-
articleId={product.article.id_article}
|
|
1848
|
-
setVersion={setVersion}
|
|
1849
|
-
companyName={product.article.company_name}
|
|
1850
|
-
currentVersion={version}
|
|
1851
|
-
setShowVersionSelector={setShowVersionSelector}
|
|
1852
|
-
jwt={token}
|
|
1853
|
-
/>
|
|
1854
|
-
)}
|
|
1855
|
-
{showRejectModal && (
|
|
1856
|
-
<Modal
|
|
1857
|
-
title={`Agregar mensaje de rechazo para ${activeTab?.toLowerCase()}`}
|
|
1858
|
-
show={showRejectModal}
|
|
1859
|
-
customComponent={
|
|
1860
|
-
<TagAndInput
|
|
1861
|
-
inputType={"textarea"}
|
|
1862
|
-
inputId={"modal-message-box"}
|
|
1863
|
-
index={0}
|
|
1864
|
-
color={"white"}
|
|
1865
|
-
/>
|
|
1866
|
-
}
|
|
1867
|
-
buttons={[
|
|
1868
|
-
<ButtonV2
|
|
1869
|
-
key={"btn-Cancelar"}
|
|
1870
|
-
type={"white"}
|
|
1871
|
-
label={"Cancelar"}
|
|
1872
|
-
size={12}
|
|
1873
|
-
onClick={() => {
|
|
1874
|
-
setShowRejectModal(false);
|
|
1875
|
-
}}
|
|
1876
|
-
/>,
|
|
1877
|
-
<ButtonV2
|
|
1878
|
-
key={"btn-Aceptar"}
|
|
1879
|
-
type={"pink"}
|
|
1880
|
-
label={"Aceptar"}
|
|
1881
|
-
size={12}
|
|
1882
|
-
onClick={async (e) => {
|
|
1883
|
-
const elements = document.querySelectorAll(
|
|
1884
|
-
"#modal-message-box .ql-container .ql-editor > p"
|
|
1885
|
-
);
|
|
1886
|
-
|
|
1887
|
-
if (!elements || elements.length === 0) {
|
|
1888
|
-
console.error("Elemento no encontrado");
|
|
1889
|
-
return;
|
|
1890
|
-
}
|
|
1891
|
-
|
|
1892
|
-
let brCounter = 0;
|
|
1893
|
-
|
|
1894
|
-
elements.forEach((el) => {
|
|
1895
|
-
const body = el.innerHTML;
|
|
1896
|
-
|
|
1897
|
-
if (typeof body !== "string") {
|
|
1898
|
-
console.log("El contenido de body no es una cadena", body);
|
|
1899
|
-
isMessageEmpty = true;
|
|
1900
|
-
return;
|
|
1901
|
-
}
|
|
1902
|
-
|
|
1903
|
-
if (!body || body.replace(/<.*?\/?>/gm, "").trim() === "") {
|
|
1904
|
-
brCounter++;
|
|
1905
|
-
}
|
|
1906
|
-
});
|
|
1907
|
-
|
|
1908
|
-
if (brCounter === elements.length) {
|
|
1909
|
-
const container = document.querySelector(
|
|
1910
|
-
".container-customComponent"
|
|
1911
|
-
);
|
|
1912
|
-
|
|
1913
|
-
const existingAlert = container.querySelector(".alert-error");
|
|
1914
|
-
if (existingAlert) {
|
|
1915
|
-
return; // Si ya existe, no crear otra
|
|
1916
|
-
}
|
|
1819
|
+
</Container>
|
|
1917
1820
|
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
background-color: #ffebee;
|
|
1924
|
-
border: 1px solid #ef5350;
|
|
1925
|
-
border-radius: 4px;
|
|
1926
|
-
padding: 12px 16px;
|
|
1927
|
-
margin-top: 10px;
|
|
1928
|
-
font-size: 14px;
|
|
1929
|
-
display: flex;
|
|
1930
|
-
align-items: center;
|
|
1931
|
-
gap: 8px;
|
|
1932
|
-
font-family: 'Roboto', sans-serif;
|
|
1933
|
-
text-align: center;
|
|
1934
|
-
`;
|
|
1935
|
-
|
|
1936
|
-
alert.innerHTML = `
|
|
1937
|
-
<span>El mensaje no puede estar vacío.</span>
|
|
1938
|
-
`;
|
|
1939
|
-
|
|
1940
|
-
container.appendChild(alert);
|
|
1941
|
-
return;
|
|
1942
|
-
}
|
|
1943
|
-
|
|
1944
|
-
let fullMessage = "";
|
|
1945
|
-
|
|
1946
|
-
elements.forEach((element) => {
|
|
1947
|
-
const body = element.innerHTML;
|
|
1948
|
-
|
|
1949
|
-
fullMessage += body;
|
|
1950
|
-
});
|
|
1951
|
-
|
|
1952
|
-
fullMessage = fullMessage.replace(/<br\s*\/?>/gi, "\n");
|
|
1953
|
-
|
|
1954
|
-
await createComment(e, fullMessage, activeTab);
|
|
1955
|
-
valRejAll ? validateAll("R") : sendToFacilitator("R");
|
|
1956
|
-
setMessage("Rechazado");
|
|
1957
|
-
setShowRejectModal(false);
|
|
1958
|
-
}}
|
|
1959
|
-
/>,
|
|
1960
|
-
]}
|
|
1961
|
-
/>
|
|
1962
|
-
)}
|
|
1963
|
-
<Modal
|
|
1964
|
-
className="container-modalAlert"
|
|
1965
|
-
show={modalAlert.show}
|
|
1966
|
-
title={modalAlert.title}
|
|
1967
|
-
message={modalAlert.message}
|
|
1968
|
-
icon={"info"}
|
|
1969
|
-
onClickBtnDefault={(event) => {
|
|
1970
|
-
setModalAlert((prev) => ({
|
|
1971
|
-
...prev,
|
|
1972
|
-
show: false,
|
|
1973
|
-
errorInputMessage: false,
|
|
1974
|
-
}));
|
|
1821
|
+
<ChangeStatusModal
|
|
1822
|
+
state={state}
|
|
1823
|
+
open={openChangeStatusModal}
|
|
1824
|
+
onClose={() => {
|
|
1825
|
+
setOpenChangeStatusModal(false);
|
|
1975
1826
|
}}
|
|
1827
|
+
reloadData={loadData}
|
|
1828
|
+
token={token}
|
|
1976
1829
|
/>
|
|
1977
|
-
</
|
|
1830
|
+
</AiProductEditionProvider>
|
|
1831
|
+
);
|
|
1832
|
+
};
|
|
1833
|
+
|
|
1834
|
+
export const RetailerProductEdition = (props) => {
|
|
1835
|
+
return (
|
|
1836
|
+
<ProviderProductEditionProvider>
|
|
1837
|
+
<RetailerProductEditionView {...props} />
|
|
1838
|
+
</ProviderProductEditionProvider>
|
|
1978
1839
|
);
|
|
1979
1840
|
};
|