@sanity/cross-dataset-duplicator 1.0.0 → 1.1.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.
@@ -1,11 +1,533 @@
1
+ /// <reference types="react" />
2
+
3
+ import {DocumentActionProps} from 'sanity'
1
4
  import {Plugin as Plugin_2} from 'sanity'
5
+ import {default as React_2} from 'react'
6
+ import {SanityDocument} from 'sanity'
2
7
 
3
8
  /**
4
- * @sanity/cross-dataset-duplicator
9
+ * Plugin: Cross Dataset Duplicator
5
10
  * @public
6
11
  */
7
12
  export declare const crossDatasetDuplicator: Plugin_2<void | PluginConfig>
8
13
 
14
+ /**
15
+ * Component to perform a migration from the Cross Dataset Duplicator plugin
16
+ * @public
17
+ */
18
+ export declare function CrossDatasetDuplicatorAction(
19
+ props: CrossDatasetDuplicatorActionProps
20
+ ): JSX.Element
21
+
22
+ /**
23
+ * Cross Dataset Duplicator document action props
24
+ * @public
25
+ */
26
+ export declare type CrossDatasetDuplicatorActionProps = {
27
+ docs: SanityDocument[]
28
+ }
29
+
30
+ /**
31
+ * Document action from the Cross Dataset Duplicator plugin
32
+ * @public
33
+ */
34
+ export declare const DuplicateToAction: {
35
+ (props: DocumentActionProps): {
36
+ disabled: SanityDocument | null
37
+ title: string | null
38
+ label: string
39
+ dialog:
40
+ | false
41
+ | {
42
+ type: string
43
+ title: string
44
+ content: JSX.Element
45
+ onClose: () => void
46
+ }
47
+ | null
48
+ onHandle: () => void
49
+ icon: React_2.ForwardRefExoticComponent<
50
+ Pick<
51
+ React_2.SVGProps<SVGSVGElement>,
52
+ | 'string'
53
+ | 'height'
54
+ | 'crossOrigin'
55
+ | 'href'
56
+ | 'max'
57
+ | 'media'
58
+ | 'method'
59
+ | 'min'
60
+ | 'name'
61
+ | 'target'
62
+ | 'type'
63
+ | 'width'
64
+ | 'className'
65
+ | 'id'
66
+ | 'lang'
67
+ | 'style'
68
+ | 'tabIndex'
69
+ | 'role'
70
+ | 'color'
71
+ | 'aria-activedescendant'
72
+ | 'aria-atomic'
73
+ | 'aria-autocomplete'
74
+ | 'aria-busy'
75
+ | 'aria-checked'
76
+ | 'aria-colcount'
77
+ | 'aria-colindex'
78
+ | 'aria-colspan'
79
+ | 'aria-controls'
80
+ | 'aria-current'
81
+ | 'aria-describedby'
82
+ | 'aria-details'
83
+ | 'aria-disabled'
84
+ | 'aria-dropeffect'
85
+ | 'aria-errormessage'
86
+ | 'aria-expanded'
87
+ | 'aria-flowto'
88
+ | 'aria-grabbed'
89
+ | 'aria-haspopup'
90
+ | 'aria-hidden'
91
+ | 'aria-invalid'
92
+ | 'aria-keyshortcuts'
93
+ | 'aria-label'
94
+ | 'aria-labelledby'
95
+ | 'aria-level'
96
+ | 'aria-live'
97
+ | 'aria-modal'
98
+ | 'aria-multiline'
99
+ | 'aria-multiselectable'
100
+ | 'aria-orientation'
101
+ | 'aria-owns'
102
+ | 'aria-placeholder'
103
+ | 'aria-posinset'
104
+ | 'aria-pressed'
105
+ | 'aria-readonly'
106
+ | 'aria-relevant'
107
+ | 'aria-required'
108
+ | 'aria-roledescription'
109
+ | 'aria-rowcount'
110
+ | 'aria-rowindex'
111
+ | 'aria-rowspan'
112
+ | 'aria-selected'
113
+ | 'aria-setsize'
114
+ | 'aria-sort'
115
+ | 'aria-valuemax'
116
+ | 'aria-valuemin'
117
+ | 'aria-valuenow'
118
+ | 'aria-valuetext'
119
+ | 'children'
120
+ | 'dangerouslySetInnerHTML'
121
+ | 'onCopy'
122
+ | 'onCopyCapture'
123
+ | 'onCut'
124
+ | 'onCutCapture'
125
+ | 'onPaste'
126
+ | 'onPasteCapture'
127
+ | 'onCompositionEnd'
128
+ | 'onCompositionEndCapture'
129
+ | 'onCompositionStart'
130
+ | 'onCompositionStartCapture'
131
+ | 'onCompositionUpdate'
132
+ | 'onCompositionUpdateCapture'
133
+ | 'onFocus'
134
+ | 'onFocusCapture'
135
+ | 'onBlur'
136
+ | 'onBlurCapture'
137
+ | 'onChange'
138
+ | 'onChangeCapture'
139
+ | 'onBeforeInput'
140
+ | 'onBeforeInputCapture'
141
+ | 'onInput'
142
+ | 'onInputCapture'
143
+ | 'onReset'
144
+ | 'onResetCapture'
145
+ | 'onSubmit'
146
+ | 'onSubmitCapture'
147
+ | 'onInvalid'
148
+ | 'onInvalidCapture'
149
+ | 'onLoad'
150
+ | 'onLoadCapture'
151
+ | 'onError'
152
+ | 'onErrorCapture'
153
+ | 'onKeyDown'
154
+ | 'onKeyDownCapture'
155
+ | 'onKeyPress'
156
+ | 'onKeyPressCapture'
157
+ | 'onKeyUp'
158
+ | 'onKeyUpCapture'
159
+ | 'onAbort'
160
+ | 'onAbortCapture'
161
+ | 'onCanPlay'
162
+ | 'onCanPlayCapture'
163
+ | 'onCanPlayThrough'
164
+ | 'onCanPlayThroughCapture'
165
+ | 'onDurationChange'
166
+ | 'onDurationChangeCapture'
167
+ | 'onEmptied'
168
+ | 'onEmptiedCapture'
169
+ | 'onEncrypted'
170
+ | 'onEncryptedCapture'
171
+ | 'onEnded'
172
+ | 'onEndedCapture'
173
+ | 'onLoadedData'
174
+ | 'onLoadedDataCapture'
175
+ | 'onLoadedMetadata'
176
+ | 'onLoadedMetadataCapture'
177
+ | 'onLoadStart'
178
+ | 'onLoadStartCapture'
179
+ | 'onPause'
180
+ | 'onPauseCapture'
181
+ | 'onPlay'
182
+ | 'onPlayCapture'
183
+ | 'onPlaying'
184
+ | 'onPlayingCapture'
185
+ | 'onProgress'
186
+ | 'onProgressCapture'
187
+ | 'onRateChange'
188
+ | 'onRateChangeCapture'
189
+ | 'onResize'
190
+ | 'onResizeCapture'
191
+ | 'onSeeked'
192
+ | 'onSeekedCapture'
193
+ | 'onSeeking'
194
+ | 'onSeekingCapture'
195
+ | 'onStalled'
196
+ | 'onStalledCapture'
197
+ | 'onSuspend'
198
+ | 'onSuspendCapture'
199
+ | 'onTimeUpdate'
200
+ | 'onTimeUpdateCapture'
201
+ | 'onVolumeChange'
202
+ | 'onVolumeChangeCapture'
203
+ | 'onWaiting'
204
+ | 'onWaitingCapture'
205
+ | 'onAuxClick'
206
+ | 'onAuxClickCapture'
207
+ | 'onClick'
208
+ | 'onClickCapture'
209
+ | 'onContextMenu'
210
+ | 'onContextMenuCapture'
211
+ | 'onDoubleClick'
212
+ | 'onDoubleClickCapture'
213
+ | 'onDrag'
214
+ | 'onDragCapture'
215
+ | 'onDragEnd'
216
+ | 'onDragEndCapture'
217
+ | 'onDragEnter'
218
+ | 'onDragEnterCapture'
219
+ | 'onDragExit'
220
+ | 'onDragExitCapture'
221
+ | 'onDragLeave'
222
+ | 'onDragLeaveCapture'
223
+ | 'onDragOver'
224
+ | 'onDragOverCapture'
225
+ | 'onDragStart'
226
+ | 'onDragStartCapture'
227
+ | 'onDrop'
228
+ | 'onDropCapture'
229
+ | 'onMouseDown'
230
+ | 'onMouseDownCapture'
231
+ | 'onMouseEnter'
232
+ | 'onMouseLeave'
233
+ | 'onMouseMove'
234
+ | 'onMouseMoveCapture'
235
+ | 'onMouseOut'
236
+ | 'onMouseOutCapture'
237
+ | 'onMouseOver'
238
+ | 'onMouseOverCapture'
239
+ | 'onMouseUp'
240
+ | 'onMouseUpCapture'
241
+ | 'onSelect'
242
+ | 'onSelectCapture'
243
+ | 'onTouchCancel'
244
+ | 'onTouchCancelCapture'
245
+ | 'onTouchEnd'
246
+ | 'onTouchEndCapture'
247
+ | 'onTouchMove'
248
+ | 'onTouchMoveCapture'
249
+ | 'onTouchStart'
250
+ | 'onTouchStartCapture'
251
+ | 'onPointerDown'
252
+ | 'onPointerDownCapture'
253
+ | 'onPointerMove'
254
+ | 'onPointerMoveCapture'
255
+ | 'onPointerUp'
256
+ | 'onPointerUpCapture'
257
+ | 'onPointerCancel'
258
+ | 'onPointerCancelCapture'
259
+ | 'onPointerEnter'
260
+ | 'onPointerEnterCapture'
261
+ | 'onPointerLeave'
262
+ | 'onPointerLeaveCapture'
263
+ | 'onPointerOver'
264
+ | 'onPointerOverCapture'
265
+ | 'onPointerOut'
266
+ | 'onPointerOutCapture'
267
+ | 'onGotPointerCapture'
268
+ | 'onGotPointerCaptureCapture'
269
+ | 'onLostPointerCapture'
270
+ | 'onLostPointerCaptureCapture'
271
+ | 'onScroll'
272
+ | 'onScrollCapture'
273
+ | 'onWheel'
274
+ | 'onWheelCapture'
275
+ | 'onAnimationStart'
276
+ | 'onAnimationStartCapture'
277
+ | 'onAnimationEnd'
278
+ | 'onAnimationEndCapture'
279
+ | 'onAnimationIteration'
280
+ | 'onAnimationIterationCapture'
281
+ | 'onTransitionEnd'
282
+ | 'onTransitionEndCapture'
283
+ | 'key'
284
+ | 'display'
285
+ | 'overflow'
286
+ | 'radius'
287
+ | 'clipPath'
288
+ | 'filter'
289
+ | 'mask'
290
+ | 'path'
291
+ | 'fill'
292
+ | 'direction'
293
+ | 'fontSize'
294
+ | 'mode'
295
+ | 'to'
296
+ | 'accentHeight'
297
+ | 'accumulate'
298
+ | 'additive'
299
+ | 'alignmentBaseline'
300
+ | 'allowReorder'
301
+ | 'alphabetic'
302
+ | 'amplitude'
303
+ | 'arabicForm'
304
+ | 'ascent'
305
+ | 'attributeName'
306
+ | 'attributeType'
307
+ | 'autoReverse'
308
+ | 'azimuth'
309
+ | 'baseFrequency'
310
+ | 'baselineShift'
311
+ | 'baseProfile'
312
+ | 'bbox'
313
+ | 'begin'
314
+ | 'bias'
315
+ | 'by'
316
+ | 'calcMode'
317
+ | 'capHeight'
318
+ | 'clip'
319
+ | 'clipPathUnits'
320
+ | 'clipRule'
321
+ | 'colorInterpolation'
322
+ | 'colorInterpolationFilters'
323
+ | 'colorProfile'
324
+ | 'colorRendering'
325
+ | 'contentScriptType'
326
+ | 'contentStyleType'
327
+ | 'cursor'
328
+ | 'cx'
329
+ | 'cy'
330
+ | 'd'
331
+ | 'decelerate'
332
+ | 'descent'
333
+ | 'diffuseConstant'
334
+ | 'divisor'
335
+ | 'dominantBaseline'
336
+ | 'dur'
337
+ | 'dx'
338
+ | 'dy'
339
+ | 'edgeMode'
340
+ | 'elevation'
341
+ | 'enableBackground'
342
+ | 'end'
343
+ | 'exponent'
344
+ | 'externalResourcesRequired'
345
+ | 'fillOpacity'
346
+ | 'fillRule'
347
+ | 'filterRes'
348
+ | 'filterUnits'
349
+ | 'floodColor'
350
+ | 'floodOpacity'
351
+ | 'focusable'
352
+ | 'fontFamily'
353
+ | 'fontSizeAdjust'
354
+ | 'fontStretch'
355
+ | 'fontStyle'
356
+ | 'fontVariant'
357
+ | 'fontWeight'
358
+ | 'format'
359
+ | 'fr'
360
+ | 'from'
361
+ | 'fx'
362
+ | 'fy'
363
+ | 'g1'
364
+ | 'g2'
365
+ | 'glyphName'
366
+ | 'glyphOrientationHorizontal'
367
+ | 'glyphOrientationVertical'
368
+ | 'glyphRef'
369
+ | 'gradientTransform'
370
+ | 'gradientUnits'
371
+ | 'hanging'
372
+ | 'horizAdvX'
373
+ | 'horizOriginX'
374
+ | 'ideographic'
375
+ | 'imageRendering'
376
+ | 'in2'
377
+ | 'in'
378
+ | 'intercept'
379
+ | 'k1'
380
+ | 'k2'
381
+ | 'k3'
382
+ | 'k4'
383
+ | 'k'
384
+ | 'kernelMatrix'
385
+ | 'kernelUnitLength'
386
+ | 'kerning'
387
+ | 'keyPoints'
388
+ | 'keySplines'
389
+ | 'keyTimes'
390
+ | 'lengthAdjust'
391
+ | 'letterSpacing'
392
+ | 'lightingColor'
393
+ | 'limitingConeAngle'
394
+ | 'local'
395
+ | 'markerEnd'
396
+ | 'markerHeight'
397
+ | 'markerMid'
398
+ | 'markerStart'
399
+ | 'markerUnits'
400
+ | 'markerWidth'
401
+ | 'maskContentUnits'
402
+ | 'maskUnits'
403
+ | 'mathematical'
404
+ | 'numOctaves'
405
+ | 'offset'
406
+ | 'opacity'
407
+ | 'operator'
408
+ | 'order'
409
+ | 'orient'
410
+ | 'orientation'
411
+ | 'origin'
412
+ | 'overlinePosition'
413
+ | 'overlineThickness'
414
+ | 'paintOrder'
415
+ | 'panose1'
416
+ | 'pathLength'
417
+ | 'patternContentUnits'
418
+ | 'patternTransform'
419
+ | 'patternUnits'
420
+ | 'pointerEvents'
421
+ | 'points'
422
+ | 'pointsAtX'
423
+ | 'pointsAtY'
424
+ | 'pointsAtZ'
425
+ | 'preserveAlpha'
426
+ | 'preserveAspectRatio'
427
+ | 'primitiveUnits'
428
+ | 'r'
429
+ | 'refX'
430
+ | 'refY'
431
+ | 'renderingIntent'
432
+ | 'repeatCount'
433
+ | 'repeatDur'
434
+ | 'requiredExtensions'
435
+ | 'requiredFeatures'
436
+ | 'restart'
437
+ | 'result'
438
+ | 'rotate'
439
+ | 'rx'
440
+ | 'ry'
441
+ | 'scale'
442
+ | 'seed'
443
+ | 'shapeRendering'
444
+ | 'slope'
445
+ | 'spacing'
446
+ | 'specularConstant'
447
+ | 'specularExponent'
448
+ | 'speed'
449
+ | 'spreadMethod'
450
+ | 'startOffset'
451
+ | 'stdDeviation'
452
+ | 'stemh'
453
+ | 'stemv'
454
+ | 'stitchTiles'
455
+ | 'stopColor'
456
+ | 'stopOpacity'
457
+ | 'strikethroughPosition'
458
+ | 'strikethroughThickness'
459
+ | 'stroke'
460
+ | 'strokeDasharray'
461
+ | 'strokeDashoffset'
462
+ | 'strokeLinecap'
463
+ | 'strokeLinejoin'
464
+ | 'strokeMiterlimit'
465
+ | 'strokeOpacity'
466
+ | 'strokeWidth'
467
+ | 'surfaceScale'
468
+ | 'systemLanguage'
469
+ | 'tableValues'
470
+ | 'targetX'
471
+ | 'targetY'
472
+ | 'textAnchor'
473
+ | 'textDecoration'
474
+ | 'textLength'
475
+ | 'textRendering'
476
+ | 'transform'
477
+ | 'u1'
478
+ | 'u2'
479
+ | 'underlinePosition'
480
+ | 'underlineThickness'
481
+ | 'unicode'
482
+ | 'unicodeBidi'
483
+ | 'unicodeRange'
484
+ | 'unitsPerEm'
485
+ | 'vAlphabetic'
486
+ | 'values'
487
+ | 'vectorEffect'
488
+ | 'version'
489
+ | 'vertAdvY'
490
+ | 'vertOriginX'
491
+ | 'vertOriginY'
492
+ | 'vHanging'
493
+ | 'vIdeographic'
494
+ | 'viewBox'
495
+ | 'viewTarget'
496
+ | 'visibility'
497
+ | 'vMathematical'
498
+ | 'widths'
499
+ | 'wordSpacing'
500
+ | 'writingMode'
501
+ | 'x1'
502
+ | 'x2'
503
+ | 'x'
504
+ | 'xChannelSelector'
505
+ | 'xHeight'
506
+ | 'xlinkActuate'
507
+ | 'xlinkArcrole'
508
+ | 'xlinkHref'
509
+ | 'xlinkRole'
510
+ | 'xlinkShow'
511
+ | 'xlinkTitle'
512
+ | 'xlinkType'
513
+ | 'xmlBase'
514
+ | 'xmlLang'
515
+ | 'xmlns'
516
+ | 'xmlnsXlink'
517
+ | 'xmlSpace'
518
+ | 'y1'
519
+ | 'y2'
520
+ | 'y'
521
+ | 'yChannelSelector'
522
+ | 'z'
523
+ | 'zoomAndPan'
524
+ > &
525
+ React_2.RefAttributes<SVGSVGElement>
526
+ >
527
+ }
528
+ action: string
529
+ }
530
+
9
531
  /**
10
532
  * Plugin configuration
11
533
  * @public
@@ -17,4 +539,10 @@ export declare interface PluginConfig {
17
539
  follow?: ('inbound' | 'outbound')[]
18
540
  }
19
541
 
542
+ /**
543
+ * Plugin config context hook from the Cross Dataset Duplicator plugin
544
+ * @public
545
+ */
546
+ export declare function useCrossDatasetDuplicatorConfig(): PluginConfig
547
+
20
548
  export {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cross-dataset-duplicator",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Empower content editors to migrate Documents and Assets between Sanity Projects and Datasets from inside Sanity Studio",
5
5
  "author": "Sanity.io <hello@sanity.io>",
6
6
  "license": "MIT",
@@ -1,18 +1,15 @@
1
1
  import React, {useState} from 'react'
2
2
  import {LaunchIcon} from '@sanity/icons'
3
3
  import {DocumentActionProps} from 'sanity'
4
- import {PluginConfig} from '../types'
5
4
 
6
- import CrossDatasetDuplicator from '../components/CrossDatasetDuplicator'
5
+ import {CrossDatasetDuplicatorAction} from '../components/CrossDatasetDuplicatorAction'
7
6
 
8
- type DuplicateToActionProps = DocumentActionProps & {pluginConfig: PluginConfig}
9
-
10
- export default function DuplicateToAction({
11
- draft,
12
- published,
13
- onComplete,
14
- pluginConfig,
15
- }: DuplicateToActionProps) {
7
+ /**
8
+ * Document action from the Cross Dataset Duplicator plugin
9
+ * @public
10
+ */
11
+ export const DuplicateToAction = (props: DocumentActionProps) => {
12
+ const {draft, published, onComplete} = props
16
13
  const [dialogOpen, setDialogOpen] = useState(false)
17
14
 
18
15
  return {
@@ -23,20 +20,7 @@ export default function DuplicateToAction({
23
20
  published && {
24
21
  type: 'modal',
25
22
  title: 'Cross Dataset Duplicator',
26
- content: (
27
- <CrossDatasetDuplicator
28
- // TODO: Re-using the tool component was not clever
29
- // Undo that decision
30
- // @ts-ignore
31
- tool={{
32
- options: {
33
- mode: 'action',
34
- docs: [published],
35
- pluginConfig,
36
- },
37
- }}
38
- />
39
- ),
23
+ content: <CrossDatasetDuplicatorAction docs={[published]} />,
40
24
  onClose: () => {
41
25
  onComplete()
42
26
  setDialogOpen(false)
@@ -46,3 +30,5 @@ export default function DuplicateToAction({
46
30
  icon: LaunchIcon,
47
31
  }
48
32
  }
33
+
34
+ DuplicateToAction.action = 'duplicateTo'
@@ -1,14 +1,14 @@
1
1
  import React, {useEffect, useState} from 'react'
2
2
  import {useSecrets, SettingsView} from '@sanity/studio-secrets'
3
3
  import {Flex, Box, Spinner} from '@sanity/ui'
4
- import {SanityDocument, Tool} from 'sanity'
4
+ import {SanityDocument} from 'sanity'
5
5
 
6
6
  import DuplicatorQuery from './DuplicatorQuery'
7
7
  import DuplicatorWrapper from './DuplicatorWrapper'
8
8
  import ResetSecret from './ResetSecret'
9
9
  import Feedback from './Feedback'
10
10
  import {SECRET_NAMESPACE} from '../helpers/constants'
11
- import {PluginConfig} from '../types'
11
+ import {useCrossDatasetDuplicatorConfig} from '../context/ConfigProvider'
12
12
 
13
13
  // Check for auth secret (required for asset uploads)
14
14
  const secretConfigKeys = [
@@ -24,18 +24,14 @@ type Secrets = {
24
24
  bearerToken?: string
25
25
  }
26
26
 
27
- export type MultiToolConfig = {
27
+ type CrossDatasetDuplicatorProps = {
28
28
  mode: 'tool' | 'action'
29
29
  docs: SanityDocument[]
30
- pluginConfig: PluginConfig
31
- }
32
-
33
- type CrossDatasetDuplicatorProps = {
34
- tool: Tool<MultiToolConfig>
35
30
  }
36
31
 
37
32
  export default function CrossDatasetDuplicator(props: CrossDatasetDuplicatorProps) {
38
- const {mode = `tool`, docs = [], pluginConfig} = props.tool.options ?? {}
33
+ const {mode = `tool`, docs = []} = props ?? {}
34
+ const pluginConfig = useCrossDatasetDuplicatorConfig()
39
35
 
40
36
  const {loading, secrets} = useSecrets<Secrets>(SECRET_NAMESPACE)
41
37
  const [showSecretsPrompt, setShowSecretsPrompt] = useState(false)
@@ -85,12 +81,5 @@ export default function CrossDatasetDuplicator(props: CrossDatasetDuplicatorProp
85
81
  return <Feedback>No plugin config</Feedback>
86
82
  }
87
83
 
88
- return (
89
- <DuplicatorWrapper
90
- docs={docs}
91
- token={secrets?.bearerToken}
92
- pluginConfig={pluginConfig}
93
- // draftIds={[]}
94
- />
95
- )
84
+ return <DuplicatorWrapper docs={docs} token={secrets?.bearerToken} pluginConfig={pluginConfig} />
96
85
  }
@@ -0,0 +1,14 @@
1
+ import React from 'react'
2
+ import {CrossDatasetDuplicatorActionProps} from '../types'
3
+
4
+ import CrossDatasetDuplicator from './CrossDatasetDuplicator'
5
+
6
+ /**
7
+ * Component to perform a migration from the Cross Dataset Duplicator plugin
8
+ * @public
9
+ */
10
+ export function CrossDatasetDuplicatorAction(props: CrossDatasetDuplicatorActionProps) {
11
+ const {docs = []} = props
12
+
13
+ return <CrossDatasetDuplicator mode="action" docs={docs} />
14
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react'
2
+ import {SanityDocument, Tool} from 'sanity'
3
+
4
+ import CrossDatasetDuplicator from './CrossDatasetDuplicator'
5
+
6
+ export type MultiToolConfig = {
7
+ docs: SanityDocument[]
8
+ }
9
+
10
+ type CrossDatasetDuplicatorProps = {
11
+ tool: Tool<MultiToolConfig>
12
+ }
13
+
14
+ export function CrossDatasetDuplicatorTool(props: CrossDatasetDuplicatorProps) {
15
+ const {docs = []} = props.tool.options ?? {}
16
+
17
+ return <CrossDatasetDuplicator mode="tool" docs={docs} />
18
+ }