contentoh-components-library 21.6.46 → 21.6.49

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.
@@ -11,6 +11,8 @@ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"))
11
11
 
12
12
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectSpread2"));
13
13
 
14
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/toConsumableArray"));
15
+
14
16
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/asyncToGenerator"));
15
17
 
16
18
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
@@ -34,9 +36,18 @@ var _jsxRuntime = require("react/jsx-runtime");
34
36
  un código en `article.variant_group` y ya. Por eso el modal no pregunta qué
35
37
  heredar: no hay nada que heredar.
36
38
 
37
- Dos formas de agrupar, y son la misma operación por debajo:
38
- - elegir un grupo que ya existe
39
- - teclear un código nuevo, que crea el grupo con este producto dentro
39
+ El modal tiene dos pasos y el segundo depende del primero:
40
+
41
+ 1. QUÉ GRUPO. Se elige uno de los que ya existen, o se crea uno nuevo. El
42
+ campo para crearlo está escondido detrás de un botón a propósito: abrirlo
43
+ de entrada le contesta al usuario una pregunta que todavía no se ha
44
+ hecho —si quiere buscar o crear— y empuja a teclear un código que
45
+ probablemente ya existe.
46
+
47
+ 2. QUÉ PRODUCTOS. Aparece solo cuando ya hay un grupo. Permite sumar varios
48
+ de una vez sin salir de aquí; antes había que volver a la tabla, entrar a
49
+ cada producto y repetir el trámite, que para un grupo de cinco eran cinco
50
+ vueltas completas.
40
51
 
41
52
  No hay tabla de grupos: un grupo existe mientras algún producto use su código.
42
53
  Eso hace que una errata no falle, solo cree un grupo de un miembro — de ahí que
@@ -95,7 +106,39 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
95
106
  var _useState13 = (0, _react.useState)(""),
96
107
  _useState14 = (0, _slicedToArray2.default)(_useState13, 2),
97
108
  nuevo = _useState14[0],
98
- setNuevo = _useState14[1];
109
+ setNuevo = _useState14[1]; // El creador arranca cerrado: que esté abierto ya es una sugerencia de crear.
110
+
111
+
112
+ var _useState15 = (0, _react.useState)(false),
113
+ _useState16 = (0, _slicedToArray2.default)(_useState15, 2),
114
+ creando = _useState16[0],
115
+ setCreando = _useState16[1]; // Paso 2: productos que se van a sumar junto con el de origen.
116
+
117
+
118
+ var _useState17 = (0, _react.useState)(""),
119
+ _useState18 = (0, _slicedToArray2.default)(_useState17, 2),
120
+ busquedaProd = _useState18[0],
121
+ setBusquedaProd = _useState18[1];
122
+
123
+ var _useState19 = (0, _react.useState)([]),
124
+ _useState20 = (0, _slicedToArray2.default)(_useState19, 2),
125
+ candidatos = _useState20[0],
126
+ setCandidatos = _useState20[1];
127
+
128
+ var _useState21 = (0, _react.useState)(0),
129
+ _useState22 = (0, _slicedToArray2.default)(_useState21, 2),
130
+ totalCandidatos = _useState22[0],
131
+ setTotalCandidatos = _useState22[1];
132
+
133
+ var _useState23 = (0, _react.useState)(false),
134
+ _useState24 = (0, _slicedToArray2.default)(_useState23, 2),
135
+ cargandoProd = _useState24[0],
136
+ setCargandoProd = _useState24[1];
137
+
138
+ var _useState25 = (0, _react.useState)([]),
139
+ _useState26 = (0, _slicedToArray2.default)(_useState25, 2),
140
+ elegidos = _useState26[0],
141
+ setElegidos = _useState26[1];
99
142
 
100
143
  var request = (0, _react.useCallback)( /*#__PURE__*/function () {
101
144
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(action, body) {
@@ -127,6 +170,11 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
127
170
  return _ref2.apply(this, arguments);
128
171
  };
129
172
  }(), [endpoint, token]);
173
+
174
+ var mensajeDe = function mensajeDe(err, porDefecto) {
175
+ return err instanceof _api.ApiError || (err === null || err === void 0 ? void 0 : err.name) === "ApiError" ? err.message : porDefecto;
176
+ };
177
+
130
178
  var buscar = (0, _react.useCallback)( /*#__PURE__*/function () {
131
179
  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(texto) {
132
180
  var _data$groups, data;
@@ -153,7 +201,7 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
153
201
  case 9:
154
202
  _context2.prev = 9;
155
203
  _context2.t0 = _context2["catch"](2);
156
- setError(_context2.t0 instanceof _api.ApiError || (_context2.t0 === null || _context2.t0 === void 0 ? void 0 : _context2.t0.name) === "ApiError" ? _context2.t0.message : "No se pudieron cargar los grupos.");
204
+ setError(mensajeDe(_context2.t0, "No se pudieron cargar los grupos."));
157
205
 
158
206
  case 12:
159
207
  _context2.prev = 12;
@@ -191,68 +239,161 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
191
239
  var codigoNuevo = normalizar(nuevo);
192
240
  var codigoFinal = selected !== null && selected !== void 0 ? selected : codigoNuevo;
193
241
  var esNuevo = !selected && !!codigoNuevo;
194
- var yaEstaba = codigoFinal && codigoFinal === currentGroup;
242
+ var yaEstaba = !!codigoFinal && codigoFinal === currentGroup;
243
+ var buscarProductos = (0, _react.useCallback)( /*#__PURE__*/function () {
244
+ var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(texto) {
245
+ var _data$candidates, _data$total, data;
246
+
247
+ return _regenerator.default.wrap(function _callee3$(_context3) {
248
+ while (1) {
249
+ switch (_context3.prev = _context3.next) {
250
+ case 0:
251
+ setCargandoProd(true);
252
+ setError(null);
253
+ _context3.prev = 2;
254
+ _context3.next = 5;
255
+ return request("group-candidates", {
256
+ articleId: articleId,
257
+ code: codigoFinal || "",
258
+ query: texto !== null && texto !== void 0 ? texto : ""
259
+ });
260
+
261
+ case 5:
262
+ data = _context3.sent;
263
+ setCandidatos((_data$candidates = data.candidates) !== null && _data$candidates !== void 0 ? _data$candidates : []);
264
+ setTotalCandidatos(Number((_data$total = data.total) !== null && _data$total !== void 0 ? _data$total : 0));
265
+ _context3.next = 13;
266
+ break;
267
+
268
+ case 10:
269
+ _context3.prev = 10;
270
+ _context3.t0 = _context3["catch"](2);
271
+ setError(mensajeDe(_context3.t0, "No se pudieron cargar los productos."));
272
+
273
+ case 13:
274
+ _context3.prev = 13;
275
+ setCargandoProd(false);
276
+ return _context3.finish(13);
277
+
278
+ case 16:
279
+ case "end":
280
+ return _context3.stop();
281
+ }
282
+ }
283
+ }, _callee3, null, [[2, 10, 13, 16]]);
284
+ }));
285
+
286
+ return function (_x4) {
287
+ return _ref4.apply(this, arguments);
288
+ };
289
+ }(), [request, articleId, codigoFinal]);
290
+ /*
291
+ La lista se recarga cuando cambia el código porque el servidor excluye a los
292
+ que ya están dentro: con otro grupo, el conjunto de candidatos es otro. Se
293
+ espera un momento porque el código nuevo se teclea letra por letra y sin la
294
+ pausa saldría una consulta por pulsación.
295
+ */
296
+
297
+ (0, _react.useEffect)(function () {
298
+ if (!codigoFinal) {
299
+ setCandidatos([]);
300
+ setTotalCandidatos(0);
301
+ return undefined;
302
+ }
303
+
304
+ var t = setTimeout(function () {
305
+ return buscarProductos(busquedaProd);
306
+ }, 300);
307
+ return function () {
308
+ return clearTimeout(t);
309
+ }; // eslint-disable-next-line react-hooks/exhaustive-deps
310
+ }, [codigoFinal]);
311
+
312
+ var alternar = function alternar(id) {
313
+ return setElegidos(function (previos) {
314
+ return previos.includes(id) ? previos.filter(function (x) {
315
+ return x !== id;
316
+ }) : [].concat((0, _toConsumableArray2.default)(previos), [id]);
317
+ });
318
+ };
195
319
 
196
320
  var guardar = /*#__PURE__*/function () {
197
- var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
321
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
198
322
  var _data$group, data;
199
323
 
200
- return _regenerator.default.wrap(function _callee3$(_context3) {
324
+ return _regenerator.default.wrap(function _callee4$(_context4) {
201
325
  while (1) {
202
- switch (_context3.prev = _context3.next) {
326
+ switch (_context4.prev = _context4.next) {
203
327
  case 0:
204
- if (!(!codigoFinal || yaEstaba)) {
205
- _context3.next = 2;
328
+ if (codigoFinal) {
329
+ _context4.next = 2;
206
330
  break;
207
331
  }
208
332
 
209
- return _context3.abrupt("return");
333
+ return _context4.abrupt("return");
210
334
 
211
335
  case 2:
336
+ if (!(yaEstaba && elegidos.length === 0)) {
337
+ _context4.next = 4;
338
+ break;
339
+ }
340
+
341
+ return _context4.abrupt("return");
342
+
343
+ case 4:
212
344
  setSaving(true);
213
345
  setError(null);
214
- _context3.prev = 4;
215
- _context3.next = 7;
346
+ _context4.prev = 6;
347
+ _context4.next = 9;
216
348
  return request("join", {
217
349
  articleId: articleId,
218
- code: codigoFinal
350
+ code: codigoFinal,
351
+ alsoArticleIds: elegidos
219
352
  });
220
353
 
221
- case 7:
222
- data = _context3.sent;
354
+ case 9:
355
+ data = _context4.sent;
223
356
  onSaved === null || onSaved === void 0 ? void 0 : onSaved((0, _objectSpread2.default)((0, _objectSpread2.default)({}, data), {}, {
224
357
  group: (_data$group = data.group) !== null && _data$group !== void 0 ? _data$group : codigoFinal
225
358
  }));
226
359
  onClose === null || onClose === void 0 ? void 0 : onClose();
227
- _context3.next = 16;
360
+ _context4.next = 18;
228
361
  break;
229
362
 
230
- case 12:
231
- _context3.prev = 12;
232
- _context3.t0 = _context3["catch"](4);
233
- setError(_context3.t0 instanceof _api.ApiError || (_context3.t0 === null || _context3.t0 === void 0 ? void 0 : _context3.t0.name) === "ApiError" ? _context3.t0.message : "No se pudo agrupar el producto. Intenta de nuevo.");
363
+ case 14:
364
+ _context4.prev = 14;
365
+ _context4.t0 = _context4["catch"](6);
366
+ setError(mensajeDe(_context4.t0, "No se pudo agrupar el producto. Intenta de nuevo."));
234
367
  setSaving(false);
235
368
 
236
- case 16:
369
+ case 18:
237
370
  case "end":
238
- return _context3.stop();
371
+ return _context4.stop();
239
372
  }
240
373
  }
241
- }, _callee3, null, [[4, 12]]);
374
+ }, _callee4, null, [[6, 14]]);
242
375
  }));
243
376
 
244
377
  return function guardar() {
245
- return _ref4.apply(this, arguments);
378
+ return _ref5.apply(this, arguments);
246
379
  };
247
- }();
380
+ }(); // Cuántos de los elegidos cambian de grupo, para avisarlo antes y no después.
381
+
382
+
383
+ var seMueven = candidatos.filter(function (c) {
384
+ return elegidos.includes(c.articleId) && c.currentGroup && c.currentGroup !== codigoFinal;
385
+ }).length;
248
386
 
249
387
  var resumen = function resumen() {
250
- if (yaEstaba) return "Este producto ya est\xE1 en \xAB".concat(codigoFinal, "\xBB.");
251
- if (esNuevo) return "Se crear\xE1 el grupo \xAB".concat(codigoNuevo, "\xBB con este producto.");
252
- if (selected) return "Se agregar\xE1 a \xAB".concat(selected, "\xBB.");
253
- return "Elige un grupo o escribe un código nuevo.";
388
+ if (!codigoFinal) return "Elige un grupo o crea uno nuevo.";
389
+ var sufijo = elegidos.length ? " y ".concat(elegidos.length, " producto").concat(elegidos.length === 1 ? "" : "s", " m\xE1s") : "";
390
+ if (yaEstaba && !elegidos.length) return "Este producto ya est\xE1 en \xAB".concat(codigoFinal, "\xBB.");
391
+ if (yaEstaba) return "Se agregar\xE1n ".concat(elegidos.length, " producto").concat(elegidos.length === 1 ? "" : "s", " a \xAB").concat(codigoFinal, "\xBB.");
392
+ if (esNuevo) return "Se crear\xE1 \xAB".concat(codigoNuevo, "\xBB con este producto").concat(sufijo, ".");
393
+ return "Se agregar\xE1 a \xAB".concat(selected, "\xBB").concat(sufijo, ".");
254
394
  };
255
395
 
396
+ var puedeGuardar = !saving && !!codigoFinal && (!yaEstaba || elegidos.length > 0);
256
397
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Overlay, {
257
398
  onClick: saving ? undefined : onClose,
258
399
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Panel, {
@@ -269,6 +410,10 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
269
410
  children: [error && /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Message, {
270
411
  className: "error",
271
412
  children: error
413
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Step, {
414
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("h3", {
415
+ children: "1 \xB7 Elige el grupo"
416
+ })
272
417
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.SearchRow, {
273
418
  onSubmit: function onSubmit(event) {
274
419
  event.preventDefault();
@@ -297,6 +442,7 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
297
442
  onChange: function onChange() {
298
443
  setSelected(grupo.code);
299
444
  setNuevo("");
445
+ setCreando(false);
300
446
  }
301
447
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
302
448
  className: "codigo",
@@ -312,17 +458,35 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
312
458
  }, grupo.code);
313
459
  })
314
460
  }), !loading && groups.length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Message, {
315
- children: query.trim() ? "Ningún grupo coincide con esa búsqueda." : "Todavía no hay grupos en esta compañía. Crea el primero abajo."
316
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.NewGroup, {
317
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("label", {
318
- htmlFor: "nuevo-grupo",
319
- children: "O crea un grupo nuevo"
461
+ children: query.trim() ? "Ningún grupo coincide con esa búsqueda." : "Todavía no hay grupos en esta compañía."
462
+ }), !creando ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.GhostButton, {
463
+ type: "button",
464
+ onClick: function onClick() {
465
+ setCreando(true);
466
+ setSelected(null);
467
+ },
468
+ children: "+ Crear un grupo nuevo"
469
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.NewGroup, {
470
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
471
+ className: "encabezado",
472
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("label", {
473
+ htmlFor: "nuevo-grupo",
474
+ children: "C\xF3digo del grupo nuevo"
475
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
476
+ type: "button",
477
+ onClick: function onClick() {
478
+ setCreando(false);
479
+ setNuevo("");
480
+ },
481
+ children: "Cancelar"
482
+ })]
320
483
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
321
484
  id: "nuevo-grupo",
322
485
  type: "text",
323
486
  value: nuevo,
324
487
  placeholder: "RELOJ-CASIO-A158",
325
488
  maxLength: 50,
489
+ autoFocus: true,
326
490
  onChange: function onChange(event) {
327
491
  setNuevo(event.target.value);
328
492
  setSelected(null);
@@ -331,6 +495,66 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
331
495
  className: "ayuda",
332
496
  children: "Letras, n\xFAmeros, guion y guion bajo. Se guarda en may\xFAsculas, as\xED que \xABabc-1\xBB y \xABABC-1\xBB son el mismo grupo."
333
497
  })]
498
+ }), !!codigoFinal && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
499
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Step, {
500
+ className: "segundo",
501
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("h3", {
502
+ children: ["2 \xB7 Agrega m\xE1s productos a \xAB", codigoFinal, "\xBB"]
503
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
504
+ children: "Opcional. Evita entrar a cada producto por separado."
505
+ })]
506
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.SearchRow, {
507
+ onSubmit: function onSubmit(event) {
508
+ event.preventDefault();
509
+ buscarProductos(busquedaProd);
510
+ },
511
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
512
+ type: "text",
513
+ value: busquedaProd,
514
+ placeholder: "Busca por UPC, SKU o nombre",
515
+ onChange: function onChange(event) {
516
+ return setBusquedaProd(event.target.value);
517
+ }
518
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
519
+ type: "submit",
520
+ disabled: cargandoProd,
521
+ children: cargandoProd ? "Buscando…" : "Buscar"
522
+ })]
523
+ }), candidatos.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Candidates, {
524
+ children: candidatos.map(function (c) {
525
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
526
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("label", {
527
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
528
+ type: "checkbox",
529
+ checked: elegidos.includes(c.articleId),
530
+ onChange: function onChange() {
531
+ return alternar(c.articleId);
532
+ }
533
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
534
+ className: "datos",
535
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
536
+ className: "nombre",
537
+ children: c.name
538
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
539
+ className: "ids",
540
+ children: [c.upc ? "UPC ".concat(c.upc) : "", c.upc && c.sku ? " · " : "", c.sku ? "SKU ".concat(c.sku) : ""]
541
+ })]
542
+ }), c.currentGroup && c.currentGroup !== codigoFinal && /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
543
+ className: "mueve",
544
+ children: ["hoy en \xAB", c.currentGroup, "\xBB"]
545
+ })]
546
+ })
547
+ }, c.articleId);
548
+ })
549
+ }), !cargandoProd && candidatos.length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.Message, {
550
+ children: busquedaProd.trim() ? "Ningún producto coincide con esa búsqueda." : "No hay otros productos que puedas agrupar aquí."
551
+ }), totalCandidatos > candidatos.length && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Message, {
552
+ className: "sutil",
553
+ children: ["Se muestran ", candidatos.length, " de ", totalCandidatos, ". Afina la b\xFAsqueda para ver el resto."]
554
+ }), seMueven > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Message, {
555
+ className: "aviso",
556
+ children: [seMueven, " de los productos elegidos ya est\xE1 en otro grupo y se mover\xE1 a \xAB", codigoFinal, "\xBB. Un producto solo puede estar en uno."]
557
+ })]
334
558
  })]
335
559
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.Footer, {
336
560
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
@@ -348,7 +572,7 @@ var VariantGroupModal = function VariantGroupModal(_ref) {
348
572
  type: "button",
349
573
  className: "primary",
350
574
  onClick: guardar,
351
- disabled: saving || !codigoFinal || yaEstaba,
575
+ disabled: !puedeGuardar,
352
576
  children: saving ? "Guardando…" : "Aceptar"
353
577
  })]
354
578
  })]
@@ -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.SearchRow = exports.Panel = exports.Overlay = exports.NewGroup = exports.Message = exports.List = exports.Header = exports.Footer = exports.Body = void 0;
8
+ exports.Step = exports.SearchRow = exports.Panel = exports.Overlay = exports.NewGroup = exports.Message = exports.List = exports.Header = exports.GhostButton = exports.Footer = exports.Candidates = exports.Body = void 0;
9
9
 
10
10
  var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/taggedTemplateLiteral"));
11
11
 
@@ -13,7 +13,7 @@ var _styledComponents = _interopRequireDefault(require("styled-components"));
13
13
 
14
14
  var _variables = require("../../../global-files/variables");
15
15
 
16
- var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9;
16
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12;
17
17
 
18
18
  var PINK = "#E13AA8";
19
19
  var PINK_RGB = "225, 58, 168";
@@ -42,14 +42,34 @@ var List = _styledComponents.default.ul(_templateObject6 || (_templateObject6 =
42
42
 
43
43
  exports.List = List;
44
44
 
45
- var NewGroup = _styledComponents.default.div(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n padding: 12px;\n border: 1px dashed rgba(", ", 0.5);\n border-radius: 6px;\n background-color: rgba(", ", 0.04);\n\n label {\n display: block;\n margin-bottom: 6px;\n font-family: ", ";\n font-size: 12px;\n color: ", ";\n }\n\n input {\n width: 100%;\n height: 36px;\n padding: 0 12px;\n border: 1px solid ", ";\n border-radius: 6px;\n font-family: inherit;\n font-size: 13px;\n text-transform: uppercase;\n color: ", ";\n }\n\n input:focus {\n outline: none;\n border-color: ", ";\n }\n\n .ayuda {\n display: block;\n margin-top: 6px;\n font-size: 11px;\n line-height: 1.4;\n color: ", ";\n }\n"])), PINK_RGB, PINK_RGB, _variables.FontFamily.Raleway_600, _variables.GlobalColors.deep_gray, _variables.GlobalColors.s2, _variables.GlobalColors.deep_gray, PINK, _variables.GlobalColors.gray);
45
+ var NewGroup = _styledComponents.default.div(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2.default)(["\n padding: 12px;\n border: 1px dashed rgba(", ", 0.5);\n border-radius: 6px;\n background-color: rgba(", ", 0.04);\n\n .encabezado {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 6px;\n }\n\n /* Salir de aqui tiene que costar lo mismo que entrar: si abrir el creador es\n un clic, cerrarlo tambien. Sin esto el usuario queda atrapado en el paso de\n crear y la unica salida visible es cerrar el modal entero. */\n .encabezado button {\n border: none;\n background: none;\n padding: 0;\n font-family: ", ";\n font-size: 11px;\n color: ", ";\n cursor: pointer;\n text-decoration: underline;\n }\n\n label {\n display: block;\n font-family: ", ";\n font-size: 12px;\n color: ", ";\n }\n\n input {\n width: 100%;\n height: 36px;\n padding: 0 12px;\n border: 1px solid ", ";\n border-radius: 6px;\n font-family: inherit;\n font-size: 13px;\n text-transform: uppercase;\n color: ", ";\n }\n\n input:focus {\n outline: none;\n border-color: ", ";\n }\n\n .ayuda {\n display: block;\n margin-top: 6px;\n font-size: 11px;\n line-height: 1.4;\n color: ", ";\n }\n"])), PINK_RGB, PINK_RGB, _variables.FontFamily.Raleway_600, _variables.GlobalColors.gray, _variables.FontFamily.Raleway_600, _variables.GlobalColors.deep_gray, _variables.GlobalColors.s2, _variables.GlobalColors.deep_gray, PINK, _variables.GlobalColors.gray);
46
46
 
47
47
  exports.NewGroup = NewGroup;
48
48
 
49
- var Message = _styledComponents.default.p(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2.default)(["\n margin: 0 0 12px;\n padding: 10px 12px;\n border-radius: 6px;\n font-size: 13px;\n line-height: 1.4;\n background-color: ", ";\n color: ", ";\n\n &.error {\n background-color: rgba(", ", 0.1);\n color: ", ";\n }\n"])), _variables.GlobalColors.s2, _variables.GlobalColors.deep_gray, PINK_RGB, PINK);
49
+ var Step = _styledComponents.default.div(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2.default)(["\n margin: 4px 0 10px;\n\n h3 {\n margin: 0;\n font-family: ", ";\n font-size: 13px;\n color: ", ";\n }\n\n p {\n margin: 2px 0 0;\n font-size: 11px;\n color: ", ";\n }\n\n /* El segundo paso aparece y desaparece segun haya grupo elegido; la linea de\n arriba es lo que evita que se lea como continuacion del bloque anterior. */\n &.segundo {\n margin-top: 18px;\n padding-top: 14px;\n border-top: 1px solid ", ";\n }\n"])), _variables.FontFamily.Raleway_700, _variables.GlobalColors.deep_gray, _variables.GlobalColors.gray, _variables.GlobalColors.s2);
50
+ /*
51
+ El boton que revela el campo de codigo nuevo.
52
+
53
+ Va deliberadamente discreto: es la salida menos frecuente —lo normal es
54
+ sumarse a un grupo que ya existe— y competir en peso con "Buscar" volveria a
55
+ empujar hacia crear, que es justo lo que se queria dejar de hacer.
56
+ */
57
+
58
+
59
+ exports.Step = Step;
60
+
61
+ var GhostButton = _styledComponents.default.button(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2.default)(["\n display: block;\n width: 100%;\n height: 36px;\n border: 1px dashed rgba(", ", 0.5);\n border-radius: 6px;\n background-color: rgba(", ", 0.04);\n font-family: ", ";\n font-size: 12px;\n color: ", ";\n cursor: pointer;\n\n &:hover {\n background-color: rgba(", ", 0.09);\n }\n"])), PINK_RGB, PINK_RGB, _variables.FontFamily.Raleway_600, PINK, PINK_RGB);
62
+
63
+ exports.GhostButton = GhostButton;
64
+
65
+ var Candidates = _styledComponents.default.ul(_templateObject10 || (_templateObject10 = (0, _taggedTemplateLiteral2.default)(["\n margin: 0 0 10px;\n padding: 0;\n list-style: none;\n border: 1px solid ", ";\n border-radius: 6px;\n /* Acotado a proposito: la lista vive dentro de un modal que ya scrollea, y sin\n tope empuja el pie fuera de la vista. */\n max-height: 210px;\n overflow-y: auto;\n\n li + li {\n border-top: 1px solid ", ";\n }\n\n label {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n cursor: pointer;\n font-size: 13px;\n color: ", ";\n }\n\n label:hover {\n background-color: ", ";\n }\n\n input[type=\"checkbox\"] {\n accent-color: ", ";\n flex-shrink: 0;\n }\n\n .datos {\n display: flex;\n flex-direction: column;\n min-width: 0;\n }\n\n .nombre {\n font-family: ", ";\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .ids {\n font-size: 11px;\n color: ", ";\n }\n\n .mueve {\n margin-left: auto;\n flex-shrink: 0;\n font-size: 11px;\n font-style: italic;\n color: ", ";\n white-space: nowrap;\n }\n"])), _variables.GlobalColors.s2, _variables.GlobalColors.s2, _variables.GlobalColors.deep_gray, _variables.GlobalColors.s1, PINK, _variables.FontFamily.Raleway_600, _variables.GlobalColors.gray, PINK);
66
+
67
+ exports.Candidates = Candidates;
68
+
69
+ var Message = _styledComponents.default.p(_templateObject11 || (_templateObject11 = (0, _taggedTemplateLiteral2.default)(["\n margin: 0 0 12px;\n padding: 10px 12px;\n border-radius: 6px;\n font-size: 13px;\n line-height: 1.4;\n background-color: ", ";\n color: ", ";\n\n &.error {\n background-color: rgba(", ", 0.1);\n color: ", ";\n }\n\n /* Informativo, no accionable: no debe competir con el contenido. */\n &.sutil {\n background: none;\n padding: 2px 0 10px;\n font-size: 11px;\n color: ", ";\n }\n\n /* Agrupar es un UPDATE, asi que sumar un producto que ya tenia grupo lo MUEVE.\n Se avisa antes de guardar, no despues. */\n &.aviso {\n background-color: rgba(", ", 0.08);\n color: ", ";\n }\n"])), _variables.GlobalColors.s2, _variables.GlobalColors.deep_gray, PINK_RGB, PINK, _variables.GlobalColors.gray, PINK_RGB, _variables.GlobalColors.deep_gray);
50
70
 
51
71
  exports.Message = Message;
52
72
 
53
- var Footer = _styledComponents.default.div(_templateObject9 || (_templateObject9 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 16px 24px;\n border-top: 1px solid ", ";\n\n .resumen {\n font-size: 12px;\n color: ", ";\n }\n\n .acciones {\n display: flex;\n gap: 10px;\n }\n\n button {\n height: 38px;\n padding: 0 16px;\n border-radius: 6px;\n cursor: pointer;\n font-family: ", ";\n font-size: 13px;\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: default;\n }\n\n .secondary {\n border: 1px solid ", ";\n background: none;\n color: ", ";\n }\n\n .primary {\n border: 1px solid ", ";\n background-color: ", ";\n color: ", ";\n }\n"])), _variables.GlobalColors.s2, _variables.GlobalColors.gray, _variables.FontFamily.Raleway_600, _variables.GlobalColors.s2, _variables.GlobalColors.deep_gray, PINK, PINK, _variables.GlobalColors.white);
73
+ var Footer = _styledComponents.default.div(_templateObject12 || (_templateObject12 = (0, _taggedTemplateLiteral2.default)(["\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 16px 24px;\n border-top: 1px solid ", ";\n\n .resumen {\n font-size: 12px;\n color: ", ";\n }\n\n .acciones {\n display: flex;\n gap: 10px;\n }\n\n button {\n height: 38px;\n padding: 0 16px;\n border-radius: 6px;\n cursor: pointer;\n font-family: ", ";\n font-size: 13px;\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: default;\n }\n\n .secondary {\n border: 1px solid ", ";\n background: none;\n color: ", ";\n }\n\n .primary {\n border: 1px solid ", ";\n background-color: ", ";\n color: ", ";\n }\n"])), _variables.GlobalColors.s2, _variables.GlobalColors.gray, _variables.FontFamily.Raleway_600, _variables.GlobalColors.s2, _variables.GlobalColors.deep_gray, PINK, PINK, _variables.GlobalColors.white);
54
74
 
55
75
  exports.Footer = Footer;
@@ -94,7 +94,7 @@ var _AiProductEdition = require("../../../contexts/AiProductEdition");
94
94
  var _jsxRuntime = require("react/jsx-runtime");
95
95
 
96
96
  var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
97
- var _location$state4, _state$product2, _state$product3, _state$product4, _state$product5, _state$product6, _state$product7, _state$product15, _family$variants2, _state$product20, _state$product21, _state$product22, _state$active_retaile4, _state$product23, _state$product24, _state$product25, _variantGroup$group, _location$state5, _location$state6, _state$active_retaile5, _state$active_retaile6, _state$images_values$2, _state$images_values10, _state$images_values11, _state$active_retaile7, _state$product26, _state$product27, _state$product28, _state$product29, _family$variants3, _family$variants4, _family$variants5, _variantGroup$members, _variantGroup$members2, _state$active_percent, _state$active_percent2, _state$active_retaile8, _state$active_retaile9, _state$active_retaile10, _state$product35, _state$descriptions_i, _state$services2, _state$services2$data, _state$product36, _state$product37, _state$datasheets_inp, _state$datasheets_inp2, _state$datasheets_inp3, _state$product38, _state$images_values12;
97
+ var _location$state4, _state$product2, _state$product3, _state$product4, _state$product5, _state$product6, _state$product7, _state$product15, _family$variants2, _variantGroup$members2, _variantGroup$group, _state$product20, _state$product21, _state$product22, _state$active_retaile4, _state$product23, _state$product24, _state$product25, _variantGroup$group2, _location$state5, _location$state6, _state$active_retaile5, _state$active_retaile6, _state$images_values$2, _state$images_values10, _state$images_values11, _state$active_retaile7, _state$product26, _state$product27, _state$product28, _state$product29, _family$variants3, _family$variants4, _family$variants5, _variantGroup$members3, _variantGroup$members4, _state$active_percent, _state$active_percent2, _state$active_retaile8, _state$active_retaile9, _state$active_retaile10, _state$product35, _state$descriptions_i, _state$services2, _state$services2$data, _state$product36, _state$product37, _state$datasheets_inp, _state$datasheets_inp2, _state$datasheets_inp3, _state$product38, _state$images_values12;
98
98
 
99
99
  var tabsSections = _ref.tabsSections,
100
100
  _ref$productSelected = _ref.productSelected,
@@ -882,15 +882,24 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
882
882
 
883
883
  case "Ficha técnica":
884
884
  {
885
- var _state$product10;
885
+ var _variantGroup$members, _state$product10;
886
886
 
887
887
  // Guardar un padre con hijos abre la decisión de propagar. Sin este
888
888
  // paso el cambio se queda solo en el padre y los hijos se van
889
889
  // separando de él sin que nadie lo note.
890
- var esPadre = ((_state$product10 = state.product) === null || _state$product10 === void 0 ? void 0 : _state$product10.variantsCount) > 0;
890
+
891
+ /*
892
+ El diálogo se abre si hay ALGÚN destino posible, no solo hijos: un
893
+ producto puede no tener hijos y aun así pertenecer a un grupo de
894
+ variantes, y ese cambio también se le puede copiar a sus compañeras.
895
+ */
896
+ var companeras = ((_variantGroup$members = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.members) !== null && _variantGroup$members !== void 0 ? _variantGroup$members : []).filter(function (m) {
897
+ return !m.isCurrent;
898
+ });
899
+ var hayDestinos = ((_state$product10 = state.product) === null || _state$product10 === void 0 ? void 0 : _state$product10.variantsCount) > 0 || companeras.length > 0;
891
900
  var cambios = cambiosDeFichaTecnica();
892
901
 
893
- if (esPadre && cambios.length > 0) {
902
+ if (hayDestinos && cambios.length > 0) {
894
903
  // Se espera a tener la familia antes de abrir: si no, el diálogo
895
904
  // aparece diciendo "0 hijos" hasta que llega la respuesta, que es
896
905
  // justo lo contrario de lo que va a preguntar.
@@ -2116,6 +2125,10 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2116
2125
  variants: ((_family$variants2 = family === null || family === void 0 ? void 0 : family.variants) !== null && _family$variants2 !== void 0 ? _family$variants2 : []).filter(function (v) {
2117
2126
  return !v.isCurrent;
2118
2127
  }),
2128
+ groupMembers: ((_variantGroup$members2 = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.members) !== null && _variantGroup$members2 !== void 0 ? _variantGroup$members2 : []).filter(function (m) {
2129
+ return !m.isCurrent;
2130
+ }),
2131
+ groupCode: (_variantGroup$group = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) !== null && _variantGroup$group !== void 0 ? _variantGroup$group : null,
2119
2132
  saving: state.saving,
2120
2133
  onCancel: function onCancel() {
2121
2134
  return setPendingPropagation(null);
@@ -2138,7 +2151,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2138
2151
  articleId: (_state$product23 = state.product) === null || _state$product23 === void 0 ? void 0 : _state$product23.id_article,
2139
2152
  articleName: (_state$product24 = state.product) === null || _state$product24 === void 0 ? void 0 : _state$product24.name,
2140
2153
  articleUpc: (_state$product25 = state.product) === null || _state$product25 === void 0 ? void 0 : _state$product25.upc,
2141
- currentGroup: (_variantGroup$group = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) !== null && _variantGroup$group !== void 0 ? _variantGroup$group : null,
2154
+ currentGroup: (_variantGroup$group2 = variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) !== null && _variantGroup$group2 !== void 0 ? _variantGroup$group2 : null,
2142
2155
  token: token,
2143
2156
  onClose: function onClose() {
2144
2157
  return setShowGroupModal(false);
@@ -2469,7 +2482,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2469
2482
  })]
2470
2483
  }), showGroup && (variantGroup === null || variantGroup === void 0 ? void 0 : variantGroup.group) && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
2471
2484
  className: "variants-family",
2472
- children: [((_variantGroup$members = variantGroup.members) !== null && _variantGroup$members !== void 0 ? _variantGroup$members : []).filter(function (miembro) {
2485
+ children: [((_variantGroup$members3 = variantGroup.members) !== null && _variantGroup$members3 !== void 0 ? _variantGroup$members3 : []).filter(function (miembro) {
2473
2486
  return !miembro.isCurrent;
2474
2487
  }).map(function (miembro) {
2475
2488
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
@@ -2493,7 +2506,7 @@ var ProviderProductEditionView = function ProviderProductEditionView(_ref) {
2493
2506
  })]
2494
2507
  })
2495
2508
  }, miembro.articleId);
2496
- }), ((_variantGroup$members2 = variantGroup.members) !== null && _variantGroup$members2 !== void 0 ? _variantGroup$members2 : []).filter(function (m) {
2509
+ }), ((_variantGroup$members4 = variantGroup.members) !== null && _variantGroup$members4 !== void 0 ? _variantGroup$members4 : []).filter(function (m) {
2497
2510
  return !m.isCurrent;
2498
2511
  }).length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)("p", {
2499
2512
  className: "loading",