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