contentoh-components-library 21.6.60 → 21.6.61

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 (76) hide show
  1. package/dist/components/organisms/ServicesNavigation/ServiceToolbar.js +210 -0
  2. package/dist/components/organisms/ServicesNavigation/ServicesNavigation.stories.js +138 -0
  3. package/dist/components/organisms/ServicesNavigation/ServicesRail.js +705 -0
  4. package/dist/components/organisms/ServicesNavigation/catalog.js +505 -0
  5. package/dist/components/organisms/ServicesNavigation/index.js +337 -0
  6. package/dist/components/organisms/ServicesNavigation/model.js +167 -0
  7. package/dist/components/organisms/ServicesNavigation/ui.js +371 -0
  8. package/dist/components/organisms/ServicesNavigation/views.js +1237 -0
  9. package/dist/components/organisms/ServicesWorkspace/AssigneePicker.js +459 -0
  10. package/dist/components/organisms/ServicesWorkspace/ServicesWorkspace.stories.js +119 -0
  11. package/dist/components/organisms/ServicesWorkspace/demo.js +137 -0
  12. package/dist/components/organisms/ServicesWorkspace/index.js +813 -0
  13. package/dist/components/organisms/ServicesWorkspace/servicesModel.js +351 -0
  14. package/dist/components/organisms/ServicesWorkspace/tooltipStyles.js +37 -0
  15. package/dist/components/pages/CreatorsProductEdition/mocks/mockApi.js +40 -0
  16. package/dist/components/pages/CreatorsProductEdition/mocks/productServices.fixtures.js +387 -0
  17. package/dist/components/pages/CreatorsProductEdition/sections/StatusChip.js +13 -4
  18. package/dist/components/pages/ProductEdition/ProductEdition.stories.js +148 -0
  19. package/dist/components/pages/ProductEdition/ProductEditionView.js +1355 -0
  20. package/dist/components/pages/ProductEdition/ServiceHeader.js +142 -0
  21. package/dist/components/pages/ProductEdition/api.js +256 -0
  22. package/dist/components/pages/ProductEdition/index.js +37 -0
  23. package/dist/components/pages/ProductEdition/permissions.js +200 -0
  24. package/dist/components/pages/ProductEdition/permissions.test.js +320 -0
  25. package/dist/components/pages/ProductEdition/sections/CatalogServicePanel.js +237 -0
  26. package/dist/components/pages/ProductEdition/sections/EditionTopBar.js +174 -0
  27. package/dist/components/pages/ProductEdition/sections/ImagePanel.js +440 -0
  28. package/dist/components/pages/ProductEdition/sections/ServiceTeam.js +275 -0
  29. package/dist/components/pages/ProductEdition/sections/ServiceTools.js +186 -0
  30. package/dist/components/pages/ProductEdition/services.js +233 -0
  31. package/dist/components/pages/ProductEdition/services.test.js +195 -0
  32. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +15 -2
  33. package/dist/components/pages/RetailerProductEdition/index.js +57 -40
  34. package/dist/components/pages/RetailerProductEdition/utils.js +6 -2
  35. package/dist/index.js +13 -0
  36. package/package.json +1 -1
  37. package/src/components/organisms/ServicesNavigation/ServiceToolbar.jsx +143 -0
  38. package/src/components/organisms/ServicesNavigation/ServicesNavigation.stories.js +101 -0
  39. package/src/components/organisms/ServicesNavigation/ServicesRail.jsx +591 -0
  40. package/src/components/organisms/ServicesNavigation/catalog.js +180 -0
  41. package/src/components/organisms/ServicesNavigation/index.jsx +232 -0
  42. package/src/components/organisms/ServicesNavigation/model.js +85 -0
  43. package/src/components/organisms/ServicesNavigation/ui.jsx +229 -0
  44. package/src/components/organisms/ServicesNavigation/views.jsx +705 -0
  45. package/src/components/organisms/ServicesWorkspace/AssigneePicker.js +348 -0
  46. package/src/components/organisms/ServicesWorkspace/ServicesWorkspace.stories.js +61 -0
  47. package/src/components/organisms/ServicesWorkspace/demo.js +58 -0
  48. package/src/components/organisms/ServicesWorkspace/index.js +556 -0
  49. package/src/components/organisms/ServicesWorkspace/servicesModel.js +203 -0
  50. package/src/components/organisms/ServicesWorkspace/tooltipStyles.js +27 -0
  51. package/src/components/pages/CreatorsProductEdition/mocks/mockApi.js +17 -0
  52. package/src/components/pages/CreatorsProductEdition/mocks/productServices.fixtures.js +175 -0
  53. package/src/components/pages/CreatorsProductEdition/sections/StatusChip.jsx +8 -4
  54. package/src/components/pages/ProductEdition/ProductEdition.stories.js +106 -0
  55. package/src/components/pages/ProductEdition/ProductEditionView.jsx +1142 -0
  56. package/src/components/pages/ProductEdition/ServiceHeader.jsx +104 -0
  57. package/src/components/pages/ProductEdition/api.js +84 -0
  58. package/src/components/pages/ProductEdition/index.js +21 -0
  59. package/src/components/pages/ProductEdition/permissions.js +128 -0
  60. package/src/components/pages/ProductEdition/permissions.test.js +249 -0
  61. package/src/components/pages/ProductEdition/sections/CatalogServicePanel.jsx +123 -0
  62. package/src/components/pages/ProductEdition/sections/EditionTopBar.jsx +134 -0
  63. package/src/components/pages/ProductEdition/sections/ImagePanel.jsx +342 -0
  64. package/src/components/pages/ProductEdition/sections/ServiceTeam.jsx +184 -0
  65. package/src/components/pages/ProductEdition/sections/ServiceTools.jsx +134 -0
  66. package/src/components/pages/ProductEdition/services.js +187 -0
  67. package/src/components/pages/ProductEdition/services.test.js +88 -0
  68. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +12 -0
  69. package/src/components/pages/RetailerProductEdition/index.js +28 -3
  70. package/src/components/pages/RetailerProductEdition/utils.js +5 -0
  71. package/src/index.js +1 -0
  72. package/.claude/settings.local.json +0 -7
  73. package/dist/ai/prompts/attribute.prompt.js +0 -28
  74. package/dist/ai/prompts/description.prompt.js +0 -33
  75. package/dist/ai/schemas/attribute.schema.js +0 -35
  76. package/dist/ai/schemas/description.schema.js +0 -27
@@ -0,0 +1,351 @@
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.pickInitialService = exports.groupServicesByStage = exports.getStatusName = exports.getStatusColor = exports.getServiceStage = exports.getRetailerStatuses = exports.getProductServices = exports.getAttention = exports.STATUS_NAMES = exports.SERVICE_STAGES = exports.EDITOR_TABS = void 0;
9
+
10
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/toConsumableArray"));
11
+
12
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectSpread2"));
13
+
14
+ /*
15
+ Modelo de servicios de un producto para la edición.
16
+
17
+ Misma lógica que la tabla de productos de Creators (ServicesCell/rowServices):
18
+ un servicio se identifica por `service_name`, se agrupa en etapas por su
19
+ estatus base y se pinta con los mismos colores, para que el usuario reconozca
20
+ lo que vio en la tabla al entrar a la edición.
21
+
22
+ Fuentes, en orden:
23
+ 1. `serviceStatuses` (listado ligero, view=summary): un elemento por servicio.
24
+ 2. Los tres estatus de siempre (datasheet/description/images_status).
25
+ 3. `demo_services`: servicios de ejemplo para revisar el diseño (ver demo.js).
26
+ */
27
+
28
+ /** Servicios que tienen editor propio en esta pantalla, y su pestaña. */
29
+ var EDITOR_TABS = {
30
+ description: "Descripción",
31
+ datasheet: "Ficha técnica",
32
+ images: "Imágenes"
33
+ };
34
+ exports.EDITOR_TABS = EDITOR_TABS;
35
+ var LEGACY = [{
36
+ service_name: "datasheet",
37
+ display_name: "Ficha técnica",
38
+ statusKey: "datasheet_status"
39
+ }, {
40
+ service_name: "description",
41
+ display_name: "Descripción",
42
+ statusKey: "description_status"
43
+ }, {
44
+ service_name: "images",
45
+ display_name: "Imágenes",
46
+ statusKey: "images_status"
47
+ }];
48
+ var NOT_REQUESTED = [undefined, null, "", "NS", "NULL", "-"];
49
+ var STATUS_NAMES = {
50
+ PA: "Por asignar",
51
+ AS: "Asignado",
52
+ R: "Recibido",
53
+ CA: "Capturando",
54
+ IE: "Información enviada",
55
+ RC: "Rechazado coordinador",
56
+ AC: "Aprobado coordinador",
57
+ RA: "Rechazado auditor",
58
+ AA: "Aprobado auditor",
59
+ RP: "Rechazado proveedor",
60
+ AP: "Aprobado proveedor",
61
+ ACA: "Aprobado cadena",
62
+ RCA: "Rechazado cadena",
63
+ SAC: "Solicitud auditoría Content-oh!",
64
+ AAC: "Aprobado auditoría Content-oh!",
65
+ RAC: "Rechazado auditoría Content-oh!",
66
+ FAP: "Finalización auditoría por proveedor",
67
+ Ex: "Exportado",
68
+ REG: "Registrado"
69
+ };
70
+ exports.STATUS_NAMES = STATUS_NAMES;
71
+
72
+ var baseStatus = function baseStatus(status) {
73
+ return String(status !== null && status !== void 0 ? status : "").split("/")[0];
74
+ };
75
+
76
+ var getStatusName = function getStatusName(status) {
77
+ var _ref, _ref2, _STATUS_NAMES$status;
78
+
79
+ return (_ref = (_ref2 = (_STATUS_NAMES$status = STATUS_NAMES[status]) !== null && _STATUS_NAMES$status !== void 0 ? _STATUS_NAMES$status : STATUS_NAMES[baseStatus(status)]) !== null && _ref2 !== void 0 ? _ref2 : status) !== null && _ref !== void 0 ? _ref : "Sin estatus";
80
+ };
81
+ /** Mismos colores que la tabla de Creators (helper.getStatusColor). */
82
+
83
+
84
+ exports.getStatusName = getStatusName;
85
+
86
+ var getStatusColor = function getStatusColor(status) {
87
+ switch (baseStatus(status)) {
88
+ case "R":
89
+ case "PA":
90
+ case "SAC":
91
+ return "#E67432";
92
+
93
+ case "ACA":
94
+ case "AC":
95
+ case "AP":
96
+ case "AA":
97
+ case "AAC":
98
+ return "#18A0FB";
99
+
100
+ case "RC":
101
+ case "RA":
102
+ case "RCA":
103
+ case "RP":
104
+ case "RAC":
105
+ return "#D74DED";
106
+
107
+ case "CA":
108
+ case "AS":
109
+ case "IE":
110
+ return "#ED9A4D";
111
+
112
+ case "Ex":
113
+ case "FAP":
114
+ return "#71DE56";
115
+
116
+ default:
117
+ return "#D4D1D7";
118
+ }
119
+ };
120
+
121
+ exports.getStatusColor = getStatusColor;
122
+ var SERVICE_STAGES = [{
123
+ stage_name: "pending",
124
+ display_name: "Por asignar",
125
+ singular: "por asignar",
126
+ plural: "por asignar",
127
+ statuses: ["R", "PA"]
128
+ }, {
129
+ stage_name: "in_progress",
130
+ display_name: "En proceso",
131
+ singular: "en proceso",
132
+ plural: "en proceso",
133
+ statuses: ["AS", "CA", "IE"]
134
+ }, {
135
+ stage_name: "rejected",
136
+ display_name: "Rechazados",
137
+ singular: "rechazado",
138
+ plural: "rechazados",
139
+ statuses: ["RC", "RA", "RP", "RCA", "RAC"]
140
+ }, {
141
+ stage_name: "review",
142
+ display_name: "En revisión y aprobación",
143
+ singular: "en revisión",
144
+ plural: "en revisión",
145
+ statuses: ["AC", "AA", "AP", "ACA", "SAC", "AAC"]
146
+ }, {
147
+ stage_name: "done",
148
+ display_name: "Terminados",
149
+ singular: "terminado",
150
+ plural: "terminados",
151
+ statuses: ["Ex", "FAP"]
152
+ }, {
153
+ stage_name: "registered",
154
+ display_name: "Registrados (solo marca)",
155
+ singular: "registrado",
156
+ plural: "registrados",
157
+ statuses: ["REG"]
158
+ }].map(function (stage) {
159
+ return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, stage), {}, {
160
+ color: stage.stage_name === "registered" ? "#CBCBCB" : getStatusColor(stage.statuses[0])
161
+ });
162
+ });
163
+ exports.SERVICE_STAGES = SERVICE_STAGES;
164
+ var STAGE_BY_NAME = Object.fromEntries(SERVICE_STAGES.map(function (stage) {
165
+ return [stage.stage_name, stage];
166
+ }));
167
+ var ATTENTION_ORDER = ["rejected", "pending", "in_progress", "review", "done", "registered"];
168
+
169
+ var getServiceStage = function getServiceStage(service) {
170
+ var _SERVICE_STAGES$find;
171
+
172
+ if (!service.has_workflow) return STAGE_BY_NAME.registered;
173
+ var base = baseStatus(service.status);
174
+ return (_SERVICE_STAGES$find = SERVICE_STAGES.find(function (stage) {
175
+ return stage.statuses.includes(base);
176
+ })) !== null && _SERVICE_STAGES$find !== void 0 ? _SERVICE_STAGES$find : STAGE_BY_NAME.in_progress;
177
+ };
178
+
179
+ exports.getServiceStage = getServiceStage;
180
+
181
+ var groupServicesByStage = function groupServicesByStage(services) {
182
+ return SERVICE_STAGES.map(function (stage) {
183
+ return {
184
+ stage: stage,
185
+ services: services.filter(function (service) {
186
+ return getServiceStage(service).stage_name === stage.stage_name;
187
+ })
188
+ };
189
+ }).filter(function (group) {
190
+ return group.services.length > 0;
191
+ });
192
+ };
193
+
194
+ exports.groupServicesByStage = groupServicesByStage;
195
+
196
+ var getAttention = function getAttention(groups) {
197
+ var workflow = groups.filter(function (group) {
198
+ return group.stage.stage_name !== "registered";
199
+ });
200
+
201
+ if (workflow.length > 0 && workflow.every(function (group) {
202
+ return group.stage.stage_name === "done";
203
+ })) {
204
+ return {
205
+ stage: STAGE_BY_NAME.done,
206
+ label: "Terminado"
207
+ };
208
+ }
209
+
210
+ var first = ATTENTION_ORDER.map(function (name) {
211
+ return groups.find(function (group) {
212
+ return group.stage.stage_name === name;
213
+ });
214
+ }).find(Boolean);
215
+ if (!first) return null;
216
+ var count = first.services.length;
217
+ return {
218
+ stage: first.stage,
219
+ label: "".concat(count, " ").concat(count === 1 ? first.stage.singular : first.stage.plural)
220
+ };
221
+ };
222
+ /** Cuál abrir primero: lo que más pide atención. */
223
+
224
+
225
+ exports.getAttention = getAttention;
226
+
227
+ var pickInitialService = function pickInitialService(services) {
228
+ var _first$services$0$ser, _first$services$;
229
+
230
+ var groups = groupServicesByStage(services);
231
+ var first = ATTENTION_ORDER.map(function (name) {
232
+ return groups.find(function (group) {
233
+ return group.stage.stage_name === name;
234
+ });
235
+ }).find(Boolean);
236
+ return (_first$services$0$ser = first === null || first === void 0 ? void 0 : (_first$services$ = first.services[0]) === null || _first$services$ === void 0 ? void 0 : _first$services$.service_name) !== null && _first$services$0$ser !== void 0 ? _first$services$0$ser : null;
237
+ };
238
+
239
+ exports.pickInitialService = pickInitialService;
240
+
241
+ var assigneesOf = function assigneesOf(product, serviceName) {
242
+ return {
243
+ especialist: (product === null || product === void 0 ? void 0 : product["id_".concat(serviceName, "_especialist")]) || null,
244
+ facilitator: (product === null || product === void 0 ? void 0 : product["id_".concat(serviceName, "_facilitator")]) || null
245
+ };
246
+ };
247
+ /**
248
+ * Servicios del producto (normalizado por la edición o con la forma del
249
+ * listado): [{ service_name, display_name, status, has_workflow,
250
+ * editor_tab, assignees: { especialist, facilitator }, is_demo }]
251
+ */
252
+
253
+
254
+ var getProductServices = function getProductServices(product) {
255
+ var _product$demo_service;
256
+
257
+ if (!product) return [];
258
+ var base;
259
+
260
+ if (Array.isArray(product.serviceStatuses) && product.serviceStatuses.length > 0) {
261
+ base = product.serviceStatuses.filter(function (service) {
262
+ return !NOT_REQUESTED.includes(service.status);
263
+ }).map(function (service) {
264
+ var _legacy$display_name;
265
+
266
+ var legacy = LEGACY.find(function (def) {
267
+ return def.service_name === service.service_name;
268
+ });
269
+ var displayName = service.display_name && service.display_name !== service.service_name ? service.display_name : (_legacy$display_name = legacy === null || legacy === void 0 ? void 0 : legacy.display_name) !== null && _legacy$display_name !== void 0 ? _legacy$display_name : service.service_name;
270
+ return {
271
+ service_name: service.service_name,
272
+ display_name: displayName,
273
+ status: service.status,
274
+ has_workflow: service.has_workflow !== false
275
+ };
276
+ });
277
+ } else {
278
+ base = LEGACY.filter(function (def) {
279
+ return !NOT_REQUESTED.includes(product[def.statusKey]);
280
+ }).map(function (def) {
281
+ return {
282
+ service_name: def.service_name,
283
+ display_name: def.display_name,
284
+ status: product[def.statusKey],
285
+ has_workflow: true
286
+ };
287
+ });
288
+ }
289
+
290
+ var demo = ((_product$demo_service = product.demo_services) !== null && _product$demo_service !== void 0 ? _product$demo_service : []).map(function (service) {
291
+ return {
292
+ service_name: service.service_name,
293
+ display_name: service.display_name,
294
+ status: service.status,
295
+ has_workflow: service.has_workflow !== false,
296
+ deliverable_type: service.deliverable_type,
297
+ is_demo: true
298
+ };
299
+ });
300
+ return [].concat((0, _toConsumableArray2.default)(base), (0, _toConsumableArray2.default)(demo)).map(function (service) {
301
+ var _EDITOR_TABS$service$;
302
+
303
+ return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, service), {}, {
304
+ editor_tab: (_EDITOR_TABS$service$ = EDITOR_TABS[service.service_name]) !== null && _EDITOR_TABS$service$ !== void 0 ? _EDITOR_TABS$service$ : null,
305
+ assignees: service.is_demo ? {} : assigneesOf(product, service.service_name)
306
+ });
307
+ });
308
+ };
309
+ /**
310
+ * Estatus del servicio en cada cadena. Sale de `statusByRetailer` (detalle del
311
+ * producto); los servicios de ejemplo lo inventan a partir del suyo.
312
+ */
313
+
314
+
315
+ exports.getProductServices = getProductServices;
316
+
317
+ var getRetailerStatuses = function getRetailerStatuses(product, service) {
318
+ var _product$statusByReta;
319
+
320
+ var retailers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
321
+
322
+ var nameOf = function nameOf(id) {
323
+ var _retailers$find$retai, _retailers$find;
324
+
325
+ return (_retailers$find$retai = (_retailers$find = retailers.find(function (retailer) {
326
+ return retailer.id_retailer === id;
327
+ })) === null || _retailers$find === void 0 ? void 0 : _retailers$find.retailer) !== null && _retailers$find$retai !== void 0 ? _retailers$find$retai : "Cadena ".concat(id);
328
+ };
329
+
330
+ if (service.is_demo) {
331
+ return retailers.map(function (retailer, index) {
332
+ return {
333
+ id_retailer: retailer.id_retailer,
334
+ retailer: retailer.retailer,
335
+ status: index === 0 ? service.status : baseStatus(service.status)
336
+ };
337
+ });
338
+ }
339
+
340
+ return ((_product$statusByReta = product === null || product === void 0 ? void 0 : product.statusByRetailer) !== null && _product$statusByReta !== void 0 ? _product$statusByReta : []).filter(function (item) {
341
+ return item.service === service.service_name;
342
+ }).map(function (item) {
343
+ return {
344
+ id_retailer: item.retailer_id,
345
+ retailer: nameOf(item.retailer_id),
346
+ status: item.status
347
+ };
348
+ });
349
+ };
350
+
351
+ exports.getRetailerStatuses = getRetailerStatuses;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.whiteTooltipProps = void 0;
7
+
8
+ /**
9
+ * Tooltip blanco con la paleta de la plataforma (en lugar del gris oscuro de
10
+ * MUI). Se pasa a <Tooltip {...whiteTooltipProps}>.
11
+ */
12
+ var whiteTooltipProps = {
13
+ componentsProps: {
14
+ tooltip: {
15
+ sx: {
16
+ backgroundColor: "#FFFFFF",
17
+ color: "#262626",
18
+ border: "1px solid #F0EEF2",
19
+ borderRadius: "10px",
20
+ boxShadow: 4,
21
+ p: 1.5,
22
+ maxWidth: 340,
23
+ fontFamily: "Lato, sans-serif",
24
+ fontSize: 12
25
+ }
26
+ },
27
+ arrow: {
28
+ sx: {
29
+ color: "#FFFFFF",
30
+ "&::before": {
31
+ border: "1px solid #F0EEF2"
32
+ }
33
+ }
34
+ }
35
+ }
36
+ };
37
+ exports.whiteTooltipProps = whiteTooltipProps;
@@ -17,6 +17,8 @@ var _axios = _interopRequireDefault(require("axios"));
17
17
 
18
18
  var _api = require("./api.fixtures");
19
19
 
20
+ var _productServices = require("./productServices.fixtures");
21
+
20
22
  var _jsxRuntime = require("react/jsx-runtime");
21
23
 
22
24
  /*
@@ -89,7 +91,20 @@ var createMockAdapter = function createMockAdapter() {
89
91
  delSolStatus: delSolStatus,
90
92
  familia: familia,
91
93
  grupo: grupo
94
+ }); // Servicios del producto (edición unificada): con estado, para que un cambio
95
+ // de estatus o de asignación se vea al volver a pedir la lista.
96
+
97
+ var productServices = (0, _productServices.buildProductServices)({
98
+ delSolStatus: delSolStatus
92
99
  });
100
+
101
+ var lambdaReply = function lambdaReply(config, statusCode, body) {
102
+ return reply(config, {
103
+ statusCode: statusCode,
104
+ body: JSON.stringify(body)
105
+ });
106
+ };
107
+
93
108
  return function (config) {
94
109
  var _fx$comments$query$co, _fx$users$query$fetch;
95
110
 
@@ -125,6 +140,31 @@ var createMockAdapter = function createMockAdapter() {
125
140
  if (path === "variants/group") return reply(config, fx.group);
126
141
  if (method === "GET" && path === "services") return reply(config, fx.services);
127
142
  if (method === "GET" && path === "versions") return reply(config, fx.versions);
143
+ if (method === "GET" && path === "product-services") return lambdaReply(config, 200, productServices);
144
+
145
+ if (method === "PUT" && path.startsWith("product-services/")) {
146
+ var action = path.split("/")[1];
147
+ var data = typeof config.data === "string" ? JSON.parse(config.data) : config.data;
148
+
149
+ var _applyProductServices = (0, _productServices.applyProductServicesChange)(productServices, action, data),
150
+ statusCode = _applyProductServices.statusCode,
151
+ message = _applyProductServices.message;
152
+
153
+ console.info("[mock API] PUT ".concat(path), data);
154
+ return lambdaReply(config, statusCode, statusCode === 200 ? {
155
+ action: action,
156
+ result: data
157
+ } : {
158
+ message: message
159
+ });
160
+ }
161
+
162
+ if (method === "GET" && path === "service-catalog" && query.view === "assignables") {
163
+ return lambdaReply(config, 200, {
164
+ users: (0, _productServices.assignablesFor)(query.assignment_role)
165
+ });
166
+ }
167
+
128
168
  if (path === "percentages") return reply(config, fx.percentages); // Sin versión auditable ni observación: con la API real de dev estas dos
129
169
  // fallan por CORS, así que la pantalla ya sabe vivir sin ellas.
130
170