@sanity/cross-dataset-duplicator 1.4.2 → 1.5.1
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/README.md +1 -1
- package/dist/index.d.mts +81 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +412 -941
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +654 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +24 -29
- package/dist/index.cjs.mjs +0 -7
- package/dist/index.esm.js +0 -1161
- package/dist/index.esm.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,69 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
var sanity = require('sanity');
|
|
7
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
-
var React = require('react');
|
|
9
|
-
var icons = require('@sanity/icons');
|
|
10
|
-
var studioSecrets = require('@sanity/studio-secrets');
|
|
11
|
-
var ui = require('@sanity/ui');
|
|
12
|
-
var mapLimit = require('async/mapLimit');
|
|
13
|
-
var asyncify = require('async/asyncify');
|
|
14
|
-
var mutator = require('@sanity/mutator');
|
|
15
|
-
var dset = require('dset');
|
|
16
|
-
var assetUtils = require('@sanity/asset-utils');
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
+
var sanity = require("sanity"), jsxRuntime = require("react/jsx-runtime"), React = require("react"), icons = require("@sanity/icons"), studioSecrets = require("@sanity/studio-secrets"), ui = require("@sanity/ui"), mapLimit = require("async/mapLimit"), asyncify = require("async/asyncify"), mutator = require("@sanity/mutator"), dset = require("dset"), assetUtils = require("@sanity/asset-utils");
|
|
17
4
|
function _interopDefaultCompat(e) {
|
|
18
|
-
return e && typeof e
|
|
19
|
-
default: e
|
|
20
|
-
};
|
|
5
|
+
return e && typeof e == "object" && "default" in e ? e : { default: e };
|
|
21
6
|
}
|
|
22
|
-
var React__default =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
7
|
+
var React__default = /* @__PURE__ */ _interopDefaultCompat(React), mapLimit__default = /* @__PURE__ */ _interopDefaultCompat(mapLimit), asyncify__default = /* @__PURE__ */ _interopDefaultCompat(asyncify);
|
|
8
|
+
function createInitialMessage(docCount = 0, refsCount = 0) {
|
|
9
|
+
return [
|
|
10
|
+
docCount === 1 ? "This Document contains" : `These ${docCount} Documents contain`,
|
|
11
|
+
refsCount === 1 ? "1 Reference." : `${refsCount} References.`,
|
|
12
|
+
refsCount === 1 ? "That Document" : "Those Documents",
|
|
13
|
+
"may have References too. If referenced Documents do not exist at the target Destination, this transaction will fail."
|
|
14
|
+
].join(" ");
|
|
30
15
|
}
|
|
31
|
-
const stickyStyles =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
backgroundColor: isDarkMode ? "rgba(10,10,10,0.95)" : "rgba(255,255,255,0.95)"
|
|
38
|
-
};
|
|
39
|
-
};
|
|
16
|
+
const stickyStyles = (isDarkMode = !0) => ({
|
|
17
|
+
position: "sticky",
|
|
18
|
+
top: 0,
|
|
19
|
+
zIndex: 100,
|
|
20
|
+
backgroundColor: isDarkMode ? "rgba(10,10,10,0.95)" : "rgba(255,255,255,0.95)"
|
|
21
|
+
});
|
|
40
22
|
async function getDocumentsInArray(options) {
|
|
41
|
-
const {
|
|
42
|
-
fetchIds
|
|
43
|
-
client,
|
|
44
|
-
pluginConfig,
|
|
45
|
-
currentIds,
|
|
46
|
-
projection
|
|
47
|
-
} = options;
|
|
48
|
-
const collection = [];
|
|
49
|
-
const filter = ["_id in $fetchIds", pluginConfig.filter].filter(Boolean).join(" && ");
|
|
50
|
-
const query = "*[".concat(filter, "]").concat(projection != null ? projection : "");
|
|
51
|
-
const data = await client.fetch(query, {
|
|
52
|
-
fetchIds: fetchIds != null ? fetchIds : []
|
|
23
|
+
const { fetchIds, client, pluginConfig, currentIds, projection } = options, collection = [], query = `*[${["_id in $fetchIds", pluginConfig.filter].filter(Boolean).join(" && ")}]${projection ?? ""}`, data = await client.fetch(query, {
|
|
24
|
+
fetchIds: fetchIds ?? []
|
|
53
25
|
});
|
|
54
|
-
if (!
|
|
26
|
+
if (!data?.length)
|
|
55
27
|
return [];
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
await Promise.all(data.map(async doc => {
|
|
63
|
-
const expr = ".._ref";
|
|
64
|
-
const references = mutator.extractWithPath(expr, doc).map(ref => ref.value);
|
|
28
|
+
const localCurrentIds = currentIds ?? /* @__PURE__ */ new Set(), newDataIds = new Set(
|
|
29
|
+
data.map((dataDoc) => dataDoc._id).filter((id) => currentIds?.size ? !localCurrentIds.has(id) : !!id)
|
|
30
|
+
);
|
|
31
|
+
return newDataIds.size && (collection.push(...data), localCurrentIds.add(...newDataIds), await Promise.all(
|
|
32
|
+
data.map(async (doc) => {
|
|
33
|
+
const references = mutator.extractWithPath(".._ref", doc).map((ref) => ref.value);
|
|
65
34
|
if (references.length) {
|
|
66
|
-
const newReferenceIds = new Set(
|
|
35
|
+
const newReferenceIds = new Set(
|
|
36
|
+
references.filter((ref) => !localCurrentIds.has(ref))
|
|
37
|
+
);
|
|
67
38
|
if (newReferenceIds.size) {
|
|
68
39
|
const referenceDocs = await getDocumentsInArray({
|
|
69
40
|
fetchIds: Array.from(newReferenceIds),
|
|
@@ -71,84 +42,63 @@ async function getDocumentsInArray(options) {
|
|
|
71
42
|
client,
|
|
72
43
|
pluginConfig
|
|
73
44
|
});
|
|
74
|
-
|
|
75
|
-
collection.push(...referenceDocs);
|
|
76
|
-
}
|
|
45
|
+
referenceDocs?.length && collection.push(...referenceDocs);
|
|
77
46
|
}
|
|
78
47
|
}
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const uniqueCollection = collection.filter(Boolean).reduce((acc, cur) => {
|
|
82
|
-
if (acc.some(doc => doc._id === cur._id)) {
|
|
83
|
-
return acc;
|
|
84
|
-
}
|
|
85
|
-
return [...acc, cur];
|
|
86
|
-
}, []);
|
|
87
|
-
return uniqueCollection;
|
|
48
|
+
})
|
|
49
|
+
)), collection.filter(Boolean).reduce((acc, cur) => acc.some((doc) => doc._id === cur._id) ? acc : [...acc, cur], []);
|
|
88
50
|
}
|
|
89
51
|
const buttons = ["All", "None", null, "New", "Existing", "Older", null, "Documents", "Assets"];
|
|
90
52
|
function SelectButtons(props) {
|
|
91
|
-
const {
|
|
92
|
-
payload,
|
|
93
|
-
setPayload
|
|
94
|
-
} = props;
|
|
95
|
-
const [disabledActions, setDisabledActions] = React.useState([]);
|
|
53
|
+
const { payload, setPayload } = props, [disabledActions, setDisabledActions] = React.useState([]);
|
|
96
54
|
React.useEffect(() => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
}, [disabledActions == null ? void 0 : disabledActions.length, payload]);
|
|
55
|
+
!disabledActions?.length && payload.every((item) => item.include) && setDisabledActions(["ALL"]);
|
|
56
|
+
}, [disabledActions?.length, payload]);
|
|
101
57
|
function handleSelectButton(action) {
|
|
102
58
|
if (!action || !payload.length) return;
|
|
103
59
|
const newPayload = [...payload];
|
|
104
60
|
switch (action) {
|
|
105
61
|
case "ALL":
|
|
106
|
-
newPayload.map(item => item.include =
|
|
62
|
+
newPayload.map((item) => item.include = !0);
|
|
107
63
|
break;
|
|
108
64
|
case "NONE":
|
|
109
|
-
newPayload.map(item => item.include =
|
|
65
|
+
newPayload.map((item) => item.include = !1);
|
|
110
66
|
break;
|
|
111
67
|
case "NEW":
|
|
112
|
-
newPayload.map(item => item.include =
|
|
68
|
+
newPayload.map((item) => item.include = item.status === "CREATE");
|
|
113
69
|
break;
|
|
114
70
|
case "EXISTING":
|
|
115
|
-
newPayload.map(item => item.include =
|
|
71
|
+
newPayload.map((item) => item.include = item.status === "EXISTS");
|
|
116
72
|
break;
|
|
117
73
|
case "OLDER":
|
|
118
|
-
newPayload.map(item => item.include =
|
|
74
|
+
newPayload.map((item) => item.include = item.status === "OVERWRITE");
|
|
119
75
|
break;
|
|
120
76
|
case "ASSETS":
|
|
121
|
-
newPayload.map(item => item.include = assetUtils.isAssetId(item.doc._id));
|
|
77
|
+
newPayload.map((item) => item.include = assetUtils.isAssetId(item.doc._id));
|
|
122
78
|
break;
|
|
123
79
|
case "DOCUMENTS":
|
|
124
|
-
newPayload.map(item => item.include = !assetUtils.isAssetId(item.doc._id));
|
|
80
|
+
newPayload.map((item) => item.include = !assetUtils.isAssetId(item.doc._id));
|
|
125
81
|
break;
|
|
126
82
|
}
|
|
127
|
-
setDisabledActions([action]);
|
|
128
|
-
setPayload(newPayload);
|
|
83
|
+
setDisabledActions([action]), setPayload(newPayload);
|
|
129
84
|
}
|
|
130
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
135
|
-
gap: 2,
|
|
136
|
-
wrap: "wrap",
|
|
137
|
-
children: buttons.map((action, actionIndex) => action ? /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
85
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 1, radius: 3, shadow: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { gap: 2, wrap: "wrap", children: buttons.map(
|
|
86
|
+
(action, actionIndex) => action ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
87
|
+
ui.Button,
|
|
88
|
+
{
|
|
138
89
|
fontSize: 1,
|
|
139
90
|
mode: "bleed",
|
|
140
91
|
padding: 2,
|
|
141
92
|
text: action,
|
|
142
93
|
disabled: disabledActions.includes(action.toUpperCase()),
|
|
143
94
|
onClick: () => handleSelectButton(action.toUpperCase())
|
|
144
|
-
},
|
|
95
|
+
},
|
|
96
|
+
action
|
|
97
|
+
) : (
|
|
145
98
|
// eslint-disable-next-line react/no-array-index-key
|
|
146
|
-
/* @__PURE__ */
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}, "divider-".concat(actionIndex)))
|
|
150
|
-
})
|
|
151
|
-
});
|
|
99
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Card, { borderLeft: !0 }, `divider-${actionIndex}`)
|
|
100
|
+
)
|
|
101
|
+
) }) });
|
|
152
102
|
}
|
|
153
103
|
const documentTones = {
|
|
154
104
|
EXISTS: "primary",
|
|
@@ -156,15 +106,13 @@ const documentTones = {
|
|
|
156
106
|
UPDATE: "caution",
|
|
157
107
|
CREATE: "positive",
|
|
158
108
|
UNPUBLISHED: "caution"
|
|
159
|
-
}
|
|
160
|
-
const assetTones = {
|
|
109
|
+
}, assetTones = {
|
|
161
110
|
EXISTS: "critical",
|
|
162
111
|
OVERWRITE: "critical",
|
|
163
112
|
UPDATE: "critical",
|
|
164
113
|
CREATE: "positive",
|
|
165
114
|
UNPUBLISHED: "default"
|
|
166
|
-
}
|
|
167
|
-
const documentMessages = {
|
|
115
|
+
}, documentMessages = {
|
|
168
116
|
// Only happens once document is copied the first time, and _updatedAt is the same
|
|
169
117
|
EXISTS: "This document already exists at the Destination with the same ID with the same Updated time.",
|
|
170
118
|
// Is true immediately after transaction as _updatedAt is updated by API after mutation
|
|
@@ -176,15 +124,13 @@ const documentMessages = {
|
|
|
176
124
|
// Document at destination doesn't exist
|
|
177
125
|
CREATE: "This document will be created at the destination.",
|
|
178
126
|
UNPUBLISHED: "A Draft version of this Document exists in this Dataset, but only the Published version will be duplicated to the destination."
|
|
179
|
-
}
|
|
180
|
-
const assetMessages = {
|
|
127
|
+
}, assetMessages = {
|
|
181
128
|
EXISTS: "This Asset already exists at the Destination",
|
|
182
129
|
OVERWRITE: "This Asset already exists at the Destination",
|
|
183
130
|
UPDATE: "This Asset already exists at the Destination",
|
|
184
131
|
CREATE: "This Asset does not yet exist at the Destination",
|
|
185
132
|
UNPUBLISHED: ""
|
|
186
|
-
}
|
|
187
|
-
const assetStatus = {
|
|
133
|
+
}, assetStatus = {
|
|
188
134
|
EXISTS: "RE-UPLOAD",
|
|
189
135
|
OVERWRITE: "RE-UPLOAD",
|
|
190
136
|
UPDATE: "RE-UPLOAD",
|
|
@@ -192,899 +138,465 @@ const assetStatus = {
|
|
|
192
138
|
UNPUBLISHED: ""
|
|
193
139
|
};
|
|
194
140
|
function StatusBadge(props) {
|
|
195
|
-
const {
|
|
196
|
-
|
|
197
|
-
isAsset
|
|
198
|
-
} = props;
|
|
199
|
-
if (!status) {
|
|
141
|
+
const { status, isAsset } = props;
|
|
142
|
+
if (!status)
|
|
200
143
|
return null;
|
|
201
|
-
}
|
|
202
144
|
const badgeTone = isAsset ? assetTones[status] : documentTones[status];
|
|
203
|
-
if (!badgeTone)
|
|
204
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Badge, {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
children:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
},
|
|
220
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
221
|
-
size: 1,
|
|
222
|
-
children: badgeText
|
|
223
|
-
})
|
|
224
|
-
}),
|
|
225
|
-
fallbackPlacements: ["right", "left"],
|
|
226
|
-
placement: "top",
|
|
227
|
-
portal: true,
|
|
228
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Badge, {
|
|
229
|
-
muted: true,
|
|
230
|
-
padding: 3,
|
|
231
|
-
fontSize: 1,
|
|
232
|
-
tone: badgeTone,
|
|
233
|
-
mode: "outline",
|
|
234
|
-
children: [badgeStatus, /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
235
|
-
marginLeft: 2,
|
|
236
|
-
display: "inline-block",
|
|
237
|
-
as: "span",
|
|
238
|
-
children: /* @__PURE__ */jsxRuntime.jsx(icons.InfoOutlineIcon, {})
|
|
239
|
-
})]
|
|
240
|
-
})
|
|
241
|
-
});
|
|
145
|
+
if (!badgeTone)
|
|
146
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { muted: !0, padding: 2, fontSize: 1, mode: "outline", children: "Checking..." });
|
|
147
|
+
const badgeText = isAsset ? assetMessages[status] : documentMessages[status], badgeStatus = isAsset ? assetStatus[status] : status;
|
|
148
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
149
|
+
ui.Tooltip,
|
|
150
|
+
{
|
|
151
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 3, style: { maxWidth: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: badgeText }) }),
|
|
152
|
+
fallbackPlacements: ["right", "left"],
|
|
153
|
+
placement: "top",
|
|
154
|
+
portal: !0,
|
|
155
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { muted: !0, padding: 3, fontSize: 1, tone: badgeTone, mode: "outline", children: [
|
|
156
|
+
badgeStatus,
|
|
157
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginLeft: 2, display: "inline-block", as: "span", children: /* @__PURE__ */ jsxRuntime.jsx(icons.InfoOutlineIcon, {}) })
|
|
158
|
+
] })
|
|
159
|
+
}
|
|
160
|
+
);
|
|
242
161
|
}
|
|
243
162
|
function Feedback(props) {
|
|
244
|
-
const {
|
|
245
|
-
|
|
246
|
-
tone = "caution"
|
|
247
|
-
} = props;
|
|
248
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
249
|
-
padding: 3,
|
|
250
|
-
radius: 2,
|
|
251
|
-
shadow: 1,
|
|
252
|
-
tone,
|
|
253
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
254
|
-
size: 1,
|
|
255
|
-
children
|
|
256
|
-
})
|
|
257
|
-
});
|
|
163
|
+
const { children, tone = "caution" } = props;
|
|
164
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 3, radius: 2, shadow: 1, tone, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children }) });
|
|
258
165
|
}
|
|
259
|
-
var __defProp$1 = Object.defineProperty;
|
|
260
|
-
var __defProps$1 = Object.defineProperties;
|
|
261
|
-
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
|
|
262
|
-
var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
|
|
263
|
-
var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
|
|
264
|
-
var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
|
|
265
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
|
|
266
|
-
enumerable: true,
|
|
267
|
-
configurable: true,
|
|
268
|
-
writable: true,
|
|
269
|
-
value
|
|
270
|
-
}) : obj[key] = value;
|
|
271
|
-
var __spreadValues$1 = (a, b) => {
|
|
272
|
-
for (var prop in b || (b = {})) if (__hasOwnProp$2.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
|
|
273
|
-
if (__getOwnPropSymbols$2) for (var prop of __getOwnPropSymbols$2(b)) {
|
|
274
|
-
if (__propIsEnum$2.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
|
|
275
|
-
}
|
|
276
|
-
return a;
|
|
277
|
-
};
|
|
278
|
-
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
279
166
|
function Duplicator(props) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
docs,
|
|
283
|
-
token,
|
|
284
|
-
pluginConfig,
|
|
285
|
-
onDuplicated
|
|
286
|
-
} = props;
|
|
287
|
-
const isDarkMode = ui.useTheme().sanity.color.dark;
|
|
288
|
-
const originClient = sanity.useClient({
|
|
289
|
-
apiVersion: pluginConfig.apiVersion
|
|
290
|
-
});
|
|
291
|
-
const schema = sanity.useSchema();
|
|
292
|
-
const workspaces = sanity.useWorkspaces();
|
|
293
|
-
const workspacesOptions = workspaces.map(workspace => __spreadProps$1(__spreadValues$1({}, workspace), {
|
|
167
|
+
const { docs, token, pluginConfig, onDuplicated } = props, isDarkMode = ui.useTheme().sanity.color.dark, originClient = sanity.useClient({ apiVersion: pluginConfig.apiVersion }), schema = sanity.useSchema(), workspaces = sanity.useWorkspaces(), workspacesOptions = workspaces.map((workspace) => ({
|
|
168
|
+
...workspace,
|
|
294
169
|
disabled: workspace.dataset === originClient.config().dataset && workspace.projectId === originClient.config().projectId
|
|
295
|
-
}))
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const [payload, setPayload] = React.useState([]);
|
|
299
|
-
const [hasReferences, setHasReferences] = React.useState(false);
|
|
300
|
-
const [isDuplicating, setIsDuplicating] = React.useState(false);
|
|
301
|
-
const [isGathering, setIsGathering] = React.useState(false);
|
|
302
|
-
const [progress, setProgress] = React.useState([0, 0]);
|
|
303
|
-
React.useEffect(() => {
|
|
304
|
-
const expr = ".._ref";
|
|
305
|
-
const initialRefs = [];
|
|
306
|
-
const initialPayload = [];
|
|
307
|
-
docs.forEach(doc => {
|
|
308
|
-
const refs = mutator.extractWithPath(expr, doc).map(ref => ref.value);
|
|
309
|
-
initialRefs.push(...refs);
|
|
310
|
-
initialPayload.push({
|
|
311
|
-
include: true,
|
|
312
|
-
doc
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
updatePayloadStatuses(initialPayload);
|
|
316
|
-
const docCount = docs.length;
|
|
317
|
-
const refsCount = initialRefs.length;
|
|
318
|
-
if (initialRefs.length) {
|
|
319
|
-
setHasReferences(true);
|
|
320
|
-
setMessage({
|
|
321
|
-
tone: "caution",
|
|
322
|
-
text: createInitialMessage(docCount, refsCount)
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
}, [docs]);
|
|
170
|
+
})), [destination, setDestination] = React.useState(
|
|
171
|
+
workspaces.length ? workspacesOptions.find((space) => !space.disabled) ?? null : null
|
|
172
|
+
), [message, setMessage] = React.useState(null), [payload, setPayload] = React.useState([]), [hasReferences, setHasReferences] = React.useState(!1), [isDuplicating, setIsDuplicating] = React.useState(!1), [isGathering, setIsGathering] = React.useState(!1), [progress, setProgress] = React.useState([0, 0]);
|
|
326
173
|
React.useEffect(() => {
|
|
174
|
+
const expr = ".._ref", initialRefs = [], initialPayload = [];
|
|
175
|
+
docs.forEach((doc) => {
|
|
176
|
+
const refs = mutator.extractWithPath(expr, doc).map((ref) => ref.value);
|
|
177
|
+
initialRefs.push(...refs), initialPayload.push({ include: !0, doc });
|
|
178
|
+
}), updatePayloadStatuses(initialPayload);
|
|
179
|
+
const docCount = docs.length, refsCount = initialRefs.length;
|
|
180
|
+
initialRefs.length && (setHasReferences(!0), setMessage({
|
|
181
|
+
tone: "caution",
|
|
182
|
+
text: createInitialMessage(docCount, refsCount)
|
|
183
|
+
}));
|
|
184
|
+
}, [docs]), React.useEffect(() => {
|
|
327
185
|
updatePayloadStatuses();
|
|
328
186
|
}, [destination]);
|
|
329
|
-
async function updatePayloadStatuses() {
|
|
330
|
-
let newPayload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
187
|
+
async function updatePayloadStatuses(newPayload = []) {
|
|
331
188
|
const payloadActual = newPayload.length ? newPayload : payload;
|
|
332
|
-
if (!payloadActual.length || !
|
|
189
|
+
if (!payloadActual.length || !destination?.name)
|
|
333
190
|
return;
|
|
334
|
-
}
|
|
335
|
-
const payloadIds = payloadActual.map(_ref => {
|
|
336
|
-
let {
|
|
337
|
-
doc
|
|
338
|
-
} = _ref;
|
|
339
|
-
return doc._id;
|
|
340
|
-
});
|
|
341
|
-
const destinationClient = originClient.withConfig({
|
|
191
|
+
const payloadIds = payloadActual.map(({ doc }) => doc._id), destinationData = await originClient.withConfig({
|
|
342
192
|
dataset: destination.dataset,
|
|
343
193
|
projectId: destination.projectId
|
|
344
|
-
})
|
|
345
|
-
|
|
346
|
-
payloadIds
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
// Document at destination is newer
|
|
357
|
-
"OVERWRITE" :
|
|
358
|
-
// Document at destination is older
|
|
359
|
-
"UPDATE";
|
|
360
|
-
}
|
|
361
|
-
} else {
|
|
362
|
-
item.status = "CREATE";
|
|
363
|
-
}
|
|
364
|
-
return item;
|
|
194
|
+
}).fetch(
|
|
195
|
+
"*[_id in $payloadIds]{ _id, _updatedAt }",
|
|
196
|
+
{ payloadIds }
|
|
197
|
+
), updatedPayload = payloadActual.map((item) => {
|
|
198
|
+
const existingDoc = destinationData.find((doc) => doc._id === item.doc._id);
|
|
199
|
+
return existingDoc?._updatedAt && item?.doc?._updatedAt ? existingDoc._updatedAt === item.doc._updatedAt ? item.status = "EXISTS" : existingDoc._updatedAt && item.doc._updatedAt && (item.status = new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt) ? (
|
|
200
|
+
// Document at destination is newer
|
|
201
|
+
"OVERWRITE"
|
|
202
|
+
) : (
|
|
203
|
+
// Document at destination is older
|
|
204
|
+
"UPDATE"
|
|
205
|
+
)) : item.status = "CREATE", item;
|
|
365
206
|
});
|
|
366
207
|
setPayload(updatedPayload);
|
|
367
208
|
}
|
|
368
209
|
function handleCheckbox(_id) {
|
|
369
|
-
const updatedPayload = payload.map(item =>
|
|
370
|
-
if (item.doc._id === _id) {
|
|
371
|
-
item.include = !item.include;
|
|
372
|
-
}
|
|
373
|
-
return item;
|
|
374
|
-
});
|
|
210
|
+
const updatedPayload = payload.map((item) => (item.doc._id === _id && (item.include = !item.include), item));
|
|
375
211
|
setPayload(updatedPayload);
|
|
376
212
|
}
|
|
377
213
|
async function handleReferences() {
|
|
378
|
-
setIsGathering(
|
|
379
|
-
const docIds = docs.map(doc => doc._id)
|
|
380
|
-
const payloadDocs = await getDocumentsInArray({
|
|
214
|
+
setIsGathering(!0);
|
|
215
|
+
const docIds = docs.map((doc) => doc._id), payloadDocs = await getDocumentsInArray({
|
|
381
216
|
fetchIds: docIds,
|
|
382
217
|
client: originClient,
|
|
383
218
|
pluginConfig
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
fetchIds: docIds.map(id => "drafts.".concat(id)),
|
|
219
|
+
}), draftDocs = await getDocumentsInArray({
|
|
220
|
+
fetchIds: docIds.map((id) => `drafts.${id}`),
|
|
387
221
|
client: originClient,
|
|
388
222
|
projection: "{_id}",
|
|
389
223
|
pluginConfig
|
|
390
|
-
})
|
|
391
|
-
const draftDocsIds = new Set(draftDocs.map(_ref2 => {
|
|
392
|
-
let {
|
|
393
|
-
_id
|
|
394
|
-
} = _ref2;
|
|
395
|
-
return _id;
|
|
396
|
-
}));
|
|
397
|
-
const payloadShaped = payloadDocs.map(doc => ({
|
|
224
|
+
}), draftDocsIds = new Set(draftDocs.map(({ _id }) => _id)), payloadShaped = payloadDocs.map((doc) => ({
|
|
398
225
|
doc,
|
|
399
226
|
// Include this in the transaction?
|
|
400
|
-
include:
|
|
227
|
+
include: !0,
|
|
401
228
|
// Does it exist at the destination?
|
|
402
229
|
status: void 0,
|
|
403
230
|
// Does it have any drafts?
|
|
404
|
-
hasDraft: draftDocsIds.has(
|
|
231
|
+
hasDraft: draftDocsIds.has(`drafts.${doc._id}`)
|
|
405
232
|
}));
|
|
406
|
-
setPayload(payloadShaped);
|
|
407
|
-
updatePayloadStatuses(payloadShaped);
|
|
408
|
-
setIsGathering(false);
|
|
233
|
+
setPayload(payloadShaped), updatePayloadStatuses(payloadShaped), setIsGathering(!1);
|
|
409
234
|
}
|
|
410
235
|
async function handleDuplicate() {
|
|
411
|
-
if (!destination)
|
|
236
|
+
if (!destination)
|
|
412
237
|
return;
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const assetsCount = payload.filter(_ref3 => {
|
|
416
|
-
let {
|
|
417
|
-
doc,
|
|
418
|
-
include
|
|
419
|
-
} = _ref3;
|
|
420
|
-
return include && assetUtils.isAssetId(doc._id);
|
|
421
|
-
}).length;
|
|
238
|
+
setIsDuplicating(!0);
|
|
239
|
+
const assetsCount = payload.filter(({ doc, include }) => include && assetUtils.isAssetId(doc._id)).length;
|
|
422
240
|
let currentProgress = 0;
|
|
423
|
-
setProgress([currentProgress, assetsCount]);
|
|
424
|
-
setMessage({
|
|
425
|
-
text: "Duplicating...",
|
|
426
|
-
tone: "transparent"
|
|
427
|
-
});
|
|
241
|
+
setProgress([currentProgress, assetsCount]), setMessage({ text: "Duplicating...", tone: "transparent" });
|
|
428
242
|
const destinationClient = originClient.withConfig({
|
|
429
243
|
apiVersion: pluginConfig.apiVersion,
|
|
430
244
|
dataset: destination.dataset,
|
|
431
245
|
projectId: destination.projectId
|
|
432
|
-
});
|
|
433
|
-
const transactionDocs = [];
|
|
434
|
-
const svgMaps = [];
|
|
246
|
+
}), transactionDocs = [], svgMaps = [];
|
|
435
247
|
async function fetchDoc(doc) {
|
|
436
248
|
if (assetUtils.isAssetId(doc._id)) {
|
|
437
|
-
const typeIsFile = assetUtils.isSanityFileAsset(doc);
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
filename: doc.originalFilename
|
|
448
|
-
};
|
|
449
|
-
const assetDoc = await destinationClient.assets.upload(typeIsFile ? "file" : "image", assetData, options);
|
|
450
|
-
if ((doc == null ? void 0 : doc.extension) === "svg") {
|
|
451
|
-
svgMaps.push({
|
|
452
|
-
old: doc._id,
|
|
453
|
-
new: assetDoc._id
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
transactionDocs.push(assetDoc);
|
|
457
|
-
doc.url = assetDoc.url;
|
|
458
|
-
doc.path = assetDoc.path;
|
|
459
|
-
});
|
|
460
|
-
currentProgress += 1;
|
|
461
|
-
setMessage({
|
|
462
|
-
text: "Duplicating ".concat(currentProgress, "/").concat(assetsCount, " ").concat(assetsCount === 1 ? "Assets" : "Assets"),
|
|
249
|
+
const typeIsFile = assetUtils.isSanityFileAsset(doc), downloadUrl = typeIsFile ? doc.url : `${doc.url}?dlRaw=true`, downloadConfig = typeIsFile ? {} : { headers: { Authorization: `Bearer ${token}` } };
|
|
250
|
+
await fetch(downloadUrl, downloadConfig).then(async (res) => {
|
|
251
|
+
const assetData = await res.blob(), options = { filename: doc.originalFilename }, assetDoc = await destinationClient.assets.upload(
|
|
252
|
+
typeIsFile ? "file" : "image",
|
|
253
|
+
assetData,
|
|
254
|
+
options
|
|
255
|
+
);
|
|
256
|
+
doc?.extension === "svg" && svgMaps.push({ old: doc._id, new: assetDoc._id }), transactionDocs.push(assetDoc), doc.url = assetDoc.url, doc.path = assetDoc.path;
|
|
257
|
+
}), currentProgress += 1, setMessage({
|
|
258
|
+
text: `Duplicating ${currentProgress}/${assetsCount} Assets`,
|
|
463
259
|
tone: "default"
|
|
464
|
-
});
|
|
465
|
-
setProgress([currentProgress, assetsCount]);
|
|
260
|
+
}), setProgress([currentProgress, assetsCount]);
|
|
466
261
|
}
|
|
467
262
|
return transactionDocs.push(doc);
|
|
468
263
|
}
|
|
469
|
-
|
|
470
|
-
const payloadIncludedDocs = payload.filter(item => item.include).map(item => item.doc);
|
|
471
|
-
mapLimit__default.default(payloadIncludedDocs, 3, asyncify__default.default(fetchDoc), err => {
|
|
472
|
-
|
|
473
|
-
setIsDuplicating(false);
|
|
474
|
-
setMessage({
|
|
475
|
-
tone: "critical",
|
|
476
|
-
text: "Duplication Failed"
|
|
477
|
-
});
|
|
478
|
-
console.error(err);
|
|
479
|
-
reject(new Error("Duplication Failed"));
|
|
480
|
-
}
|
|
481
|
-
resolve();
|
|
264
|
+
await new Promise((resolve, reject) => {
|
|
265
|
+
const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc);
|
|
266
|
+
mapLimit__default.default(payloadIncludedDocs, 3, asyncify__default.default(fetchDoc), (err) => {
|
|
267
|
+
err && (setIsDuplicating(!1), setMessage({ tone: "critical", text: "Duplication Failed" }), console.error(err), reject(new Error("Duplication Failed"))), resolve();
|
|
482
268
|
});
|
|
483
269
|
});
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
if (!references.length) {
|
|
489
|
-
return doc;
|
|
490
|
-
}
|
|
491
|
-
references.forEach(ref => {
|
|
492
|
-
var _a2;
|
|
493
|
-
const newRefValue = (_a2 = svgMaps.find(asset => asset.old === ref.value)) == null ? void 0 : _a2.new;
|
|
270
|
+
const transactionDocsMapped = transactionDocs.map((doc) => {
|
|
271
|
+
const references = mutator.extractWithPath(".._ref", doc);
|
|
272
|
+
return references.length && references.forEach((ref) => {
|
|
273
|
+
const newRefValue = svgMaps.find((asset) => asset.old === ref.value)?.new;
|
|
494
274
|
if (newRefValue) {
|
|
495
275
|
const refPath = ref.path.join(".");
|
|
496
276
|
dset.dset(doc, refPath, newRefValue);
|
|
497
277
|
}
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
const transaction = destinationClient.transaction();
|
|
502
|
-
transactionDocsMapped.forEach(doc => {
|
|
278
|
+
}), doc;
|
|
279
|
+
}), transaction = destinationClient.transaction();
|
|
280
|
+
if (transactionDocsMapped.forEach((doc) => {
|
|
503
281
|
transaction.createOrReplace(doc);
|
|
504
|
-
})
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
});
|
|
510
|
-
updatePayloadStatuses();
|
|
511
|
-
}).catch(err => {
|
|
512
|
-
setMessage({
|
|
513
|
-
tone: "critical",
|
|
514
|
-
text: err.details.description
|
|
515
|
-
});
|
|
516
|
-
});
|
|
517
|
-
setIsDuplicating(false);
|
|
518
|
-
setProgress([0, 0]);
|
|
519
|
-
if (onDuplicated) {
|
|
282
|
+
}), await transaction.commit().then((res) => {
|
|
283
|
+
setMessage({ tone: "positive", text: "Duplication complete!" }), updatePayloadStatuses();
|
|
284
|
+
}).catch((err) => {
|
|
285
|
+
setMessage({ tone: "critical", text: err.details.description });
|
|
286
|
+
}), setIsDuplicating(!1), setProgress([0, 0]), onDuplicated)
|
|
520
287
|
try {
|
|
521
288
|
await onDuplicated();
|
|
522
289
|
} catch (error) {
|
|
523
|
-
setMessage({
|
|
524
|
-
tone: "critical",
|
|
525
|
-
text: "Error in onDuplicated hook: ".concat(error)
|
|
526
|
-
});
|
|
290
|
+
setMessage({ tone: "critical", text: `Error in onDuplicated hook: ${error}` });
|
|
527
291
|
}
|
|
528
|
-
}
|
|
529
292
|
}
|
|
530
293
|
function handleChange(e) {
|
|
531
|
-
if (!workspacesOptions.length)
|
|
294
|
+
if (!workspacesOptions.length)
|
|
532
295
|
return;
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
if (targeted) {
|
|
536
|
-
setDestination(targeted);
|
|
537
|
-
}
|
|
296
|
+
const targeted = workspacesOptions.find((space) => space.name === e.currentTarget.value);
|
|
297
|
+
targeted && setDestination(targeted);
|
|
538
298
|
}
|
|
539
|
-
const payloadCount = payload.length
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
return doc.extension === "svg";
|
|
545
|
-
});
|
|
546
|
-
const selectedDocumentsCount = payload.filter(item => item.include && !assetUtils.isAssetId(item.doc._id)).length;
|
|
547
|
-
const selectedAssetsCount = payload.filter(item => item.include && assetUtils.isAssetId(item.doc._id)).length;
|
|
548
|
-
const selectedTotal = selectedDocumentsCount + selectedAssetsCount;
|
|
549
|
-
const destinationTitle = (_b = destination == null ? void 0 : destination.title) != null ? _b : destination == null ? void 0 : destination.name;
|
|
550
|
-
const hasMultipleProjectIds = new Set(workspacesOptions.map(space => space == null ? void 0 : space.projectId).filter(Boolean)).size > 1;
|
|
551
|
-
const headingText = [selectedTotal, "/", payloadCount, "Documents and Assets selected"].join(" ");
|
|
552
|
-
const buttonText = React__default.default.useMemo(() => {
|
|
299
|
+
const payloadCount = payload.length, firstSvgIndex = payload.findIndex(({ doc }) => doc.extension === "svg"), selectedDocumentsCount = payload.filter(
|
|
300
|
+
(item) => item.include && !assetUtils.isAssetId(item.doc._id)
|
|
301
|
+
).length, selectedAssetsCount = payload.filter(
|
|
302
|
+
(item) => item.include && assetUtils.isAssetId(item.doc._id)
|
|
303
|
+
).length, selectedTotal = selectedDocumentsCount + selectedAssetsCount, destinationTitle = destination?.title ?? destination?.name, hasMultipleProjectIds = new Set(workspacesOptions.map((space) => space?.projectId).filter(Boolean)).size > 1, headingText = [selectedTotal, "/", payloadCount, "Documents and Assets selected"].join(" "), buttonText = React__default.default.useMemo(() => {
|
|
553
304
|
const text = ["Duplicate"];
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
space:
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
radius: 2,
|
|
663
|
-
shadow: 1,
|
|
664
|
-
tone: message.tone,
|
|
665
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
666
|
-
size: 1,
|
|
667
|
-
children: message.text
|
|
668
|
-
})
|
|
669
|
-
}), payload.length > 0 ? /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
|
|
670
|
-
children: payload.map((_ref5, index) => {
|
|
671
|
-
let {
|
|
672
|
-
doc,
|
|
673
|
-
include,
|
|
674
|
-
status,
|
|
675
|
-
hasDraft
|
|
676
|
-
} = _ref5;
|
|
677
|
-
const schemaType = schema.get(doc._type);
|
|
678
|
-
return /* @__PURE__ */jsxRuntime.jsxs(React__default.default.Fragment, {
|
|
679
|
-
children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
680
|
-
align: "center",
|
|
681
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Checkbox, {
|
|
682
|
-
checked: include,
|
|
683
|
-
onChange: () => handleCheckbox(doc._id)
|
|
684
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
685
|
-
flex: 1,
|
|
686
|
-
paddingX: 3,
|
|
687
|
-
children: schemaType ? /* @__PURE__ */jsxRuntime.jsx(sanity.Preview, {
|
|
688
|
-
value: doc,
|
|
689
|
-
schemaType
|
|
690
|
-
}) : /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
691
|
-
tone: "caution",
|
|
692
|
-
children: "Invalid schema type"
|
|
693
|
-
})
|
|
694
|
-
}), /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
695
|
-
align: "center",
|
|
696
|
-
gap: 2,
|
|
697
|
-
children: [hasDraft ? /* @__PURE__ */jsxRuntime.jsx(StatusBadge, {
|
|
698
|
-
status: "UNPUBLISHED",
|
|
699
|
-
isAsset: false
|
|
700
|
-
}) : null, /* @__PURE__ */jsxRuntime.jsx(StatusBadge, {
|
|
701
|
-
status,
|
|
702
|
-
isAsset: assetUtils.isAssetId(doc._id)
|
|
703
|
-
})]
|
|
704
|
-
})]
|
|
705
|
-
}), (doc == null ? void 0 : doc.extension) === "svg" && index === firstSvgIndex && /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
706
|
-
padding: 3,
|
|
707
|
-
radius: 2,
|
|
708
|
-
shadow: 1,
|
|
709
|
-
tone: "caution",
|
|
710
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
711
|
-
size: 1,
|
|
712
|
-
children: ["Due to how SVGs are sanitized after first uploaded, duplicated SVG assets may have new ", /* @__PURE__ */jsxRuntime.jsx("code", {
|
|
713
|
-
children: "_id"
|
|
714
|
-
}), "'s at the destination. The newly generated ", /* @__PURE__ */jsxRuntime.jsx("code", {
|
|
715
|
-
children: "_id"
|
|
716
|
-
}), " will be the same in each duplication, but it will never be the same ", /* @__PURE__ */jsxRuntime.jsx("code", {
|
|
717
|
-
children: "_id"
|
|
718
|
-
}), " as the first time this Asset was uploaded. References to the asset will be updated to use the new ", /* @__PURE__ */jsxRuntime.jsx("code", {
|
|
719
|
-
children: "_id"
|
|
720
|
-
}), "."]
|
|
721
|
-
})
|
|
722
|
-
})]
|
|
723
|
-
}, doc._id);
|
|
724
|
-
})
|
|
725
|
-
}) : /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
726
|
-
padding: 4,
|
|
727
|
-
align: "center",
|
|
728
|
-
justify: "center",
|
|
729
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})
|
|
730
|
-
}), /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
731
|
-
space: 2,
|
|
732
|
-
children: [hasReferences && /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
733
|
-
fontSize: 2,
|
|
734
|
-
padding: 4,
|
|
735
|
-
tone: "positive",
|
|
736
|
-
mode: "ghost",
|
|
737
|
-
icon: icons.SearchIcon,
|
|
738
|
-
onClick: handleReferences,
|
|
739
|
-
text: "Gather References",
|
|
740
|
-
disabled: isDuplicating || !selectedTotal || isGathering
|
|
741
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
742
|
-
fontSize: 2,
|
|
743
|
-
padding: 4,
|
|
744
|
-
tone: "positive",
|
|
745
|
-
icon: icons.LaunchIcon,
|
|
746
|
-
onClick: handleDuplicate,
|
|
747
|
-
text: buttonText,
|
|
748
|
-
disabled: isDuplicating || !selectedTotal || isGathering
|
|
749
|
-
})]
|
|
750
|
-
})]
|
|
751
|
-
})
|
|
752
|
-
})]
|
|
753
|
-
})
|
|
754
|
-
})
|
|
755
|
-
});
|
|
305
|
+
return selectedDocumentsCount > 1 && text.push(
|
|
306
|
+
String(selectedDocumentsCount),
|
|
307
|
+
selectedDocumentsCount === 1 ? "Document" : "Documents"
|
|
308
|
+
), selectedAssetsCount > 1 && text.push("and", String(selectedAssetsCount), selectedAssetsCount === 1 ? "Asset" : "Assets"), originClient.config().projectId !== destination?.projectId && text.push("between Projects"), text.push("to", String(destinationTitle)), text.join(" ");
|
|
309
|
+
}, [
|
|
310
|
+
selectedDocumentsCount,
|
|
311
|
+
selectedAssetsCount,
|
|
312
|
+
originClient,
|
|
313
|
+
destination?.projectId,
|
|
314
|
+
destinationTitle
|
|
315
|
+
]);
|
|
316
|
+
return workspacesOptions.length < 2 ? /* @__PURE__ */ jsxRuntime.jsxs(Feedback, { tone: "critical", children: [
|
|
317
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { children: "sanity.config.ts" }),
|
|
318
|
+
" must contain at least two Workspaces to use this plugin."
|
|
319
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { width: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { border: !0, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { children: [
|
|
320
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 4, style: stickyStyles(isDarkMode), children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 3, children: [
|
|
322
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { style: { flex: 1 }, space: 3, children: [
|
|
323
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Duplicate from" }),
|
|
324
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select, { readOnly: !0, value: workspacesOptions.find((space) => space.disabled)?.name, children: workspacesOptions.filter((space) => space.disabled).map((space) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: space.name, disabled: space.disabled, children: [
|
|
325
|
+
space.title ?? space.name,
|
|
326
|
+
hasMultipleProjectIds ? ` (${space.projectId})` : ""
|
|
327
|
+
] }, space.name)) })
|
|
328
|
+
] }),
|
|
329
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 4, paddingTop: 5, paddingBottom: 0, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 3, children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowRightIcon, {}) }) }),
|
|
330
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { style: { flex: 1 }, space: 3, children: [
|
|
331
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "To Destination" }),
|
|
332
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select, { onChange: handleChange, children: workspacesOptions.map((space) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: space.name, disabled: space.disabled, children: [
|
|
333
|
+
space.title ?? space.name,
|
|
334
|
+
hasMultipleProjectIds ? ` (${space.projectId})` : "",
|
|
335
|
+
space.disabled ? " (Current)" : ""
|
|
336
|
+
] }, space.name)) })
|
|
337
|
+
] })
|
|
338
|
+
] }),
|
|
339
|
+
isDuplicating && /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { border: !0, radius: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
340
|
+
ui.Card,
|
|
341
|
+
{
|
|
342
|
+
style: {
|
|
343
|
+
width: "100%",
|
|
344
|
+
transform: `scaleX(${progress[0] / progress[1]})`,
|
|
345
|
+
transformOrigin: "left",
|
|
346
|
+
transition: "transform .2s ease",
|
|
347
|
+
boxSizing: "border-box"
|
|
348
|
+
},
|
|
349
|
+
padding: 1,
|
|
350
|
+
tone: "positive"
|
|
351
|
+
}
|
|
352
|
+
) }),
|
|
353
|
+
payload.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
354
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: headingText }),
|
|
355
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectButtons, { payload, setPayload })
|
|
356
|
+
] })
|
|
357
|
+
] }) }),
|
|
358
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Card, { borderTop: !0, padding: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
|
|
359
|
+
message && /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 3, radius: 2, shadow: 1, tone: message.tone, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: message.text }) }),
|
|
360
|
+
payload.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { children: payload.map(({ doc, include, status, hasDraft }, index) => {
|
|
361
|
+
const schemaType = schema.get(doc._type);
|
|
362
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
|
|
363
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", children: [
|
|
364
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { checked: include, onChange: () => handleCheckbox(doc._id) }),
|
|
365
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, paddingX: 3, children: schemaType ? /* @__PURE__ */ jsxRuntime.jsx(sanity.Preview, { value: doc, schemaType }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { tone: "caution", children: "Invalid schema type" }) }),
|
|
366
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", gap: 2, children: [
|
|
367
|
+
hasDraft ? /* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status: "UNPUBLISHED", isAsset: !1 }) : null,
|
|
368
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusBadge, { status, isAsset: assetUtils.isAssetId(doc._id) })
|
|
369
|
+
] })
|
|
370
|
+
] }),
|
|
371
|
+
doc?.extension === "svg" && index === firstSvgIndex && /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 3, radius: 2, shadow: 1, tone: "caution", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: 1, children: [
|
|
372
|
+
"Due to how SVGs are sanitized after first uploaded, duplicated SVG assets may have new ",
|
|
373
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { children: "_id" }),
|
|
374
|
+
"'s at the destination. The newly generated ",
|
|
375
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { children: "_id" }),
|
|
376
|
+
" will be the same in each duplication, but it will never be the same ",
|
|
377
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { children: "_id" }),
|
|
378
|
+
" as the first time this Asset was uploaded. References to the asset will be updated to use the new ",
|
|
379
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { children: "_id" }),
|
|
380
|
+
"."
|
|
381
|
+
] }) })
|
|
382
|
+
] }, doc._id);
|
|
383
|
+
}) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { padding: 4, align: "center", justify: "center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {}) }),
|
|
384
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
|
|
385
|
+
hasReferences && /* @__PURE__ */ jsxRuntime.jsx(
|
|
386
|
+
ui.Button,
|
|
387
|
+
{
|
|
388
|
+
fontSize: 2,
|
|
389
|
+
padding: 4,
|
|
390
|
+
tone: "positive",
|
|
391
|
+
mode: "ghost",
|
|
392
|
+
icon: icons.SearchIcon,
|
|
393
|
+
onClick: handleReferences,
|
|
394
|
+
text: "Gather References",
|
|
395
|
+
disabled: isDuplicating || !selectedTotal || isGathering
|
|
396
|
+
}
|
|
397
|
+
),
|
|
398
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
399
|
+
ui.Button,
|
|
400
|
+
{
|
|
401
|
+
fontSize: 2,
|
|
402
|
+
padding: 4,
|
|
403
|
+
tone: "positive",
|
|
404
|
+
icon: icons.LaunchIcon,
|
|
405
|
+
onClick: handleDuplicate,
|
|
406
|
+
text: buttonText,
|
|
407
|
+
disabled: isDuplicating || !selectedTotal || isGathering
|
|
408
|
+
}
|
|
409
|
+
)
|
|
410
|
+
] })
|
|
411
|
+
] }) })
|
|
412
|
+
] }) }) });
|
|
756
413
|
}
|
|
757
414
|
function DuplicatorQuery(props) {
|
|
758
|
-
|
|
759
|
-
const {
|
|
760
|
-
token,
|
|
761
|
-
pluginConfig
|
|
762
|
-
} = props;
|
|
763
|
-
const {
|
|
764
|
-
queries: preDefinedQueries,
|
|
765
|
-
apiVersion
|
|
766
|
-
} = pluginConfig;
|
|
767
|
-
const originClient = sanity.useClient({
|
|
768
|
-
apiVersion
|
|
769
|
-
});
|
|
770
|
-
const schema = sanity.useSchema();
|
|
771
|
-
const schemaTypes = schema.getTypeNames();
|
|
772
|
-
const [value, setValue] = React.useState("");
|
|
773
|
-
const [fetched, setFetched] = React.useState(false);
|
|
774
|
-
const [initialData, setInitialData] = React.useState({
|
|
415
|
+
const { token, pluginConfig } = props, { queries: preDefinedQueries, apiVersion } = pluginConfig, originClient = sanity.useClient({ apiVersion }), schemaTypes = sanity.useSchema().getTypeNames(), [value, setValue] = React.useState(""), [fetched, setFetched] = React.useState(!1), [initialData, setInitialData] = React.useState({
|
|
775
416
|
docs: []
|
|
776
417
|
});
|
|
777
418
|
function handleSubmit(e) {
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
const registeredAndPublishedDocs = res.length ? res.filter(doc => schemaTypes.includes(doc._type)).filter(doc => !doc._id.startsWith("drafts.")) : [];
|
|
419
|
+
e && e.preventDefault(), originClient.fetch(value).then((res) => {
|
|
420
|
+
const registeredAndPublishedDocs = res.length ? res.filter((doc) => schemaTypes.includes(doc._type)).filter((doc) => !doc._id.startsWith("drafts.")) : [];
|
|
781
421
|
setInitialData({
|
|
782
422
|
docs: registeredAndPublishedDocs
|
|
783
|
-
});
|
|
784
|
-
|
|
785
|
-
}).catch(err => console.error(err));
|
|
423
|
+
}), setFetched(!0);
|
|
424
|
+
}).catch((err) => console.error(err));
|
|
786
425
|
}
|
|
787
|
-
React.useEffect(() => {
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
padding: 4,
|
|
845
|
-
radius: 3,
|
|
846
|
-
border: true,
|
|
847
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
848
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
849
|
-
space: 4,
|
|
850
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
851
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Label, {
|
|
852
|
-
children: "Predefined Queries"
|
|
853
|
-
})
|
|
854
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
|
|
855
|
-
space: 2,
|
|
856
|
-
children: preDefinedQueries.map(query => /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
857
|
-
padding: 2,
|
|
858
|
-
paddingX: 4,
|
|
859
|
-
tone: "primary",
|
|
860
|
-
onClick: () => setValue("*[".concat(query.query, "]")),
|
|
861
|
-
text: query.label
|
|
862
|
-
}, query.label.replace(/\s+/g, "-")))
|
|
863
|
-
})]
|
|
864
|
-
})
|
|
865
|
-
})
|
|
866
|
-
})]
|
|
867
|
-
}), fetched && initialData.docs.length < 1 && /* @__PURE__ */jsxRuntime.jsx(ui.Container, {
|
|
868
|
-
width: 1,
|
|
869
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
870
|
-
padding: 5,
|
|
871
|
-
children: value ? "No documents match this query" : "Start with a valid GROQ query"
|
|
872
|
-
})
|
|
873
|
-
}), ((_a = initialData.docs) == null ? void 0 : _a.length) > 0 && /* @__PURE__ */jsxRuntime.jsx(Duplicator, {
|
|
874
|
-
docs: initialData.docs,
|
|
875
|
-
token,
|
|
876
|
-
pluginConfig
|
|
877
|
-
})]
|
|
878
|
-
})
|
|
879
|
-
})
|
|
880
|
-
});
|
|
426
|
+
return React.useEffect(() => {
|
|
427
|
+
!initialData.docs?.length && value && handleSubmit();
|
|
428
|
+
}, []), /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: [0, 0, 0, 5], children: /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: [1, 1, 1, 2], gap: [1, 1, 1, 4], children: [
|
|
429
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Box, { padding: [2, 2, 2, 0], children: [
|
|
430
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 4, radius: 3, border: !0, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [
|
|
431
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Initial Documents Query" }) }),
|
|
432
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Start with a valid GROQ query to load initial documents. The query will need to return an Array of Objects. Drafts will be removed from the results." }) }),
|
|
433
|
+
/* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { children: [
|
|
434
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: 1, paddingRight: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
435
|
+
ui.TextInput,
|
|
436
|
+
{
|
|
437
|
+
style: { fontFamily: "monospace" },
|
|
438
|
+
fontSize: 2,
|
|
439
|
+
onChange: (event) => setValue(event.currentTarget.value),
|
|
440
|
+
padding: 4,
|
|
441
|
+
placeholder: '*[_type == "article"]',
|
|
442
|
+
value: value ?? ""
|
|
443
|
+
}
|
|
444
|
+
) }),
|
|
445
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
446
|
+
ui.Button,
|
|
447
|
+
{
|
|
448
|
+
padding: 2,
|
|
449
|
+
paddingX: 4,
|
|
450
|
+
tone: "primary",
|
|
451
|
+
onClick: handleSubmit,
|
|
452
|
+
text: "Query",
|
|
453
|
+
disabled: !value
|
|
454
|
+
}
|
|
455
|
+
)
|
|
456
|
+
] }) })
|
|
457
|
+
] }) }),
|
|
458
|
+
preDefinedQueries && preDefinedQueries?.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { marginTop: 2, padding: 4, radius: 3, border: !0, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [
|
|
459
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Predefined Queries" }) }),
|
|
460
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 2, children: preDefinedQueries.map((query) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
461
|
+
ui.Button,
|
|
462
|
+
{
|
|
463
|
+
padding: 2,
|
|
464
|
+
paddingX: 4,
|
|
465
|
+
tone: "primary",
|
|
466
|
+
onClick: () => setValue(`*[${query.query}]`),
|
|
467
|
+
text: query.label
|
|
468
|
+
},
|
|
469
|
+
query.label.replace(/\s+/g, "-")
|
|
470
|
+
)) })
|
|
471
|
+
] }) }) })
|
|
472
|
+
] }),
|
|
473
|
+
fetched && initialData.docs.length < 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { width: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 5, children: value ? "No documents match this query" : "Start with a valid GROQ query" }) }),
|
|
474
|
+
initialData.docs?.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
475
|
+
Duplicator,
|
|
476
|
+
{
|
|
477
|
+
docs: initialData.docs,
|
|
478
|
+
token,
|
|
479
|
+
pluginConfig
|
|
480
|
+
}
|
|
481
|
+
)
|
|
482
|
+
] }) }) });
|
|
881
483
|
}
|
|
882
484
|
function DuplicatorWrapper(props) {
|
|
883
|
-
const {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
onDuplicated
|
|
888
|
-
} = props;
|
|
889
|
-
const [inbound, setInbound] = React.useState([]);
|
|
890
|
-
const {
|
|
891
|
-
follow = [],
|
|
892
|
-
apiVersion
|
|
893
|
-
} = pluginConfig;
|
|
894
|
-
const [mode, setMode] = React.useState(follow.length === 1 ? follow[0] : "outbound");
|
|
895
|
-
const client = sanity.useClient({
|
|
896
|
-
apiVersion
|
|
897
|
-
});
|
|
898
|
-
React.useEffect(() => {
|
|
485
|
+
const { docs, token, pluginConfig, onDuplicated } = props, [inbound, setInbound] = React.useState([]), { follow = [], apiVersion } = pluginConfig, [mode, setMode] = React.useState(
|
|
486
|
+
follow.length === 1 ? follow[0] : "outbound"
|
|
487
|
+
), client = sanity.useClient({ apiVersion });
|
|
488
|
+
return React.useEffect(() => {
|
|
899
489
|
(async () => {
|
|
900
490
|
if (follow.includes("inbound")) {
|
|
901
|
-
const inboundReferences = await client.fetch("*[references($id)]", {
|
|
902
|
-
id: docs[0]._id
|
|
903
|
-
});
|
|
491
|
+
const inboundReferences = await client.fetch("*[references($id)]", { id: docs[0]._id });
|
|
904
492
|
setInbound([...props.docs, ...inboundReferences]);
|
|
905
493
|
}
|
|
906
494
|
})();
|
|
907
|
-
}, [])
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
marginBottom: 4,
|
|
913
|
-
borderBottom: true,
|
|
914
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Grid, {
|
|
915
|
-
columns: 2,
|
|
916
|
-
gap: 4,
|
|
917
|
-
children: [follow.includes("outbound") ? /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
495
|
+
}, []), /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { children: [
|
|
496
|
+
follow.length > 1 && (follow.includes("inbound") || follow.includes("outbound")) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { paddingX: 4, paddingBottom: 4, marginBottom: 4, borderBottom: !0, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: 2, gap: 4, children: [
|
|
497
|
+
follow.includes("outbound") ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
498
|
+
ui.Button,
|
|
499
|
+
{
|
|
918
500
|
mode: "ghost",
|
|
919
501
|
tone: "primary",
|
|
920
502
|
selected: mode === "outbound",
|
|
921
503
|
onClick: () => setMode("outbound"),
|
|
922
504
|
text: "Outbound"
|
|
923
|
-
}
|
|
505
|
+
}
|
|
506
|
+
) : null,
|
|
507
|
+
follow.includes("inbound") ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
508
|
+
ui.Button,
|
|
509
|
+
{
|
|
924
510
|
mode: "ghost",
|
|
925
511
|
tone: "primary",
|
|
926
512
|
selected: mode === "inbound",
|
|
927
513
|
onClick: () => setMode("inbound"),
|
|
928
514
|
disabled: inbound.length === 0,
|
|
929
|
-
text: inbound.length > 0 ?
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
}) : null,
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
515
|
+
text: inbound.length > 0 ? `Inbound (${inbound.length})` : "No inbound references"
|
|
516
|
+
}
|
|
517
|
+
) : null
|
|
518
|
+
] }) }) : null,
|
|
519
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
520
|
+
Duplicator,
|
|
521
|
+
{
|
|
522
|
+
docs: mode === "outbound" ? docs : inbound,
|
|
523
|
+
token,
|
|
524
|
+
pluginConfig,
|
|
525
|
+
onDuplicated
|
|
526
|
+
}
|
|
527
|
+
)
|
|
528
|
+
] });
|
|
939
529
|
}
|
|
940
|
-
const SECRET_NAMESPACE = "CrossDatasetDuplicator"
|
|
941
|
-
const DEFAULT_CONFIG = {
|
|
530
|
+
const SECRET_NAMESPACE = "CrossDatasetDuplicator", DEFAULT_CONFIG = {
|
|
942
531
|
apiVersion: "2025-02-19",
|
|
943
|
-
tool:
|
|
532
|
+
tool: !0,
|
|
944
533
|
types: [],
|
|
945
534
|
filter: "",
|
|
946
535
|
follow: ["outbound"],
|
|
947
536
|
queries: []
|
|
948
537
|
};
|
|
949
|
-
function ResetSecret(
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
} = _ref6;
|
|
953
|
-
const client = sanity.useClient({
|
|
954
|
-
apiVersion
|
|
955
|
-
});
|
|
956
|
-
const handleClick = React.useCallback(() => {
|
|
957
|
-
client.delete({
|
|
958
|
-
query: '*[_id == "secrets.'.concat(SECRET_NAMESPACE, '"]')
|
|
959
|
-
});
|
|
538
|
+
function ResetSecret({ apiVersion }) {
|
|
539
|
+
const client = sanity.useClient({ apiVersion }), handleClick = React.useCallback(() => {
|
|
540
|
+
client.delete({ query: `*[_id == "secrets.${SECRET_NAMESPACE}"]` });
|
|
960
541
|
}, [client]);
|
|
961
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
paddingX: [2, 2, 2, 5],
|
|
965
|
-
paddingY: 5,
|
|
966
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
542
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { align: "center", justify: "flex-end", paddingX: [2, 2, 2, 5], paddingY: 5, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
543
|
+
ui.Button,
|
|
544
|
+
{
|
|
967
545
|
text: "Reset Secret",
|
|
968
546
|
onClick: handleClick,
|
|
969
547
|
mode: "ghost",
|
|
970
548
|
tone: "critical",
|
|
971
549
|
fontSize: 1,
|
|
972
550
|
padding: 2
|
|
973
|
-
}
|
|
974
|
-
});
|
|
551
|
+
}
|
|
552
|
+
) });
|
|
975
553
|
}
|
|
976
|
-
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
977
|
-
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
978
|
-
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
979
|
-
var __objRest = (source, exclude) => {
|
|
980
|
-
var target = {};
|
|
981
|
-
for (var prop in source) if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop];
|
|
982
|
-
if (source != null && __getOwnPropSymbols$1) for (var prop of __getOwnPropSymbols$1(source)) {
|
|
983
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop)) target[prop] = source[prop];
|
|
984
|
-
}
|
|
985
|
-
return target;
|
|
986
|
-
};
|
|
987
554
|
const CrossDatasetDuplicatorContext = React.createContext(DEFAULT_CONFIG);
|
|
988
555
|
function useCrossDatasetDuplicatorConfig() {
|
|
989
|
-
|
|
990
|
-
return pluginConfig;
|
|
556
|
+
return React.useContext(CrossDatasetDuplicatorContext);
|
|
991
557
|
}
|
|
992
558
|
function ConfigProvider(props) {
|
|
993
|
-
const
|
|
994
|
-
|
|
995
|
-
pluginConfig
|
|
996
|
-
} = _a,
|
|
997
|
-
rest = __objRest(_a, ["pluginConfig"]);
|
|
998
|
-
return /* @__PURE__ */jsxRuntime.jsx(CrossDatasetDuplicatorContext.Provider, {
|
|
999
|
-
value: pluginConfig,
|
|
1000
|
-
children: props.renderDefault(rest)
|
|
1001
|
-
});
|
|
559
|
+
const { pluginConfig, ...rest } = props;
|
|
560
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CrossDatasetDuplicatorContext.Provider, { value: pluginConfig, children: props.renderDefault(rest) });
|
|
1002
561
|
}
|
|
1003
|
-
const secretConfigKeys = [
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
function CrossDatasetDuplicator(props) {
|
|
1009
|
-
const {
|
|
1010
|
-
mode = "tool",
|
|
1011
|
-
docs = [],
|
|
1012
|
-
onDuplicated
|
|
1013
|
-
} = props != null ? props : {};
|
|
1014
|
-
const pluginConfig = useCrossDatasetDuplicatorConfig();
|
|
1015
|
-
const {
|
|
1016
|
-
loading,
|
|
1017
|
-
secrets
|
|
1018
|
-
} = studioSecrets.useSecrets(SECRET_NAMESPACE);
|
|
1019
|
-
const [showSecretsPrompt, setShowSecretsPrompt] = React.useState(false);
|
|
1020
|
-
React.useEffect(() => {
|
|
1021
|
-
if (secrets) {
|
|
1022
|
-
setShowSecretsPrompt(!(secrets == null ? void 0 : secrets.bearerToken));
|
|
1023
|
-
}
|
|
1024
|
-
}, [secrets]);
|
|
1025
|
-
if (loading) {
|
|
1026
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
1027
|
-
justify: "center",
|
|
1028
|
-
align: "center",
|
|
1029
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
1030
|
-
padding: 5,
|
|
1031
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})
|
|
1032
|
-
})
|
|
1033
|
-
});
|
|
562
|
+
const secretConfigKeys = [
|
|
563
|
+
{
|
|
564
|
+
key: "bearerToken",
|
|
565
|
+
title: "An API token with Viewer permissions is required to duplicate the original files of assets, and will be used for all Duplications. Create one at sanity.io/manage",
|
|
566
|
+
description: ""
|
|
1034
567
|
}
|
|
1035
|
-
|
|
1036
|
-
|
|
568
|
+
];
|
|
569
|
+
function CrossDatasetDuplicator(props) {
|
|
570
|
+
const { mode = "tool", docs = [], onDuplicated } = props ?? {}, pluginConfig = useCrossDatasetDuplicatorConfig(), { loading, secrets } = studioSecrets.useSecrets(SECRET_NAMESPACE), [showSecretsPrompt, setShowSecretsPrompt] = React.useState(!1);
|
|
571
|
+
return React.useEffect(() => {
|
|
572
|
+
secrets && setShowSecretsPrompt(!secrets?.bearerToken);
|
|
573
|
+
}, [secrets]), loading ? /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { justify: "center", align: "center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 5, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {}) }) }) : !loading && showSecretsPrompt || !secrets?.bearerToken ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
574
|
+
studioSecrets.SettingsView,
|
|
575
|
+
{
|
|
1037
576
|
title: "Token Required",
|
|
1038
577
|
namespace: SECRET_NAMESPACE,
|
|
1039
578
|
keys: secretConfigKeys,
|
|
1040
|
-
onClose: () => setShowSecretsPrompt(
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
return /* @__PURE__ */jsxRuntime.jsx(Feedback, {
|
|
1055
|
-
children: "No docs passed into Duplicator Tool"
|
|
1056
|
-
});
|
|
1057
|
-
}
|
|
1058
|
-
if (!pluginConfig) {
|
|
1059
|
-
return /* @__PURE__ */jsxRuntime.jsx(Feedback, {
|
|
1060
|
-
children: "No plugin config"
|
|
1061
|
-
});
|
|
1062
|
-
}
|
|
1063
|
-
return /* @__PURE__ */jsxRuntime.jsx(DuplicatorWrapper, {
|
|
1064
|
-
docs,
|
|
1065
|
-
token: secrets == null ? void 0 : secrets.bearerToken,
|
|
1066
|
-
pluginConfig,
|
|
1067
|
-
onDuplicated
|
|
1068
|
-
});
|
|
579
|
+
onClose: () => setShowSecretsPrompt(!1)
|
|
580
|
+
}
|
|
581
|
+
) : mode === "tool" && pluginConfig ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
582
|
+
/* @__PURE__ */ jsxRuntime.jsx(DuplicatorQuery, { token: secrets?.bearerToken, pluginConfig }),
|
|
583
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResetSecret, { apiVersion: pluginConfig.apiVersion })
|
|
584
|
+
] }) : docs?.length ? pluginConfig ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
585
|
+
DuplicatorWrapper,
|
|
586
|
+
{
|
|
587
|
+
docs,
|
|
588
|
+
token: secrets?.bearerToken,
|
|
589
|
+
pluginConfig,
|
|
590
|
+
onDuplicated
|
|
591
|
+
}
|
|
592
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(Feedback, { children: "No plugin config" }) : /* @__PURE__ */ jsxRuntime.jsx(Feedback, { children: "No docs passed into Duplicator Tool" });
|
|
1069
593
|
}
|
|
1070
594
|
function CrossDatasetDuplicatorAction(props) {
|
|
1071
|
-
const {
|
|
1072
|
-
|
|
1073
|
-
onDuplicated
|
|
1074
|
-
} = props;
|
|
1075
|
-
return /* @__PURE__ */jsxRuntime.jsx(CrossDatasetDuplicator, {
|
|
1076
|
-
mode: "action",
|
|
1077
|
-
docs,
|
|
1078
|
-
onDuplicated
|
|
1079
|
-
});
|
|
595
|
+
const { docs = [], onDuplicated } = props;
|
|
596
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CrossDatasetDuplicator, { mode: "action", docs, onDuplicated });
|
|
1080
597
|
}
|
|
1081
|
-
const DuplicateToAction = props => {
|
|
1082
|
-
const {
|
|
1083
|
-
draft,
|
|
1084
|
-
published,
|
|
1085
|
-
onComplete
|
|
1086
|
-
} = props;
|
|
1087
|
-
const [dialogOpen, setDialogOpen] = React.useState(false);
|
|
598
|
+
const DuplicateToAction = (props) => {
|
|
599
|
+
const { draft, published, onComplete } = props, [dialogOpen, setDialogOpen] = React.useState(!1);
|
|
1088
600
|
return {
|
|
1089
601
|
disabled: draft,
|
|
1090
602
|
title: draft ? "Document must be Published to begin" : null,
|
|
@@ -1092,28 +604,19 @@ const DuplicateToAction = props => {
|
|
|
1092
604
|
dialog: dialogOpen && published && {
|
|
1093
605
|
type: "modal",
|
|
1094
606
|
title: "Cross Dataset Duplicator",
|
|
1095
|
-
content: /* @__PURE__ */jsxRuntime.jsx(CrossDatasetDuplicatorAction, {
|
|
1096
|
-
docs: [published]
|
|
1097
|
-
}),
|
|
607
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(CrossDatasetDuplicatorAction, { docs: [published] }),
|
|
1098
608
|
onClose: () => {
|
|
1099
|
-
onComplete();
|
|
1100
|
-
setDialogOpen(false);
|
|
609
|
+
onComplete(), setDialogOpen(!1);
|
|
1101
610
|
}
|
|
1102
611
|
},
|
|
1103
|
-
onHandle: () => setDialogOpen(
|
|
612
|
+
onHandle: () => setDialogOpen(!0),
|
|
1104
613
|
icon: icons.LaunchIcon
|
|
1105
614
|
};
|
|
1106
615
|
};
|
|
1107
616
|
DuplicateToAction.action = "duplicateTo";
|
|
1108
617
|
function CrossDatasetDuplicatorTool(props) {
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
docs = []
|
|
1112
|
-
} = (_a = props.tool.options) != null ? _a : {};
|
|
1113
|
-
return /* @__PURE__ */jsxRuntime.jsx(CrossDatasetDuplicator, {
|
|
1114
|
-
mode: "tool",
|
|
1115
|
-
docs
|
|
1116
|
-
});
|
|
618
|
+
const { docs = [] } = props.tool.options ?? {};
|
|
619
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CrossDatasetDuplicator, { mode: "tool", docs });
|
|
1117
620
|
}
|
|
1118
621
|
const crossDatasetDuplicatorTool = () => ({
|
|
1119
622
|
title: "Duplicator",
|
|
@@ -1123,50 +626,18 @@ const crossDatasetDuplicatorTool = () => ({
|
|
|
1123
626
|
options: {
|
|
1124
627
|
docs: []
|
|
1125
628
|
}
|
|
1126
|
-
})
|
|
1127
|
-
|
|
1128
|
-
var __defProps = Object.defineProperties;
|
|
1129
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
1130
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
1131
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
1132
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
1133
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
1134
|
-
enumerable: true,
|
|
1135
|
-
configurable: true,
|
|
1136
|
-
writable: true,
|
|
1137
|
-
value
|
|
1138
|
-
}) : obj[key] = value;
|
|
1139
|
-
var __spreadValues = (a, b) => {
|
|
1140
|
-
for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
1141
|
-
if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) {
|
|
1142
|
-
if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
|
|
1143
|
-
}
|
|
1144
|
-
return a;
|
|
1145
|
-
};
|
|
1146
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
1147
|
-
const crossDatasetDuplicator = sanity.definePlugin(function () {
|
|
1148
|
-
let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
1149
|
-
const pluginConfig = __spreadValues(__spreadValues({}, DEFAULT_CONFIG), config);
|
|
1150
|
-
const {
|
|
1151
|
-
types
|
|
1152
|
-
} = pluginConfig;
|
|
629
|
+
}), crossDatasetDuplicator = sanity.definePlugin((config = {}) => {
|
|
630
|
+
const pluginConfig = { ...DEFAULT_CONFIG, ...config }, { types } = pluginConfig;
|
|
1153
631
|
return {
|
|
1154
632
|
name: "@sanity/cross-dataset-duplicator",
|
|
1155
|
-
tools: prev => pluginConfig.tool ? [...prev, crossDatasetDuplicatorTool()] : prev,
|
|
633
|
+
tools: (prev) => pluginConfig.tool ? [...prev, crossDatasetDuplicatorTool()] : prev,
|
|
1156
634
|
studio: {
|
|
1157
635
|
components: {
|
|
1158
|
-
layout: props => ConfigProvider(
|
|
1159
|
-
pluginConfig
|
|
1160
|
-
}))
|
|
636
|
+
layout: (props) => ConfigProvider({ ...props, pluginConfig })
|
|
1161
637
|
}
|
|
1162
638
|
},
|
|
1163
639
|
document: {
|
|
1164
|
-
actions: (prev,
|
|
1165
|
-
let {
|
|
1166
|
-
schemaType
|
|
1167
|
-
} = _ref7;
|
|
1168
|
-
return types && types.includes(schemaType) ? [...prev, DuplicateToAction] : prev;
|
|
1169
|
-
}
|
|
640
|
+
actions: (prev, { schemaType }) => types && types.includes(schemaType) ? [...prev, DuplicateToAction] : prev
|
|
1170
641
|
}
|
|
1171
642
|
};
|
|
1172
643
|
});
|