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.
Files changed (70) hide show
  1. package/dist/ai/utils/compare-strings.js +45 -0
  2. package/dist/components/atoms/GeneralButton/styles.js +1 -1
  3. package/dist/components/atoms/GeneralInput/index.js +249 -54
  4. package/dist/components/atoms/GeneralInput/styles.js +7 -3
  5. package/dist/components/atoms/InputFormatter/index.js +223 -68
  6. package/dist/components/atoms/InputFormatter/styles.js +20 -4
  7. package/dist/components/molecules/StatusAsignationInfo/index.js +11 -1
  8. package/dist/components/molecules/TabsMenu/index.js +13 -1
  9. package/dist/components/molecules/TagAndInput/index.js +364 -24
  10. package/dist/components/molecules/TagAndInput/styles.js +2 -2
  11. package/dist/components/organisms/ChangeStatusModal/index.js +531 -0
  12. package/dist/components/organisms/ChangeStatusModal/styles.js +85 -0
  13. package/dist/components/organisms/FullProductNameHeader/index.js +6 -22
  14. package/dist/components/organisms/InputGroup/index.js +22 -18
  15. package/dist/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +150 -337
  16. package/dist/components/pages/ProviderProductEdition/context/provider-product-edition.context.js +15 -15
  17. package/dist/components/pages/ProviderProductEdition/index.js +395 -361
  18. package/dist/components/pages/ProviderProductEdition/utils.js +1 -0
  19. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +125 -211
  20. package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.context.js +59 -260
  21. package/dist/components/pages/RetailerProductEdition/context/reducers/product.js +50 -38
  22. package/dist/components/pages/RetailerProductEdition/index.js +1741 -2239
  23. package/dist/components/pages/RetailerProductEdition/styles.js +4 -2
  24. package/dist/components/pages/RetailerProductEdition/utils.js +251 -2
  25. package/dist/contexts/AiProductEdition.js +244 -160
  26. package/dist/global-files/statusDictionary.js +103 -0
  27. package/package.json +4 -2
  28. package/src/ai/utils/compare-strings.js +45 -0
  29. package/src/assets/images/Icons/arrow.png +0 -0
  30. package/src/assets/images/Icons/cancel.png +0 -0
  31. package/src/assets/images/Icons/ia-icon.png +0 -0
  32. package/src/assets/images/Icons/loading.svg +5 -0
  33. package/src/assets/images/Icons/reload.png +0 -0
  34. package/src/components/atoms/GeneralButton/styles.js +4 -0
  35. package/src/components/atoms/GeneralInput/index.js +241 -60
  36. package/src/components/atoms/GeneralInput/styles.js +81 -0
  37. package/src/components/atoms/InputFormatter/index.js +200 -51
  38. package/src/components/atoms/InputFormatter/styles.js +284 -0
  39. package/src/components/atoms/RetailerSelector/RetailerSelector.stories.js +10 -0
  40. package/src/components/atoms/RetailerSelector/index.js +3 -0
  41. package/src/components/atoms/RetailerSelector/styles.js +0 -0
  42. package/src/components/molecules/StatusAsignationInfo/index.js +9 -1
  43. package/src/components/molecules/TabsMenu/index.js +12 -0
  44. package/src/components/molecules/TagAndInput/index.js +294 -21
  45. package/src/components/molecules/TagAndInput/styles.js +59 -17
  46. package/src/components/organisms/ChangeStatusModal/index.jsx +488 -0
  47. package/src/components/organisms/ChangeStatusModal/styles.js +333 -0
  48. package/src/components/organisms/FullProductNameHeader/index.js +4 -28
  49. package/src/components/organisms/FullTabsMenu/index.js +1 -1
  50. package/src/components/organisms/InputGroup/index.js +12 -4
  51. package/src/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +174 -202
  52. package/src/components/pages/ProviderProductEdition/context/provider-product-edition.context.jsx +14 -14
  53. package/src/components/pages/ProviderProductEdition/index.js +497 -437
  54. package/src/components/pages/ProviderProductEdition/utils.js +2 -2
  55. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +136 -243
  56. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +575 -0
  57. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +62 -0
  58. package/src/components/pages/RetailerProductEdition/context/reducers/active-state.js +344 -0
  59. package/src/components/pages/RetailerProductEdition/context/reducers/inputs.js +155 -0
  60. package/src/components/pages/RetailerProductEdition/context/reducers/product.js +114 -0
  61. package/src/components/pages/RetailerProductEdition/context/reducers/system.js +60 -0
  62. package/src/components/pages/RetailerProductEdition/index.js +1563 -1717
  63. package/src/components/pages/RetailerProductEdition/index_old.js +1979 -0
  64. package/src/components/pages/RetailerProductEdition/stories/Auditor.stories.js +101 -0
  65. package/src/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +115 -0
  66. package/src/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +174 -0
  67. package/src/components/pages/RetailerProductEdition/styles.js +67 -2
  68. package/src/components/pages/RetailerProductEdition/utils.js +240 -0
  69. package/src/contexts/AiProductEdition.jsx +347 -0
  70. package/src/global-files/statusDictionary.js +103 -0
@@ -42,6 +42,7 @@ import errorIcon from "../../../assets/images/genericModal/errorModal.svg";
42
42
  import warningIcon from "../../../assets/images/genericModal/genericModalWarning.svg";
43
43
 
44
44
  import { Container } from "./styles";
45
+ import { AiProductEditionProvider } from "../../../contexts/AiProductEdition";
45
46
 
46
47
  const ProviderProductEditionView = ({
47
48
  tabsSections,
@@ -142,48 +143,36 @@ const ProviderProductEditionView = ({
142
143
  useEffect(() => {
143
144
  const setProductData = () => {
144
145
  try {
145
- const product = JSON.parse(sessionStorage.getItem("productSelected"))
146
- ? JSON.parse(sessionStorage.getItem("productSelected"))
147
- : productSelected;
146
+ const product = productSelected
147
+ ? productSelected
148
+ : JSON.parse(sessionStorage.getItem("productSelected"));
148
149
 
149
150
  const productNormalized = normalizeProduct(product);
150
151
 
151
- console.log({ productNormalized });
152
-
153
152
  dispatch({
154
153
  type: "SET_PRODUCT",
155
154
  payload: productNormalized,
156
155
  });
156
+ dispatch({
157
+ type: "SET_ACTIVE_RETAILER",
158
+ payload: productNormalized.categoryRetailer[0],
159
+ });
157
160
 
158
- if (
159
- productNormalized.categoryRetailerInOrder.length > 0 &&
160
- productNormalized.statusByRetailer
161
- ) {
162
- dispatch({
163
- type: "SET_ACTIVE_RETAILER",
164
- payload: productNormalized.categoryRetailerInOrder[0],
165
- });
166
- const firstRetailerStatus =
167
- productNormalized.statusByRetailer[
168
- productNormalized.categoryRetailerInOrder[0].id_retailer
169
- ];
170
- const initialTab = firstRetailerStatus.description
171
- ? "Descripción"
172
- : firstRetailerStatus.datasheet
173
- ? "Ficha técnica"
174
- : firstRetailerStatus.images
175
- ? "Imágenes"
176
- : "Imágenes";
177
- dispatch({
178
- type: "SET_ACTIVE_TAB",
179
- payload: initialTab,
180
- });
181
- } else {
182
- dispatch({
183
- type: "SET_ACTIVE_RETAILER",
184
- payload: productNormalized.categoryRetailer[0],
185
- });
186
- }
161
+ const firstRetailerStatus =
162
+ productNormalized.statusByRetailer[
163
+ productNormalized.categoryRetailerInOrder[0].id_retailer
164
+ ];
165
+ const initialTab = firstRetailerStatus.description
166
+ ? "Descripción"
167
+ : firstRetailerStatus.datasheet
168
+ ? "Ficha técnica"
169
+ : firstRetailerStatus.images
170
+ ? "Imágenes"
171
+ : "Imágenes";
172
+ dispatch({
173
+ type: "SET_ACTIVE_TAB",
174
+ payload: initialTab,
175
+ });
187
176
  } catch (error) {
188
177
  console.log("Error setting product data: ", error);
189
178
  }
@@ -227,7 +216,7 @@ const ProviderProductEditionView = ({
227
216
  id_category,
228
217
  version,
229
218
  token,
230
- id_retailer,
219
+ id_retailer
231
220
  ),
232
221
  getPercentage({ data, headers }),
233
222
  getServicesData({
@@ -241,20 +230,43 @@ const ProviderProductEditionView = ({
241
230
  const percentages =
242
231
  JSON.parse(percentageRes?.[0]?.body)?.[0]?.relations ?? [];
243
232
 
244
- const orderMap =
245
- services[2].inputsByRetailer ??
246
- [].flat().reduce((acc, item) => {
233
+ const orderMap = services[2].inputsByRetailer
234
+ .flat()
235
+ .reduce((acc, item) => {
247
236
  acc[item.id_image] = item.order;
248
237
  return acc;
249
238
  }, {});
250
239
 
251
- const orderedValues = [...(services[2].values ?? [])].sort((a, b) => {
240
+ const orderedValues = [...services[2].values].sort((a, b) => {
252
241
  const orderA = orderMap[a.image_id] ?? Number.MAX_SAFE_INTEGER;
253
242
  const orderB = orderMap[b.image_id] ?? Number.MAX_SAFE_INTEGER;
254
243
 
255
244
  return orderA - orderB;
256
245
  });
257
246
 
247
+ //Cuando carguemos la información de los servicios, las actualizamos en el estado del producto
248
+
249
+ const updatedStatusByRetailer = servicesDataRes.reduce(
250
+ (acc, current, idx) => {
251
+ const { id_retailer, service, status } = current;
252
+
253
+ if (!acc[id_retailer]) acc[id_retailer] = {};
254
+
255
+ acc[id_retailer][service] = status;
256
+
257
+ return acc;
258
+ },
259
+ {},
260
+ );
261
+
262
+ dispatch({
263
+ type: "SET_PRODUCT",
264
+ payload: {
265
+ ...state.product,
266
+ statusByRetailer: updatedStatusByRetailer,
267
+ },
268
+ });
269
+
258
270
  dispatch({
259
271
  type: "SET_SERVICES",
260
272
  payload: {
@@ -274,7 +286,7 @@ const ProviderProductEditionView = ({
274
286
  dispatch({
275
287
  type: "SET_ACTIVE_PERCENTAGES",
276
288
  payload: percentages.find(
277
- ({ id_retailer: rId }) => rId === id_retailer,
289
+ ({ id_retailer: rId }) => rId === id_retailer
278
290
  ),
279
291
  });
280
292
  } catch (error) {
@@ -286,7 +298,16 @@ const ProviderProductEditionView = ({
286
298
  };
287
299
 
288
300
  fetchData();
289
- }, [state.product, state.active_retailer, token]);
301
+ }, [
302
+ state.product?.datasheet_status,
303
+ state.product?.description_status,
304
+ state.product?.images_status,
305
+ state.product?.status,
306
+ state.product?.percentages,
307
+ state.product?.version,
308
+ state.active_retailer,
309
+ token
310
+ ]);
290
311
 
291
312
  // Actualizador de campos del ui para que coincidan con el retailer activo
292
313
  useEffect(() => {
@@ -294,15 +315,14 @@ const ProviderProductEditionView = ({
294
315
  console.log("Actualizar inputs del retailer activo");
295
316
  const updateInputsActiveRetailer = () => {
296
317
  if (!state.services) return;
318
+
297
319
  if (state.services.datasheets) {
298
320
  const retailerDatasheets =
299
321
  state.services.datasheets[state.active_retailer.id_retailer];
300
-
301
322
  const datasheetsActiveRetailer = {
302
323
  ...retailerDatasheets,
303
324
  data: Object.values(retailerDatasheets.data),
304
325
  };
305
-
306
326
  dispatch({
307
327
  type: "SET_DATASHEETS_INPUTS",
308
328
  payload: [datasheetsActiveRetailer, state.services.datasheets.inputs],
@@ -349,7 +369,16 @@ const ProviderProductEditionView = ({
349
369
  if (!state.product?.statusByRetailer) return false;
350
370
 
351
371
  const currentService = getConceptByTab(state.active_tab);
352
- const currentStatus = state.product[`${currentService}_status`];
372
+ // const currentStatus = state.product[`${currentService}_status`];
373
+ const currentRetailer = state.active_retailer.id_retailer;
374
+
375
+ //Información del servicio de la cadena seleccionada
376
+ const { status: currentStatus } = state.services_data.find(
377
+ (service) =>
378
+ service.service === currentService &&
379
+ service.id_retailer === currentRetailer,
380
+ );
381
+
353
382
  const originTab = origin[state.active_tab];
354
383
  const isRetailerUser = user?.is_retailer === 1;
355
384
 
@@ -372,13 +401,17 @@ const ProviderProductEditionView = ({
372
401
  // No retailer
373
402
  const hasNoOrder = !state.product.id_order && !state.product.orderId;
374
403
 
375
- return (
376
- (originTab === "RequestWithoutContentoh" &&
377
- (["R", "CA"].includes(currentStatus) ||
378
- (currentStatus === "RCA" && hasNoOrder))) ||
379
- (["RequestWithContentoh", "Contentoh"].includes(originTab) &&
380
- currentStatus === "AA")
381
- );
404
+ const condition =
405
+ (
406
+ originTab === "RequestWithoutContentoh" && (
407
+ ["R", "CA"].includes(currentStatus) || (currentStatus === "RCA" && hasNoOrder)
408
+ )
409
+ ) ||
410
+ (
411
+ ["RequestWithContentoh", "Contentoh"].includes(originTab) && currentStatus === "AA"
412
+ )
413
+
414
+ return condition;
382
415
  };
383
416
 
384
417
  const canShowSaveButton = (version_status) => {
@@ -399,6 +432,7 @@ const ProviderProductEditionView = ({
399
432
 
400
433
  const currentService = getConceptByTab(state.active_tab);
401
434
  const currentRetailer = state.active_retailer.id_retailer;
435
+
402
436
  const currentStatus =
403
437
  statusByRetailer[currentRetailer][currentService] || "ERR";
404
438
  return currentStatus;
@@ -410,7 +444,7 @@ const ProviderProductEditionView = ({
410
444
  name: e?.name,
411
445
  required: e?.required,
412
446
  active: state.images_values?.values?.some(
413
- (value) => value?.image_id === e?.id,
447
+ (value) => value?.image_id === e?.id
414
448
  ),
415
449
  }));
416
450
  const imageType = state.images_values?.imageType?.map((e) => ({
@@ -421,7 +455,7 @@ const ProviderProductEditionView = ({
421
455
  (e) => ({
422
456
  value: e?.id,
423
457
  name: e?.name,
424
- }),
458
+ })
425
459
  );
426
460
 
427
461
  return state.images_values?.values?.map((image, index) => (
@@ -662,6 +696,7 @@ const ProviderProductEditionView = ({
662
696
  state.product[sectionStatusKey] || state.product?.version_status;
663
697
 
664
698
  let data = { articleId, orderId, concept, evalStatus };
699
+
665
700
  const retailerId = state.active_retailer?.id_retailer;
666
701
 
667
702
  try {
@@ -676,13 +711,15 @@ const ProviderProductEditionView = ({
676
711
  headers: {
677
712
  Authorization: token,
678
713
  },
679
- },
714
+ }
680
715
  );
681
716
 
682
717
  const newStatuses = JSON.parse(res.data.body);
683
718
  const serviceStatus =
684
719
  newStatuses.newServiceStatus[articleId][`${concept}Status`];
685
720
 
721
+ console.log({product: state.product, newStatuses, serviceStatus, servicesData: state.services_data});
722
+
686
723
  // Actualizar el producto con los nuevos estados
687
724
  const updatedProduct = {
688
725
  ...state.product,
@@ -690,12 +727,19 @@ const ProviderProductEditionView = ({
690
727
  ...state.product.statusByRetailer,
691
728
  [retailerId]: {
692
729
  ...state.product.statusByRetailer[retailerId],
693
- [concept]: serviceStatus,
730
+ [concept]: newStatuses?.newStatus ?? serviceStatus,
694
731
  },
695
732
  },
696
733
  };
697
734
 
698
- console.log({ updatedProduct });
735
+ const updatedServicesData = state.services_data?.map(service => ({
736
+ ...service,
737
+ status: service?.id_retailer === retailerId && service?.service === concept ? (newStatuses?.newStatus ?? serviceStatus) : service?.status
738
+ }));
739
+
740
+ dispatch({ type: "SET_SERVICES_DATA", payload: updatedServicesData });
741
+
742
+ // console.log({ updatedProduct });
699
743
 
700
744
  dispatch({ type: "SET_PRODUCT", payload: updatedProduct });
701
745
 
@@ -924,7 +968,7 @@ const ProviderProductEditionView = ({
924
968
  headers: {
925
969
  Authorization: token,
926
970
  },
927
- }),
971
+ })
928
972
  );
929
973
  });
930
974
 
@@ -969,7 +1013,7 @@ const ProviderProductEditionView = ({
969
1013
  ArticleId: updatedProduct.id_article,
970
1014
  idCategory: updatedProduct.id_category,
971
1015
  product: updatedProduct,
972
- }),
1016
+ })
973
1017
  );
974
1018
 
975
1019
  // Mostrar modal de éxito
@@ -1035,411 +1079,427 @@ const ProviderProductEditionView = ({
1035
1079
  if (state.loading || !state.services || !state.product) return <Loading />;
1036
1080
 
1037
1081
  return (
1038
- <Container headerTop={headerTop}>
1039
- {/* <button onClick={() => console.log(state)}>log</button> */}
1040
- {showVersionSelector && (
1041
- <VersionSelector
1042
- modalId={"version-selector"}
1043
- articleId={state.product.id_article}
1044
- setVersion={handleOnChangeProductVersion}
1045
- companyName={company.company_name}
1046
- currentVersion={state.product.version}
1047
- setShowVersionSelector={setShowVersionSelector}
1048
- jwt={token}
1049
- />
1050
- )}
1051
- {showModal && (
1052
- <ProductImageModal
1053
- images={state.images_values}
1054
- setShowModal={setShowModal}
1055
- approveRejectButtons={canShowValidationButtons()}
1056
- sendToFacilitator={handleOnSendEvaluation}
1057
- />
1058
- )}
1059
- {state.modal.show && (
1060
- <GenericModal
1061
- componentsArray={[
1062
- state.modal.image && (
1063
- <img key="1" src={state.modal.image} alt="modal icon" />
1064
- ),
1065
- state.modal.title && (
1066
- <ScreenHeader
1067
- key="2"
1068
- headerType={"retailer-name-header"}
1069
- text={state.modal.title}
1070
- color={"white"}
1071
- />
1072
- ),
1073
- state.modal.message && (
1074
- <ScreenHeader
1075
- key="3"
1076
- headerType={"retailer-name-header"}
1077
- text={state.modal.message}
1082
+ <AiProductEditionProvider
1083
+ isCreatorsEdition={false}
1084
+ state={state}
1085
+ >
1086
+ <Container headerTop={headerTop}>
1087
+ {showVersionSelector && (
1088
+ <VersionSelector
1089
+ modalId={"version-selector"}
1090
+ articleId={state.product.id_article}
1091
+ setVersion={handleOnChangeProductVersion}
1092
+ companyName={company.company_name}
1093
+ currentVersion={state.product.version}
1094
+ setShowVersionSelector={setShowVersionSelector}
1095
+ jwt={token}
1096
+ />
1097
+ )}
1098
+ {showModal && (
1099
+ <ProductImageModal
1100
+ images={state.images_values}
1101
+ setShowModal={setShowModal}
1102
+ approveRejectButtons={canShowValidationButtons()}
1103
+ sendToFacilitator={handleOnSendEvaluation}
1104
+ />
1105
+ )}
1106
+ {state.modal.show && (
1107
+ <GenericModal
1108
+ componentsArray={[
1109
+ state.modal.image && (
1110
+ <img key="1" src={state.modal.image} alt="modal icon" />
1111
+ ),
1112
+ state.modal.title && (
1113
+ <ScreenHeader
1114
+ key="2"
1115
+ headerType={"retailer-name-header"}
1116
+ text={state.modal.title}
1117
+ color={"white"}
1118
+ />
1119
+ ),
1120
+ state.modal.message && (
1121
+ <ScreenHeader
1122
+ key="3"
1123
+ headerType={"retailer-name-header"}
1124
+ text={state.modal.message}
1125
+ color={"white"}
1126
+ />
1127
+ ),
1128
+ state.modal.buttons && (
1129
+ <div key="4" style={{ marginTop: "16px" }}>
1130
+ {state.modal.buttons.map((button, index) => (
1131
+ <Button
1132
+ key={index}
1133
+ buttonType={button.buttonType}
1134
+ label={button.text}
1135
+ onClick={button.action}
1136
+ />
1137
+ ))}
1138
+ </div>
1139
+ ),
1140
+ ].filter(Boolean)}
1141
+ onClick={() =>
1142
+ dispatch({
1143
+ type: "SET_MODAL",
1144
+ payload: { show: false, title: "", message: "", image: null },
1145
+ })
1146
+ }
1147
+ />
1148
+ )}
1149
+ {showRejectModal && (
1150
+ <Modal
1151
+ title={
1152
+ rejectAll
1153
+ ? "Agregar mensaje para rechazar todo"
1154
+ : "Agregar mensaje de rechazo"
1155
+ }
1156
+ show={showRejectModal}
1157
+ customComponent={
1158
+ <TagAndInput
1159
+ inputType={"textarea"}
1160
+ inputId={"modal-message-box"}
1161
+ index={0}
1078
1162
  color={"white"}
1079
1163
  />
1080
- ),
1081
- state.modal.buttons && (
1082
- <div key="4" style={{ marginTop: "16px" }}>
1083
- {state.modal.buttons.map((button, index) => (
1084
- <Button
1085
- key={index}
1086
- buttonType={button.buttonType}
1087
- label={button.text}
1088
- onClick={button.action}
1089
- />
1090
- ))}
1091
- </div>
1092
- ),
1093
- ].filter(Boolean)}
1094
- onClick={() =>
1095
- dispatch({
1096
- type: "SET_MODAL",
1097
- payload: { show: false, title: "", message: "", image: null },
1098
- })
1099
- }
1100
- />
1101
- )}
1102
- {showRejectModal && (
1103
- <Modal
1104
- title={
1105
- rejectAll
1106
- ? "Agregar mensaje para rechazar todo"
1107
- : "Agregar mensaje de rechazo"
1108
- }
1109
- show={showRejectModal}
1110
- customComponent={
1111
- <TagAndInput
1112
- inputType={"textarea"}
1113
- inputId={"modal-message-box"}
1114
- index={0}
1115
- color={"white"}
1116
- />
1117
- }
1118
- buttons={[
1119
- <ButtonV2
1120
- key={"btn-Cancelar"}
1121
- type={"white"}
1122
- label={"Cancelar"}
1123
- size={12}
1124
- onClick={() => {
1125
- setShowRejectModal(false);
1126
- }}
1127
- />,
1128
- <ButtonV2
1129
- key={"btn-Aceptar"}
1130
- type={"pink"}
1131
- label={"Aceptar"}
1132
- size={12}
1133
- onClick={async () => {
1134
- const elements = document.querySelectorAll(
1135
- "#modal-message-box .ql-container .ql-editor > p",
1136
- );
1137
-
1138
- if (!elements || elements.length === 0) {
1139
- console.error("Elemento no encontrado");
1140
- return;
1141
- }
1164
+ }
1165
+ buttons={[
1166
+ <ButtonV2
1167
+ key={"btn-Cancelar"}
1168
+ type={"white"}
1169
+ label={"Cancelar"}
1170
+ size={12}
1171
+ onClick={() => {
1172
+ setShowRejectModal(false);
1173
+ }}
1174
+ />,
1175
+ <ButtonV2
1176
+ key={"btn-Aceptar"}
1177
+ type={"pink"}
1178
+ label={"Aceptar"}
1179
+ size={12}
1180
+ onClick={async () => {
1181
+ const elements = document.querySelectorAll(
1182
+ "#modal-message-box .ql-container .ql-editor > p",
1183
+ );
1142
1184
 
1143
- const isMessageEmpty = Array.from(elements).every((el) => {
1144
- const body = el.innerHTML;
1145
- return !body || body.replace(/<.*?\/?>/gm, "").trim() === "";
1146
- });
1185
+ if (!elements || elements.length === 0) {
1186
+ console.error("Elemento no encontrado");
1187
+ return;
1188
+ }
1147
1189
 
1148
- if (isMessageEmpty) {
1149
- const container = document.querySelector(
1150
- ".container-customComponent",
1151
- );
1152
- const existingAlert = container.querySelector(".alert-error");
1153
-
1154
- if (!existingAlert) {
1155
- const alert = document.createElement("div");
1156
- alert.className = "alert-error";
1157
- alert.style.cssText = `
1158
- color: #d32f2f;
1159
- background-color: #ffebee;
1160
- border: 1px solid #ef5350;
1161
- border-radius: 4px;
1162
- padding: 12px 16px;
1163
- margin-top: 10px;
1164
- font-size: 14px;
1165
- display: flex;
1166
- align-items: center;
1167
- gap: 8px;
1168
- font-family: 'Roboto', sans-serif;
1169
- text-align: center;
1170
- `;
1171
- alert.innerHTML = `<span>El mensaje no puede estar vacío.</span>`;
1172
- container.appendChild(alert);
1190
+ const isMessageEmpty = Array.from(elements).every((el) => {
1191
+ const body = el.innerHTML;
1192
+ return (
1193
+ !body || body.replace(/<.*?\/?>/gm, "").trim() === ""
1194
+ );
1195
+ });
1196
+
1197
+ if (isMessageEmpty) {
1198
+ const container = document.querySelector(
1199
+ ".container-customComponent",
1200
+ );
1201
+ const existingAlert =
1202
+ container.querySelector(".alert-error");
1203
+
1204
+ if (!existingAlert) {
1205
+ const alert = document.createElement("div");
1206
+ alert.className = "alert-error";
1207
+ alert.style.cssText = `
1208
+ color: #d32f2f;
1209
+ background-color: #ffebee;
1210
+ border: 1px solid #ef5350;
1211
+ border-radius: 4px;
1212
+ padding: 12px 16px;
1213
+ margin-top: 10px;
1214
+ font-size: 14px;
1215
+ display: flex;
1216
+ align-items: center;
1217
+ gap: 8px;
1218
+ font-family: 'Roboto', sans-serif;
1219
+ text-align: center;
1220
+ `;
1221
+ alert.innerHTML = `<span>El mensaje no puede estar vacío.</span>`;
1222
+ container.appendChild(alert);
1223
+ }
1224
+ return;
1173
1225
  }
1174
- return;
1175
- }
1176
1226
 
1177
- const fullMessage = Array.from(elements)
1178
- .map((element) => element.innerHTML)
1179
- .join("")
1180
- .replace(/<br\s*\/?>/gi, "\n");
1227
+ const fullMessage = Array.from(elements)
1228
+ .map((element) => element.innerHTML)
1229
+ .join("")
1230
+ .replace(/<br\s*\/?>/gi, "\n");
1181
1231
 
1182
- await createComment(fullMessage);
1232
+ await createComment(fullMessage, token);
1183
1233
 
1184
- rejectAll
1185
- ? handleOnEvaluateAll("R")
1186
- : handleOnSendEvaluation("R");
1187
- setShowRejectModal(false);
1188
- }}
1189
- />,
1190
- ]}
1191
- />
1192
- )}
1193
- <HeaderTop
1194
- setHeaderTop={setHeaderTop}
1195
- withChat={location?.state?.withChat}
1196
- chatType={location?.state?.chatType}
1197
- productSelected={state.product}
1198
- token={token}
1199
- activeRetailer={{
1200
- id: state.active_retailer?.id_retailer,
1201
- name: state.active_retailer?.retailer,
1202
- }}
1203
- />
1204
- <div className="data-container">
1205
- <div className="image-data-panel">
1206
- <ImagePreviewer
1207
- activeImage={state.images_values.values[state.current_image] ?? {}}
1208
- imagesArray={state.images_values || []}
1209
- setActiveImage={handleOnChangeCurrentImage}
1210
- setShowModal={handleOnShowModalGalery}
1234
+ rejectAll
1235
+ ? handleOnEvaluateAll("R")
1236
+ : handleOnSendEvaluation("R");
1237
+ setShowRejectModal(false);
1238
+ }}
1239
+ />,
1240
+ ]}
1211
1241
  />
1212
- <ImageDataTable
1213
- lists={state.images_values || []}
1214
- activeImage={
1215
- state.images_values?.values
1216
- ? state.images_values?.values[state.current_image]
1217
- : {}
1218
- }
1219
- assignationsImages={assig}
1220
- retailerSelected={state.active_retailer?.id_retailer}
1221
- imagesStatus={state.product?.images_status || "-"}
1222
- isRetailer={isRetailer}
1223
- setShowVersionSelector={setShowVersionSelector}
1224
- version={state.product.version}
1225
- setImages={handleOnChangeCurrentImage}
1226
- onClickSave={handleOnClickSaveImages}
1227
- setAssignation={handleOnChangeAssignations} // No se usa?
1228
- />
1229
- </div>
1230
- <div className="product-information">
1231
- <div className="product-information">
1232
- <FullProductNameHeader
1233
- headerData={state.product}
1234
- percent={state.active_percentage.percentagesGeneral.required}
1235
- activeRetailer={{
1236
- id: state.active_retailer?.id_retailer,
1237
- name: state.active_retailer?.retailer,
1238
- image: state.active_retailer?.image,
1239
- }}
1240
- showValidationButtons={canShowValidationButtons()}
1241
- showApproveRejectAll={canShowValidationButtons()}
1242
- servicesData={state.services_data ? state.services_data : null}
1243
- approveAll={handleOnApproveAll}
1244
- rejectAll={handleOnRejectAll}
1245
- approve={() => handleOnSendEvaluation("A")}
1246
- reject={handleOnReject}
1247
- setActiveRetailer={handleOnChangeActiveRetailer}
1242
+ )}
1243
+ <HeaderTop
1244
+ setHeaderTop={setHeaderTop}
1245
+ withChat={location?.state?.withChat}
1246
+ chatType={location?.state?.chatType}
1247
+ productSelected={state.product}
1248
+ token={token}
1249
+ activeRetailer={{
1250
+ id: state.active_retailer?.id_retailer,
1251
+ name: state.active_retailer?.retailer,
1252
+ }}
1253
+ />
1254
+ <div className="data-container">
1255
+ <div className="image-data-panel">
1256
+ <ImagePreviewer
1257
+ activeImage={
1258
+ state.images_values.values[state.current_image] ?? {}
1259
+ }
1260
+ imagesArray={state.images_values || []}
1261
+ setActiveImage={handleOnChangeCurrentImage}
1262
+ setShowModal={handleOnShowModalGalery}
1248
1263
  />
1249
- <FullTabsMenu
1250
- tabsSections={tabsSections}
1251
- status={getStatusByCurrentServiceAndRetailer()}
1252
- activeTab={state.active_tab}
1253
- user={user}
1264
+ <ImageDataTable
1265
+ lists={state.images_values || []}
1266
+ activeImage={
1267
+ state.images_values?.values
1268
+ ? state.images_values?.values[state.current_image]
1269
+ : {}
1270
+ }
1271
+ assignationsImages={assig}
1272
+ retailerSelected={state.active_retailer?.id_retailer}
1273
+ imagesStatus={state.product?.images_status || "-"}
1254
1274
  isRetailer={isRetailer}
1255
- assig={assig}
1256
- version={state.product.version}
1257
- updatedDescriptions={state.updated_descriptions_inputs}
1258
- updatedDatasheets={state.updated_datasheets_inputs}
1259
- updatedImages={state.updated_images_values}
1260
- images={state.services.images}
1261
- // actions
1262
- downloadImages={handleOnDownloadImages}
1263
- askToDeleteImages={handleOnAskToDeleteImages}
1264
- showSaveButton={canShowSaveButton(state.product.version_status)}
1265
- onClickSave={handleOnClickSave}
1266
- // setters
1267
- setActiveTab={handleOnChangeActiveTab}
1268
- setImageLayout={handleOnSetImageLayout}
1269
- setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1270
- setUpdatedDatasheets={handleOnSetUpdatedDatasheets}
1271
- setAssignation={handleOnSetAssignation} // No se usa?
1272
- setImages={handleOnSetImages} // No se usa?
1273
- // setSelectedImages={handleOnSetSelectedImages} // Se pasa hasta TabsMenu, pero no se usa
1274
1275
  setShowVersionSelector={setShowVersionSelector}
1276
+ version={state.product.version}
1277
+ setImages={handleOnChangeCurrentImage}
1278
+ onClickSave={handleOnClickSaveImages}
1279
+ setAssignation={handleOnChangeAssignations} // No se usa?
1275
1280
  />
1276
- <div
1277
- className={
1278
- "services-information-container " +
1279
- (imageLayout && state.active_tab === "Imágenes"
1280
- ? "image-services"
1281
- : "")
1282
- }
1283
- >
1284
- {state.saving ? (
1285
- <Loading />
1286
- ) : (
1287
- <>
1288
- {state.active_tab === "Descripción" &&
1289
- (state.product?.description_status !== "NS" ? (
1290
- <InputGroup
1291
- activeSection={state.active_tab}
1292
- inputGroup={state.descriptions_inputs[0]}
1293
- updatedDescriptions={state.updated_descriptions_inputs}
1294
- articleId={state.product?.id_article}
1295
- version={state.product.version}
1296
- isShowbox={false}
1297
- dinamicHeight={true}
1298
- setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1299
- updateApprovedInputs={handleOnUpdateApprovedInputs} // No se usa?
1300
- />
1301
- ) : (
1302
- <ScreenHeader
1303
- text={"No cuentas con este servicio"}
1304
- headerType={"input-name-header"}
1305
- />
1306
- ))}
1307
-
1308
- {state.active_tab === "Ficha técnica" &&
1309
- (state.product?.datasheet_status !== "NS" ? (
1310
- <>
1311
- {state.datasheets_inputs[0].data?.map(
1312
- (dataGroup, index) => (
1313
- <InputGroup
1314
- index={index}
1315
- key={index + "-" + state.active_retailer.retailer}
1316
- articleId={state.product.id_article}
1317
- version={state.version}
1318
- activeSection={state.active_tab}
1319
- inputGroup={dataGroup}
1320
- dataInputs={state.datasheets_inputs[1] ?? []}
1321
- activeRetailer={
1322
- state.services.datasheets[
1323
- state.active_retailer.id_retailer
1324
- ]
1325
- }
1326
- groupData={
1327
- state.services.datasheets[
1328
- state.active_retailer.id_retailer
1329
- ].data
1330
- }
1331
- updatedDatasheets={
1332
- state.updated_datasheets_inputs
1333
- }
1334
- setUpdatedDatasheets={
1335
- handleOnSetUpdatedDatasheets
1336
- }
1337
- isShowbox={true}
1338
- setUpdatedBoxData={(e) => {
1339
- setBoxData(e);
1340
- }}
1341
- updateApprovedInputs={
1342
- handleOnUpdateApprovedInputs // No se usa?
1343
- }
1281
+ </div>
1282
+ <div className="product-information">
1283
+ <div className="product-information">
1284
+ <FullProductNameHeader
1285
+ headerData={state.product}
1286
+ percent={state.active_percentage.percentagesGeneral.required}
1287
+ activeRetailer={{
1288
+ id: state.active_retailer?.id_retailer,
1289
+ name: state.active_retailer?.retailer,
1290
+ image: state.active_retailer?.image,
1291
+ }}
1292
+ showValidationButtons={canShowValidationButtons()}
1293
+ showApproveRejectAll={canShowValidationButtons()}
1294
+ servicesData={state.services_data ? state.services_data : null}
1295
+ approveAll={handleOnApproveAll}
1296
+ rejectAll={handleOnRejectAll}
1297
+ approve={() => handleOnSendEvaluation("A")}
1298
+ reject={handleOnReject}
1299
+ setActiveRetailer={handleOnChangeActiveRetailer}
1300
+ />
1301
+ <FullTabsMenu
1302
+ tabsSections={tabsSections}
1303
+ status={getStatusByCurrentServiceAndRetailer()}
1304
+ activeTab={state.active_tab}
1305
+ user={user}
1306
+ isRetailer={isRetailer}
1307
+ assig={assig}
1308
+ version={state.product.version}
1309
+ updatedDescriptions={state.updated_descriptions_inputs}
1310
+ updatedDatasheets={state.updated_datasheets_inputs}
1311
+ updatedImages={state.updated_images_values}
1312
+ images={state.services.images}
1313
+ // actions
1314
+ downloadImages={handleOnDownloadImages}
1315
+ askToDeleteImages={handleOnAskToDeleteImages}
1316
+ showSaveButton={canShowSaveButton(state.product.version_status)}
1317
+ onClickSave={handleOnClickSave}
1318
+ // setters
1319
+ setActiveTab={handleOnChangeActiveTab}
1320
+ setImageLayout={handleOnSetImageLayout}
1321
+ setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1322
+ setUpdatedDatasheets={handleOnSetUpdatedDatasheets}
1323
+ setAssignation={handleOnSetAssignation} // No se usa?
1324
+ setImages={handleOnSetImages} // No se usa?
1325
+ // setSelectedImages={handleOnSetSelectedImages} // Se pasa hasta TabsMenu, pero no se usa
1326
+ setShowVersionSelector={setShowVersionSelector}
1327
+ />
1328
+ <div
1329
+ className={
1330
+ "services-information-container " +
1331
+ (imageLayout && state.active_tab === "Imágenes"
1332
+ ? "image-services"
1333
+ : "")
1334
+ }
1335
+ >
1336
+ {state.saving ? (
1337
+ <Loading />
1338
+ ) : (
1339
+ <>
1340
+ {state.active_tab === "Descripción" &&
1341
+ (state.product?.description_status !== "NS" ? (
1342
+ <InputGroup
1343
+ activeSection={state.active_tab}
1344
+ inputGroup={state.descriptions_inputs[0]}
1345
+ updatedDescriptions={
1346
+ state.updated_descriptions_inputs
1347
+ }
1348
+ articleId={state.product?.id_article}
1349
+ version={state.product.version}
1350
+ isShowbox={false}
1351
+ dinamicHeight={true}
1352
+ setUpdatedDescriptions={
1353
+ handleOnSetUpdatedDescriptions
1354
+ }
1355
+ updateApprovedInputs={handleOnUpdateApprovedInputs} // No se usa?
1356
+ />
1357
+ ) : (
1358
+ <ScreenHeader
1359
+ text={"No cuentas con este servicio"}
1360
+ headerType={"input-name-header"}
1361
+ />
1362
+ ))}
1363
+
1364
+ {state.active_tab === "Ficha técnica" &&
1365
+ (state.product?.datasheet_status !== "NS" ? (
1366
+ <>
1367
+ {state.datasheets_inputs[0]?.data?.map(
1368
+ (dataGroup, index) => (
1369
+ <InputGroup
1370
+ index={index}
1371
+ key={
1372
+ index + "-" + state.active_retailer.retailer
1373
+ }
1374
+ articleId={state.product.id_article}
1375
+ version={state.version}
1376
+ activeSection={state.active_tab}
1377
+ inputGroup={dataGroup}
1378
+ dataInputs={state.datasheets_inputs[1] ?? []}
1379
+ activeRetailer={
1380
+ state.services.datasheets[
1381
+ state.active_retailer.id_retailer
1382
+ ]
1383
+ }
1384
+ groupData={
1385
+ state.services.datasheets[
1386
+ state.active_retailer.id_retailer
1387
+ ].data
1388
+ }
1389
+ updatedDatasheets={
1390
+ state.updated_datasheets_inputs
1391
+ }
1392
+ setUpdatedDatasheets={
1393
+ handleOnSetUpdatedDatasheets
1394
+ }
1395
+ isShowbox={true}
1396
+ setUpdatedBoxData={(e) => {
1397
+ setBoxData(e);
1398
+ }}
1399
+ updateApprovedInputs={
1400
+ handleOnUpdateApprovedInputs // No se usa?
1401
+ }
1402
+ />
1403
+ ),
1404
+ )}
1405
+ </>
1406
+ ) : (
1407
+ <ScreenHeader
1408
+ text={"No cuentas con este servicio"}
1409
+ headerType={"input-name-header"}
1410
+ />
1411
+ ))}
1412
+
1413
+ {state.active_tab === "Imágenes" &&
1414
+ (state.product?.images_status !== "NS" ? (
1415
+ <>
1416
+ {!imageLayout && (
1417
+ <GalleryHeader
1418
+ checkAll={state.all_image_checked} // Determina si el checkbox "Seleccionar todo" está marcado
1419
+ setCheckAll={handleOnSetCheckAll} // Toggler de true o false para el checkbox "Seleccionar todo"
1420
+ setSelectedImages={handleOnSetSelectedImages}
1344
1421
  />
1345
- ),
1346
- )}
1347
- </>
1348
- ) : (
1349
- <ScreenHeader
1350
- text={"No cuentas con este servicio"}
1351
- headerType={"input-name-header"}
1352
- />
1353
- ))}
1354
-
1355
- {state.active_tab === "Imágenes" &&
1356
- (state.product?.images_status !== "NS" ? (
1357
- <>
1358
- {!imageLayout && (
1359
- <GalleryHeader
1360
- checkAll={state.all_image_checked} // Determina si el checkbox "Seleccionar todo" está marcado
1361
- setCheckAll={handleOnSetCheckAll} // Toggler de true o false para el checkbox "Seleccionar todo"
1362
- setSelectedImages={handleOnSetSelectedImages}
1363
- />
1364
- )}
1365
- <section
1366
- className="container"
1367
- style={{ position: "relative" }}
1368
- >
1369
- <div
1370
- {...getRootProps({
1371
- className: `dropzone ${
1372
- isDragActive ? "drag-active" : ""
1373
- }`,
1374
- })}
1422
+ )}
1423
+ <section
1424
+ className="container"
1425
+ style={{ position: "relative" }}
1375
1426
  >
1376
- <input {...getInputProps()} />
1377
- {isDragActive && (
1378
- <div className="drag-overlay">
1379
- <p>Suelta las imágenes aquí</p>
1380
- </div>
1381
- )}
1382
- <aside>{thumbs()}</aside>
1383
- </div>
1384
- {state.images_values?.values.length === 0 && (
1385
1427
  <div
1386
- style={{
1387
- position: "absolute",
1388
- top: "50%",
1389
- left: "50%",
1390
- transform: "translate(-50%, -50%)",
1391
- textAlign: "center",
1392
- padding: "40px",
1393
- width: "80%",
1394
- maxWidth: "500px",
1395
- fontFamily: "Arial, sans-serif",
1396
- }}
1428
+ {...getRootProps({
1429
+ className: `dropzone ${
1430
+ isDragActive ? "drag-active" : ""
1431
+ }`,
1432
+ })}
1397
1433
  >
1398
- <p
1399
- style={{
1400
- fontSize: "18px",
1401
- color: "#666",
1402
- marginBottom: "16px",
1403
- }}
1404
- >
1405
- Este producto no tiene imágenes
1406
- </p>
1407
- <p
1434
+ <input {...getInputProps()} />
1435
+ {isDragActive && (
1436
+ <div className="drag-overlay">
1437
+ <p>Suelta las imágenes aquí</p>
1438
+ </div>
1439
+ )}
1440
+ <aside>{thumbs()}</aside>
1441
+ </div>
1442
+ {state.images_values?.values.length === 0 && (
1443
+ <div
1408
1444
  style={{
1409
- fontSize: "14px",
1410
- color: "#999",
1411
- marginBottom: "20px",
1445
+ position: "absolute",
1446
+ top: "50%",
1447
+ left: "50%",
1448
+ transform: "translate(-50%, -50%)",
1449
+ textAlign: "center",
1450
+ padding: "40px",
1451
+ width: "80%",
1452
+ maxWidth: "500px",
1453
+ fontFamily: "Arial, sans-serif",
1412
1454
  }}
1413
1455
  >
1414
- Arrastra las imágenes aquí o{" "}
1415
- <span
1416
- onClick={open}
1456
+ <p
1417
1457
  style={{
1418
- color: "#007bff",
1419
- cursor: "pointer",
1420
- textDecoration: "underline",
1458
+ fontSize: "18px",
1459
+ color: "#666",
1460
+ marginBottom: "16px",
1421
1461
  }}
1422
1462
  >
1423
- haz clic para abrir el explorador de archivos
1424
- </span>
1425
- </p>
1426
- </div>
1427
- )}
1428
- </section>
1429
- </>
1430
- ) : (
1431
- <ScreenHeader
1432
- text={"No cuentas con este servicio"}
1433
- headerType={"input-name-header"}
1434
- />
1435
- ))}
1436
- </>
1437
- )}
1463
+ Este producto no tiene imágenes
1464
+ </p>
1465
+ <p
1466
+ style={{
1467
+ fontSize: "14px",
1468
+ color: "#999",
1469
+ marginBottom: "20px",
1470
+ }}
1471
+ >
1472
+ Arrastra las imágenes aquí o{" "}
1473
+ <span
1474
+ onClick={open}
1475
+ style={{
1476
+ color: "#007bff",
1477
+ cursor: "pointer",
1478
+ textDecoration: "underline",
1479
+ }}
1480
+ >
1481
+ haz clic para abrir el explorador de
1482
+ archivos
1483
+ </span>
1484
+ </p>
1485
+ </div>
1486
+ )}
1487
+ </section>
1488
+ </>
1489
+ ) : (
1490
+ <ScreenHeader
1491
+ text={"No cuentas con este servicio"}
1492
+ headerType={"input-name-header"}
1493
+ />
1494
+ ))}
1495
+ </>
1496
+ )}
1497
+ </div>
1438
1498
  </div>
1439
1499
  </div>
1440
1500
  </div>
1441
- </div>
1442
- </Container>
1501
+ </Container>
1502
+ </AiProductEditionProvider>
1443
1503
  );
1444
1504
  };
1445
1505