@sanity/document-internationalization 3.0.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { TrashIcon, CogIcon, SplitVerticalIcon, CheckmarkIcon, AddIcon, EditIcon, TranslateIcon, InfoOutlineIcon } from "@sanity/icons";
2
+ import { TrashIcon, CopyIcon, CogIcon, SplitVerticalIcon, CheckmarkIcon, AddIcon, EditIcon, TranslateIcon, InfoOutlineIcon } from "@sanity/icons";
3
3
  import { Flex, Spinner, Stack, Text, Card, Grid, Button, useToast, Tooltip, Box, Badge, useClickOutside, TextInput, Popover, Inline, Dialog } from "@sanity/ui";
4
4
  import { useMemo, useEffect, createContext, useContext, useState, useCallback } from "react";
5
- import { useSchema, Preview, useClient, useWorkspace, isDocumentSchemaType, pathToString, useEditState, useValidationStatus, TextWithTone, PatchEvent, unset, defineType, defineField, definePlugin, isSanityDocument } from "sanity";
5
+ import { useSchema, Preview, useClient, useWorkspace, defineLocaleResourceBundle, useDocumentStore, useDocumentOperation, useDocumentPairPermissions, DEFAULT_STUDIO_CLIENT_OPTIONS, useTranslation, useCurrentUser, InsufficientPermissionsMessage, isDocumentSchemaType, pathToString, useEditState, useValidationStatus, TextWithTone, PatchEvent, unset, defineType, defineField, definePlugin, isSanityDocument } from "sanity";
6
6
  import { Feedback, useListeningQuery } from "sanity-plugin-utils";
7
7
  import { uuid } from "@sanity/uuid";
8
- import { RouterContext } from "sanity/router";
9
- import { usePaneRouter, useDocumentPane } from "sanity/structure";
8
+ import { useRouter, RouterContext } from "sanity/router";
9
+ import { structureLocaleNamespace, usePaneRouter, useDocumentPane } from "sanity/structure";
10
10
  import { Mutation, extractWithPath } from "@sanity/mutator";
11
11
  import { styled } from "styled-components";
12
12
  import { internationalizedArray } from "sanity-plugin-internationalized-array";
@@ -21,7 +21,8 @@ const METADATA_SCHEMA_NAME = "translation.metadata", TRANSLATIONS_ARRAY_NAME = "
21
21
  weakReferences: !1,
22
22
  bulkPublish: !1,
23
23
  metadataFields: [],
24
- apiVersion: API_VERSION
24
+ apiVersion: API_VERSION,
25
+ allowCreateMetaDoc: !1
25
26
  };
26
27
  function separateReferences(data = []) {
27
28
  const translations = [], otherReferences = [];
@@ -110,7 +111,7 @@ function shallowEqualArrays(arrA, arrB, equal = (a, b) => a === b) {
110
111
  return !1;
111
112
  return !0;
112
113
  }
113
- function query$1(fn, keys = null, preload = !1, config = {}) {
114
+ function query$1(fn, keys = null, preload = !1, config2 = {}) {
114
115
  keys === null && (keys = [fn]);
115
116
  for (const entry2 of globalCache)
116
117
  if (shallowEqualArrays(keys, entry2.keys, entry2.equal)) {
@@ -119,13 +120,13 @@ function query$1(fn, keys = null, preload = !1, config = {}) {
119
120
  if (Object.prototype.hasOwnProperty.call(entry2, "error"))
120
121
  throw entry2.error;
121
122
  if (Object.prototype.hasOwnProperty.call(entry2, "response"))
122
- return config.lifespan && config.lifespan > 0 && (entry2.timeout && clearTimeout(entry2.timeout), entry2.timeout = setTimeout(entry2.remove, config.lifespan)), entry2.response;
123
+ return config2.lifespan && config2.lifespan > 0 && (entry2.timeout && clearTimeout(entry2.timeout), entry2.timeout = setTimeout(entry2.remove, config2.lifespan)), entry2.response;
123
124
  if (!preload)
124
125
  throw entry2.promise;
125
126
  }
126
127
  const entry = {
127
128
  keys,
128
- equal: config.equal,
129
+ equal: config2.equal,
129
130
  remove: () => {
130
131
  const index = globalCache.indexOf(entry);
131
132
  index !== -1 && globalCache.splice(index, 1);
@@ -133,14 +134,14 @@ function query$1(fn, keys = null, preload = !1, config = {}) {
133
134
  promise: (
134
135
  // Execute the promise
135
136
  (isPromise(fn) ? fn : fn(...keys)).then((response) => {
136
- entry.response = response, config.lifespan && config.lifespan > 0 && (entry.timeout = setTimeout(entry.remove, config.lifespan));
137
+ entry.response = response, config2.lifespan && config2.lifespan > 0 && (entry.timeout = setTimeout(entry.remove, config2.lifespan));
137
138
  }).catch((error) => entry.error = error)
138
139
  )
139
140
  };
140
141
  if (globalCache.push(entry), !preload)
141
142
  throw entry.promise;
142
143
  }
143
- const suspend = (fn, keys, config) => query$1(fn, keys, !1, config), DocumentInternationalizationContext = createContext(DEFAULT_CONFIG);
144
+ const suspend = (fn, keys, config2) => query$1(fn, keys, !1, config2), DocumentInternationalizationContext = createContext(DEFAULT_CONFIG);
144
145
  function useDocumentInternationalizationContext() {
145
146
  return useContext(DocumentInternationalizationContext);
146
147
  }
@@ -212,7 +213,392 @@ const DeleteTranslationAction = (props) => {
212
213
  )
213
214
  }
214
215
  };
215
- }, query = `*[_type == $translationSchema && $id in translations[].value._ref]{
216
+ };
217
+ var extendStatics = function(d, b) {
218
+ return extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
219
+ d2.__proto__ = b2;
220
+ } || function(d2, b2) {
221
+ for (var p in b2)
222
+ Object.prototype.hasOwnProperty.call(b2, p) && (d2[p] = b2[p]);
223
+ }, extendStatics(d, b);
224
+ };
225
+ function __extends(d, b) {
226
+ if (typeof b != "function" && b !== null)
227
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
228
+ extendStatics(d, b);
229
+ function __() {
230
+ this.constructor = d;
231
+ }
232
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
233
+ }
234
+ function __values(o) {
235
+ var s = typeof Symbol == "function" && Symbol.iterator, m = s && o[s], i = 0;
236
+ if (m)
237
+ return m.call(o);
238
+ if (o && typeof o.length == "number")
239
+ return {
240
+ next: function() {
241
+ return o && i >= o.length && (o = void 0), { value: o && o[i++], done: !o };
242
+ }
243
+ };
244
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
245
+ }
246
+ function __read(o, n) {
247
+ var m = typeof Symbol == "function" && o[Symbol.iterator];
248
+ if (!m)
249
+ return o;
250
+ var i = m.call(o), r, ar = [], e;
251
+ try {
252
+ for (; (n === void 0 || n-- > 0) && !(r = i.next()).done; )
253
+ ar.push(r.value);
254
+ } catch (error) {
255
+ e = { error };
256
+ } finally {
257
+ try {
258
+ r && !r.done && (m = i.return) && m.call(i);
259
+ } finally {
260
+ if (e)
261
+ throw e.error;
262
+ }
263
+ }
264
+ return ar;
265
+ }
266
+ function __spreadArray(to, from, pack) {
267
+ if (pack || arguments.length === 2)
268
+ for (var i = 0, l = from.length, ar; i < l; i++)
269
+ (ar || !(i in from)) && (ar || (ar = Array.prototype.slice.call(from, 0, i)), ar[i] = from[i]);
270
+ return to.concat(ar || Array.prototype.slice.call(from));
271
+ }
272
+ function isFunction(value) {
273
+ return typeof value == "function";
274
+ }
275
+ function createErrorClass(createImpl) {
276
+ var _super = function(instance) {
277
+ Error.call(instance), instance.stack = new Error().stack;
278
+ }, ctorFunc = createImpl(_super);
279
+ return ctorFunc.prototype = Object.create(Error.prototype), ctorFunc.prototype.constructor = ctorFunc, ctorFunc;
280
+ }
281
+ var UnsubscriptionError = createErrorClass(function(_super) {
282
+ return function(errors) {
283
+ _super(this), this.message = errors ? errors.length + ` errors occurred during unsubscription:
284
+ ` + errors.map(function(err, i) {
285
+ return i + 1 + ") " + err.toString();
286
+ }).join(`
287
+ `) : "", this.name = "UnsubscriptionError", this.errors = errors;
288
+ };
289
+ });
290
+ function arrRemove(arr, item) {
291
+ if (arr) {
292
+ var index = arr.indexOf(item);
293
+ 0 <= index && arr.splice(index, 1);
294
+ }
295
+ }
296
+ var Subscription = function() {
297
+ function Subscription2(initialTeardown) {
298
+ this.initialTeardown = initialTeardown, this.closed = !1, this._parentage = null, this._finalizers = null;
299
+ }
300
+ return Subscription2.prototype.unsubscribe = function() {
301
+ var e_1, _a, e_2, _b, errors;
302
+ if (!this.closed) {
303
+ this.closed = !0;
304
+ var _parentage = this._parentage;
305
+ if (_parentage)
306
+ if (this._parentage = null, Array.isArray(_parentage))
307
+ try {
308
+ for (var _parentage_1 = __values(_parentage), _parentage_1_1 = _parentage_1.next(); !_parentage_1_1.done; _parentage_1_1 = _parentage_1.next()) {
309
+ var parent_1 = _parentage_1_1.value;
310
+ parent_1.remove(this);
311
+ }
312
+ } catch (e_1_1) {
313
+ e_1 = { error: e_1_1 };
314
+ } finally {
315
+ try {
316
+ _parentage_1_1 && !_parentage_1_1.done && (_a = _parentage_1.return) && _a.call(_parentage_1);
317
+ } finally {
318
+ if (e_1)
319
+ throw e_1.error;
320
+ }
321
+ }
322
+ else
323
+ _parentage.remove(this);
324
+ var initialFinalizer = this.initialTeardown;
325
+ if (isFunction(initialFinalizer))
326
+ try {
327
+ initialFinalizer();
328
+ } catch (e) {
329
+ errors = e instanceof UnsubscriptionError ? e.errors : [e];
330
+ }
331
+ var _finalizers = this._finalizers;
332
+ if (_finalizers) {
333
+ this._finalizers = null;
334
+ try {
335
+ for (var _finalizers_1 = __values(_finalizers), _finalizers_1_1 = _finalizers_1.next(); !_finalizers_1_1.done; _finalizers_1_1 = _finalizers_1.next()) {
336
+ var finalizer = _finalizers_1_1.value;
337
+ try {
338
+ execFinalizer(finalizer);
339
+ } catch (err) {
340
+ errors = errors != null ? errors : [], err instanceof UnsubscriptionError ? errors = __spreadArray(__spreadArray([], __read(errors)), __read(err.errors)) : errors.push(err);
341
+ }
342
+ }
343
+ } catch (e_2_1) {
344
+ e_2 = { error: e_2_1 };
345
+ } finally {
346
+ try {
347
+ _finalizers_1_1 && !_finalizers_1_1.done && (_b = _finalizers_1.return) && _b.call(_finalizers_1);
348
+ } finally {
349
+ if (e_2)
350
+ throw e_2.error;
351
+ }
352
+ }
353
+ }
354
+ if (errors)
355
+ throw new UnsubscriptionError(errors);
356
+ }
357
+ }, Subscription2.prototype.add = function(teardown) {
358
+ var _a;
359
+ if (teardown && teardown !== this)
360
+ if (this.closed)
361
+ execFinalizer(teardown);
362
+ else {
363
+ if (teardown instanceof Subscription2) {
364
+ if (teardown.closed || teardown._hasParent(this))
365
+ return;
366
+ teardown._addParent(this);
367
+ }
368
+ (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);
369
+ }
370
+ }, Subscription2.prototype._hasParent = function(parent) {
371
+ var _parentage = this._parentage;
372
+ return _parentage === parent || Array.isArray(_parentage) && _parentage.includes(parent);
373
+ }, Subscription2.prototype._addParent = function(parent) {
374
+ var _parentage = this._parentage;
375
+ this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;
376
+ }, Subscription2.prototype._removeParent = function(parent) {
377
+ var _parentage = this._parentage;
378
+ _parentage === parent ? this._parentage = null : Array.isArray(_parentage) && arrRemove(_parentage, parent);
379
+ }, Subscription2.prototype.remove = function(teardown) {
380
+ var _finalizers = this._finalizers;
381
+ _finalizers && arrRemove(_finalizers, teardown), teardown instanceof Subscription2 && teardown._removeParent(this);
382
+ }, Subscription2.EMPTY = function() {
383
+ var empty = new Subscription2();
384
+ return empty.closed = !0, empty;
385
+ }(), Subscription2;
386
+ }();
387
+ function isSubscription(value) {
388
+ return value instanceof Subscription || value && "closed" in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe);
389
+ }
390
+ function execFinalizer(finalizer) {
391
+ isFunction(finalizer) ? finalizer() : finalizer.unsubscribe();
392
+ }
393
+ var config = {
394
+ onUnhandledError: null,
395
+ onStoppedNotification: null,
396
+ Promise: void 0,
397
+ useDeprecatedSynchronousErrorHandling: !1,
398
+ useDeprecatedNextContext: !1
399
+ }, timeoutProvider = {
400
+ setTimeout: function(handler, timeout) {
401
+ for (var args = [], _i = 2; _i < arguments.length; _i++)
402
+ args[_i - 2] = arguments[_i];
403
+ return setTimeout.apply(void 0, __spreadArray([handler, timeout], __read(args)));
404
+ },
405
+ clearTimeout: function(handle) {
406
+ return clearTimeout(handle);
407
+ },
408
+ delegate: void 0
409
+ };
410
+ function reportUnhandledError(err) {
411
+ timeoutProvider.setTimeout(function() {
412
+ throw err;
413
+ });
414
+ }
415
+ function noop() {
416
+ }
417
+ var Subscriber = function(_super) {
418
+ __extends(Subscriber2, _super);
419
+ function Subscriber2(destination) {
420
+ var _this = _super.call(this) || this;
421
+ return _this.isStopped = !1, destination ? (_this.destination = destination, isSubscription(destination) && destination.add(_this)) : _this.destination = EMPTY_OBSERVER, _this;
422
+ }
423
+ return Subscriber2.create = function(next, error, complete) {
424
+ return new SafeSubscriber(next, error, complete);
425
+ }, Subscriber2.prototype.next = function(value) {
426
+ this.isStopped || this._next(value);
427
+ }, Subscriber2.prototype.error = function(err) {
428
+ this.isStopped || (this.isStopped = !0, this._error(err));
429
+ }, Subscriber2.prototype.complete = function() {
430
+ this.isStopped || (this.isStopped = !0, this._complete());
431
+ }, Subscriber2.prototype.unsubscribe = function() {
432
+ this.closed || (this.isStopped = !0, _super.prototype.unsubscribe.call(this), this.destination = null);
433
+ }, Subscriber2.prototype._next = function(value) {
434
+ this.destination.next(value);
435
+ }, Subscriber2.prototype._error = function(err) {
436
+ try {
437
+ this.destination.error(err);
438
+ } finally {
439
+ this.unsubscribe();
440
+ }
441
+ }, Subscriber2.prototype._complete = function() {
442
+ try {
443
+ this.destination.complete();
444
+ } finally {
445
+ this.unsubscribe();
446
+ }
447
+ }, Subscriber2;
448
+ }(Subscription), _bind = Function.prototype.bind;
449
+ function bind(fn, thisArg) {
450
+ return _bind.call(fn, thisArg);
451
+ }
452
+ var ConsumerObserver = function() {
453
+ function ConsumerObserver2(partialObserver) {
454
+ this.partialObserver = partialObserver;
455
+ }
456
+ return ConsumerObserver2.prototype.next = function(value) {
457
+ var partialObserver = this.partialObserver;
458
+ if (partialObserver.next)
459
+ try {
460
+ partialObserver.next(value);
461
+ } catch (error) {
462
+ handleUnhandledError(error);
463
+ }
464
+ }, ConsumerObserver2.prototype.error = function(err) {
465
+ var partialObserver = this.partialObserver;
466
+ if (partialObserver.error)
467
+ try {
468
+ partialObserver.error(err);
469
+ } catch (error) {
470
+ handleUnhandledError(error);
471
+ }
472
+ else
473
+ handleUnhandledError(err);
474
+ }, ConsumerObserver2.prototype.complete = function() {
475
+ var partialObserver = this.partialObserver;
476
+ if (partialObserver.complete)
477
+ try {
478
+ partialObserver.complete();
479
+ } catch (error) {
480
+ handleUnhandledError(error);
481
+ }
482
+ }, ConsumerObserver2;
483
+ }(), SafeSubscriber = function(_super) {
484
+ __extends(SafeSubscriber2, _super);
485
+ function SafeSubscriber2(observerOrNext, error, complete) {
486
+ var _this = _super.call(this) || this, partialObserver;
487
+ if (isFunction(observerOrNext) || !observerOrNext)
488
+ partialObserver = {
489
+ next: observerOrNext != null ? observerOrNext : void 0,
490
+ error: error != null ? error : void 0,
491
+ complete: complete != null ? complete : void 0
492
+ };
493
+ else {
494
+ var context_1;
495
+ _this && config.useDeprecatedNextContext ? (context_1 = Object.create(observerOrNext), context_1.unsubscribe = function() {
496
+ return _this.unsubscribe();
497
+ }, partialObserver = {
498
+ next: observerOrNext.next && bind(observerOrNext.next, context_1),
499
+ error: observerOrNext.error && bind(observerOrNext.error, context_1),
500
+ complete: observerOrNext.complete && bind(observerOrNext.complete, context_1)
501
+ }) : partialObserver = observerOrNext;
502
+ }
503
+ return _this.destination = new ConsumerObserver(partialObserver), _this;
504
+ }
505
+ return SafeSubscriber2;
506
+ }(Subscriber);
507
+ function handleUnhandledError(error) {
508
+ reportUnhandledError(error);
509
+ }
510
+ function defaultErrorHandler(err) {
511
+ throw err;
512
+ }
513
+ var EMPTY_OBSERVER = {
514
+ closed: !0,
515
+ next: noop,
516
+ error: defaultErrorHandler,
517
+ complete: noop
518
+ };
519
+ function hasLift(source) {
520
+ return isFunction(source == null ? void 0 : source.lift);
521
+ }
522
+ function operate(init) {
523
+ return function(source) {
524
+ if (hasLift(source))
525
+ return source.lift(function(liftedSource) {
526
+ try {
527
+ return init(liftedSource, this);
528
+ } catch (err) {
529
+ this.error(err);
530
+ }
531
+ });
532
+ throw new TypeError("Unable to lift unknown Observable type");
533
+ };
534
+ }
535
+ function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) {
536
+ return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);
537
+ }
538
+ var OperatorSubscriber = function(_super) {
539
+ __extends(OperatorSubscriber2, _super);
540
+ function OperatorSubscriber2(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) {
541
+ var _this = _super.call(this, destination) || this;
542
+ return _this.onFinalize = onFinalize, _this.shouldUnsubscribe = shouldUnsubscribe, _this._next = onNext ? function(value) {
543
+ try {
544
+ onNext(value);
545
+ } catch (err) {
546
+ destination.error(err);
547
+ }
548
+ } : _super.prototype._next, _this._error = onError ? function(err) {
549
+ try {
550
+ onError(err);
551
+ } catch (err2) {
552
+ destination.error(err2);
553
+ } finally {
554
+ this.unsubscribe();
555
+ }
556
+ } : _super.prototype._error, _this._complete = onComplete ? function() {
557
+ try {
558
+ onComplete();
559
+ } catch (err) {
560
+ destination.error(err);
561
+ } finally {
562
+ this.unsubscribe();
563
+ }
564
+ } : _super.prototype._complete, _this;
565
+ }
566
+ return OperatorSubscriber2.prototype.unsubscribe = function() {
567
+ var _a;
568
+ if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {
569
+ var closed_1 = this.closed;
570
+ _super.prototype.unsubscribe.call(this), !closed_1 && ((_a = this.onFinalize) === null || _a === void 0 || _a.call(this));
571
+ }
572
+ }, OperatorSubscriber2;
573
+ }(Subscriber), EmptyError = createErrorClass(function(_super) {
574
+ return function() {
575
+ _super(this), this.name = "EmptyError", this.message = "no elements in sequence";
576
+ };
577
+ });
578
+ function firstValueFrom(source, config2) {
579
+ var hasConfig = typeof config2 == "object";
580
+ return new Promise(function(resolve, reject) {
581
+ var subscriber = new SafeSubscriber({
582
+ next: function(value) {
583
+ resolve(value), subscriber.unsubscribe();
584
+ },
585
+ error: reject,
586
+ complete: function() {
587
+ hasConfig ? resolve(config2.defaultValue) : reject(new EmptyError());
588
+ }
589
+ });
590
+ source.subscribe(subscriber);
591
+ });
592
+ }
593
+ function filter(predicate, thisArg) {
594
+ return operate(function(source, subscriber) {
595
+ var index = 0;
596
+ source.subscribe(createOperatorSubscriber(subscriber, function(value) {
597
+ return predicate.call(thisArg, value, index++) && subscriber.next(value);
598
+ }));
599
+ });
600
+ }
601
+ const query = `*[_type == $translationSchema && $id in translations[].value._ref]{
216
602
  _id,
217
603
  _createdAt,
218
604
  translations
@@ -223,6 +609,129 @@ function useTranslationMetadata(id) {
223
609
  });
224
610
  return { data, loading, error };
225
611
  }
612
+ const documenti18nLocaleNamespace = "document-internationalization", documentInternationalizationUsEnglishLocaleBundle = defineLocaleResourceBundle({
613
+ locale: "en-US",
614
+ namespace: documenti18nLocaleNamespace,
615
+ resources: () => import("./_legacy/resources.esm.js")
616
+ }), DISABLED_REASON_KEY = {
617
+ METADATA_NOT_FOUND: "action.duplicate.disabled.missing-metadata",
618
+ MULTIPLE_METADATA: "action.duplicate.disabled.multiple-metadata",
619
+ NOTHING_TO_DUPLICATE: "action.duplicate.disabled.nothing-to-duplicate",
620
+ NOT_READY: "action.duplicate.disabled.not-ready"
621
+ }, DuplicateWithTranslationsAction = ({
622
+ id,
623
+ type,
624
+ onComplete
625
+ }) => {
626
+ const documentStore = useDocumentStore(), { duplicate } = useDocumentOperation(id, type), { navigateIntent } = useRouter(), [isDuplicating, setDuplicating] = useState(!1), [permissions, isPermissionsLoading] = useDocumentPairPermissions({
627
+ id,
628
+ type,
629
+ permission: "duplicate"
630
+ }), { data, loading: isMetadataDocumentLoading } = useTranslationMetadata(id), hasOneMetadataDocument = useMemo(() => Array.isArray(data) && data.length <= 1, [data]), metadataDocument = Array.isArray(data) && data.length ? data[0] : null, client = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS), toast = useToast(), { t: s } = useTranslation(structureLocaleNamespace), { t: d } = useTranslation(documenti18nLocaleNamespace), currentUser = useCurrentUser(), handle = useCallback(async () => {
631
+ setDuplicating(!0);
632
+ try {
633
+ if (!metadataDocument)
634
+ throw new Error("Metadata document not found");
635
+ const translations = /* @__PURE__ */ new Map();
636
+ await Promise.all(
637
+ metadataDocument[TRANSLATIONS_ARRAY_NAME].map(async (translation) => {
638
+ var _a;
639
+ const dupeId2 = uuid(), locale = translation._key, docId = (_a = translation.value) == null ? void 0 : _a._ref;
640
+ if (!docId)
641
+ throw new Error("Translation document not found");
642
+ const { duplicate: duplicateTranslation } = await firstValueFrom(
643
+ documentStore.pair.editOperations(docId, type).pipe(filter((op) => op.duplicate.disabled !== "NOT_READY"))
644
+ );
645
+ if (duplicateTranslation.disabled)
646
+ throw new Error("Cannot duplicate document");
647
+ const duplicateTranslationSuccess = firstValueFrom(
648
+ documentStore.pair.operationEvents(docId, type).pipe(filter((e) => e.op === "duplicate" && e.type === "success"))
649
+ );
650
+ duplicateTranslation.execute(dupeId2), await duplicateTranslationSuccess, translations.set(locale, dupeId2);
651
+ })
652
+ );
653
+ const { duplicate: duplicateMetadata } = await firstValueFrom(
654
+ documentStore.pair.editOperations(metadataDocument._id, METADATA_SCHEMA_NAME).pipe(filter((op) => op.duplicate.disabled !== "NOT_READY"))
655
+ );
656
+ if (duplicateMetadata.disabled)
657
+ throw new Error("Cannot duplicate document");
658
+ const duplicateMetadataSuccess = firstValueFrom(
659
+ documentStore.pair.operationEvents(metadataDocument._id, METADATA_SCHEMA_NAME).pipe(filter((e) => e.op === "duplicate" && e.type === "success"))
660
+ ), dupeId = uuid();
661
+ duplicateMetadata.execute(dupeId), await duplicateMetadataSuccess;
662
+ const patch = {
663
+ set: Object.fromEntries(
664
+ Array.from(translations.entries()).map(([locale, documentId]) => [
665
+ `${TRANSLATIONS_ARRAY_NAME}[_key == "${locale}"].value._ref`,
666
+ documentId
667
+ ])
668
+ )
669
+ };
670
+ await client.transaction().patch(dupeId, patch).commit(), navigateIntent("edit", {
671
+ id: Array.from(translations.values()).at(0),
672
+ type
673
+ }), onComplete();
674
+ } catch (error) {
675
+ console.error(error), toast.push({
676
+ status: "error",
677
+ title: "Error duplicating document",
678
+ description: error instanceof Error ? error.message : "Failed to duplicate document"
679
+ });
680
+ } finally {
681
+ setDuplicating(!1);
682
+ }
683
+ }, [
684
+ client,
685
+ documentStore.pair,
686
+ metadataDocument,
687
+ navigateIntent,
688
+ onComplete,
689
+ toast,
690
+ type
691
+ ]);
692
+ return useMemo(() => !isPermissionsLoading && !(permissions != null && permissions.granted) ? {
693
+ icon: CopyIcon,
694
+ disabled: !0,
695
+ label: d("action.duplicate.label"),
696
+ title: /* @__PURE__ */ jsx(
697
+ InsufficientPermissionsMessage,
698
+ {
699
+ context: "duplicate-document",
700
+ currentUser
701
+ }
702
+ )
703
+ } : !isMetadataDocumentLoading && !metadataDocument ? {
704
+ icon: CopyIcon,
705
+ disabled: !0,
706
+ label: d("action.duplicate.label"),
707
+ title: d(DISABLED_REASON_KEY.METADATA_NOT_FOUND)
708
+ } : hasOneMetadataDocument ? {
709
+ icon: CopyIcon,
710
+ disabled: isDuplicating || !!duplicate.disabled || isPermissionsLoading || isMetadataDocumentLoading,
711
+ label: isDuplicating ? s("action.duplicate.running.label") : d("action.duplicate.label"),
712
+ title: duplicate.disabled ? s(DISABLED_REASON_KEY[duplicate.disabled]) : "",
713
+ onHandle: handle
714
+ } : {
715
+ icon: CopyIcon,
716
+ disabled: !0,
717
+ label: d("action.duplicate.label"),
718
+ title: d(DISABLED_REASON_KEY.MULTIPLE_METADATA)
719
+ }, [
720
+ currentUser,
721
+ duplicate.disabled,
722
+ handle,
723
+ hasOneMetadataDocument,
724
+ isDuplicating,
725
+ isMetadataDocumentLoading,
726
+ isPermissionsLoading,
727
+ metadataDocument,
728
+ permissions == null ? void 0 : permissions.granted,
729
+ s,
730
+ d
731
+ ]);
732
+ };
733
+ DuplicateWithTranslationsAction.action = "duplicate";
734
+ DuplicateWithTranslationsAction.displayName = "DuplicateWithTranslationsAction";
226
735
  function useOpenInNewPane(id, type) {
227
736
  const routerContext = useContext(RouterContext), { routerPanesState, groupIndex } = usePaneRouter();
228
737
  return useCallback(() => {
@@ -243,42 +752,75 @@ function useOpenInNewPane(id, type) {
243
752
  routerContext.navigateUrl({ path: href });
244
753
  }, [id, type, routerContext, routerPanesState, groupIndex]);
245
754
  }
755
+ function createReference(key, ref, type, strengthenOnPublish = !0) {
756
+ return {
757
+ _key: key,
758
+ _type: "internationalizedArrayReferenceValue",
759
+ value: {
760
+ _type: "reference",
761
+ _ref: ref,
762
+ _weak: !0,
763
+ // If the user has configured weakReferences, we won't want to strengthen them
764
+ ...strengthenOnPublish ? { _strengthenOnPublish: { type } } : {}
765
+ }
766
+ };
767
+ }
246
768
  function LanguageManage(props) {
247
- const { id } = props, open = useOpenInNewPane(id, METADATA_SCHEMA_NAME);
769
+ const { id, metadataId, schemaType, documentId, sourceLanguageId } = props, open = useOpenInNewPane(id, METADATA_SCHEMA_NAME), openCreated = useOpenInNewPane(metadataId, METADATA_SCHEMA_NAME), { allowCreateMetaDoc, apiVersion, weakReferences } = useDocumentInternationalizationContext(), client = useClient({ apiVersion }), [userHasClicked, setUserHasClicked] = useState(!1), canCreate = !id && !!metadataId && allowCreateMetaDoc, handleClick = useCallback(() => {
770
+ if (!id && metadataId && sourceLanguageId) {
771
+ setUserHasClicked(!0);
772
+ const transaction = client.transaction(), sourceReference = createReference(
773
+ sourceLanguageId,
774
+ documentId,
775
+ schemaType.name,
776
+ !weakReferences
777
+ ), newMetadataDocument = {
778
+ _id: metadataId,
779
+ _type: METADATA_SCHEMA_NAME,
780
+ schemaTypes: [schemaType.name],
781
+ translations: [sourceReference]
782
+ };
783
+ transaction.createIfNotExists(newMetadataDocument), transaction.commit().then(() => {
784
+ setUserHasClicked(!1), openCreated();
785
+ }).catch((err) => {
786
+ console.error(err), setUserHasClicked(!1);
787
+ });
788
+ } else
789
+ open();
790
+ }, [
791
+ id,
792
+ metadataId,
793
+ sourceLanguageId,
794
+ client,
795
+ documentId,
796
+ schemaType.name,
797
+ weakReferences,
798
+ openCreated,
799
+ open
800
+ ]);
248
801
  return /* @__PURE__ */ jsx(
249
802
  Tooltip,
250
803
  {
251
804
  animate: !0,
252
- content: id ? null : /* @__PURE__ */ jsx(Box, { padding: 2, children: /* @__PURE__ */ jsx(Text, { muted: !0, size: 1, children: "Document has no other translations" }) }),
805
+ content: /* @__PURE__ */ jsx(Box, { padding: 2, children: /* @__PURE__ */ jsx(Text, { muted: !0, size: 1, children: "Document has no other translations" }) }),
253
806
  fallbackPlacements: ["right", "left"],
254
807
  placement: "top",
255
808
  portal: !0,
809
+ disabled: !!id || canCreate,
256
810
  children: /* @__PURE__ */ jsx(Stack, { children: /* @__PURE__ */ jsx(
257
811
  Button,
258
812
  {
259
- disabled: !id,
813
+ disabled: !id && !canCreate || canCreate && !sourceLanguageId || userHasClicked,
260
814
  mode: "ghost",
261
815
  text: "Manage Translations",
262
816
  icon: CogIcon,
263
- onClick: () => open()
817
+ loading: userHasClicked,
818
+ onClick: handleClick
264
819
  }
265
820
  ) })
266
821
  }
267
822
  );
268
823
  }
269
- function createReference(key, ref, type, strengthenOnPublish = !0) {
270
- return {
271
- _key: key,
272
- _type: "internationalizedArrayReferenceValue",
273
- value: {
274
- _type: "reference",
275
- _ref: ref,
276
- _weak: !0,
277
- // If the user has configured weakReferences, we won't want to strengthen them
278
- ...strengthenOnPublish ? { _strengthenOnPublish: { type } } : {}
279
- }
280
- };
281
- }
282
824
  function removeExcludedPaths(doc, schemaType) {
283
825
  if (!isDocumentSchemaType(schemaType) || !doc)
284
826
  return doc;
@@ -496,7 +1038,16 @@ function DocumentInternationalizationMenu(props) {
496
1038
  supportedLanguages
497
1039
  ), valid;
498
1040
  }, [supportedLanguages]), content = /* @__PURE__ */ jsx(Box, { padding: 1, children: error ? /* @__PURE__ */ jsx(Card, { tone: "critical", padding: 1, children: /* @__PURE__ */ jsx(Text, { children: "There was an error returning translations metadata" }) }) : /* @__PURE__ */ jsxs(Stack, { space: 1, children: [
499
- /* @__PURE__ */ jsx(LanguageManage, { id: metadata2 == null ? void 0 : metadata2._id }),
1041
+ /* @__PURE__ */ jsx(
1042
+ LanguageManage,
1043
+ {
1044
+ id: metadata2 == null ? void 0 : metadata2._id,
1045
+ documentId,
1046
+ metadataId,
1047
+ schemaType,
1048
+ sourceLanguageId
1049
+ }
1050
+ ),
500
1051
  supportedLanguages.length > 4 ? /* @__PURE__ */ jsx(
501
1052
  TextInput,
502
1053
  {
@@ -883,8 +1434,8 @@ var metadata = (schemaTypes, metadataFields) => defineType({
883
1434
  }
884
1435
  });
885
1436
  const documentInternationalization = definePlugin(
886
- (config) => {
887
- const pluginConfig = { ...DEFAULT_CONFIG, ...config }, {
1437
+ (config2) => {
1438
+ const pluginConfig = { ...DEFAULT_CONFIG, ...config2 }, {
888
1439
  supportedLanguages,
889
1440
  schemaTypes,
890
1441
  languageField,
@@ -902,6 +1453,9 @@ const documentInternationalization = definePlugin(
902
1453
  layout: (props) => DocumentInternationalizationProvider({ ...props, pluginConfig })
903
1454
  }
904
1455
  },
1456
+ i18n: {
1457
+ bundles: [documentInternationalizationUsEnglishLocaleBundle]
1458
+ },
905
1459
  // Adds:
906
1460
  // - A bulk-publishing UI component to the form
907
1461
  // - Will only work for projects on a compatible plan
@@ -1042,6 +1596,7 @@ const documentInternationalization = definePlugin(
1042
1596
  export {
1043
1597
  DeleteTranslationAction,
1044
1598
  DocumentInternationalizationMenu,
1599
+ DuplicateWithTranslationsAction,
1045
1600
  documentInternationalization,
1046
1601
  useDocumentInternationalizationContext
1047
1602
  };