@crystaldesign/diva-backoffice 26.7.0-rc.3 → 26.7.0-rc.5

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 (17) hide show
  1. package/build/esm/index.js +383 -165
  2. package/build/types/backoffice/src/ui/Table/BaseTable/cellRenderer/MediaViewerCell/index.d.ts.map +1 -1
  3. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/components/AIImageSelector/components/SortableImageRow/index.d.ts.map +1 -1
  4. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/components/AIImageSelector/index.d.ts +3 -3
  5. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/components/AIImageSelector/index.d.ts.map +1 -1
  6. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/components/ImageSelectionWorkspace/index.d.ts +4 -3
  7. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/components/ImageSelectionWorkspace/index.d.ts.map +1 -1
  8. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/hooks/useRenderJobData.d.ts +3 -1
  9. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/hooks/useRenderJobData.d.ts.map +1 -1
  10. package/build/types/backoffice/src/ui/TableRenderJobs/components/RenderApprove/index.d.ts.map +1 -1
  11. package/build/types/backoffice/src/ui/TableRenderJobs/components/UploadImageModal/index.d.ts +11 -1
  12. package/build/types/backoffice/src/ui/TableRenderJobs/components/UploadImageModal/index.d.ts.map +1 -1
  13. package/build/types/backoffice/src/ui/TableRenderJobs/hooks/useUploadRenderImage.d.ts +14 -0
  14. package/build/types/backoffice/src/ui/TableRenderJobs/hooks/useUploadRenderImage.d.ts.map +1 -0
  15. package/build/types/backoffice/src/ui/TableRenderJobs/types.d.ts +10 -3
  16. package/build/types/backoffice/src/ui/TableRenderJobs/types.d.ts.map +1 -1
  17. package/package.json +9 -9
@@ -28551,9 +28551,11 @@ function MediaViewerCell (_ref) {
28551
28551
  actions.loadModelViewer();
28552
28552
  }, []);
28553
28553
 
28554
- // The field value may be a plain url or an array of urls (e.g. renderImages);
28555
- // in the array case the first entry is shown.
28556
- var rawValue = Array.isArray(children === null || children === void 0 ? void 0 : children[1]) ? children[1][0] : children === null || children === void 0 ? void 0 : children[1];
28554
+ // The field value may be a plain url or an array (e.g. renderImages); in the
28555
+ // array case the first entry is shown. Entries may be plain urls or objects
28556
+ // carrying a `url` (e.g. renderImages: { mediaItemRefId?, url }).
28557
+ var firstEntry = Array.isArray(children === null || children === void 0 ? void 0 : children[1]) ? children[1][0] : children === null || children === void 0 ? void 0 : children[1];
28558
+ var rawValue = firstEntry && _typeof(firstEntry) === 'object' ? firstEntry.url : firstEntry;
28557
28559
  if (!rawValue) {
28558
28560
  return /*#__PURE__*/jsx(Fragment, {});
28559
28561
  }
@@ -53665,7 +53667,6 @@ var thumbPlaceholder = "thumbPlaceholder-zX1-S";
53665
53667
  var info = "info-8ZlUD";
53666
53668
  var label = "label-y-wTq";
53667
53669
  var meta = "meta-Ihuqr";
53668
- var referenceTag = "referenceTag-gyKQR";
53669
53670
  var css_248z$g = ".root-7OUrP {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border: 1px solid #d9d9d9;\n border: 1px solid var(--ant-color-border, #d9d9d9);\n border-radius: 8px;\n background: #fff;\n background: var(--ant-color-bg-container, #fff);\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n\n.root-7OUrP:active {\n cursor: grabbing;\n}\n\n.rootSelected-Z8LGb {\n border-color: #1677ff;\n border-color: var(--ant-color-primary, #1677ff);\n background: #e6f4ff;\n background: var(--ant-color-primary-bg, #e6f4ff);\n}\n\n.dragHandle-xo0vD {\n display: inline-flex;\n align-items: center;\n cursor: grab;\n color: #999;\n color: var(--ant-color-text-tertiary, #999);\n touch-action: none;\n}\n\n.dragHandle-xo0vD:active {\n cursor: grabbing;\n}\n\n.badge-7hZ6T {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 600;\n color: #fff;\n background: #1677ff;\n background: var(--ant-color-primary, #1677ff);\n}\n\n.thumb-ePFWB {\n width: 88px;\n height: 88px;\n -o-object-fit: cover;\n object-fit: cover;\n border-radius: 6px;\n flex: 0 0 auto;\n background: #f0f0f0;\n background: var(--ant-color-fill-secondary, #f0f0f0);\n cursor: pointer;\n}\n\n.thumbPlaceholder-zX1-S {\n width: 88px;\n height: 88px;\n border-radius: 6px;\n background: #f0f0f0;\n background: var(--ant-color-fill-secondary, #f0f0f0);\n flex: 0 0 auto;\n}\n\n.info-8ZlUD {\n display: flex;\n flex-direction: column;\n min-width: 0;\n flex: 1 1 auto;\n}\n\n.label-y-wTq {\n font-size: 14px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.meta-Ihuqr {\n font-size: 12px;\n color: #888;\n color: var(--ant-color-text-secondary, #888);\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.referenceTag-gyKQR {\n align-self: flex-start;\n margin-top: 4px;\n padding: 1px 8px;\n border-radius: 4px;\n font-size: 11px;\n font-weight: 500;\n color: #1677ff;\n color: var(--ant-color-primary, #1677ff);\n background: #e6f4ff;\n background: var(--ant-color-primary-bg, #e6f4ff);\n border: 1px solid #91caff;\n border: 1px solid var(--ant-color-primary-border, #91caff);\n white-space: nowrap;\n}\n";
53670
53671
  styleInject(css_248z$g);
53671
53672
 
@@ -53766,12 +53767,6 @@ function SortableImageRow(_ref) {
53766
53767
  className: meta,
53767
53768
  title: metaText,
53768
53769
  children: ["(", metaText, ")"]
53769
- }) : null, selected && typeof orderNumber === 'number' ? /*#__PURE__*/jsx("span", {
53770
- className: referenceTag,
53771
- children: t('backoffice.renderapprove.aiImageSelector.referenceTag', {
53772
- defaultValue: 'used as AI reference ({{order}})',
53773
- order: orderNumber
53774
- })
53775
53770
  }) : null]
53776
53771
  })]
53777
53772
  }))
@@ -53847,11 +53842,14 @@ function buildItems(slides, selectedUrls) {
53847
53842
  });
53848
53843
  });
53849
53844
  }
53850
- function orderedSelectedUrls(items) {
53845
+ function orderedSelectedImages(items) {
53851
53846
  return items.filter(function (it) {
53852
53847
  return it.selected && it.media.url != null;
53853
53848
  }).map(function (it) {
53854
- return it.media.url;
53849
+ return {
53850
+ mediaItemRefId: it.media.mediaItemRefId,
53851
+ url: it.media.url
53852
+ };
53855
53853
  });
53856
53854
  }
53857
53855
 
@@ -53894,7 +53892,7 @@ function AIImageSelector(_ref2) {
53894
53892
  }));
53895
53893
  var commit = function commit(next) {
53896
53894
  setItems(next);
53897
- onChange === null || onChange === void 0 || onChange(orderedSelectedUrls(next));
53895
+ onChange === null || onChange === void 0 || onChange(orderedSelectedImages(next));
53898
53896
  };
53899
53897
  var toggle = function toggle(key) {
53900
53898
  commit(items.map(function (it) {
@@ -53991,25 +53989,42 @@ function AIImageSelector(_ref2) {
53991
53989
  * approve / reject / upload, since there is nothing to decide yet.
53992
53990
  */
53993
53991
  function ImageSelectionWorkspace(_ref) {
53992
+ var _job$renderImages;
53994
53993
  var job = _ref.job,
53995
53994
  slides = _ref.slides,
53996
53995
  selectionDisabled = _ref.selectionDisabled,
53997
53996
  onSelectionChange = _ref.onSelectionChange,
53998
53997
  onOpenFullscreen = _ref.onOpenFullscreen,
53998
+ onUpload = _ref.onUpload,
53999
53999
  actionDisabled = _ref.actionDisabled,
54000
54000
  busy = _ref.busy,
54001
54001
  isFirst = _ref.isFirst,
54002
54002
  shortcutItems = _ref.shortcutItems,
54003
54003
  onPrev = _ref.onPrev,
54004
54004
  onNext = _ref.onNext;
54005
+ var _useTranslation = useTranslation(),
54006
+ t = _useTranslation.t;
54005
54007
  return /*#__PURE__*/jsxs(Fragment, {
54006
54008
  children: [/*#__PURE__*/jsx(AIImageSelector, {
54007
54009
  slides: slides,
54008
- selectedUrls: job.renderImages,
54010
+ selectedUrls: (_job$renderImages = job.renderImages) === null || _job$renderImages === void 0 ? void 0 : _job$renderImages.map(function (image) {
54011
+ return image.url;
54012
+ }),
54009
54013
  disabled: selectionDisabled,
54010
54014
  onChange: onSelectionChange,
54011
54015
  onOpenFullscreen: onOpenFullscreen
54012
- }, job._id), /*#__PURE__*/jsx(ActionBar, {
54016
+ }, job._id), onUpload && /*#__PURE__*/jsx(Button, {
54017
+ icon: /*#__PURE__*/jsx(UploadOutlined, {}),
54018
+ onClick: onUpload,
54019
+ disabled: selectionDisabled,
54020
+ style: {
54021
+ marginTop: 12
54022
+ },
54023
+ block: true,
54024
+ children: t('backoffice.renderapprove.aiImageSelector.uploadImage', {
54025
+ defaultValue: 'Bild hochladen'
54026
+ })
54027
+ }), /*#__PURE__*/jsx(ActionBar, {
54013
54028
  disabled: actionDisabled,
54014
54029
  busy: busy,
54015
54030
  isFirst: isFirst,
@@ -55347,12 +55362,14 @@ function UploadImageModal(_ref) {
55347
55362
  var open = _ref.open,
55348
55363
  renderJob = _ref.renderJob,
55349
55364
  onClose = _ref.onClose,
55350
- onSuccess = _ref.onSuccess;
55365
+ onSuccess = _ref.onSuccess,
55366
+ uploadOverride = _ref.uploadOverride,
55367
+ skipValidation = _ref.skipValidation,
55368
+ allowedExtensions = _ref.allowedExtensions;
55351
55369
  var _useTranslation = useTranslation(),
55352
55370
  t = _useTranslation.t;
55353
55371
  var _useUploadRenderJobIm = useUploadRenderJobImage(),
55354
- upload = _useUploadRenderJobIm.upload,
55355
- uploading = _useUploadRenderJobIm.uploading;
55372
+ upload = _useUploadRenderJobIm.upload;
55356
55373
  var _useState = useState(null),
55357
55374
  _useState2 = _slicedToArray(_useState, 2),
55358
55375
  selectedFile = _useState2[0],
@@ -55365,10 +55382,14 @@ function UploadImageModal(_ref) {
55365
55382
  _useState6 = _slicedToArray(_useState5, 2),
55366
55383
  validating = _useState6[0],
55367
55384
  setValidating = _useState6[1];
55368
- var _useState7 = useState(null),
55385
+ var _useState7 = useState(false),
55369
55386
  _useState8 = _slicedToArray(_useState7, 2),
55370
- uploadError = _useState8[0],
55371
- setUploadError = _useState8[1];
55387
+ uploading = _useState8[0],
55388
+ setUploading = _useState8[1];
55389
+ var _useState9 = useState(null),
55390
+ _useState10 = _slicedToArray(_useState9, 2),
55391
+ uploadError = _useState10[0],
55392
+ setUploadError = _useState10[1];
55372
55393
  var reset = function reset() {
55373
55394
  setSelectedFile(null);
55374
55395
  setWarnings([]);
@@ -55381,35 +55402,51 @@ function UploadImageModal(_ref) {
55381
55402
  };
55382
55403
  var handleFileSelect = /*#__PURE__*/function () {
55383
55404
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(file) {
55384
- var w;
55405
+ var _file$name$split$pop$, _file$name$split$pop, ext, w;
55385
55406
  return _regeneratorRuntime.wrap(function _callee$(_context) {
55386
55407
  while (1) switch (_context.prev = _context.next) {
55387
55408
  case 0:
55388
- setSelectedFile(file);
55389
55409
  setUploadError(null);
55390
55410
  setWarnings([]);
55391
- if (!renderJob) {
55392
- _context.next = 13;
55411
+ if (!(allowedExtensions && allowedExtensions.length > 0)) {
55412
+ _context.next = 8;
55413
+ break;
55414
+ }
55415
+ ext = (_file$name$split$pop$ = (_file$name$split$pop = file.name.split('.').pop()) === null || _file$name$split$pop === void 0 ? void 0 : _file$name$split$pop.toLowerCase()) !== null && _file$name$split$pop$ !== void 0 ? _file$name$split$pop$ : '';
55416
+ if (allowedExtensions.includes(ext)) {
55417
+ _context.next = 8;
55418
+ break;
55419
+ }
55420
+ setSelectedFile(null);
55421
+ setUploadError(t('backoffice.renderapprove.uploadModal.invalidImageType', {
55422
+ defaultValue: 'Nur folgende Bildformate sind erlaubt: {{formats}}',
55423
+ formats: allowedExtensions.join(', ')
55424
+ }));
55425
+ return _context.abrupt("return", false);
55426
+ case 8:
55427
+ setSelectedFile(file);
55428
+ if (!(!skipValidation && renderJob)) {
55429
+ _context.next = 19;
55393
55430
  break;
55394
55431
  }
55395
55432
  setValidating(true);
55396
- _context.prev = 5;
55397
- _context.next = 8;
55433
+ _context.prev = 11;
55434
+ _context.next = 14;
55398
55435
  return validateImageFile(file, renderJob, t);
55399
- case 8:
55436
+ case 14:
55400
55437
  w = _context.sent;
55401
55438
  setWarnings(w);
55402
- case 10:
55403
- _context.prev = 10;
55439
+ case 16:
55440
+ _context.prev = 16;
55404
55441
  setValidating(false);
55405
- return _context.finish(10);
55406
- case 13:
55442
+ return _context.finish(16);
55443
+ case 19:
55407
55444
  return _context.abrupt("return", false);
55408
- case 14:
55445
+ case 20:
55409
55446
  case "end":
55410
55447
  return _context.stop();
55411
55448
  }
55412
- }, _callee, null, [[5,, 10, 13]]);
55449
+ }, _callee, null, [[11,, 16, 19]]);
55413
55450
  }));
55414
55451
  return function handleFileSelect(_x) {
55415
55452
  return _ref2.apply(this, arguments);
@@ -55428,25 +55465,30 @@ function UploadImageModal(_ref) {
55428
55465
  return _context2.abrupt("return");
55429
55466
  case 2:
55430
55467
  setUploadError(null);
55431
- _context2.prev = 3;
55432
- _context2.next = 6;
55433
- return upload(selectedFile, renderJob);
55434
- case 6:
55468
+ setUploading(true);
55469
+ _context2.prev = 4;
55470
+ _context2.next = 7;
55471
+ return (uploadOverride !== null && uploadOverride !== void 0 ? uploadOverride : upload)(selectedFile, renderJob);
55472
+ case 7:
55435
55473
  reset();
55436
55474
  onSuccess === null || onSuccess === void 0 || onSuccess();
55437
- _context2.next = 13;
55475
+ _context2.next = 14;
55438
55476
  break;
55439
- case 10:
55440
- _context2.prev = 10;
55441
- _context2.t0 = _context2["catch"](3);
55477
+ case 11:
55478
+ _context2.prev = 11;
55479
+ _context2.t0 = _context2["catch"](4);
55442
55480
  setUploadError((_message = _context2.t0 === null || _context2.t0 === void 0 ? void 0 : _context2.t0.message) !== null && _message !== void 0 ? _message : t('backoffice.renderapprove.uploadModal.uploadFailed', {
55443
55481
  defaultValue: 'Upload fehlgeschlagen'
55444
55482
  }));
55445
- case 13:
55483
+ case 14:
55484
+ _context2.prev = 14;
55485
+ setUploading(false);
55486
+ return _context2.finish(14);
55487
+ case 17:
55446
55488
  case "end":
55447
55489
  return _context2.stop();
55448
55490
  }
55449
- }, _callee2, null, [[3, 10]]);
55491
+ }, _callee2, null, [[4, 11, 14, 17]]);
55450
55492
  }));
55451
55493
  return function handleUpload() {
55452
55494
  return _ref3.apply(this, arguments);
@@ -55474,7 +55516,9 @@ function UploadImageModal(_ref) {
55474
55516
  children: /*#__PURE__*/jsxs(Spin, {
55475
55517
  spinning: validating || uploading,
55476
55518
  children: [/*#__PURE__*/jsxs(Upload$2.Dragger, {
55477
- accept: "image/*",
55519
+ accept: allowedExtensions && allowedExtensions.length > 0 ? allowedExtensions.map(function (e) {
55520
+ return ".".concat(e);
55521
+ }).join(',') : 'image/*',
55478
55522
  beforeUpload: handleFileSelect,
55479
55523
  maxCount: 1,
55480
55524
  showUploadList: !!selectedFile,
@@ -56165,12 +56209,12 @@ function fetchJson(_x, _x2) {
56165
56209
  return _fetchJson.apply(this, arguments);
56166
56210
  }
56167
56211
  function _fetchJson() {
56168
- _fetchJson = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(url, jwt) {
56212
+ _fetchJson = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(url, jwt) {
56169
56213
  var response;
56170
- return _regeneratorRuntime.wrap(function _callee2$(_context2) {
56171
- while (1) switch (_context2.prev = _context2.next) {
56214
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
56215
+ while (1) switch (_context3.prev = _context3.next) {
56172
56216
  case 0:
56173
- _context2.next = 2;
56217
+ _context3.next = 2;
56174
56218
  return fetch(url, {
56175
56219
  headers: _objectSpread$g({
56176
56220
  'Content-Type': 'application/json'
@@ -56179,24 +56223,24 @@ function _fetchJson() {
56179
56223
  } : {})
56180
56224
  });
56181
56225
  case 2:
56182
- response = _context2.sent;
56226
+ response = _context3.sent;
56183
56227
  if (response.ok) {
56184
- _context2.next = 5;
56228
+ _context3.next = 5;
56185
56229
  break;
56186
56230
  }
56187
56231
  throw new DivaError("Request failed: ".concat(response.status, " ").concat(response.statusText), {
56188
56232
  code: 'RENDERAPPROVE_FETCH_FAILED'
56189
56233
  });
56190
56234
  case 5:
56191
- _context2.next = 7;
56235
+ _context3.next = 7;
56192
56236
  return response.json();
56193
56237
  case 7:
56194
- return _context2.abrupt("return", _context2.sent);
56238
+ return _context3.abrupt("return", _context3.sent);
56195
56239
  case 8:
56196
56240
  case "end":
56197
- return _context2.stop();
56241
+ return _context3.stop();
56198
56242
  }
56199
- }, _callee2);
56243
+ }, _callee3);
56200
56244
  }));
56201
56245
  return _fetchJson.apply(this, arguments);
56202
56246
  }
@@ -56233,22 +56277,22 @@ function fetchProductMedia(_x3, _x4, _x5, _x6, _x7) {
56233
56277
  return _fetchProductMedia.apply(this, arguments);
56234
56278
  }
56235
56279
  function _fetchProductMedia() {
56236
- _fetchProductMedia = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(catalogService, baseUrl, jwt, productId, excludeUrl) {
56280
+ _fetchProductMedia = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(catalogService, baseUrl, jwt, productId, excludeUrl) {
56237
56281
  var data, product, media, sorted, seen, result, _iterator2, _step2, _mapped$metadata, item, mapped, ref;
56238
- return _regeneratorRuntime.wrap(function _callee4$(_context4) {
56239
- while (1) switch (_context4.prev = _context4.next) {
56282
+ return _regeneratorRuntime.wrap(function _callee5$(_context5) {
56283
+ while (1) switch (_context5.prev = _context5.next) {
56240
56284
  case 0:
56241
- _context4.next = 2;
56285
+ _context5.next = 2;
56242
56286
  return fetchJson("".concat(catalogService, "/v1/products/").concat(encodeURIComponent(productId), "/list"), jwt);
56243
56287
  case 2:
56244
- data = _context4.sent;
56288
+ data = _context5.sent;
56245
56289
  product = Array.isArray(data) ? data[0] : undefined;
56246
56290
  media = product === null || product === void 0 ? void 0 : product.media;
56247
56291
  if (!(!Array.isArray(media) || media.length === 0)) {
56248
- _context4.next = 7;
56292
+ _context5.next = 7;
56249
56293
  break;
56250
56294
  }
56251
- return _context4.abrupt("return", []);
56295
+ return _context5.abrupt("return", []);
56252
56296
  case 7:
56253
56297
  sorted = _toConsumableArray(media).sort(function (a, b) {
56254
56298
  var pa = typeof (a === null || a === void 0 ? void 0 : a.position) === 'number' ? a.position : Number.MAX_SAFE_INTEGER;
@@ -56259,42 +56303,45 @@ function _fetchProductMedia() {
56259
56303
  if (excludeUrl) seen.add(excludeUrl);
56260
56304
  result = [];
56261
56305
  _iterator2 = _createForOfIteratorHelper$9(sorted);
56262
- _context4.prev = 12;
56306
+ _context5.prev = 12;
56263
56307
  _iterator2.s();
56264
56308
  case 14:
56265
56309
  if ((_step2 = _iterator2.n()).done) {
56266
- _context4.next = 32;
56310
+ _context5.next = 32;
56267
56311
  break;
56268
56312
  }
56269
56313
  item = _step2.value;
56270
56314
  if (!(item !== null && item !== void 0 && item.functionType && EXCLUDED_FUNCTION_TYPES.has(item.functionType))) {
56271
- _context4.next = 18;
56315
+ _context5.next = 18;
56272
56316
  break;
56273
56317
  }
56274
- return _context4.abrupt("continue", 30);
56318
+ return _context5.abrupt("continue", 30);
56275
56319
  case 18:
56276
56320
  if (!(item !== null && item !== void 0 && item.mediaType && !ALLOWED_MEDIA_TYPES.has(item.mediaType))) {
56277
- _context4.next = 20;
56321
+ _context5.next = 20;
56278
56322
  break;
56279
56323
  }
56280
- return _context4.abrupt("continue", 30);
56324
+ return _context5.abrupt("continue", 30);
56281
56325
  case 20:
56282
56326
  mapped = toMedia(item);
56283
56327
  if (!(!mapped || !mapped.url)) {
56284
- _context4.next = 23;
56328
+ _context5.next = 23;
56285
56329
  break;
56286
56330
  }
56287
- return _context4.abrupt("continue", 30);
56331
+ return _context5.abrupt("continue", 30);
56288
56332
  case 23:
56289
56333
  if (!seen.has(mapped.url)) {
56290
- _context4.next = 25;
56334
+ _context5.next = 25;
56291
56335
  break;
56292
56336
  }
56293
- return _context4.abrupt("continue", 30);
56337
+ return _context5.abrupt("continue", 30);
56294
56338
  case 25:
56295
56339
  seen.add(mapped.url);
56296
56340
  ref = typeof (item === null || item === void 0 ? void 0 : item.ref) === 'string' ? item.ref : undefined;
56297
- if (ref) mapped.id = ref;
56341
+ if (ref) {
56342
+ mapped.id = ref;
56343
+ mapped.mediaItemRefId = ref;
56344
+ }
56298
56345
  // Base metadata already available from the product list.
56299
56346
  mapped.metadata = _objectSpread$g(_objectSpread$g({}, item !== null && item !== void 0 && item.functionType ? {
56300
56347
  functionType: item.functionType
@@ -56304,38 +56351,38 @@ function _fetchProductMedia() {
56304
56351
  ref: ref
56305
56352
  });
56306
56353
  case 30:
56307
- _context4.next = 14;
56354
+ _context5.next = 14;
56308
56355
  break;
56309
56356
  case 32:
56310
- _context4.next = 37;
56357
+ _context5.next = 37;
56311
56358
  break;
56312
56359
  case 34:
56313
- _context4.prev = 34;
56314
- _context4.t0 = _context4["catch"](12);
56315
- _iterator2.e(_context4.t0);
56360
+ _context5.prev = 34;
56361
+ _context5.t0 = _context5["catch"](12);
56362
+ _iterator2.e(_context5.t0);
56316
56363
  case 37:
56317
- _context4.prev = 37;
56364
+ _context5.prev = 37;
56318
56365
  _iterator2.f();
56319
- return _context4.finish(37);
56366
+ return _context5.finish(37);
56320
56367
  case 40:
56321
- _context4.next = 42;
56368
+ _context5.next = 42;
56322
56369
  return Promise.all(result.map(/*#__PURE__*/function () {
56323
- var _ref7 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref6) {
56370
+ var _ref9 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(_ref8) {
56324
56371
  var media, ref, _yield$Promise$allSet3, _yield$Promise$allSet4, mediaItemRes, refRes, item, _media$metadata, payload, refDoc, _media$metadata2;
56325
- return _regeneratorRuntime.wrap(function _callee3$(_context3) {
56326
- while (1) switch (_context3.prev = _context3.next) {
56372
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
56373
+ while (1) switch (_context4.prev = _context4.next) {
56327
56374
  case 0:
56328
- media = _ref6.media, ref = _ref6.ref;
56375
+ media = _ref8.media, ref = _ref8.ref;
56329
56376
  if (ref) {
56330
- _context3.next = 3;
56377
+ _context4.next = 3;
56331
56378
  break;
56332
56379
  }
56333
- return _context3.abrupt("return");
56380
+ return _context4.abrupt("return");
56334
56381
  case 3:
56335
- _context3.next = 5;
56382
+ _context4.next = 5;
56336
56383
  return Promise.allSettled([fetchJson("".concat(baseUrl, "/v1/mediaitemref/").concat(encodeURIComponent(ref), "/mediaitem"), jwt), fetchJson("".concat(baseUrl, "/v1/mediaitems/refs?filter=").concat(encodeURIComponent("{_id,eq,'".concat(ref, "'}"))), jwt)]);
56337
56384
  case 5:
56338
- _yield$Promise$allSet3 = _context3.sent;
56385
+ _yield$Promise$allSet3 = _context4.sent;
56339
56386
  _yield$Promise$allSet4 = _slicedToArray(_yield$Promise$allSet3, 2);
56340
56387
  mediaItemRes = _yield$Promise$allSet4[0];
56341
56388
  refRes = _yield$Promise$allSet4[1];
@@ -56355,23 +56402,23 @@ function _fetchProductMedia() {
56355
56402
  }
56356
56403
  case 11:
56357
56404
  case "end":
56358
- return _context3.stop();
56405
+ return _context4.stop();
56359
56406
  }
56360
- }, _callee3);
56407
+ }, _callee4);
56361
56408
  }));
56362
- return function (_x12) {
56363
- return _ref7.apply(this, arguments);
56409
+ return function (_x13) {
56410
+ return _ref9.apply(this, arguments);
56364
56411
  };
56365
56412
  }()));
56366
56413
  case 42:
56367
- return _context4.abrupt("return", result.map(function (r) {
56414
+ return _context5.abrupt("return", result.map(function (r) {
56368
56415
  return r.media;
56369
56416
  }));
56370
56417
  case 43:
56371
56418
  case "end":
56372
- return _context4.stop();
56419
+ return _context5.stop();
56373
56420
  }
56374
- }, _callee4, null, [[12, 34, 37, 40]]);
56421
+ }, _callee5, null, [[12, 34, 37, 40]]);
56375
56422
  }));
56376
56423
  return _fetchProductMedia.apply(this, arguments);
56377
56424
  }
@@ -56387,47 +56434,47 @@ function resolveMediaItem(_x8, _x9, _x10, _x11) {
56387
56434
  * session hook can call them without depending on the currently-loaded job.
56388
56435
  */
56389
56436
  function _resolveMediaItem() {
56390
- _resolveMediaItem = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5(baseUrl, jwt, mediaItemId, mediaItemRef) {
56437
+ _resolveMediaItem = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee6(baseUrl, jwt, mediaItemId, mediaItemRef) {
56391
56438
  var item, media, _item, _media;
56392
- return _regeneratorRuntime.wrap(function _callee5$(_context5) {
56393
- while (1) switch (_context5.prev = _context5.next) {
56439
+ return _regeneratorRuntime.wrap(function _callee6$(_context6) {
56440
+ while (1) switch (_context6.prev = _context6.next) {
56394
56441
  case 0:
56395
56442
  if (!mediaItemRef) {
56396
- _context5.next = 7;
56443
+ _context6.next = 7;
56397
56444
  break;
56398
56445
  }
56399
- _context5.next = 3;
56446
+ _context6.next = 3;
56400
56447
  return fetchJson("".concat(baseUrl, "/v1/mediaitemref/").concat(encodeURIComponent(mediaItemRef), "/mediaitem"), jwt);
56401
56448
  case 3:
56402
- item = _context5.sent;
56449
+ item = _context6.sent;
56403
56450
  media = toMedia(item);
56404
56451
  if (!media) {
56405
- _context5.next = 7;
56452
+ _context6.next = 7;
56406
56453
  break;
56407
56454
  }
56408
- return _context5.abrupt("return", media);
56455
+ return _context6.abrupt("return", media);
56409
56456
  case 7:
56410
56457
  if (!mediaItemId) {
56411
- _context5.next = 14;
56458
+ _context6.next = 14;
56412
56459
  break;
56413
56460
  }
56414
- _context5.next = 10;
56461
+ _context6.next = 10;
56415
56462
  return fetchJson("".concat(baseUrl, "/v1/mediaitems/").concat(encodeURIComponent(mediaItemId)), jwt);
56416
56463
  case 10:
56417
- _item = _context5.sent;
56464
+ _item = _context6.sent;
56418
56465
  _media = toMedia(_item);
56419
56466
  if (!_media) {
56420
- _context5.next = 14;
56467
+ _context6.next = 14;
56421
56468
  break;
56422
56469
  }
56423
- return _context5.abrupt("return", _media);
56470
+ return _context6.abrupt("return", _media);
56424
56471
  case 14:
56425
- return _context5.abrupt("return", null);
56472
+ return _context6.abrupt("return", null);
56426
56473
  case 15:
56427
56474
  case "end":
56428
- return _context5.stop();
56475
+ return _context6.stop();
56429
56476
  }
56430
- }, _callee5);
56477
+ }, _callee6);
56431
56478
  }));
56432
56479
  return _resolveMediaItem.apply(this, arguments);
56433
56480
  }
@@ -56472,21 +56519,21 @@ function useRenderJobData(id, refreshKey) {
56472
56519
  setError(undefined);
56473
56520
  setJob(undefined);
56474
56521
  setImages({});
56475
- _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
56476
- var _fetchedJob$realTimeR, fetchedJob, left, initialSlides, mediaItemId, mediaItemRef, productId, rightPromise, productPromise, _yield$Promise$allSet, _yield$Promise$allSet2, rightResult, productResult, right, _rightResult$value, _rightResult$reason, productMedia, _productResult$reason, renderImageUrls, productByUrl, _iterator, _step, m, renderImageSet, remainingProduct, leftSlides, renderImageSlides, previewAfter, _message, message;
56477
- return _regeneratorRuntime.wrap(function _callee$(_context) {
56478
- while (1) switch (_context.prev = _context.next) {
56522
+ _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
56523
+ var _fetchedJob$realTimeR, fetchedJob, left, initialSlides, mediaItemId, mediaItemRef, productId, rightPromise, productPromise, _yield$Promise$allSet, _yield$Promise$allSet2, rightResult, productResult, right, _rightResult$value, _rightResult$reason, productMedia, _productResult$reason, renderImages, productByUrl, _iterator, _step, m, renderImageSet, remainingProduct, leftSlides, renderImageSlides, previewAfter, _message, message;
56524
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
56525
+ while (1) switch (_context2.prev = _context2.next) {
56479
56526
  case 0:
56480
- _context.prev = 0;
56481
- _context.next = 3;
56527
+ _context2.prev = 0;
56528
+ _context2.next = 3;
56482
56529
  return fetchJson("".concat(baseUrl, "/renderjobs/").concat(encodeURIComponent(id)), jwt);
56483
56530
  case 3:
56484
- fetchedJob = _context.sent;
56531
+ fetchedJob = _context2.sent;
56485
56532
  if (!cancelled) {
56486
- _context.next = 6;
56533
+ _context2.next = 6;
56487
56534
  break;
56488
56535
  }
56489
- return _context.abrupt("return");
56536
+ return _context2.abrupt("return");
56490
56537
  case 6:
56491
56538
  setJob(fetchedJob);
56492
56539
 
@@ -56508,18 +56555,18 @@ function useRenderJobData(id, refreshKey) {
56508
56555
  // failure cannot block the right panel and vice versa.
56509
56556
  rightPromise = mediaItemId || mediaItemRef ? resolveMediaItem(baseUrl, jwt, mediaItemId, mediaItemRef) : Promise.resolve(null);
56510
56557
  productPromise = catalogService && typeof productId === 'string' && productId.length > 0 ? fetchProductMedia(catalogService, baseUrl, jwt, productId, left.url) : Promise.resolve([]);
56511
- _context.next = 17;
56558
+ _context2.next = 17;
56512
56559
  return Promise.allSettled([rightPromise, productPromise]);
56513
56560
  case 17:
56514
- _yield$Promise$allSet = _context.sent;
56561
+ _yield$Promise$allSet = _context2.sent;
56515
56562
  _yield$Promise$allSet2 = _slicedToArray(_yield$Promise$allSet, 2);
56516
56563
  rightResult = _yield$Promise$allSet2[0];
56517
56564
  productResult = _yield$Promise$allSet2[1];
56518
56565
  if (!cancelled) {
56519
- _context.next = 23;
56566
+ _context2.next = 23;
56520
56567
  break;
56521
56568
  }
56522
- return _context.abrupt("return");
56569
+ return _context2.abrupt("return");
56523
56570
  case 23:
56524
56571
  if (rightResult.status === 'fulfilled') {
56525
56572
  right = (_rightResult$value = rightResult.value) !== null && _rightResult$value !== void 0 ? _rightResult$value : {
@@ -56545,8 +56592,8 @@ function useRenderJobData(id, refreshKey) {
56545
56592
  // The realtime preview is shown first only when there are no renderImages;
56546
56593
  // once renderImages exist it comes right after them, and only if it is
56547
56594
  // not already one of them.
56548
- renderImageUrls = Array.isArray(fetchedJob === null || fetchedJob === void 0 ? void 0 : fetchedJob.renderImages) ? fetchedJob.renderImages.filter(function (u) {
56549
- return typeof u === 'string' && u.length > 0;
56595
+ renderImages = Array.isArray(fetchedJob === null || fetchedJob === void 0 ? void 0 : fetchedJob.renderImages) ? fetchedJob.renderImages.filter(function (image) {
56596
+ return typeof (image === null || image === void 0 ? void 0 : image.url) === 'string' && image.url.length > 0;
56550
56597
  }) : [];
56551
56598
  productByUrl = new Map();
56552
56599
  _iterator = _createForOfIteratorHelper$9(productMedia);
@@ -56560,16 +56607,24 @@ function useRenderJobData(id, refreshKey) {
56560
56607
  } finally {
56561
56608
  _iterator.f();
56562
56609
  }
56563
- renderImageSet = new Set(renderImageUrls);
56610
+ renderImageSet = new Set(renderImages.map(function (image) {
56611
+ return image.url;
56612
+ }));
56564
56613
  remainingProduct = productMedia.filter(function (m) {
56565
56614
  return !(m.url && renderImageSet.has(m.url));
56566
56615
  });
56567
- if (renderImageUrls.length > 0) {
56568
- renderImageSlides = renderImageUrls.map(function (url) {
56616
+ if (renderImages.length > 0) {
56617
+ // Product media (rich metadata) wins on url match; otherwise build a
56618
+ // minimal slide that carries the stored MediaItemRef id so uploaded
56619
+ // images keep their ref when re-selected.
56620
+ renderImageSlides = renderImages.map(function (_ref6) {
56569
56621
  var _productByUrl$get;
56622
+ var url = _ref6.url,
56623
+ mediaItemRefId = _ref6.mediaItemRefId;
56570
56624
  return url === left.url ? left : (_productByUrl$get = productByUrl.get(url)) !== null && _productByUrl$get !== void 0 ? _productByUrl$get : {
56571
56625
  url: url,
56572
- mediaType: 'PCT'
56626
+ mediaType: 'PCT',
56627
+ mediaItemRefId: mediaItemRefId
56573
56628
  };
56574
56629
  });
56575
56630
  previewAfter = left.url != null && !renderImageSet.has(left.url) ? [left] : [];
@@ -56577,49 +56632,183 @@ function useRenderJobData(id, refreshKey) {
56577
56632
  } else {
56578
56633
  leftSlides = [left].concat(_toConsumableArray(remainingProduct));
56579
56634
  }
56635
+
56636
+ // Uploaded AI input images are not part of the product media, so their
56637
+ // display name (filename) is resolved from the MediaItemRef (best-effort).
56638
+ _context2.next = 35;
56639
+ return Promise.all(leftSlides.map(/*#__PURE__*/function () {
56640
+ var _ref7 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(slide) {
56641
+ var item;
56642
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
56643
+ while (1) switch (_context.prev = _context.next) {
56644
+ case 0:
56645
+ if (!(slide.name || !slide.mediaItemRefId)) {
56646
+ _context.next = 2;
56647
+ break;
56648
+ }
56649
+ return _context.abrupt("return");
56650
+ case 2:
56651
+ _context.prev = 2;
56652
+ _context.next = 5;
56653
+ return fetchJson("".concat(baseUrl, "/v1/mediaitemref/").concat(encodeURIComponent(slide.mediaItemRefId), "/mediaitem"), jwt);
56654
+ case 5:
56655
+ item = _context.sent;
56656
+ if (typeof (item === null || item === void 0 ? void 0 : item.name) === 'string' && item.name.length > 0) slide.name = item.name;
56657
+ _context.next = 11;
56658
+ break;
56659
+ case 9:
56660
+ _context.prev = 9;
56661
+ _context.t0 = _context["catch"](2);
56662
+ case 11:
56663
+ case "end":
56664
+ return _context.stop();
56665
+ }
56666
+ }, _callee, null, [[2, 9]]);
56667
+ }));
56668
+ return function (_x12) {
56669
+ return _ref7.apply(this, arguments);
56670
+ };
56671
+ }()));
56672
+ case 35:
56673
+ if (!cancelled) {
56674
+ _context2.next = 37;
56675
+ break;
56676
+ }
56677
+ return _context2.abrupt("return");
56678
+ case 37:
56580
56679
  setImages({
56581
56680
  left: left,
56582
56681
  leftSlides: leftSlides,
56583
56682
  right: right
56584
56683
  });
56585
- _context.next = 43;
56684
+ _context2.next = 47;
56586
56685
  break;
56587
- case 36:
56588
- _context.prev = 36;
56589
- _context.t0 = _context["catch"](0);
56686
+ case 40:
56687
+ _context2.prev = 40;
56688
+ _context2.t0 = _context2["catch"](0);
56590
56689
  if (!cancelled) {
56591
- _context.next = 40;
56690
+ _context2.next = 44;
56592
56691
  break;
56593
56692
  }
56594
- return _context.abrupt("return");
56595
- case 40:
56596
- message = (_message = _context.t0 === null || _context.t0 === void 0 ? void 0 : _context.t0.message) !== null && _message !== void 0 ? _message : 'Unknown error';
56693
+ return _context2.abrupt("return");
56694
+ case 44:
56695
+ message = (_message = _context2.t0 === null || _context2.t0 === void 0 ? void 0 : _context2.t0.message) !== null && _message !== void 0 ? _message : 'Unknown error';
56597
56696
  LOG$4.error(new DivaError("Failed to load render job ".concat(id, ": ").concat(message), {
56598
56697
  code: 'RENDERAPPROVE_LOAD_JOB'
56599
56698
  }));
56600
56699
  setError(message);
56601
- case 43:
56602
- _context.prev = 43;
56700
+ case 47:
56701
+ _context2.prev = 47;
56603
56702
  if (!cancelled) setLoading(false);
56604
- return _context.finish(43);
56605
- case 46:
56703
+ return _context2.finish(47);
56704
+ case 50:
56606
56705
  case "end":
56607
- return _context.stop();
56706
+ return _context2.stop();
56608
56707
  }
56609
- }, _callee, null, [[0, 36, 43, 46]]);
56708
+ }, _callee2, null, [[0, 40, 47, 50]]);
56610
56709
  }))();
56611
56710
  return function () {
56612
56711
  cancelled = true;
56613
56712
  };
56614
56713
  }, [id, baseUrl, catalogService, jwt, t, refreshKey]);
56714
+ var applyRenderImages = useCallback(function (renderImages) {
56715
+ setJob(function (prev) {
56716
+ return prev ? _objectSpread$g(_objectSpread$g({}, prev), {}, {
56717
+ renderImages: renderImages
56718
+ }) : prev;
56719
+ });
56720
+ }, []);
56615
56721
  return useMemo(function () {
56616
56722
  return {
56617
56723
  job: job,
56618
56724
  images: images,
56619
56725
  loading: loading,
56620
- error: error
56726
+ error: error,
56727
+ applyRenderImages: applyRenderImages
56728
+ };
56729
+ }, [job, images, loading, error, applyRenderImages]);
56730
+ }
56731
+
56732
+ /**
56733
+ * Uploads an image as a MediaItem/MediaItemRef (same asset pipeline as the
56734
+ * regular RenderApprove upload) and appends it to the render job's
56735
+ * `renderImages` so it becomes one of the AI input images. Unlike
56736
+ * `useUploadRenderJobImage` it does not touch `mediaItemRef`/`fileUrl` or change
56737
+ * the render job state - the job stays in the image-selection phase.
56738
+ */
56739
+ function useUploadRenderImage() {
56740
+ var _root$configurationSt, _root$configurationSt2, _root$dataStore$jwt;
56741
+ var root = useStore();
56742
+ var baseUrl = (_root$configurationSt = (_root$configurationSt2 = root.configurationStore.apiConfig) === null || _root$configurationSt2 === void 0 ? void 0 : _root$configurationSt2.mediaService) !== null && _root$configurationSt !== void 0 ? _root$configurationSt : '';
56743
+ var jwt = (_root$dataStore$jwt = root.dataStore.jwt) !== null && _root$dataStore$jwt !== void 0 ? _root$dataStore$jwt : '';
56744
+ var patchJob = useUpdateRenderJobPatch();
56745
+ var _useState = useState(false),
56746
+ _useState2 = _slicedToArray(_useState, 2),
56747
+ uploading = _useState2[0],
56748
+ setUploading = _useState2[1];
56749
+ var _useState3 = useState(null),
56750
+ _useState4 = _slicedToArray(_useState3, 2),
56751
+ error = _useState4[0],
56752
+ setError = _useState4[1];
56753
+ var upload = useCallback(/*#__PURE__*/function () {
56754
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(file, job) {
56755
+ var _job$organization, _job$renderImages, result, newImage, renderImages, op, err;
56756
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
56757
+ while (1) switch (_context.prev = _context.next) {
56758
+ case 0:
56759
+ setUploading(true);
56760
+ setError(null);
56761
+ _context.prev = 2;
56762
+ _context.next = 5;
56763
+ return uploadMediaItem(baseUrl, jwt, {
56764
+ organizationId: (_job$organization = job.organization) !== null && _job$organization !== void 0 ? _job$organization : '',
56765
+ file: file,
56766
+ mediaType: 'PCT',
56767
+ functionType: 'SHO'
56768
+ });
56769
+ case 5:
56770
+ result = _context.sent;
56771
+ newImage = {
56772
+ mediaItemRefId: result.ref._id,
56773
+ url: result.ref.url
56774
+ };
56775
+ renderImages = [].concat(_toConsumableArray((_job$renderImages = job.renderImages) !== null && _job$renderImages !== void 0 ? _job$renderImages : []), [newImage]); // RFC 6902: `add` is rejected when the path already exists, so replace
56776
+ // when the job already carries a renderImages list.
56777
+ op = job.renderImages === undefined ? 'add' : 'replace';
56778
+ _context.next = 11;
56779
+ return patchJob(job._id, [{
56780
+ op: op,
56781
+ path: '/renderImages',
56782
+ value: renderImages
56783
+ }], true);
56784
+ case 11:
56785
+ _context.next = 18;
56786
+ break;
56787
+ case 13:
56788
+ _context.prev = 13;
56789
+ _context.t0 = _context["catch"](2);
56790
+ err = _context.t0;
56791
+ setError(err);
56792
+ throw err;
56793
+ case 18:
56794
+ _context.prev = 18;
56795
+ setUploading(false);
56796
+ return _context.finish(18);
56797
+ case 21:
56798
+ case "end":
56799
+ return _context.stop();
56800
+ }
56801
+ }, _callee, null, [[2, 13, 18, 21]]);
56802
+ }));
56803
+ return function (_x, _x2) {
56804
+ return _ref.apply(this, arguments);
56621
56805
  };
56622
- }, [job, images, loading, error]);
56806
+ }(), [baseUrl, jwt, patchJob]);
56807
+ return {
56808
+ upload: upload,
56809
+ uploading: uploading,
56810
+ error: error
56811
+ };
56623
56812
  }
56624
56813
 
56625
56814
  /** Return `false` when the shortcut should not run (e.g. modal open) so default browser behavior is preserved. */
@@ -56746,7 +56935,7 @@ function focusBackConfirmButton(button) {
56746
56935
  ok === null || ok === void 0 || ok.focus();
56747
56936
  }
56748
56937
  function RenderApprove() {
56749
- var _data$job, _data$job2, _data$images$right2, _data$images$right3, _data$images$leftSlid, _data$job3, _data$job4, _imageFullscreen$name;
56938
+ var _data$job, _data$job2, _data$images$right2, _data$images$right3, _data$images$leftSlid, _data$job3, _data$job4, _data$job5, _imageFullscreen$name;
56750
56939
  var store = useStore();
56751
56940
  var navigate = useNavigate();
56752
56941
  var _useTranslation = useTranslation(),
@@ -56788,10 +56977,16 @@ function RenderApprove() {
56788
56977
  _useState16 = _slicedToArray(_useState15, 2),
56789
56978
  uploadOpen = _useState16[0],
56790
56979
  setUploadOpen = _useState16[1];
56791
- var _useState17 = useState(0),
56980
+ var _useState17 = useState(false),
56792
56981
  _useState18 = _slicedToArray(_useState17, 2),
56793
- dataRefreshKey = _useState18[0],
56794
- setDataRefreshKey = _useState18[1];
56982
+ selectionUploadOpen = _useState18[0],
56983
+ setSelectionUploadOpen = _useState18[1];
56984
+ var _useUploadRenderImage = useUploadRenderImage(),
56985
+ uploadRenderImage = _useUploadRenderImage.upload;
56986
+ var _useState19 = useState(0),
56987
+ _useState20 = _slicedToArray(_useState19, 2),
56988
+ dataRefreshKey = _useState20[0],
56989
+ setDataRefreshKey = _useState20[1];
56795
56990
  var data = useRenderJobData(session.currentId, dataRefreshKey);
56796
56991
  var leftSwiperRef = useRef(null);
56797
56992
  var isAiJob = typeof ((_data$job = data.job) === null || _data$job === void 0 ? void 0 : _data$job.engine) === 'string' && data.job.engine.trim().toLowerCase() === 'ai';
@@ -57121,10 +57316,10 @@ function RenderApprove() {
57121
57316
  };
57122
57317
 
57123
57318
  // Persists the ordered selection of input images on the render job. The
57124
- // `renderImages` array (CDN urls, in order) is the source of truth the AI
57125
- // generation consumes.
57319
+ // `renderImages` array (CDN url + MediaItemRef id, in order) is the source of
57320
+ // truth the AI generation consumes.
57126
57321
  var persistImageSelection = /*#__PURE__*/function () {
57127
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(orderedUrls) {
57322
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(renderImages) {
57128
57323
  var op;
57129
57324
  return _regeneratorRuntime.wrap(function _callee4$(_context4) {
57130
57325
  while (1) switch (_context4.prev = _context4.next) {
@@ -57135,30 +57330,33 @@ function RenderApprove() {
57135
57330
  }
57136
57331
  return _context4.abrupt("return");
57137
57332
  case 2:
57333
+ // Optimistically update the in-memory job so re-renders (and a subsequent
57334
+ // upload) use this order instead of snapping back to the last fetched one.
57335
+ data.applyRenderImages(renderImages);
57138
57336
  // RFC 6902: `add` is rejected when the path already exists (AI jobs often
57139
57337
  // ship with a default renderImages list), so replace when it's present.
57140
57338
  op = data.job.renderImages === undefined ? 'add' : 'replace';
57141
- _context4.prev = 3;
57142
- _context4.next = 6;
57339
+ _context4.prev = 4;
57340
+ _context4.next = 7;
57143
57341
  return updateRenderJobPatch(data.job._id, [{
57144
57342
  op: op,
57145
57343
  path: '/renderImages',
57146
- value: orderedUrls
57344
+ value: renderImages
57147
57345
  }]);
57148
- case 6:
57149
- _context4.next = 11;
57346
+ case 7:
57347
+ _context4.next = 12;
57150
57348
  break;
57151
- case 8:
57152
- _context4.prev = 8;
57153
- _context4.t0 = _context4["catch"](3);
57349
+ case 9:
57350
+ _context4.prev = 9;
57351
+ _context4.t0 = _context4["catch"](4);
57154
57352
  message.error(t('backoffice.renderapprove.aiImageSelector.saveFailed', {
57155
57353
  defaultValue: 'Bildauswahl konnte nicht gespeichert werden.'
57156
57354
  }));
57157
- case 11:
57355
+ case 12:
57158
57356
  case "end":
57159
57357
  return _context4.stop();
57160
57358
  }
57161
- }, _callee4, null, [[3, 8]]);
57359
+ }, _callee4, null, [[4, 9]]);
57162
57360
  }));
57163
57361
  return function persistImageSelection(_x2) {
57164
57362
  return _ref3.apply(this, arguments);
@@ -57297,10 +57495,15 @@ function RenderApprove() {
57297
57495
  promptWarningMessage: !showImageSelector ? t('backoffice.renderapprove.prompt.warningMessage') : undefined,
57298
57496
  children: showImageSelector && data.job ? /*#__PURE__*/jsx(ImageSelectionWorkspace, {
57299
57497
  job: data.job,
57300
- slides: (_data$images$leftSlid = data.images.leftSlides) !== null && _data$images$leftSlid !== void 0 ? _data$images$leftSlid : [],
57498
+ slides: ((_data$images$leftSlid = data.images.leftSlides) !== null && _data$images$leftSlid !== void 0 ? _data$images$leftSlid : []).filter(function (slide) {
57499
+ return slide.mediaType !== 'AR';
57500
+ }),
57301
57501
  selectionDisabled: session.isCurrentReadOnly || session.isUpdating,
57302
57502
  onSelectionChange: persistImageSelection,
57303
57503
  onOpenFullscreen: setImageFullscreen,
57504
+ onUpload: function onUpload() {
57505
+ return setSelectionUploadOpen(true);
57506
+ },
57304
57507
  actionDisabled: data.loading || !data.job,
57305
57508
  busy: session.isUpdating || promptRestarting,
57306
57509
  isFirst: session.isFirst,
@@ -57353,6 +57556,21 @@ function RenderApprove() {
57353
57556
  return k + 1;
57354
57557
  });
57355
57558
  }
57559
+ }), /*#__PURE__*/jsx(UploadImageModal, {
57560
+ open: selectionUploadOpen,
57561
+ renderJob: (_data$job5 = data.job) !== null && _data$job5 !== void 0 ? _data$job5 : null,
57562
+ uploadOverride: uploadRenderImage,
57563
+ skipValidation: true,
57564
+ allowedExtensions: ['webp', 'png', 'jpg', 'jpeg'],
57565
+ onClose: function onClose() {
57566
+ return setSelectionUploadOpen(false);
57567
+ },
57568
+ onSuccess: function onSuccess() {
57569
+ setSelectionUploadOpen(false);
57570
+ setDataRefreshKey(function (k) {
57571
+ return k + 1;
57572
+ });
57573
+ }
57356
57574
  }), /*#__PURE__*/jsx(FullscreenViewer, {
57357
57575
  open: fullscreenSide !== null,
57358
57576
  media: fullscreenMedia,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/ui/Table/BaseTable/cellRenderer/MediaViewerCell/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AAMxC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,GAAG,CAAC;QACZ,UAAU,iBAAiB;YACzB,cAAc,EAAE,GAAG,CAAC;SACrB;KACF;CACF;AAED,MAAM,CAAC,OAAO,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,kBAAkB,qBAqFhE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/ui/Table/BaseTable/cellRenderer/MediaViewerCell/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AAMxC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,GAAG,CAAC;QACZ,UAAU,iBAAiB;YACzB,cAAc,EAAE,GAAG,CAAC;SACrB;KACF;CACF;AAED,MAAM,CAAC,OAAO,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,kBAAkB,qBAuFhE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/components/AIImageSelector/components/SortableImageRow/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,kBAAkB,CAAC;IAC1B,iFAAiF;IACjF,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAcD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,KAAK,qBA2DxI"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/components/AIImageSelector/components/SortableImageRow/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,kBAAkB,CAAC;IAC1B,iFAAiF;IACjF,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAcD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,KAAK,qBAmDxI"}
@@ -1,13 +1,13 @@
1
1
  import React from 'react';
2
- import { RenderApproveMedia } from '../../../../types';
2
+ import { RenderApproveMedia, RenderImage } from '../../../../types';
3
3
  interface Props {
4
4
  /** All available images (realtime preview + product media), order as loaded. */
5
5
  slides: RenderApproveMedia[];
6
6
  /** Persisted order/selection from the render job `renderImages` (CDN urls). */
7
7
  selectedUrls?: string[];
8
8
  disabled?: boolean;
9
- /** Fires with the ordered list of selected image urls on every user change. */
10
- onChange?: (orderedUrls: string[]) => void;
9
+ /** Fires with the ordered list of selected images (CDN url + MediaItemRef id) on every user change. */
10
+ onChange?: (orderedImages: RenderImage[]) => void;
11
11
  /** Opens an image in fullscreen (double-click on its thumbnail). */
12
12
  onOpenFullscreen?: (media: RenderApproveMedia) => void;
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/components/AIImageSelector/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAYvD,UAAU,KAAK;IACb,gFAAgF;IAChF,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACxD;AAoCD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,KAAK,4BA+E5G"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/components/AIImageSelector/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAYpE,UAAU,KAAK;IACb,gFAAgF;IAChF,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uGAAuG;IACvG,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IAClD,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACxD;AAoCD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,KAAK,4BA+E5G"}
@@ -1,12 +1,13 @@
1
1
  import React from 'react';
2
2
  import { ShortcutItem } from '../ShortcutLegend';
3
- import { RenderApproveMedia, RenderJob } from '../../../../types';
3
+ import { RenderApproveMedia, RenderImage, RenderJob } from '../../../../types';
4
4
  interface Props {
5
5
  job: RenderJob;
6
6
  slides: RenderApproveMedia[];
7
7
  selectionDisabled?: boolean;
8
- onSelectionChange: (orderedUrls: string[]) => void;
8
+ onSelectionChange: (orderedImages: RenderImage[]) => void;
9
9
  onOpenFullscreen: (media: RenderApproveMedia) => void;
10
+ onUpload?: () => void;
10
11
  actionDisabled?: boolean;
11
12
  busy?: boolean;
12
13
  isFirst?: boolean;
@@ -19,6 +20,6 @@ interface Props {
19
20
  * product images sent to the AI. The action bar only carries navigation - no
20
21
  * approve / reject / upload, since there is nothing to decide yet.
21
22
  */
22
- export default function ImageSelectionWorkspace({ job, slides, selectionDisabled, onSelectionChange, onOpenFullscreen, actionDisabled, busy, isFirst, shortcutItems, onPrev, onNext, }: Props): React.JSX.Element;
23
+ export default function ImageSelectionWorkspace({ job, slides, selectionDisabled, onSelectionChange, onOpenFullscreen, onUpload, actionDisabled, busy, isFirst, shortcutItems, onPrev, onNext, }: Props): React.JSX.Element;
23
24
  export {};
24
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/components/ImageSelectionWorkspace/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAElE,UAAU,KAAK;IACb,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnD,gBAAgB,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAC9C,GAAG,EACH,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,IAAI,EACJ,OAAO,EACP,aAAa,EACb,MAAM,EACN,MAAM,GACP,EAAE,KAAK,qBAcP"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/components/ImageSelectionWorkspace/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE/E,UAAU,KAAK;IACb,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IAC1D,gBAAgB,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAC9C,GAAG,EACH,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,IAAI,EACJ,OAAO,EACP,aAAa,EACb,MAAM,EACN,MAAM,GACP,EAAE,KAAK,qBAoBP"}
@@ -1,9 +1,11 @@
1
- import { RenderApproveImages, RenderJob } from '../../../types';
1
+ import { RenderApproveImages, RenderImage, RenderJob } from '../../../types';
2
2
  interface UseRenderJobDataResult {
3
3
  job?: RenderJob;
4
4
  images: RenderApproveImages;
5
5
  loading: boolean;
6
6
  error?: string;
7
+ /** Optimistically updates the in-memory job's renderImages (after persisting a reorder/selection) so re-renders don't snap back to the last fetched order. */
8
+ applyRenderImages: (renderImages: RenderImage[]) => void;
7
9
  }
8
10
  /**
9
11
  * Loads the render job by id together with the left (real-time render) and
@@ -1 +1 @@
1
- {"version":3,"file":"useRenderJobData.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/hooks/useRenderJobData.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAsB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIpF,UAAU,sBAAsB;IAC9B,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgJD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAuHjG"}
1
+ {"version":3,"file":"useRenderJobData.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/hooks/useRenderJobData.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAsB,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIjG,UAAU,sBAAsB;IAC9B,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8JAA8J;IAC9J,iBAAiB,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;CAC1D;AAmJD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,sBAAsB,CA6IjG"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAiE3D,MAAM,CAAC,OAAO,UAAU,aAAa,sBAkfpC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/ui/TableRenderJobs/components/RenderApprove/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAkE3D,MAAM,CAAC,OAAO,UAAU,aAAa,sBAogBpC"}
@@ -5,7 +5,17 @@ interface Props {
5
5
  renderJob: RenderJob | null;
6
6
  onClose: () => void;
7
7
  onSuccess?: () => void;
8
+ /**
9
+ * Custom upload handler. When provided it replaces the default
10
+ * (replace-final-render) upload - used by the image-selection phase to append
11
+ * the uploaded image to `renderImages` instead.
12
+ */
13
+ uploadOverride?: (file: File, job: RenderJob) => Promise<void>;
14
+ /** Skip the render-job format/resolution deviation validation (no warnings). */
15
+ skipValidation?: boolean;
16
+ /** Restrict selectable file extensions (e.g. ['webp','png','jpg','jpeg']). Defaults to any image. */
17
+ allowedExtensions?: string[];
8
18
  }
9
- export default function UploadImageModal({ open, renderJob, onClose, onSuccess }: Props): React.JSX.Element;
19
+ export default function UploadImageModal({ open, renderJob, onClose, onSuccess, uploadOverride, skipValidation, allowedExtensions }: Props): React.JSX.Element;
10
20
  export {};
11
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/ui/TableRenderJobs/components/UploadImageModal/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,UAAU,KAAK;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,qBA8GtF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../src/ui/TableRenderJobs/components/UploadImageModal/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,UAAU,KAAK;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,gFAAgF;IAChF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qGAAqG;IACrG,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,EAAE,KAAK,qBA+HzI"}
@@ -0,0 +1,14 @@
1
+ import { RenderJob } from '../types';
2
+ /**
3
+ * Uploads an image as a MediaItem/MediaItemRef (same asset pipeline as the
4
+ * regular RenderApprove upload) and appends it to the render job's
5
+ * `renderImages` so it becomes one of the AI input images. Unlike
6
+ * `useUploadRenderJobImage` it does not touch `mediaItemRef`/`fileUrl` or change
7
+ * the render job state - the job stays in the image-selection phase.
8
+ */
9
+ export default function useUploadRenderImage(): {
10
+ upload: (file: File, job: RenderJob) => Promise<void>;
11
+ uploading: boolean;
12
+ error: Error | null;
13
+ };
14
+ //# sourceMappingURL=useUploadRenderImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUploadRenderImage.d.ts","sourceRoot":"","sources":["../../../../../../../src/ui/TableRenderJobs/hooks/useUploadRenderImage.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB;mBAU3B,IAAI,OAAO,SAAS,KAAG,OAAO,CAAC,IAAI,CAAC;;;EA6BpD"}
@@ -5,6 +5,11 @@ export interface TableRenderJobsConfiguration extends BaseModulConfiguration {
5
5
  export interface RenderApproveConfiguration extends BaseModulConfiguration {
6
6
  type: 'RenderApprove';
7
7
  }
8
+ /** One AI input image: its CDN url and (when known) the originating MediaItemRef id. */
9
+ export interface RenderImage {
10
+ mediaItemRefId?: string;
11
+ url: string;
12
+ }
8
13
  /**
9
14
  * Subset of the render job payload returned by `GET /renderjobs/:id`
10
15
  * that the RenderApprove session actually uses. Extra fields from the API
@@ -36,8 +41,8 @@ export interface RenderJob {
36
41
  id: string;
37
42
  viewpointName?: string;
38
43
  }[];
39
- /** Ordered list of CDN urls sent to the AI as input images. */
40
- renderImages?: string[];
44
+ /** Ordered list of input images sent to the AI, each with its CDN url and (when known) its MediaItemRef id. */
45
+ renderImages?: RenderImage[];
41
46
  created?: number;
42
47
  [key: string]: any;
43
48
  }
@@ -56,8 +61,10 @@ export interface RenderApproveMedia {
56
61
  mimeType?: string;
57
62
  /** File size in bytes, if provided by the MediaItem. */
58
63
  fileSize?: number;
59
- /** MediaItem / MediaItemRef id, if resolved from a media record. */
64
+ /** MediaItem / MediaItemRef id, if resolved from a media record. May be a MediaItem id, so do NOT treat as a ref. */
60
65
  id?: string;
66
+ /** MediaItemRef id, set only when the slide genuinely originates from a MediaItemRef (never a MediaItem id). */
67
+ mediaItemRefId?: string;
61
68
  /** Display name of the underlying MediaItem / MediaItemRef. */
62
69
  name?: string;
63
70
  /** Free-form metadata dictionary of the MediaItem / MediaItemRef. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/TableRenderJobs/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,4BAA6B,SAAQ,sBAAsB;IAC1E,IAAI,EAAE,iBAAiB,CAAC;CACzB;AACD,MAAM,WAAW,0BAA2B,SAAQ,sBAAsB;IACxE,IAAI,EAAE,eAAe,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjE,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,gFAAgF;IAChF,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/TableRenderJobs/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,4BAA6B,SAAQ,sBAAsB;IAC1E,IAAI,EAAE,iBAAiB,CAAC;CACzB;AACD,MAAM,WAAW,0BAA2B,SAAQ,sBAAsB;IACxE,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,wFAAwF;AACxF,MAAM,WAAW,WAAW;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjE,+GAA+G;IAC/G,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qHAAqH;IACrH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gHAAgH;IAChH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,gFAAgF;IAChF,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crystaldesign/diva-backoffice",
3
- "version": "26.7.0-rc.3",
3
+ "version": "26.7.0-rc.5",
4
4
  "license": "COMMERCIAL",
5
5
  "devDependencies": {
6
6
  "@testing-library/jest-dom": "^6.5.0",
@@ -15,13 +15,13 @@
15
15
  "dependencies": {
16
16
  "@ant-design/icons": "6.1.0",
17
17
  "@babel/runtime": "7.24.7",
18
- "@crystaldesign/content-box": "26.7.0-rc.3",
19
- "@crystaldesign/content-item": "26.7.0-rc.3",
20
- "@crystaldesign/diva-core": "26.7.0-rc.3",
21
- "@crystaldesign/diva-utils": "26.7.0-rc.3",
22
- "@crystaldesign/media-upload": "26.7.0-rc.3",
23
- "@crystaldesign/rtf-editor": "26.7.0-rc.3",
24
- "@crystaldesign/spreadsheet": "26.7.0-rc.3",
18
+ "@crystaldesign/content-box": "26.7.0-rc.5",
19
+ "@crystaldesign/content-item": "26.7.0-rc.5",
20
+ "@crystaldesign/diva-core": "26.7.0-rc.5",
21
+ "@crystaldesign/diva-utils": "26.7.0-rc.5",
22
+ "@crystaldesign/media-upload": "26.7.0-rc.5",
23
+ "@crystaldesign/rtf-editor": "26.7.0-rc.5",
24
+ "@crystaldesign/spreadsheet": "26.7.0-rc.5",
25
25
  "@dnd-kit/core": "^6.1.0",
26
26
  "@dnd-kit/sortable": "^8.0.0",
27
27
  "@dnd-kit/utilities": "^3.2.2",
@@ -56,5 +56,5 @@
56
56
  },
57
57
  "module": "build/esm/index.js",
58
58
  "types": "./build/types/backoffice/src/index.d.ts",
59
- "gitHead": "4a22acbdf6891238ec4d7d8d8ba5860234ee9785"
59
+ "gitHead": "0b2c71ea87d1a02923cbfd26e01ca04342e9688b"
60
60
  }