contentoh-components-library 21.6.56 → 21.6.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/atoms/AsignationOption/index.js +1 -0
- package/dist/components/atoms/AsignationOption/styles.js +1 -1
- package/dist/components/molecules/GalleryAssetElement/styles.js +1 -1
- package/dist/components/molecules/RetailerSelector/RetailerSelector.stories.js +23 -2
- package/dist/components/molecules/RetailerSelector/index.js +7 -2
- package/dist/components/molecules/RetailerSelectorv2/index.js +6 -2
- package/dist/components/organisms/DigitalAssetsTray/DigitalAssetsTray.stories.js +73 -9
- package/dist/components/organisms/DigitalAssetsTray/index.js +13 -5
- package/dist/components/pages/CreatorsProductEdition/CreatorsProductEditionView.js +905 -0
- package/dist/components/pages/CreatorsProductEdition/constants.js +19 -0
- package/dist/components/pages/CreatorsProductEdition/hooks/useCreatorsProductEdition.js +2967 -0
- package/dist/components/pages/CreatorsProductEdition/index.js +33 -0
- package/dist/components/pages/CreatorsProductEdition/mocks/api.fixtures.js +537 -0
- package/dist/components/pages/CreatorsProductEdition/mocks/mockApi.js +251 -0
- package/dist/components/pages/CreatorsProductEdition/sections/CommentBox.js +311 -0
- package/dist/components/pages/CreatorsProductEdition/sections/ImagePanel.js +421 -0
- package/dist/components/pages/CreatorsProductEdition/sections/ImagesSection.js +473 -0
- package/dist/components/pages/CreatorsProductEdition/sections/ProductHeader.js +379 -0
- package/dist/components/pages/CreatorsProductEdition/sections/ProductMedia.js +138 -0
- package/dist/components/pages/CreatorsProductEdition/sections/RetailerMenu.js +162 -0
- package/dist/components/pages/CreatorsProductEdition/sections/ServiceActions.js +542 -0
- package/dist/components/pages/CreatorsProductEdition/sections/StatusChip.js +50 -0
- package/dist/components/pages/CreatorsProductEdition/sections/TabsBar.js +247 -0
- package/dist/components/pages/CreatorsProductEdition/sections/VariantsPanel.js +389 -0
- package/dist/components/pages/CreatorsProductEdition/sections/tokens.js +90 -0
- package/dist/components/pages/CreatorsProductEdition/stories/CreatorsProductEdition.stories.js +168 -0
- package/dist/components/pages/CreatorsProductEdition/stories/CreatorsProductEditionAPI.stories.js +74 -0
- package/dist/components/pages/CreatorsProductEdition/styles.js +46 -0
- package/dist/global-files/digital-assets/assetTypes.js +49 -12
- package/dist/global-files/digital-assets/uploadAssets.js +39 -16
- package/dist/global-files/digital-assets/useDigitalAssets.js +38 -25
- package/package.json +1 -1
- package/src/components/atoms/AsignationOption/index.js +1 -1
- package/src/components/atoms/AsignationOption/styles.js +9 -0
- package/src/components/molecules/GalleryAssetElement/styles.js +5 -1
- package/src/components/molecules/RetailerSelector/RetailerSelector.stories.js +15 -1
- package/src/components/molecules/RetailerSelector/index.js +8 -1
- package/src/components/molecules/RetailerSelectorv2/index.js +7 -1
- package/src/components/organisms/DigitalAssetsTray/DigitalAssetsTray.stories.js +67 -4
- package/src/components/organisms/DigitalAssetsTray/index.js +8 -4
- package/src/global-files/digital-assets/assetTypes.js +42 -10
- package/src/global-files/digital-assets/uploadAssets.js +38 -23
- package/src/global-files/digital-assets/useDigitalAssets.js +19 -8
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.statusName = exports.statusColor = exports.retailerImage = exports.retailerId = exports.FONTS = exports.COLORS = void 0;
|
|
7
|
+
|
|
8
|
+
var _variables = require("../../../../global-files/variables");
|
|
9
|
+
|
|
10
|
+
var _statusDictionary = require("../../../../global-files/statusDictionary");
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
Colores y tipografía de la edición de producto, en un solo lugar para las
|
|
14
|
+
secciones hechas con MUI. Son los mismos de los componentes originales
|
|
15
|
+
(Status, FeatureTag, TabSection, ScreenHeader...): el diseño no cambia.
|
|
16
|
+
*/
|
|
17
|
+
var COLORS = _variables.GlobalColors;
|
|
18
|
+
exports.COLORS = COLORS;
|
|
19
|
+
var FONTS = _variables.FontFamily;
|
|
20
|
+
/** Color de fondo de la etiqueta de estatus, como en `atoms/Status/styles.js`. */
|
|
21
|
+
|
|
22
|
+
exports.FONTS = FONTS;
|
|
23
|
+
var STATUS_COLORS = {
|
|
24
|
+
CA: _variables.GlobalColors.in_progress,
|
|
25
|
+
IE: _variables.GlobalColors.in_progress,
|
|
26
|
+
GLD: _variables.GlobalColors.in_progress,
|
|
27
|
+
R: _variables.GlobalColors.reception,
|
|
28
|
+
AS: _variables.GlobalColors.reception,
|
|
29
|
+
SAC: _variables.GlobalColors.reception,
|
|
30
|
+
PA: _variables.GlobalColors.reception,
|
|
31
|
+
AA: _variables.GlobalColors.finished,
|
|
32
|
+
AP: _variables.GlobalColors.finished,
|
|
33
|
+
AC: _variables.GlobalColors.finished,
|
|
34
|
+
AAC: _variables.GlobalColors.finished,
|
|
35
|
+
ACA: _variables.GlobalColors.finished,
|
|
36
|
+
RA: _variables.GlobalColors.rejected_status,
|
|
37
|
+
RC: _variables.GlobalColors.rejected_status,
|
|
38
|
+
RP: _variables.GlobalColors.rejected_status,
|
|
39
|
+
RAC: _variables.GlobalColors.rejected_status,
|
|
40
|
+
RCA: _variables.GlobalColors.rejected_status,
|
|
41
|
+
Dat: _variables.GlobalColors.s4,
|
|
42
|
+
Dsc: _variables.GlobalColors.s4,
|
|
43
|
+
Imgs: _variables.GlobalColors.s4,
|
|
44
|
+
FAP: _variables.GlobalColors.exported,
|
|
45
|
+
Ex: _variables.GlobalColors.exported,
|
|
46
|
+
DDI: _variables.GlobalColors.original_purpura,
|
|
47
|
+
TAB: _variables.GlobalColors.deep_gray,
|
|
48
|
+
Pt: _variables.GlobalColors.s2
|
|
49
|
+
};
|
|
50
|
+
/** "RA/AS" se pinta con el color de la primera parte, igual que el original. */
|
|
51
|
+
|
|
52
|
+
var statusColor = function statusColor(status) {
|
|
53
|
+
var _STATUS_COLORS$String;
|
|
54
|
+
|
|
55
|
+
return (_STATUS_COLORS$String = STATUS_COLORS[String(status !== null && status !== void 0 ? status : "").replace(/\/.*/, "")]) !== null && _STATUS_COLORS$String !== void 0 ? _STATUS_COLORS$String : _variables.GlobalColors.s3;
|
|
56
|
+
};
|
|
57
|
+
/** Nombre legible: "RA/AS" → "Rechazado Auditor / Asignado". */
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
exports.statusColor = statusColor;
|
|
61
|
+
|
|
62
|
+
var statusName = function statusName(status) {
|
|
63
|
+
if (!status) return null;
|
|
64
|
+
var names = String(status).split("/").map(function (key) {
|
|
65
|
+
var _STATUS_DICTIONARY$ke;
|
|
66
|
+
|
|
67
|
+
return (_STATUS_DICTIONARY$ke = _statusDictionary.STATUS_DICTIONARY[key]) === null || _STATUS_DICTIONARY$ke === void 0 ? void 0 : _STATUS_DICTIONARY$ke.name;
|
|
68
|
+
}).filter(Boolean);
|
|
69
|
+
return names.length > 0 ? names.join(" / ") : null;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
exports.statusName = statusName;
|
|
73
|
+
|
|
74
|
+
var retailerImage = function retailerImage(retailer) {
|
|
75
|
+
var _retailer$id;
|
|
76
|
+
|
|
77
|
+
return (retailer === null || retailer === void 0 ? void 0 : retailer.image) || "https://content-management-images.s3.amazonaws.com/retailers/".concat((_retailer$id = retailer === null || retailer === void 0 ? void 0 : retailer.id) !== null && _retailer$id !== void 0 ? _retailer$id : retailer === null || retailer === void 0 ? void 0 : retailer.id_retailer, ".png");
|
|
78
|
+
};
|
|
79
|
+
/** El id de una cadena llega como `id` o como `id_retailer` según el origen. */
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
exports.retailerImage = retailerImage;
|
|
83
|
+
|
|
84
|
+
var retailerId = function retailerId(retailer) {
|
|
85
|
+
var _retailer$id2;
|
|
86
|
+
|
|
87
|
+
return (_retailer$id2 = retailer === null || retailer === void 0 ? void 0 : retailer.id) !== null && _retailer$id2 !== void 0 ? _retailer$id2 : retailer === null || retailer === void 0 ? void 0 : retailer.id_retailer;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
exports.retailerId = retailerId;
|
package/dist/components/pages/CreatorsProductEdition/stories/CreatorsProductEdition.stories.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
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.SinImagenes = exports.HijoDeOtro = exports.EspecialistaTextosCelular = exports.EspecialistaTextos = exports.EspecialistaImagenesTablet = exports.EspecialistaImagenesCelular = exports.EspecialistaImagenes = exports.ErrorAlCargar = exports.ConVariantesCelular = exports.ConVariantes = exports.AuditorQATablet = exports.AuditorQACelular = exports.AuditorQA = exports.AuditorPorEvaluarCelular = exports.AuditorPorEvaluar = void 0;
|
|
9
|
+
|
|
10
|
+
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectSpread2"));
|
|
11
|
+
|
|
12
|
+
var _index = require("../index");
|
|
13
|
+
|
|
14
|
+
var _mockApi = require("../mocks/mockApi");
|
|
15
|
+
|
|
16
|
+
var _ImageEditor = require("../../RetailerProductEdition/stories/ImageEditor.stories");
|
|
17
|
+
|
|
18
|
+
var _TextEditor = require("../../RetailerProductEdition/stories/TextEditor.stories");
|
|
19
|
+
|
|
20
|
+
var _Auditor = require("../../RetailerProductEdition/stories/Auditor.stories");
|
|
21
|
+
|
|
22
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
Historias con datos locales: no le pegan a ninguna API, así que funcionan
|
|
26
|
+
siempre, sin token ni producto vivo en dev. Las respuestas están en
|
|
27
|
+
`mocks/api.fixtures.js`. Guardar, aprobar o rechazar se acepta sin hacer
|
|
28
|
+
nada (queda en la consola como `[mock API]`).
|
|
29
|
+
|
|
30
|
+
El producto y los usuarios salen de las historias de RetailerProductEdition
|
|
31
|
+
para que las dos vistas se comparen con lo mismo. El token va solo porque la
|
|
32
|
+
pantalla lo exige: aquí no sale a ningún lado.
|
|
33
|
+
*/
|
|
34
|
+
var _default = {
|
|
35
|
+
title: "Components/pages/CreatorsProductEdition",
|
|
36
|
+
component: _index.CreatorsProductEdition,
|
|
37
|
+
decorators: [(0, _mockApi.withMockApi)()],
|
|
38
|
+
parameters: {
|
|
39
|
+
layout: "fullscreen"
|
|
40
|
+
}
|
|
41
|
+
}; // Como en la app: la pantalla vive en una caja de altura fija que no se
|
|
42
|
+
// desplaza. El scroll tiene que darlo la propia pantalla, en todos los tamaños.
|
|
43
|
+
|
|
44
|
+
exports.default = _default;
|
|
45
|
+
|
|
46
|
+
var Template = function Template(args) {
|
|
47
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
48
|
+
style: {
|
|
49
|
+
height: "100vh",
|
|
50
|
+
display: "flex",
|
|
51
|
+
overflow: "hidden"
|
|
52
|
+
},
|
|
53
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.CreatorsProductEdition, (0, _objectSpread2.default)({}, args))
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
var base = {
|
|
58
|
+
token: _ImageEditor.ImageEditor.args.token,
|
|
59
|
+
productSelected: _ImageEditor.ImageEditor.args.productSelected,
|
|
60
|
+
enableDigitalAssets: true
|
|
61
|
+
};
|
|
62
|
+
var TODAS_LAS_PESTAÑAS = {
|
|
63
|
+
Descripción: true,
|
|
64
|
+
"Ficha técnica": true,
|
|
65
|
+
Imágenes: true
|
|
66
|
+
};
|
|
67
|
+
var celular = {
|
|
68
|
+
viewport: {
|
|
69
|
+
defaultViewport: "mobile2"
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var tablet = {
|
|
73
|
+
viewport: {
|
|
74
|
+
defaultViewport: "tablet"
|
|
75
|
+
}
|
|
76
|
+
}; // --- Especialista de edición (rol 8): pestaña de imágenes -------------------
|
|
77
|
+
|
|
78
|
+
var EspecialistaImagenes = Template.bind({});
|
|
79
|
+
exports.EspecialistaImagenes = EspecialistaImagenes;
|
|
80
|
+
EspecialistaImagenes.args = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, base), {}, {
|
|
81
|
+
tabsSections: _ImageEditor.ImageEditor.args.tabsSections,
|
|
82
|
+
user: _ImageEditor.ImageEditor.args.user
|
|
83
|
+
});
|
|
84
|
+
var EspecialistaImagenesTablet = Template.bind({});
|
|
85
|
+
exports.EspecialistaImagenesTablet = EspecialistaImagenesTablet;
|
|
86
|
+
EspecialistaImagenesTablet.args = EspecialistaImagenes.args;
|
|
87
|
+
EspecialistaImagenesTablet.parameters = tablet;
|
|
88
|
+
var EspecialistaImagenesCelular = Template.bind({});
|
|
89
|
+
exports.EspecialistaImagenesCelular = EspecialistaImagenesCelular;
|
|
90
|
+
EspecialistaImagenesCelular.args = EspecialistaImagenes.args;
|
|
91
|
+
EspecialistaImagenesCelular.parameters = celular; // --- Especialista de textos (rol 7): descripción ----------------------------
|
|
92
|
+
|
|
93
|
+
var EspecialistaTextos = Template.bind({});
|
|
94
|
+
exports.EspecialistaTextos = EspecialistaTextos;
|
|
95
|
+
EspecialistaTextos.args = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, base), {}, {
|
|
96
|
+
tabsSections: _TextEditor.TextEditor.args.tabsSections,
|
|
97
|
+
user: _TextEditor.TextEditor.args.user
|
|
98
|
+
});
|
|
99
|
+
var EspecialistaTextosCelular = Template.bind({});
|
|
100
|
+
exports.EspecialistaTextosCelular = EspecialistaTextosCelular;
|
|
101
|
+
EspecialistaTextosCelular.args = EspecialistaTextos.args;
|
|
102
|
+
EspecialistaTextosCelular.parameters = celular; // --- Auditor QA (rol 6): las tres pestañas ----------------------------------
|
|
103
|
+
|
|
104
|
+
var AuditorQA = Template.bind({});
|
|
105
|
+
exports.AuditorQA = AuditorQA;
|
|
106
|
+
AuditorQA.args = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, base), {}, {
|
|
107
|
+
tabsSections: TODAS_LAS_PESTAÑAS,
|
|
108
|
+
user: _Auditor.Auditor.args.user
|
|
109
|
+
});
|
|
110
|
+
var AuditorQATablet = Template.bind({});
|
|
111
|
+
exports.AuditorQATablet = AuditorQATablet;
|
|
112
|
+
AuditorQATablet.args = AuditorQA.args;
|
|
113
|
+
AuditorQATablet.parameters = tablet;
|
|
114
|
+
var AuditorQACelular = Template.bind({});
|
|
115
|
+
exports.AuditorQACelular = AuditorQACelular;
|
|
116
|
+
AuditorQACelular.args = AuditorQA.args;
|
|
117
|
+
AuditorQACelular.parameters = celular; // Del Sol en "AC": el auditor asignado ve el botón para validar o rechazar.
|
|
118
|
+
|
|
119
|
+
var AuditorPorEvaluar = Template.bind({});
|
|
120
|
+
exports.AuditorPorEvaluar = AuditorPorEvaluar;
|
|
121
|
+
AuditorPorEvaluar.args = AuditorQA.args;
|
|
122
|
+
AuditorPorEvaluar.decorators = [(0, _mockApi.withMockApi)({
|
|
123
|
+
delSolStatus: "AC"
|
|
124
|
+
})];
|
|
125
|
+
var AuditorPorEvaluarCelular = Template.bind({});
|
|
126
|
+
exports.AuditorPorEvaluarCelular = AuditorPorEvaluarCelular;
|
|
127
|
+
AuditorPorEvaluarCelular.args = AuditorQA.args;
|
|
128
|
+
AuditorPorEvaluarCelular.decorators = [(0, _mockApi.withMockApi)({
|
|
129
|
+
delSolStatus: "AC"
|
|
130
|
+
})];
|
|
131
|
+
AuditorPorEvaluarCelular.parameters = celular; // --- Variantes ---------------------------------------------------------------
|
|
132
|
+
// Padre con dos hijos y en un grupo de variantes.
|
|
133
|
+
|
|
134
|
+
var ConVariantes = Template.bind({});
|
|
135
|
+
exports.ConVariantes = ConVariantes;
|
|
136
|
+
ConVariantes.args = EspecialistaTextos.args;
|
|
137
|
+
ConVariantes.decorators = [(0, _mockApi.withMockApi)({
|
|
138
|
+
familia: "padre",
|
|
139
|
+
grupo: true
|
|
140
|
+
})];
|
|
141
|
+
var ConVariantesCelular = Template.bind({});
|
|
142
|
+
exports.ConVariantesCelular = ConVariantesCelular;
|
|
143
|
+
ConVariantesCelular.args = EspecialistaTextos.args;
|
|
144
|
+
ConVariantesCelular.decorators = [(0, _mockApi.withMockApi)({
|
|
145
|
+
familia: "padre",
|
|
146
|
+
grupo: true
|
|
147
|
+
})];
|
|
148
|
+
ConVariantesCelular.parameters = celular; // Hijo de otro producto: no ofrece ligar ni agrupar.
|
|
149
|
+
|
|
150
|
+
var HijoDeOtro = Template.bind({});
|
|
151
|
+
exports.HijoDeOtro = HijoDeOtro;
|
|
152
|
+
HijoDeOtro.args = EspecialistaTextos.args;
|
|
153
|
+
HijoDeOtro.decorators = [(0, _mockApi.withMockApi)({
|
|
154
|
+
familia: "hijo"
|
|
155
|
+
})]; // --- Casos límite -----------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
var SinImagenes = Template.bind({});
|
|
158
|
+
exports.SinImagenes = SinImagenes;
|
|
159
|
+
SinImagenes.args = EspecialistaImagenes.args;
|
|
160
|
+
SinImagenes.decorators = [(0, _mockApi.withMockApi)({
|
|
161
|
+
images: false
|
|
162
|
+
})];
|
|
163
|
+
var ErrorAlCargar = Template.bind({});
|
|
164
|
+
exports.ErrorAlCargar = ErrorAlCargar;
|
|
165
|
+
ErrorAlCargar.args = EspecialistaImagenes.args;
|
|
166
|
+
ErrorAlCargar.decorators = [(0, _mockApi.withMockApi)({
|
|
167
|
+
failLoad: true
|
|
168
|
+
})];
|
package/dist/components/pages/CreatorsProductEdition/stories/CreatorsProductEditionAPI.stories.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
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.Textos = exports.ImagenesTablet = exports.ImagenesCelular = exports.Imagenes = exports.AuditorQA = void 0;
|
|
9
|
+
|
|
10
|
+
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectSpread2"));
|
|
11
|
+
|
|
12
|
+
var _index = require("../index");
|
|
13
|
+
|
|
14
|
+
var _mockApi = require("../mocks/mockApi");
|
|
15
|
+
|
|
16
|
+
var _ImageEditor = require("../../RetailerProductEdition/stories/ImageEditor.stories");
|
|
17
|
+
|
|
18
|
+
var _Auditor = require("../../RetailerProductEdition/stories/Auditor.stories");
|
|
19
|
+
|
|
20
|
+
var _TextEditor = require("../../RetailerProductEdition/stories/TextEditor.stories");
|
|
21
|
+
|
|
22
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
Historias contra la API real de dev, con los MISMOS datos que las de
|
|
26
|
+
RetailerProductEdition (se importan de allá para no duplicar el token ni el
|
|
27
|
+
producto). Sirven para comparar las dos vistas lado a lado con datos reales.
|
|
28
|
+
|
|
29
|
+
Dependen de que el token siga sirviendo y el producto exista en dev: si una
|
|
30
|
+
falla al cargar, revisar primero eso. Las historias con datos locales, que no
|
|
31
|
+
dependen de nada, están en `CreatorsProductEdition.stories.js`.
|
|
32
|
+
*/
|
|
33
|
+
var _default = {
|
|
34
|
+
title: "Components/pages/CreatorsProductEdition/API real",
|
|
35
|
+
component: _index.CreatorsProductEdition,
|
|
36
|
+
// Por si se llega desde una historia con datos locales: la API real.
|
|
37
|
+
decorators: [_mockApi.withRealApi]
|
|
38
|
+
};
|
|
39
|
+
exports.default = _default;
|
|
40
|
+
|
|
41
|
+
var Template = function Template(args) {
|
|
42
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.CreatorsProductEdition, (0, _objectSpread2.default)({}, args));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
var Imagenes = Template.bind({});
|
|
46
|
+
exports.Imagenes = Imagenes;
|
|
47
|
+
Imagenes.args = (0, _objectSpread2.default)({}, _ImageEditor.ImageEditor.args);
|
|
48
|
+
var ImagenesTablet = Template.bind({});
|
|
49
|
+
exports.ImagenesTablet = ImagenesTablet;
|
|
50
|
+
ImagenesTablet.args = (0, _objectSpread2.default)({}, _ImageEditor.ImageEditor.args);
|
|
51
|
+
ImagenesTablet.parameters = {
|
|
52
|
+
viewport: {
|
|
53
|
+
defaultViewport: "tablet"
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var ImagenesCelular = Template.bind({});
|
|
57
|
+
exports.ImagenesCelular = ImagenesCelular;
|
|
58
|
+
ImagenesCelular.args = (0, _objectSpread2.default)({}, _ImageEditor.ImageEditor.args);
|
|
59
|
+
ImagenesCelular.parameters = {
|
|
60
|
+
viewport: {
|
|
61
|
+
defaultViewport: "mobile2"
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var AuditorQA = Template.bind({});
|
|
65
|
+
exports.AuditorQA = AuditorQA;
|
|
66
|
+
AuditorQA.args = (0, _objectSpread2.default)({}, _Auditor.Auditor.args); // El usuario de textos (rol 7) con el producto de la historia de imágenes: el
|
|
67
|
+
// de TextEditor (150504) no existe en dev y la pantalla no puede cargar.
|
|
68
|
+
|
|
69
|
+
var Textos = Template.bind({});
|
|
70
|
+
exports.Textos = Textos;
|
|
71
|
+
Textos.args = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, _TextEditor.TextEditor.args), {}, {
|
|
72
|
+
token: _ImageEditor.ImageEditor.args.token,
|
|
73
|
+
productSelected: _ImageEditor.ImageEditor.args.productSelected
|
|
74
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
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 = exports.BREAKPOINTS = 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
|
+
Estilos de la edición de producto de Creators.
|
|
20
|
+
|
|
21
|
+
Parte de `RetailerProductEdition/styles.js` (mismo diseño) y agrega lo que la
|
|
22
|
+
hace responsiva. Tres tamaños, los mismos que usa MUI por omisión:
|
|
23
|
+
|
|
24
|
+
- celular (< 600px): una columna, un solo scroll para toda la pantalla.
|
|
25
|
+
- tablet (600-899px): igual, con más aire.
|
|
26
|
+
- desktop (>= 900px): las dos columnas de siempre, cada una con su scroll.
|
|
27
|
+
|
|
28
|
+
Varios hijos (ImagePreviewer, ImageDataTable, InputGroup...) traen anchos fijos
|
|
29
|
+
y la regla es no tocarlos. Donde estorban se ajustan DESDE AQUÍ, con selectores
|
|
30
|
+
acotados a esta página. Las fases siguientes los van reemplazando por MUI y
|
|
31
|
+
estos ajustes desaparecen con ellos.
|
|
32
|
+
*/
|
|
33
|
+
var BREAKPOINTS = {
|
|
34
|
+
tablet: 600,
|
|
35
|
+
desktop: 900
|
|
36
|
+
};
|
|
37
|
+
exports.BREAKPOINTS = BREAKPOINTS;
|
|
38
|
+
var mobile = "@media (max-width: ".concat(BREAKPOINTS.tablet - 1, "px)");
|
|
39
|
+
var belowDesktop = "@media (max-width: ".concat(BREAKPOINTS.desktop - 1, "px)");
|
|
40
|
+
|
|
41
|
+
var Container = _styledComponents.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n flex-direction: column;\n height: 100%;\n flex: 1;\n min-width: 0;\n overflow: auto;\n box-sizing: border-box;\n\n /* El scroll lo lleva SIEMPRE este contenedor, como en la vista original: en\n la app la pantalla vive dentro de un layout de altura fija, y si se dejara\n al documento, en celular no habr\xEDa nada que desplazar. */\n ", " {\n overflow-x: hidden;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n /* Sin overscroll-behavior: contain. Al llegar al final, el scroll tiene\n que poder pasar al contenedor de afuera (el lienzo de Storybook, o la\n p\xE1gina si la app la mete en algo que se desplaza); con contain se queda\n atorado y no hay forma de ver lo que est\xE1 debajo. */\n }\n\n .data-container {\n display: flex;\n flex: 0%;\n gap: 16px;\n min-width: 0;\n height: calc(100% - ", "px);\n padding: 0 12px 12px;\n box-sizing: border-box;\n\n ", " {\n flex-direction: column;\n flex: none;\n height: auto;\n }\n\n ", " {\n padding: 0 8px 12px;\n gap: 12px;\n }\n\n .image-data-panel {\n flex: 0 0 clamp(280px, 30%, 360px);\n min-width: 0;\n\n ", " {\n flex: 0 0 auto;\n width: 100%;\n }\n\n ", " {\n max-width: 480px;\n align-self: center;\n }\n }\n\n .product-information {\n flex: 1;\n min-width: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n\n ", " {\n height: auto;\n }\n\n /* Cabecera, pesta\xF1as y grupos de inputs: que puedan encogerse en vez de\n empujar la p\xE1gina hacia los lados. */\n & > * {\n min-width: 0;\n max-width: 100%;\n }\n\n .services-information-container {\n height: 100%;\n min-width: 0;\n overflow: auto;\n\n ", " {\n height: auto;\n overflow: visible;\n }\n }\n\n }\n }\n\n #modal-message-box {\n width: min(400px, 80vw);\n height: 100px;\n }\n"])), belowDesktop, function (_ref) {
|
|
42
|
+
var headerTop = _ref.headerTop;
|
|
43
|
+
return headerTop;
|
|
44
|
+
}, belowDesktop, mobile, belowDesktop, mobile, belowDesktop, belowDesktop);
|
|
45
|
+
|
|
46
|
+
exports.Container = Container;
|
|
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.warnAssetFile = exports.validateAssetFile = exports.validateAssetDuration = exports.suggestAssetType = exports.resolvePreviewKind = exports.humanizeDuration = exports.getExtension = exports.getAssetType = exports.formatDuration = exports.formatBytes = exports.buildDropzoneAccept = exports.assetTypeOptions = exports.acceptedMimes = exports.acceptedFormatsLabel = exports.acceptedExtensions = exports.VIDEO_DURATION_SECONDS = exports.PLAYABLE_VIDEO_EXTENSIONS = exports.MAX_ASSETS_PER_PRODUCT = exports.IMAGE_EXTENSIONS = exports.ASSET_TYPE_ORDER = exports.ASSET_TYPES = exports.ASSET_PREVIEW = void 0;
|
|
8
|
+
exports.warnUnreadableVideo = exports.warnAssetFile = exports.validateAssetFile = exports.validateAssetDuration = exports.suggestAssetType = exports.resolvePreviewKind = exports.humanizeDuration = exports.getExtension = exports.getAssetType = exports.formatDuration = exports.formatBytes = exports.buildDropzoneAccept = exports.assetTypeOptions = exports.acceptedMimes = exports.acceptedFormatsLabel = exports.acceptedExtensions = exports.VIDEO_DURATION_SECONDS = exports.PLAYABLE_VIDEO_EXTENSIONS = exports.MAX_ASSETS_PER_PRODUCT = exports.IMAGE_EXTENSIONS = exports.ASSET_TYPE_ORDER = exports.ASSET_TYPES = exports.ASSET_PREVIEW = void 0;
|
|
9
9
|
|
|
10
10
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/toConsumableArray"));
|
|
11
11
|
|
|
@@ -68,6 +68,22 @@ var VIDEO_DURATION_SECONDS = {
|
|
|
68
68
|
};
|
|
69
69
|
exports.VIDEO_DURATION_SECONDS = VIDEO_DURATION_SECONDS;
|
|
70
70
|
var ASSET_TYPES = {
|
|
71
|
+
/*
|
|
72
|
+
Imágenes sueltas: fotos de ambientación, lifestyle, material de campaña.
|
|
73
|
+
No sustituyen a la galería de la pestaña Imágenes, que valida tomas
|
|
74
|
+
contra `image_manager`; aquí no cuentan para el avance ni tienen orden.
|
|
75
|
+
El gif tiene su propio tipo y el svg vive en "editable": se sirve como
|
|
76
|
+
descarga porque un svg abierto en el navegador ejecuta scripts.
|
|
77
|
+
*/
|
|
78
|
+
imagen: {
|
|
79
|
+
id: "imagen",
|
|
80
|
+
label: "Imagen",
|
|
81
|
+
description: "Foto o imagen suelta (ambientación, lifestyle, campaña)",
|
|
82
|
+
mimes: ["image/jpeg", "image/png", "image/webp", "image/bmp", "image/avif", "image/tiff"],
|
|
83
|
+
extensions: ["jpg", "jpeg", "png", "webp", "bmp", "avif", "tif", "tiff"],
|
|
84
|
+
maxBytes: 50 * MB,
|
|
85
|
+
validatesDuration: false
|
|
86
|
+
},
|
|
71
87
|
360: {
|
|
72
88
|
id: "360",
|
|
73
89
|
label: "360",
|
|
@@ -158,7 +174,7 @@ var ASSET_TYPES = {
|
|
|
158
174
|
/** Orden en que se muestran en el selector de tipo. */
|
|
159
175
|
|
|
160
176
|
exports.ASSET_TYPES = ASSET_TYPES;
|
|
161
|
-
var ASSET_TYPE_ORDER = ["360", "video", "gif", "documento", "hoja_calculo", "editable", "comprimido", "otro"];
|
|
177
|
+
var ASSET_TYPE_ORDER = ["imagen", "360", "video", "gif", "documento", "hoja_calculo", "editable", "comprimido", "otro"];
|
|
162
178
|
/** Opciones listas para el componente `Select` (espera `{ value, name }`). */
|
|
163
179
|
|
|
164
180
|
exports.ASSET_TYPE_ORDER = ASSET_TYPE_ORDER;
|
|
@@ -384,15 +400,9 @@ var validateAssetFile = function validateAssetFile(file) {
|
|
|
384
400
|
code: "NO_FILE",
|
|
385
401
|
message: "No se recibió ningún archivo."
|
|
386
402
|
};
|
|
387
|
-
}
|
|
403
|
+
} // El cupo se revisa al final: un archivo que no se puede subir de todos modos
|
|
404
|
+
// (formato o peso) debe decir ESA razón, no "ya no hay lugar".
|
|
388
405
|
|
|
389
|
-
if (currentCount >= MAX_ASSETS_PER_PRODUCT) {
|
|
390
|
-
return {
|
|
391
|
-
valid: false,
|
|
392
|
-
code: "MAX_ASSETS",
|
|
393
|
-
message: "Solo puedes almacenar ".concat(MAX_ASSETS_PER_PRODUCT, " activos digitales por producto.")
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
406
|
|
|
397
407
|
var assetTypeId = suggestAssetType({
|
|
398
408
|
mime: file.type,
|
|
@@ -416,6 +426,14 @@ var validateAssetFile = function validateAssetFile(file) {
|
|
|
416
426
|
};
|
|
417
427
|
}
|
|
418
428
|
|
|
429
|
+
if (currentCount >= MAX_ASSETS_PER_PRODUCT) {
|
|
430
|
+
return {
|
|
431
|
+
valid: false,
|
|
432
|
+
code: "MAX_ASSETS",
|
|
433
|
+
message: "\"".concat(file.name, "\" no se agreg\xF3: solo puedes almacenar ").concat(MAX_ASSETS_PER_PRODUCT, " activos digitales por producto.")
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
419
437
|
return {
|
|
420
438
|
valid: true,
|
|
421
439
|
assetType: assetTypeId,
|
|
@@ -443,20 +461,39 @@ var warnAssetFile = function warnAssetFile(file, assetTypeId) {
|
|
|
443
461
|
if (PLAYABLE_VIDEO_EXTENSIONS.includes(ext)) return null;
|
|
444
462
|
return "\"".concat(file === null || file === void 0 ? void 0 : file.name, "\" se guardar\xE1 y se podr\xE1 descargar, pero el navegador no puede reproducir los .").concat(ext, ". Convi\xE9rtelo a MP4 si necesitas verlo aqu\xED.");
|
|
445
463
|
};
|
|
464
|
+
/**
|
|
465
|
+
* Aviso para un video cuya duración el navegador no pudo leer (códec que no
|
|
466
|
+
* conoce, archivo dañado). No se rechaza: sirve igual para entregarlo, solo que
|
|
467
|
+
* aquí no se podrá ver ni se sabe cuánto dura.
|
|
468
|
+
*/
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
exports.warnAssetFile = warnAssetFile;
|
|
472
|
+
|
|
473
|
+
var warnUnreadableVideo = function warnUnreadableVideo(fileName) {
|
|
474
|
+
return "\"".concat(fileName, "\" se guardar\xE1 y se podr\xE1 descargar, pero el navegador no pudo leerlo: no se podr\xE1 reproducir aqu\xED ni se valid\xF3 su duraci\xF3n.");
|
|
475
|
+
};
|
|
446
476
|
/**
|
|
447
477
|
* Valida la duración de un video. Va aparte de `validateAssetFile` porque
|
|
448
478
|
* obtenerla es asíncrono (hay que cargar el archivo en un <video>) y no se
|
|
449
479
|
* quiere pagar ese costo en archivos que ya fueron rechazados por peso.
|
|
480
|
+
*
|
|
481
|
+
* `seconds` en null significa "no se pudo medir" y no se rechaza: `Number(null)`
|
|
482
|
+
* es 0 y, sin esta guarda, todo video ilegible salía como "dura menos de 10 s".
|
|
450
483
|
*/
|
|
451
484
|
|
|
452
485
|
|
|
453
|
-
exports.
|
|
486
|
+
exports.warnUnreadableVideo = warnUnreadableVideo;
|
|
454
487
|
|
|
455
488
|
var validateAssetDuration = function validateAssetDuration(seconds, assetTypeId) {
|
|
489
|
+
var fileName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "El video";
|
|
456
490
|
var assetType = getAssetType(assetTypeId);
|
|
457
491
|
if (!assetType.validatesDuration) return {
|
|
458
492
|
valid: true
|
|
459
493
|
};
|
|
494
|
+
if (seconds === null || seconds === undefined) return {
|
|
495
|
+
valid: true
|
|
496
|
+
};
|
|
460
497
|
var value = Number(seconds);
|
|
461
498
|
if (!Number.isFinite(value)) return {
|
|
462
499
|
valid: true
|
|
@@ -468,7 +505,7 @@ var validateAssetDuration = function validateAssetDuration(seconds, assetTypeId)
|
|
|
468
505
|
return {
|
|
469
506
|
valid: false,
|
|
470
507
|
code: "DURATION",
|
|
471
|
-
message: "
|
|
508
|
+
message: "\"".concat(fileName, "\" dura ").concat(humanizeDuration(value), "; los videos deben durar entre ").concat(humanizeDuration(min), " y ").concat(humanizeDuration(max), ".")
|
|
472
509
|
};
|
|
473
510
|
}
|
|
474
511
|
|
|
@@ -47,16 +47,17 @@ var _assets = require("./assets.adapter");
|
|
|
47
47
|
*/
|
|
48
48
|
var requestPresign = /*#__PURE__*/function () {
|
|
49
49
|
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
|
|
50
|
-
var _data$body, _body$uploads, _body$rejected;
|
|
50
|
+
var _data, _data$body, _data2, _data3, _body$uploads, _body$rejected;
|
|
51
51
|
|
|
52
|
-
var articleId, assets, token, _yield$axios$post,
|
|
52
|
+
var articleId, assets, token, data, _yield$axios$post, body;
|
|
53
53
|
|
|
54
54
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
55
55
|
while (1) {
|
|
56
56
|
switch (_context.prev = _context.next) {
|
|
57
57
|
case 0:
|
|
58
58
|
articleId = _ref.articleId, assets = _ref.assets, token = _ref.token;
|
|
59
|
-
_context.
|
|
59
|
+
_context.prev = 1;
|
|
60
|
+
_context.next = 4;
|
|
60
61
|
return _axios.default.post(process.env.REACT_APP_ASSETS_PRESIGN_ENDPOINT, {
|
|
61
62
|
articleId: articleId,
|
|
62
63
|
files: assets.map(function (asset) {
|
|
@@ -73,32 +74,44 @@ var requestPresign = /*#__PURE__*/function () {
|
|
|
73
74
|
}
|
|
74
75
|
});
|
|
75
76
|
|
|
76
|
-
case
|
|
77
|
+
case 4:
|
|
77
78
|
_yield$axios$post = _context.sent;
|
|
78
79
|
data = _yield$axios$post.data;
|
|
80
|
+
_context.next = 12;
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
case 8:
|
|
84
|
+
_context.prev = 8;
|
|
85
|
+
_context.t0 = _context["catch"](1);
|
|
86
|
+
// "Network Error" o "Request failed with status code 502" no le dicen nada
|
|
87
|
+
// al usuario. El detalle queda en la consola para quien lo diagnostique.
|
|
88
|
+
console.error("Activos digitales: falló la firma de la subida", _context.t0);
|
|
89
|
+
throw new Error("No se pudo preparar la subida. Revisa tu conexión e inténtalo de nuevo.");
|
|
90
|
+
|
|
91
|
+
case 12:
|
|
79
92
|
// `integration: lambda` de API Gateway devuelve el objeto del handler tal
|
|
80
93
|
// cual, con el cuerpo como cadena, en vez de traducirlo a una respuesta HTTP.
|
|
81
|
-
body = typeof (data === null ||
|
|
94
|
+
body = typeof ((_data = data) === null || _data === void 0 ? void 0 : _data.body) === "string" ? JSON.parse(data.body) : (_data$body = (_data2 = data) === null || _data2 === void 0 ? void 0 : _data2.body) !== null && _data$body !== void 0 ? _data$body : data;
|
|
82
95
|
|
|
83
|
-
if (!(data !== null &&
|
|
84
|
-
_context.next =
|
|
96
|
+
if (!((_data3 = data) !== null && _data3 !== void 0 && _data3.statusCode && data.statusCode >= 400)) {
|
|
97
|
+
_context.next = 15;
|
|
85
98
|
break;
|
|
86
99
|
}
|
|
87
100
|
|
|
88
101
|
throw new Error((body === null || body === void 0 ? void 0 : body.message) || "No se pudo preparar la subida");
|
|
89
102
|
|
|
90
|
-
case
|
|
103
|
+
case 15:
|
|
91
104
|
return _context.abrupt("return", {
|
|
92
105
|
uploads: (_body$uploads = body === null || body === void 0 ? void 0 : body.uploads) !== null && _body$uploads !== void 0 ? _body$uploads : [],
|
|
93
106
|
rejected: (_body$rejected = body === null || body === void 0 ? void 0 : body.rejected) !== null && _body$rejected !== void 0 ? _body$rejected : []
|
|
94
107
|
});
|
|
95
108
|
|
|
96
|
-
case
|
|
109
|
+
case 16:
|
|
97
110
|
case "end":
|
|
98
111
|
return _context.stop();
|
|
99
112
|
}
|
|
100
113
|
}
|
|
101
|
-
}, _callee);
|
|
114
|
+
}, _callee, null, [[1, 8]]);
|
|
102
115
|
}));
|
|
103
116
|
|
|
104
117
|
return function requestPresign(_x) {
|
|
@@ -157,15 +170,25 @@ var uploadToS3 = function uploadToS3(_ref3) {
|
|
|
157
170
|
*/
|
|
158
171
|
|
|
159
172
|
|
|
160
|
-
var code = (_$exec = /<Code>(.*?)<\/Code>/.exec(xhr.responseText)) === null || _$exec === void 0 ? void 0 : _$exec[1];
|
|
161
|
-
|
|
173
|
+
var code = (_$exec = /<Code>(.*?)<\/Code>/.exec(xhr.responseText)) === null || _$exec === void 0 ? void 0 : _$exec[1]; // El código técnico va a la consola; al usuario, algo que pueda hacer.
|
|
174
|
+
|
|
175
|
+
console.error("Activos digitales: S3 rechazó la subida", code || xhr.status, xhr.responseText);
|
|
176
|
+
|
|
177
|
+
if (code === "EntityTooLarge") {
|
|
178
|
+
reject(new Error("El archivo supera el tamaño permitido."));
|
|
179
|
+
} else if (code === "AccessDenied") {
|
|
180
|
+
reject(new Error("No se pudo subir el archivo. Avisa a soporte (permiso de almacenamiento)."));
|
|
181
|
+
} else {
|
|
182
|
+
reject(new Error("No se pudo subir el archivo (".concat(code || xhr.status, "). Int\xE9ntalo de nuevo; si sigue fallando, avisa a soporte.")));
|
|
183
|
+
}
|
|
162
184
|
};
|
|
163
185
|
|
|
164
186
|
xhr.onerror = function () {
|
|
165
|
-
|
|
166
|
-
// permitir POST desde el origen de la aplicación
|
|
167
|
-
//
|
|
168
|
-
"
|
|
187
|
+
// Un fallo de red sin estatus casi siempre es CORS (el bucket tiene que
|
|
188
|
+
// permitir POST desde el origen de la aplicación) o una conexión caída. El
|
|
189
|
+
// navegador corta la petición y no deja rastro en ningún log del servidor.
|
|
190
|
+
console.error("Activos digitales: no hubo respuesta de S3 (red o CORS del bucket)");
|
|
191
|
+
reject(new Error("No se pudo conectar para subir el archivo. Revisa tu conexión e inténtalo de nuevo."));
|
|
169
192
|
};
|
|
170
193
|
|
|
171
194
|
xhr.onabort = function () {
|