contentoh-components-library 21.6.49 → 21.6.50

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 (90) hide show
  1. package/.claude/launch.json +14 -0
  2. package/.env.test +1 -0
  3. package/dist/ai/prompts/attribute.prompt.js +28 -0
  4. package/dist/ai/prompts/description.prompt.js +33 -0
  5. package/dist/ai/schemas/attribute.schema.js +35 -0
  6. package/dist/ai/schemas/description.schema.js +27 -0
  7. package/dist/components/atoms/AssetPreview/AssetPreview.stories.js +118 -0
  8. package/dist/components/atoms/AssetPreview/index.js +150 -0
  9. package/dist/components/atoms/AssetPreview/styles.js +28 -0
  10. package/dist/components/atoms/IconFile/index.js +85 -2
  11. package/dist/components/atoms/IconFile/styles.js +1 -1
  12. package/dist/components/atoms/ProductImage/ProductImage.stories.js +70 -2
  13. package/dist/components/atoms/ProductImage/index.js +100 -27
  14. package/dist/components/atoms/ProductImage/styles.js +3 -1
  15. package/dist/components/molecules/EditionActiveImage/index.js +4 -2
  16. package/dist/components/molecules/GalleryAssetElement/GalleryAssetElement.stories.js +147 -0
  17. package/dist/components/molecules/GalleryAssetElement/index.js +178 -0
  18. package/dist/components/molecules/GalleryAssetElement/styles.js +26 -0
  19. package/dist/components/molecules/GalleryElement/index.js +13 -4
  20. package/dist/components/molecules/GalleryHeader/index.js +96 -24
  21. package/dist/components/molecules/GalleryHeader/styles.js +4 -1
  22. package/dist/components/molecules/GalleryTrayTabs/GalleryTrayTabs.stories.js +56 -0
  23. package/dist/components/molecules/GalleryTrayTabs/index.js +60 -0
  24. package/dist/components/molecules/GalleryTrayTabs/styles.js +20 -0
  25. package/dist/components/molecules/ImageSelector/index.js +1 -0
  26. package/dist/components/organisms/DigitalAssetsTray/DigitalAssetsTray.stories.js +171 -0
  27. package/dist/components/organisms/DigitalAssetsTray/index.js +211 -0
  28. package/dist/components/organisms/DigitalAssetsTray/styles.js +22 -0
  29. package/dist/components/organisms/ImagePreviewer/index.js +1 -0
  30. package/dist/components/organisms/ProductImageModal/index.js +3 -2
  31. package/dist/components/organisms/PropagateChangesModal/index.js +12 -1
  32. package/dist/components/organisms/PropagateChangesModal/non-propagable.js +45 -0
  33. package/dist/components/pages/ProviderProductEdition/index.js +11 -1
  34. package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.context.js +330 -15
  35. package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +12 -2
  36. package/dist/components/pages/RetailerProductEdition/index.js +605 -414
  37. package/dist/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +1 -0
  38. package/dist/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +45 -145
  39. package/dist/global-files/data.js +16 -3
  40. package/dist/global-files/digital-assets/assetTypes.js +480 -0
  41. package/dist/global-files/digital-assets/assets.actions.js +64 -0
  42. package/dist/global-files/digital-assets/assets.adapter.js +304 -0
  43. package/dist/global-files/digital-assets/assets.mock.js +136 -0
  44. package/dist/global-files/digital-assets/assets.reducer.js +220 -0
  45. package/dist/global-files/digital-assets/uploadAssets.js +179 -0
  46. package/dist/global-files/digital-assets/useDigitalAssets.js +522 -0
  47. package/dist/index.js +142 -90
  48. package/docs/activos-digitales.md +273 -0
  49. package/package.json +1 -1
  50. package/src/components/atoms/AssetPreview/AssetPreview.stories.js +78 -0
  51. package/src/components/atoms/AssetPreview/index.js +119 -0
  52. package/src/components/atoms/AssetPreview/styles.js +190 -0
  53. package/src/components/atoms/IconFile/index.js +28 -1
  54. package/src/components/atoms/IconFile/styles.js +8 -0
  55. package/src/components/atoms/ProductImage/ProductImage.stories.js +38 -0
  56. package/src/components/atoms/ProductImage/index.js +95 -20
  57. package/src/components/atoms/ProductImage/styles.js +92 -7
  58. package/src/components/molecules/EditionActiveImage/index.js +2 -2
  59. package/src/components/molecules/GalleryAssetElement/GalleryAssetElement.stories.js +102 -0
  60. package/src/components/molecules/GalleryAssetElement/index.js +162 -0
  61. package/src/components/molecules/GalleryAssetElement/styles.js +159 -0
  62. package/src/components/molecules/GalleryElement/index.js +9 -0
  63. package/src/components/molecules/GalleryHeader/index.js +65 -13
  64. package/src/components/molecules/GalleryHeader/styles.js +2 -1
  65. package/src/components/molecules/GalleryTrayTabs/GalleryTrayTabs.stories.js +32 -0
  66. package/src/components/molecules/GalleryTrayTabs/index.js +41 -0
  67. package/src/components/molecules/GalleryTrayTabs/styles.js +52 -0
  68. package/src/components/molecules/ImageSelector/index.js +1 -0
  69. package/src/components/organisms/DigitalAssetsTray/DigitalAssetsTray.stories.js +101 -0
  70. package/src/components/organisms/DigitalAssetsTray/index.js +189 -0
  71. package/src/components/organisms/DigitalAssetsTray/styles.js +183 -0
  72. package/src/components/organisms/ImagePreviewer/index.js +1 -0
  73. package/src/components/organisms/ProductImageModal/index.js +1 -0
  74. package/src/components/organisms/PropagateChangesModal/index.js +11 -1
  75. package/src/components/organisms/PropagateChangesModal/non-propagable.js +29 -0
  76. package/src/components/pages/ProviderProductEdition/index.js +10 -1
  77. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +201 -0
  78. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +12 -0
  79. package/src/components/pages/RetailerProductEdition/index.js +366 -140
  80. package/src/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +1 -0
  81. package/src/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +51 -104
  82. package/src/global-files/data.js +17 -2
  83. package/src/global-files/digital-assets/assetTypes.js +419 -0
  84. package/src/global-files/digital-assets/assets.actions.js +50 -0
  85. package/src/global-files/digital-assets/assets.adapter.js +229 -0
  86. package/src/global-files/digital-assets/assets.mock.js +122 -0
  87. package/src/global-files/digital-assets/assets.reducer.js +197 -0
  88. package/src/global-files/digital-assets/uploadAssets.js +109 -0
  89. package/src/global-files/digital-assets/useDigitalAssets.js +329 -0
  90. package/src/index.js +4 -0
@@ -7,46 +7,119 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.ProductImage = void 0;
9
9
 
10
- var _styles = require("./styles");
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
11
+
12
+ var _react = require("react");
11
13
 
12
14
  var _reactImageFallback = _interopRequireDefault(require("react-image-fallback"));
13
15
 
16
+ var _styles = require("./styles");
17
+
18
+ var _assetTypes = require("../../../global-files/digital-assets/assetTypes");
19
+
14
20
  var _defaultProductImage = _interopRequireDefault(require("../../../assets/images/defaultImages/defaultProductImage.png"));
15
21
 
16
22
  var _jsxRuntime = require("react/jsx-runtime");
17
23
 
24
+ /*
25
+ Tamaños en los que un video se muestra como miniatura y no como reproductor.
26
+
27
+ Los controles nativos del navegador necesitan alrededor de 150px de ancho
28
+ para ser usables; en un recuadro de 60 o de 85 se pintan encimados y no se
29
+ puede ni dar play. Peor aún, un <video> con controles se traga el clic, así
30
+ que un video en el carrusel no se podía ni seleccionar: `onClick` nunca
31
+ llegaba a correr.
32
+
33
+ En estos tamaños se muestra el primer fotograma con su duración y un botón de
34
+ play, y el recuadro completo lleva al visor grande, que es donde el video sí
35
+ se ve y se controla.
36
+ */
37
+ var THUMBNAIL_TYPES = ["carousel-image", "catalogue-image-small-size", "catalogue-image-big-size", "catalogue-modal-image"];
38
+
39
+ var PlayBadge = function PlayBadge() {
40
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
41
+ className: "play-badge",
42
+ "aria-hidden": "true",
43
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
44
+ viewBox: "0 0 24 24",
45
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("circle", {
46
+ cx: "12",
47
+ cy: "12",
48
+ r: "11"
49
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("polygon", {
50
+ points: "9.5,7.5 17,12 9.5,16.5"
51
+ })]
52
+ })
53
+ });
54
+ };
55
+ /**
56
+ * Imagen —o video— de producto.
57
+ *
58
+ * El tipo de archivo se decide por `ext`/`mime` cuando quien llama los conoce.
59
+ * Antes se comprobaba con `/\.mp4$/` sobre la URL, y nunca acertaba: la URL
60
+ * guardada apunta al redimensionador de CloudFront y no conserva la extensión.
61
+ * El regex queda solo como respaldo para los llamadores que aún mandan `img`
62
+ * a secas.
63
+ */
64
+
65
+
18
66
  var ProductImage = function ProductImage(_ref) {
19
67
  var img = _ref.img,
20
68
  imageType = _ref.imageType,
21
69
  altText = _ref.altText,
22
- onClick = _ref.onClick;
23
- // Expresión regular para validar que los últimos tres caracteres sean ".mp4"
24
- var regex = /\.mp4$/;
25
-
26
- if (regex.test(img)) {
27
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Container, {
28
- className: imageType,
29
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("video", {
30
- controls: true,
31
- width: "100%",
32
- height: "auto",
33
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("source", {
34
- src: img,
35
- type: "video/mp4"
36
- })
37
- })
38
- });
39
- } else {
40
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Container, {
41
- className: imageType,
42
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactImageFallback.default, {
43
- src: img,
44
- fallbackImage: _defaultProductImage.default,
45
- alt: altText,
46
- onClick: onClick
47
- })
70
+ onClick = _ref.onClick,
71
+ ext = _ref.ext,
72
+ mime = _ref.mime,
73
+ poster = _ref.poster;
74
+
75
+ // La duración no está en la base: se toma de los metadatos, que el navegador
76
+ // ya descarga por el `preload="metadata"`. No cuesta una petición extra.
77
+ var _useState = (0, _react.useState)(null),
78
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
79
+ duration = _useState2[0],
80
+ setDuration = _useState2[1];
81
+
82
+ var kind = ext || mime ? (0, _assetTypes.resolvePreviewKind)({
83
+ ext: ext,
84
+ mime: mime
85
+ }) : /\.mp4($|[?#])/i.test(img || "") ? _assetTypes.ASSET_PREVIEW.VIDEO : _assetTypes.ASSET_PREVIEW.IMAGE;
86
+
87
+ if (kind === _assetTypes.ASSET_PREVIEW.VIDEO) {
88
+ var isThumbnail = THUMBNAIL_TYPES.includes(imageType);
89
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Container, {
90
+ className: "".concat(imageType, " ").concat(isThumbnail ? "video-thumbnail" : "video-player"),
91
+ onClick: isThumbnail ? onClick : undefined,
92
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("video", {
93
+ // `#t=0.5` hace que el navegador muestre el fotograma del medio
94
+ // segundo en lugar de un cuadro negro, sin descargar el archivo
95
+ // completo.
96
+ src: poster ? img : "".concat(img, "#t=0.5"),
97
+ poster: poster || undefined,
98
+ controls: !isThumbnail,
99
+ muted: isThumbnail,
100
+ playsInline: true,
101
+ preload: "metadata",
102
+ onLoadedMetadata: function onLoadedMetadata(e) {
103
+ return setDuration(e.target.duration);
104
+ }
105
+ }), isThumbnail && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
106
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(PlayBadge, {}), duration ? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
107
+ className: "video-duration",
108
+ children: (0, _assetTypes.formatDuration)(duration)
109
+ }) : null]
110
+ })]
48
111
  });
49
112
  }
113
+
114
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Container, {
115
+ className: imageType,
116
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactImageFallback.default, {
117
+ src: img,
118
+ fallbackImage: _defaultProductImage.default,
119
+ alt: altText,
120
+ onClick: onClick
121
+ })
122
+ });
50
123
  };
51
124
 
52
125
  exports.ProductImage = ProductImage;
@@ -11,8 +11,10 @@ var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/hel
11
11
 
12
12
  var _styledComponents = _interopRequireDefault(require("styled-components"));
13
13
 
14
+ var _variables = require("../../../global-files/variables");
15
+
14
16
  var _templateObject;
15
17
 
16
- var Container = _styledComponents.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n width: fit-content;\n\n img {\n object-fit: contain;\n }\n\n &.carousel-image {\n img {\n width: 85px;\n height: 55px;\n cursor: pointer;\n }\n\n & + * {\n margin-left: 1px;\n }\n }\n\n &.main-image {\n img {\n width: 340px;\n height: 295px;\n }\n }\n\n &.catalogue-image-big-size {\n display: flex; \n justify-content: center; \n align-items: center; \n img {\n width: 179px;\n height: 179px;\n }\n }\n\n &.catalogue-image-small-size {\n img {\n width: 60px;\n height: 60px;\n }\n }\n\n &.catalogue-modal-image {\n flex: 1 0 50%;\n cursor: pointer;\n\n img {\n width: 168px;\n height: 108px;\n }\n }\n\n &.expanded-modal-image {\n width: 710px;\n height: 710px;\n display: flex; \n justify-content: center; \n align-items: center; \n\n img {\n width: 710px;\n height: 710px;\n }\n }\n"])));
18
+ var Container = _styledComponents.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n width: fit-content;\n\n img,\n video {\n object-fit: contain;\n }\n\n /*\n Miniatura de video: fotograma quieto, con su duraci\xF3n y un bot\xF3n de play.\n El clic lo recibe el contenedor, no el <video>, para que lleve al visor\n grande en vez de quedarse peleando con los controles.\n */\n &.video-thumbnail {\n position: relative;\n cursor: pointer;\n\n video {\n pointer-events: none;\n background: #000;\n }\n\n .play-badge {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n pointer-events: none;\n\n svg {\n width: 100%;\n height: 100%;\n display: block;\n }\n\n circle {\n fill: rgba(0, 0, 0, 0.55);\n }\n\n polygon {\n fill: #ffffff;\n }\n }\n\n &:hover .play-badge circle {\n fill: rgba(0, 0, 0, 0.75);\n }\n\n .video-duration {\n position: absolute;\n right: 4px;\n bottom: 4px;\n padding: 0 4px;\n border-radius: 3px;\n background: rgba(0, 0, 0, 0.75);\n color: #ffffff;\n font-family: ", ";\n font-size: 10px;\n line-height: 15px;\n pointer-events: none;\n }\n }\n\n /* En 60px un badge de 32 tapa el fotograma completo. */\n &.catalogue-image-small-size.video-thumbnail .play-badge {\n width: 20px;\n height: 20px;\n }\n\n &.carousel-image.video-thumbnail {\n .play-badge {\n width: 22px;\n height: 22px;\n }\n\n .video-duration {\n font-size: 9px;\n line-height: 13px;\n }\n }\n\n &.carousel-image {\n img,\n video {\n width: 85px;\n height: 55px;\n cursor: pointer;\n }\n\n & + * {\n margin-left: 1px;\n }\n }\n\n &.main-image {\n img,\n video {\n width: 340px;\n height: 295px;\n }\n }\n\n &.catalogue-image-big-size {\n display: flex; \n justify-content: center; \n align-items: center; \n img,\n video {\n width: 179px;\n height: 179px;\n }\n }\n\n &.catalogue-image-small-size {\n img,\n video {\n width: 60px;\n height: 60px;\n }\n }\n\n &.catalogue-modal-image {\n flex: 1 0 50%;\n cursor: pointer;\n\n img,\n\n video {\n width: 168px;\n height: 108px;\n }\n }\n\n &.expanded-modal-image {\n width: 710px;\n height: 710px;\n display: flex; \n justify-content: center; \n align-items: center; \n\n img,\n\n video {\n width: 710px;\n height: 710px;\n }\n }\n"])), _variables.FontFamily.Lato);
17
19
 
18
20
  exports.Container = Container;
@@ -16,12 +16,14 @@ var _jsxRuntime = require("react/jsx-runtime");
16
16
  var EditionActiveImage = function EditionActiveImage(_ref) {
17
17
  var img = _ref.img,
18
18
  altText = _ref.altText,
19
- setShowModal = _ref.setShowModal;
19
+ setShowModal = _ref.setShowModal,
20
+ ext = _ref.ext;
20
21
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Container, {
21
22
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index.ProductImage, {
22
23
  img: img,
23
24
  imageType: "main-image",
24
- altText: altText
25
+ altText: altText,
26
+ ext: ext
25
27
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Button, {
26
28
  buttonType: "open-modal-button",
27
29
  onClick: function onClick() {
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = exports.Subiendo = exports.Fila = exports.EncabezadosComparados = exports.Cuadricula = exports.ConError = exports.BandejaCompleta = void 0;
9
+
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
11
+
12
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectSpread2"));
13
+
14
+ var _react = require("react");
15
+
16
+ var _index = require("./index");
17
+
18
+ var _GalleryHeader = require("../GalleryHeader");
19
+
20
+ var _assets = require("../../../global-files/digital-assets/assets.adapter");
21
+
22
+ var _assets2 = require("../../../global-files/digital-assets/assets.mock");
23
+
24
+ var _jsxRuntime = require("react/jsx-runtime");
25
+
26
+ var SAMPLES = {
27
+ mp4: "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
28
+ gif: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"
29
+ };
30
+ /* Las claves del mock apuntan a S3, que todavía no tiene nada: se sustituyen
31
+ por archivos públicos para poder ver el componente. */
32
+
33
+ var assets = (0, _assets.fromBackendList)(_assets2.backendAssetsMock).map(function (asset) {
34
+ return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, asset), {}, {
35
+ url: asset.ext === "mp4" ? SAMPLES.mp4 : asset.ext === "gif" ? SAMPLES.gif : "",
36
+ poster: ""
37
+ });
38
+ });
39
+ var _default = {
40
+ title: "Components/molecules/GalleryAssetElement",
41
+ component: _index.GalleryAssetElement
42
+ };
43
+ exports.default = _default;
44
+
45
+ var Template = function Template(args) {
46
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.GalleryAssetElement, (0, _objectSpread2.default)({}, args));
47
+ };
48
+
49
+ var Fila = Template.bind({});
50
+ exports.Fila = Fila;
51
+ Fila.args = {
52
+ asset: assets[0],
53
+ index: 0
54
+ };
55
+ var Cuadricula = Template.bind({});
56
+ exports.Cuadricula = Cuadricula;
57
+ Cuadricula.args = {
58
+ asset: assets[0],
59
+ index: 0,
60
+ gridLayout: true
61
+ };
62
+ var Subiendo = Template.bind({});
63
+ exports.Subiendo = Subiendo;
64
+ Subiendo.args = {
65
+ asset: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, assets[2]), {}, {
66
+ status: _assets.ASSET_STATUS.UPLOADING,
67
+ progress: 42
68
+ }),
69
+ index: 0
70
+ };
71
+ var ConError = Template.bind({});
72
+ exports.ConError = ConError;
73
+ ConError.args = {
74
+ asset: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, assets[3]), {}, {
75
+ status: _assets.ASSET_STATUS.ERROR,
76
+ error: "No se pudo subir el archivo. Intenta de nuevo."
77
+ }),
78
+ index: 0
79
+ };
80
+ /** La bandeja completa con su encabezado: es el uso real del componente. */
81
+
82
+ var BandejaCompleta = function BandejaCompleta() {
83
+ var _useState = (0, _react.useState)([]),
84
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
85
+ selected = _useState2[0],
86
+ setSelected = _useState2[1];
87
+
88
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
89
+ style: {
90
+ width: 900
91
+ },
92
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_GalleryHeader.GalleryHeader, {
93
+ variant: "asset",
94
+ checkAllId: "check-all-assets",
95
+ itemSelector: "[id^='gallery-asset-']",
96
+ setCheckAll: function setCheckAll() {},
97
+ setSelectedImages: setSelected
98
+ }), assets.map(function (asset, index) {
99
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.GalleryAssetElement, {
100
+ asset: asset,
101
+ index: index,
102
+ selectedAssets: selected,
103
+ setSelectedAssets: setSelected,
104
+ setCheckAll: function setCheckAll() {},
105
+ changeAsset: function changeAsset(_ref) {
106
+ var value = _ref.value;
107
+ return console.log("nuevo tipo:", value);
108
+ },
109
+ onRemove: function onRemove(item) {
110
+ return console.log("quitar:", item.name);
111
+ }
112
+ }, asset.id);
113
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", {
114
+ style: {
115
+ fontFamily: "Lato",
116
+ fontSize: 12,
117
+ marginTop: 12
118
+ },
119
+ children: ["Seleccionados: ", selected.length]
120
+ })]
121
+ });
122
+ };
123
+ /** Comparación de los dos encabezados, para verificar que no se movió el de imágenes. */
124
+
125
+
126
+ exports.BandejaCompleta = BandejaCompleta;
127
+
128
+ var EncabezadosComparados = function EncabezadosComparados() {
129
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
130
+ style: {
131
+ width: 900
132
+ },
133
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_GalleryHeader.GalleryHeader, {
134
+ variant: "image",
135
+ setCheckAll: function setCheckAll() {},
136
+ setSelectedImages: function setSelectedImages() {}
137
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_GalleryHeader.GalleryHeader, {
138
+ variant: "asset",
139
+ checkAllId: "check-all-assets-demo",
140
+ itemSelector: "[id^='gallery-asset-demo-']",
141
+ setCheckAll: function setCheckAll() {},
142
+ setSelectedImages: function setSelectedImages() {}
143
+ })]
144
+ });
145
+ };
146
+
147
+ exports.EncabezadosComparados = EncabezadosComparados;
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.GalleryAssetElement = void 0;
9
+
10
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/toConsumableArray"));
11
+
12
+ var _styles = require("./styles");
13
+
14
+ var _AssetPreview = require("../../atoms/AssetPreview");
15
+
16
+ var _CheckBox = require("../../atoms/CheckBox");
17
+
18
+ var _Select = _interopRequireDefault(require("../../atoms/Select"));
19
+
20
+ var _assetTypes = require("../../../global-files/digital-assets/assetTypes");
21
+
22
+ var _assets = require("../../../global-files/digital-assets/assets.adapter");
23
+
24
+ var _jsxRuntime = require("react/jsx-runtime");
25
+
26
+ /*
27
+ Fila de un activo digital en la bandeja.
28
+
29
+ Es un componente aparte de `GalleryElement` a propósito, no una bifurcación
30
+ dentro de él. Un activo no comparte casi nada con una imagen de producto: no
31
+ tiene tipo de toma, ni leyenda, ni panel de validación, ni comparación contra
32
+ la versión auditable. Meterlo en el mismo archivo habría partido su render en
33
+ dos mitades y puesto en riesgo la bandeja de imágenes, que ya funciona.
34
+
35
+ Lo que sí comparte —rejilla, tamaños, colores— vive en los estilos, calcados
36
+ de `GalleryElement` para que las dos listas se vean como una sola tabla.
37
+ */
38
+ var GalleryAssetElement = function GalleryAssetElement(_ref) {
39
+ var _asset$progress;
40
+
41
+ var _ref$asset = _ref.asset,
42
+ asset = _ref$asset === void 0 ? {} : _ref$asset,
43
+ _ref$index = _ref.index,
44
+ index = _ref$index === void 0 ? 0 : _ref$index,
45
+ _ref$gridLayout = _ref.gridLayout,
46
+ gridLayout = _ref$gridLayout === void 0 ? false : _ref$gridLayout,
47
+ id = _ref.id,
48
+ label = _ref.label,
49
+ _ref$selectedAssets = _ref.selectedAssets,
50
+ selectedAssets = _ref$selectedAssets === void 0 ? [] : _ref$selectedAssets,
51
+ setSelectedAssets = _ref.setSelectedAssets,
52
+ setCheckAll = _ref.setCheckAll,
53
+ changeAsset = _ref.changeAsset,
54
+ onRemove = _ref.onRemove,
55
+ _ref$readOnly = _ref.readOnly,
56
+ readOnly = _ref$readOnly === void 0 ? false : _ref$readOnly,
57
+ _ref$checkAllId = _ref.checkAllId,
58
+ checkAllId = _ref$checkAllId === void 0 ? "check-all-assets" : _ref$checkAllId,
59
+ _ref$itemSelector = _ref.itemSelector,
60
+ itemSelector = _ref$itemSelector === void 0 ? "[id^='gallery-asset-']" : _ref$itemSelector;
61
+ var elementId = id || "gallery-asset-".concat(index);
62
+ var key = (0, _assets.assetKey)(asset);
63
+ var isUploading = asset.status === _assets.ASSET_STATUS.UPLOADING;
64
+ var hasError = asset.status === _assets.ASSET_STATUS.ERROR;
65
+
66
+ var checkOnChange = function checkOnChange(e) {
67
+ var chkGlobal = document.getElementById(checkAllId);
68
+ var checkboxList = document.querySelectorAll(itemSelector);
69
+ var temp = selectedAssets.slice(); // Se compara por `assetKey` y no por `id`: un activo recién soltado todavía
70
+ // no tiene id del backend, y comparando por id todos los pendientes serían
71
+ // "el mismo" y se quitarían juntos de la selección.
72
+
73
+ temp = e.target.checked ? [].concat((0, _toConsumableArray2.default)(temp), [asset]) : temp.filter(function (item) {
74
+ return (0, _assets.assetKey)(item) !== key;
75
+ });
76
+ var counter = 0;
77
+ checkboxList === null || checkboxList === void 0 ? void 0 : checkboxList.forEach(function (chk) {
78
+ return chk.checked && counter++;
79
+ });
80
+ if (chkGlobal) chkGlobal.checked = checkboxList.length === counter;
81
+ setCheckAll === null || setCheckAll === void 0 ? void 0 : setCheckAll(checkboxList.length === counter);
82
+ setSelectedAssets === null || setSelectedAssets === void 0 ? void 0 : setSelectedAssets(temp);
83
+ };
84
+ /*
85
+ Abrir el activo en otra pestaña.
86
+ Sirve para TODOS los tipos y por eso se prefiere a un visor propio: un video
87
+ se reproduce con el reproductor del navegador, un PDF se abre, y un .psd se
88
+ descarga. Sin esto, la bandeja mostraba el archivo pero no había forma de
89
+ verlo — un video quedaba como un fotograma fijo sin botón de reproducir.
90
+ Solo cuando ya está en S3: un activo recién soltado apunta al archivo del
91
+ disco del usuario y abrirlo no le diría nada nuevo.
92
+ */
93
+
94
+
95
+ var abrir = function abrir() {
96
+ if (!asset.id || !asset.url) return;
97
+ window.open(asset.url, "_blank", "noopener,noreferrer");
98
+ };
99
+
100
+ var onChangeType = function onChangeType(e) {
101
+ changeAsset === null || changeAsset === void 0 ? void 0 : changeAsset({
102
+ action: "changeAssetInfo",
103
+ attribute: "assetType",
104
+ value: e.target.value,
105
+ index: index
106
+ });
107
+ };
108
+
109
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Container, {
110
+ className: "".concat(gridLayout ? "grid-gallery" : "row-gallery", " ").concat(hasError ? "asset-error" : "").trim(),
111
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
112
+ className: "buttons-container",
113
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CheckBox.CheckBox, {
114
+ id: elementId,
115
+ label: label,
116
+ onChange: checkOnChange
117
+ })
118
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
119
+ className: "asset-container",
120
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_AssetPreview.AssetPreview, {
121
+ asset: asset,
122
+ size: "catalogue-image-".concat(gridLayout ? "big" : "small", "-size")
123
+ /*
124
+ En cuadrícula hay sitio para el reproductor; en la fila, de 60px,
125
+ los controles no caben y estorban al clic.
126
+ */
127
+ ,
128
+ controls: gridLayout && (0, _assetTypes.resolvePreviewKind)(asset) === _assetTypes.ASSET_PREVIEW.VIDEO,
129
+ onClick: abrir
130
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
131
+ className: "information-container",
132
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
133
+ className: asset.id ? "asset-name asset-link" : "asset-name",
134
+ title: asset.id ? "Abrir ".concat(asset.name) : asset.name,
135
+ onClick: abrir,
136
+ children: asset.name
137
+ }), !gridLayout && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
138
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
139
+ className: "asset-weight",
140
+ children: (0, _assetTypes.formatBytes)(asset.sizeBytes)
141
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
142
+ className: "asset-format",
143
+ children: (asset.ext || "").toUpperCase()
144
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Select.default, {
145
+ width: "100%",
146
+ placeholder: "Tipo de activo",
147
+ options: (0, _assetTypes.assetTypeOptions)(),
148
+ valueSelected: asset.assetType,
149
+ onChange: onChangeType,
150
+ className: readOnly ? "disabled" : ""
151
+ })]
152
+ })]
153
+ })]
154
+ }), isUploading && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
155
+ className: "asset-progress",
156
+ "aria-label": "Subiendo activo",
157
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
158
+ className: "asset-progress-fill",
159
+ style: {
160
+ width: "".concat(Math.min(100, Math.max(0, (_asset$progress = asset.progress) !== null && _asset$progress !== void 0 ? _asset$progress : 0)), "%")
161
+ }
162
+ })
163
+ }), hasError && /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
164
+ className: "asset-error-message",
165
+ children: asset.error
166
+ }), onRemove && !readOnly && /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
167
+ type: "button",
168
+ className: "asset-remove",
169
+ onClick: function onClick() {
170
+ return onRemove(asset);
171
+ },
172
+ title: "Quitar activo",
173
+ children: "\xD7"
174
+ })]
175
+ });
176
+ };
177
+
178
+ exports.GalleryAssetElement = GalleryAssetElement;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.Container = void 0;
9
+
10
+ var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/taggedTemplateLiteral"));
11
+
12
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
13
+
14
+ var _variables = require("../../../global-files/variables");
15
+
16
+ var _templateObject;
17
+
18
+ /*
19
+ Calcado de `GalleryElement/styles.js` para que imágenes y activos se lean como
20
+ una sola tabla. Cambia solo la rejilla de la fila —cuatro columnas en vez de
21
+ cinco, porque un activo no tiene leyenda— y lo propio de un archivo que se
22
+ está subiendo: barra de progreso, mensaje de error y botón de quitar.
23
+ */
24
+ var Container = _styledComponents.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n position: relative;\n\n &.grid-gallery {\n width: 179px;\n border-radius: 3px;\n overflow: hidden;\n\n .buttons-container {\n position: absolute;\n top: 5px;\n left: 5px;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .asset-container {\n border: 1px solid #f0eef2;\n\n .information-container {\n background-color: ", ";\n display: flex;\n justify-content: space-between;\n padding: 0 2px;\n\n p {\n font-family: ", ";\n color: ", ";\n font-size: 11px;\n line-height: 17px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n }\n }\n }\n\n &.row-gallery {\n width: 100%;\n display: grid;\n grid-template-columns: 0.05fr 1fr;\n align-items: center;\n padding-right: 10px;\n\n .buttons-container {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .asset-container {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: center;\n flex: 1;\n\n .information-container {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n align-items: center;\n\n p {\n font-family: ", ";\n color: ", ";\n font-size: 14px;\n line-height: 17px;\n text-align: center;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n & > * {\n flex: 1;\n padding: 5px;\n }\n }\n }\n }\n\n /* El nombre es el sitio donde uno intenta hacer clic para abrir un archivo. */\n .asset-link {\n cursor: pointer;\n text-decoration: underline;\n text-underline-offset: 2px;\n\n &:hover {\n color: ", ";\n }\n }\n\n &.asset-error {\n border: 1px solid ", ";\n border-radius: 3px;\n }\n\n /* Progreso de subida. Ocupa el borde inferior de la fila para no empujar el\n resto del contenido mientras aparece y desaparece. */\n .asset-progress {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n height: 3px;\n background: ", ";\n border-radius: 2px;\n overflow: hidden;\n }\n\n .asset-progress-fill {\n height: 100%;\n background: ", ";\n transition: width 0.2s ease-out;\n }\n\n .asset-error-message {\n margin: 2px 0 0;\n padding: 0 8px;\n font-family: ", ";\n font-size: 11px;\n line-height: 15px;\n color: ", ";\n }\n\n .asset-remove {\n position: absolute;\n top: 4px;\n right: 6px;\n width: 18px;\n height: 18px;\n display: grid;\n place-items: center;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: ", ";\n color: ", ";\n font-size: 14px;\n line-height: 1;\n cursor: pointer;\n\n &:hover {\n background: ", ";\n }\n }\n"])), _variables.GlobalColors.s2, _variables.FontFamily.Lato, _variables.GlobalColors.s4, _variables.FontFamily.Lato, _variables.GlobalColors.s4, _variables.GlobalColors.color_purple, _variables.GlobalColors.secondary_magenta, _variables.GlobalColors.s3, _variables.GlobalColors.color_purple, _variables.FontFamily.Lato, _variables.GlobalColors.secondary_magenta, _variables.GlobalColors.s2, _variables.GlobalColors.s5, _variables.GlobalColors.s3);
25
+
26
+ exports.Container = Container;
@@ -36,7 +36,7 @@ var _Tooltip = require("../../atoms/Tooltip");
36
36
  var _jsxRuntime = require("react/jsx-runtime");
37
37
 
38
38
  var GalleryElement = function GalleryElement(_ref) {
39
- var _auditImages$values$n, _auditImages$values$n2;
39
+ var _auditImages$values$n, _auditImages$values$n2, _auditImages$values$n3;
40
40
 
41
41
  var image = _ref.image,
42
42
  _ref$gridLayout = _ref.gridLayout,
@@ -54,7 +54,8 @@ var GalleryElement = function GalleryElement(_ref) {
54
54
  setCheckAll = _ref.setCheckAll,
55
55
  auditImages = _ref.auditImages,
56
56
  compare = _ref.compare,
57
- updateApprovedInputsImages = _ref.updateApprovedInputsImages;
57
+ updateApprovedInputsImages = _ref.updateApprovedInputsImages,
58
+ onSelect = _ref.onSelect;
58
59
 
59
60
  var _useState = (0, _react.useState)(false),
60
61
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
@@ -133,8 +134,16 @@ var GalleryElement = function GalleryElement(_ref) {
133
134
  className: "image-container",
134
135
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ProductImage.ProductImage, {
135
136
  img: compare ? auditImages === null || auditImages === void 0 ? void 0 : (_auditImages$values$n2 = auditImages.values[number]) === null || _auditImages$values$n2 === void 0 ? void 0 : _auditImages$values$n2.src : image === null || image === void 0 ? void 0 : image.src,
136
- altText: image === null || image === void 0 ? void 0 : image.altText,
137
- imageType: "catalogue-image-".concat(gridLayout ? "big" : "small", "-size")
137
+ altText: image === null || image === void 0 ? void 0 : image.altText // Sin `ext`, un video se pinta como <img> rota: la URL guardada no
138
+ // conserva la extensión del archivo.
139
+ ,
140
+ ext: compare ? auditImages === null || auditImages === void 0 ? void 0 : (_auditImages$values$n3 = auditImages.values[number]) === null || _auditImages$values$n3 === void 0 ? void 0 : _auditImages$values$n3.ext : image === null || image === void 0 ? void 0 : image.ext,
141
+ imageType: "catalogue-image-".concat(gridLayout ? "big" : "small", "-size") // La miniatura de un video ya no lleva controles, así que el clic es
142
+ // la única forma de llegar al visor grande. Se aplica también a las
143
+ // imágenes: dos recuadros idénticos donde solo uno responde al clic
144
+ // sería peor que no responder ninguno.
145
+ ,
146
+ onClick: onSelect
138
147
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
139
148
  className: "information-container",
140
149
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", {