@sanity/cross-dataset-duplicator 0.3.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/.babelrc +3 -0
- package/.eslintignore +1 -0
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/config.dist.json +4 -0
- package/lib/actions/DuplicateToAction.js +59 -0
- package/lib/actions/DuplicateToAction.js.map +1 -0
- package/lib/actions/index.js +38 -0
- package/lib/actions/index.js.map +1 -0
- package/lib/components/CrossDatasetDuplicator.js +107 -0
- package/lib/components/CrossDatasetDuplicator.js.map +1 -0
- package/lib/components/DuplicatorQuery.js +113 -0
- package/lib/components/DuplicatorQuery.js.map +1 -0
- package/lib/components/DuplicatorTool.js +557 -0
- package/lib/components/DuplicatorTool.js.map +1 -0
- package/lib/components/Feedback.js +27 -0
- package/lib/components/Feedback.js.map +1 -0
- package/lib/components/ResetSecret.js +43 -0
- package/lib/components/ResetSecret.js.map +1 -0
- package/lib/components/SelectButtons.js +109 -0
- package/lib/components/SelectButtons.js.map +1 -0
- package/lib/components/StatusBadge.js +87 -0
- package/lib/components/StatusBadge.js.map +1 -0
- package/lib/helpers/clientConfig.js +11 -0
- package/lib/helpers/clientConfig.js.map +1 -0
- package/lib/helpers/constants.js +9 -0
- package/lib/helpers/constants.js.map +1 -0
- package/lib/helpers/getDocumentsInArray.js +80 -0
- package/lib/helpers/getDocumentsInArray.js.map +1 -0
- package/lib/helpers/index.js +30 -0
- package/lib/helpers/index.js.map +1 -0
- package/lib/index.js +24 -0
- package/lib/index.js.map +1 -0
- package/lib/tool/index.js +24 -0
- package/lib/tool/index.js.map +1 -0
- package/lib/types/index.js +2 -0
- package/lib/types/index.js.map +1 -0
- package/package.json +71 -0
- package/sanity.json +16 -0
- package/src/actions/DuplicateToAction.tsx +22 -0
- package/src/actions/index.ts +22 -0
- package/src/components/CrossDatasetDuplicator.tsx +100 -0
- package/src/components/DuplicatorQuery.tsx +93 -0
- package/src/components/DuplicatorTool.tsx +460 -0
- package/src/components/Feedback.tsx +18 -0
- package/src/components/ResetSecret.tsx +27 -0
- package/src/components/SelectButtons.tsx +80 -0
- package/src/components/StatusBadge.tsx +97 -0
- package/src/helpers/clientConfig.ts +1 -0
- package/src/helpers/constants.ts +1 -0
- package/src/helpers/getDocumentsInArray.ts +74 -0
- package/src/helpers/index.ts +23 -0
- package/src/index.js +7 -0
- package/src/tool/index.ts +13 -0
- package/src/types/index.ts +10 -0
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = DuplicatorTool;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _mapLimit = _interopRequireDefault(require("async/mapLimit"));
|
|
11
|
+
|
|
12
|
+
var _asyncify = _interopRequireDefault(require("async/asyncify"));
|
|
13
|
+
|
|
14
|
+
var _mutator = require("@sanity/mutator");
|
|
15
|
+
|
|
16
|
+
var _dset = require("dset");
|
|
17
|
+
|
|
18
|
+
var _ui = require("@sanity/ui");
|
|
19
|
+
|
|
20
|
+
var _icons = require("@sanity/icons");
|
|
21
|
+
|
|
22
|
+
var _client = _interopRequireDefault(require("part:@sanity/base/client"));
|
|
23
|
+
|
|
24
|
+
var _preview = _interopRequireDefault(require("part:@sanity/base/preview"));
|
|
25
|
+
|
|
26
|
+
var _schema = _interopRequireDefault(require("part:@sanity/base/schema"));
|
|
27
|
+
|
|
28
|
+
var _configSanity = _interopRequireDefault(require("config:sanity"));
|
|
29
|
+
|
|
30
|
+
var _helpers = require("../helpers");
|
|
31
|
+
|
|
32
|
+
var _getDocumentsInArray = require("../helpers/getDocumentsInArray");
|
|
33
|
+
|
|
34
|
+
var _SelectButtons = _interopRequireDefault(require("./SelectButtons"));
|
|
35
|
+
|
|
36
|
+
var _StatusBadge = _interopRequireDefault(require("./StatusBadge"));
|
|
37
|
+
|
|
38
|
+
var _Feedback = _interopRequireDefault(require("./Feedback"));
|
|
39
|
+
|
|
40
|
+
var _clientConfig = require("../helpers/clientConfig");
|
|
41
|
+
|
|
42
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
43
|
+
|
|
44
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
45
|
+
|
|
46
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
47
|
+
|
|
48
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
49
|
+
|
|
50
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
51
|
+
|
|
52
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
53
|
+
|
|
54
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
55
|
+
|
|
56
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
57
|
+
|
|
58
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
59
|
+
|
|
60
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
61
|
+
|
|
62
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
63
|
+
|
|
64
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
65
|
+
|
|
66
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
67
|
+
|
|
68
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
69
|
+
|
|
70
|
+
function DuplicatorTool(props) {
|
|
71
|
+
var _config$__experimenta, _destination$title, _spacesOptions$find, _message$tone;
|
|
72
|
+
|
|
73
|
+
var docs = props.docs,
|
|
74
|
+
token = props.token; // Prepare origin (this Studio) client
|
|
75
|
+
// In function-scope so it is up to date on every render
|
|
76
|
+
|
|
77
|
+
var originClient = _client.default.withConfig(_clientConfig.clientConfig); // Create list of dataset options
|
|
78
|
+
// and set initial value of dropdown
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
var spacesOptions = _configSanity.default !== null && _configSanity.default !== void 0 && (_config$__experimenta = _configSanity.default.__experimental_spaces) !== null && _config$__experimenta !== void 0 && _config$__experimenta.length ? _configSanity.default.__experimental_spaces.map(space => _objectSpread(_objectSpread({}, space), {}, {
|
|
82
|
+
disabled: space.api.dataset === originClient.config().dataset
|
|
83
|
+
})) : [];
|
|
84
|
+
|
|
85
|
+
var _useState = (0, _react.useState)(spacesOptions.length ? spacesOptions.find(space => !space.disabled) : {}),
|
|
86
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
87
|
+
destination = _useState2[0],
|
|
88
|
+
setDestination = _useState2[1];
|
|
89
|
+
|
|
90
|
+
var _useState3 = (0, _react.useState)({}),
|
|
91
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
92
|
+
message = _useState4[0],
|
|
93
|
+
setMessage = _useState4[1];
|
|
94
|
+
|
|
95
|
+
var _useState5 = (0, _react.useState)(docs.length ? docs.map(item => ({
|
|
96
|
+
doc: item,
|
|
97
|
+
include: true,
|
|
98
|
+
status: null
|
|
99
|
+
})) : []),
|
|
100
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
101
|
+
payload = _useState6[0],
|
|
102
|
+
setPayload = _useState6[1];
|
|
103
|
+
|
|
104
|
+
var _useState7 = (0, _react.useState)(false),
|
|
105
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
106
|
+
hasReferences = _useState8[0],
|
|
107
|
+
setHasReferences = _useState8[1];
|
|
108
|
+
|
|
109
|
+
var _useState9 = (0, _react.useState)(false),
|
|
110
|
+
_useState10 = _slicedToArray(_useState9, 2),
|
|
111
|
+
isDuplicating = _useState10[0],
|
|
112
|
+
setIsDuplicating = _useState10[1];
|
|
113
|
+
|
|
114
|
+
var _useState11 = (0, _react.useState)(false),
|
|
115
|
+
_useState12 = _slicedToArray(_useState11, 2),
|
|
116
|
+
isGathering = _useState12[0],
|
|
117
|
+
setIsGathering = _useState12[1];
|
|
118
|
+
|
|
119
|
+
var _useState13 = (0, _react.useState)([0, 0]),
|
|
120
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
121
|
+
progress = _useState14[0],
|
|
122
|
+
setProgress = _useState14[1]; // Check for References and update message
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
(0, _react.useEffect)(() => {
|
|
126
|
+
var expr = ".._ref";
|
|
127
|
+
var initialRefs = [];
|
|
128
|
+
var initialPayload = [];
|
|
129
|
+
docs.forEach(doc => {
|
|
130
|
+
initialRefs.push(...(0, _mutator.extract)(expr, doc));
|
|
131
|
+
initialPayload.push({
|
|
132
|
+
include: true,
|
|
133
|
+
doc
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
setPayload(initialPayload);
|
|
137
|
+
var docCount = docs.length;
|
|
138
|
+
var refsCount = initialRefs.length;
|
|
139
|
+
|
|
140
|
+
if (initialRefs.length) {
|
|
141
|
+
setHasReferences(true);
|
|
142
|
+
setMessage({
|
|
143
|
+
tone: "caution",
|
|
144
|
+
text: (0, _helpers.createInitialMessage)(docCount, refsCount)
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}, [docs]); // Re-check payload on destination when value changes
|
|
148
|
+
// (On initial render + select change)
|
|
149
|
+
|
|
150
|
+
(0, _react.useEffect)(() => {
|
|
151
|
+
updatePayloadStatuses();
|
|
152
|
+
}, [destination, docs]); // Check if payload documents exist at destination
|
|
153
|
+
|
|
154
|
+
function updatePayloadStatuses() {
|
|
155
|
+
return _updatePayloadStatuses.apply(this, arguments);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function _updatePayloadStatuses() {
|
|
159
|
+
_updatePayloadStatuses = _asyncToGenerator(function* () {
|
|
160
|
+
var newPayload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
161
|
+
var payloadActual = newPayload.length ? newPayload : payload;
|
|
162
|
+
|
|
163
|
+
if (!payloadActual.length || !(destination !== null && destination !== void 0 && destination.name)) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
var payloadIds = payloadActual.map(_ref3 => {
|
|
168
|
+
var doc = _ref3.doc;
|
|
169
|
+
return doc._id;
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
var destinationClient = _client.default.withConfig(_objectSpread(_objectSpread({}, _clientConfig.clientConfig), {}, {
|
|
173
|
+
dataset: destination.api.dataset,
|
|
174
|
+
projectId: destination.api.projectId
|
|
175
|
+
}));
|
|
176
|
+
|
|
177
|
+
var destinationData = yield destinationClient.fetch("*[_id in $payloadIds]{ _id, _updatedAt }", {
|
|
178
|
+
payloadIds
|
|
179
|
+
});
|
|
180
|
+
var updatedPayload = payloadActual.map(item => {
|
|
181
|
+
var _item$doc;
|
|
182
|
+
|
|
183
|
+
var existingDoc = destinationData.find(doc => doc._id === item.doc._id);
|
|
184
|
+
|
|
185
|
+
if (existingDoc !== null && existingDoc !== void 0 && existingDoc._updatedAt && item !== null && item !== void 0 && (_item$doc = item.doc) !== null && _item$doc !== void 0 && _item$doc._updatedAt) {
|
|
186
|
+
if (existingDoc._updatedAt === item.doc._updatedAt) {
|
|
187
|
+
// Exact same document exists at destination
|
|
188
|
+
// We don't compare by _rev because that is updated in a transaction
|
|
189
|
+
item.status = "EXISTS";
|
|
190
|
+
} else if (existingDoc._updatedAt && item.doc._updatedAt) {
|
|
191
|
+
item.status = new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt) ? // Document at destination is newer
|
|
192
|
+
"OVERWRITE" : // Document at destination is older
|
|
193
|
+
"UPDATE";
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
item.status = 'CREATE';
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return item;
|
|
200
|
+
});
|
|
201
|
+
setPayload(updatedPayload);
|
|
202
|
+
});
|
|
203
|
+
return _updatePayloadStatuses.apply(this, arguments);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function handleCheckbox(_id) {
|
|
207
|
+
var updatedPayload = payload.map(item => {
|
|
208
|
+
if (item.doc._id === _id) {
|
|
209
|
+
item.include = !item.include;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return item;
|
|
213
|
+
});
|
|
214
|
+
setPayload(updatedPayload);
|
|
215
|
+
} // Find and recursively follow references beginning with this document
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
function handleReferences() {
|
|
219
|
+
return _handleReferences.apply(this, arguments);
|
|
220
|
+
} // Duplicate payload to destination dataset
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
function _handleReferences() {
|
|
224
|
+
_handleReferences = _asyncToGenerator(function* () {
|
|
225
|
+
setIsGathering(true);
|
|
226
|
+
var docIds = docs.map(doc => doc._id);
|
|
227
|
+
var payloadDocs = yield (0, _getDocumentsInArray.getDocumentsInArray)(docIds, originClient, null); // Shape it up
|
|
228
|
+
|
|
229
|
+
var payloadShaped = payloadDocs.map(doc => ({
|
|
230
|
+
doc,
|
|
231
|
+
// Include this in the transaction?
|
|
232
|
+
include: true,
|
|
233
|
+
// Does it exist at the destination?
|
|
234
|
+
status: ''
|
|
235
|
+
}));
|
|
236
|
+
setPayload(payloadShaped);
|
|
237
|
+
updatePayloadStatuses(payloadShaped);
|
|
238
|
+
setIsGathering(false);
|
|
239
|
+
});
|
|
240
|
+
return _handleReferences.apply(this, arguments);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function handleDuplicate() {
|
|
244
|
+
return _handleDuplicate.apply(this, arguments);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function _handleDuplicate() {
|
|
248
|
+
_handleDuplicate = _asyncToGenerator(function* () {
|
|
249
|
+
setIsDuplicating(true);
|
|
250
|
+
var assetsCount = payload.filter(_ref4 => {
|
|
251
|
+
var doc = _ref4.doc,
|
|
252
|
+
include = _ref4.include;
|
|
253
|
+
return include && (0, _helpers.typeIsAsset)(doc._type);
|
|
254
|
+
}).length;
|
|
255
|
+
var currentProgress = 0;
|
|
256
|
+
setProgress([currentProgress, assetsCount]);
|
|
257
|
+
setMessage({
|
|
258
|
+
text: 'Duplicating...'
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
var destinationClient = _client.default.withConfig(_objectSpread(_objectSpread({}, _clientConfig.clientConfig), {}, {
|
|
262
|
+
dataset: destination.api.dataset,
|
|
263
|
+
projectId: destination.api.projectId
|
|
264
|
+
}));
|
|
265
|
+
|
|
266
|
+
var transactionDocs = [];
|
|
267
|
+
var svgMaps = []; // Upload assets and then add to transaction
|
|
268
|
+
|
|
269
|
+
function fetchDoc(_x) {
|
|
270
|
+
return _fetchDoc.apply(this, arguments);
|
|
271
|
+
} // Promises are limited to three at once
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
function _fetchDoc() {
|
|
275
|
+
_fetchDoc = _asyncToGenerator(function* (doc) {
|
|
276
|
+
if ((0, _helpers.typeIsAsset)(doc._type)) {
|
|
277
|
+
// Download and upload asset
|
|
278
|
+
// Get the *original* image with this dlRaw param to create the same determenistic _id
|
|
279
|
+
var uploadType = doc._type.split('.').pop().replace('Asset', '');
|
|
280
|
+
|
|
281
|
+
var downloadUrl = uploadType === 'image' ? "".concat(doc.url, "?dlRaw=true") : doc.url;
|
|
282
|
+
var downloadConfig = uploadType === 'image' ? {
|
|
283
|
+
headers: {
|
|
284
|
+
Authorization: token ? "Bearer ".concat(token) : ""
|
|
285
|
+
}
|
|
286
|
+
} : {};
|
|
287
|
+
yield fetch(downloadUrl, downloadConfig).then( /*#__PURE__*/function () {
|
|
288
|
+
var _ref5 = _asyncToGenerator(function* (res) {
|
|
289
|
+
var assetData = yield res.blob();
|
|
290
|
+
var options = {
|
|
291
|
+
filename: doc.originalFilename
|
|
292
|
+
};
|
|
293
|
+
var assetDoc = yield destinationClient.assets.upload(uploadType, assetData, options); // SVG _id's need remapping before transaction
|
|
294
|
+
|
|
295
|
+
if ((doc === null || doc === void 0 ? void 0 : doc.extension) === 'svg') {
|
|
296
|
+
svgMaps.push({
|
|
297
|
+
old: doc._id,
|
|
298
|
+
new: assetDoc._id
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
transactionDocs.push(assetDoc);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
return function (_x2) {
|
|
306
|
+
return _ref5.apply(this, arguments);
|
|
307
|
+
};
|
|
308
|
+
}());
|
|
309
|
+
currentProgress += 1;
|
|
310
|
+
setMessage({
|
|
311
|
+
text: "Duplicating ".concat(currentProgress, "/").concat(assetsCount, " ").concat(assetsCount === 1 ? "Assets" : "Assets")
|
|
312
|
+
});
|
|
313
|
+
return setProgress([currentProgress, assetsCount]);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return transactionDocs.push(doc);
|
|
317
|
+
});
|
|
318
|
+
return _fetchDoc.apply(this, arguments);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
var result = new Promise((resolve, reject) => {
|
|
322
|
+
var payloadIncludedDocs = payload.filter(item => item.include).map(item => item.doc);
|
|
323
|
+
(0, _mapLimit.default)(payloadIncludedDocs, 3, (0, _asyncify.default)(fetchDoc), err => {
|
|
324
|
+
if (err) {
|
|
325
|
+
setIsDuplicating(false);
|
|
326
|
+
setMessage({
|
|
327
|
+
tone: 'critical',
|
|
328
|
+
text: "Duplication Failed"
|
|
329
|
+
});
|
|
330
|
+
console.error(err);
|
|
331
|
+
reject(new Error('Duplication Failed'));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
resolve();
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
yield result; // Remap SVG references to new _id's
|
|
338
|
+
|
|
339
|
+
var transactionDocsMapped = transactionDocs.map(doc => {
|
|
340
|
+
var expr = ".._ref";
|
|
341
|
+
var references = (0, _mutator.extractWithPath)(expr, doc);
|
|
342
|
+
|
|
343
|
+
if (!references.length) {
|
|
344
|
+
return doc;
|
|
345
|
+
} // For every found _ref, search for an SVG asset _id and update
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
references.forEach(ref => {
|
|
349
|
+
var _svgMaps$find;
|
|
350
|
+
|
|
351
|
+
var newRefValue = (_svgMaps$find = svgMaps.find(asset => asset.old === ref.value)) === null || _svgMaps$find === void 0 ? void 0 : _svgMaps$find.new;
|
|
352
|
+
|
|
353
|
+
if (newRefValue) {
|
|
354
|
+
var refPath = ref.path.join('.');
|
|
355
|
+
(0, _dset.dset)(doc, refPath, newRefValue);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
return doc;
|
|
359
|
+
}); // Create transaction
|
|
360
|
+
|
|
361
|
+
var transaction = destinationClient.transaction();
|
|
362
|
+
transactionDocsMapped.forEach(doc => {
|
|
363
|
+
transaction.createOrReplace(doc);
|
|
364
|
+
});
|
|
365
|
+
yield transaction.commit().then(res => {
|
|
366
|
+
setMessage({
|
|
367
|
+
tone: 'positive',
|
|
368
|
+
text: 'Duplication complete!'
|
|
369
|
+
});
|
|
370
|
+
updatePayloadStatuses();
|
|
371
|
+
}).catch(err => {
|
|
372
|
+
setMessage({
|
|
373
|
+
tone: 'critical',
|
|
374
|
+
text: err.details.description
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
setIsDuplicating(false);
|
|
378
|
+
setProgress(0);
|
|
379
|
+
});
|
|
380
|
+
return _handleDuplicate.apply(this, arguments);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function handleChange(e) {
|
|
384
|
+
setDestination(spacesOptions.find(space => space.name === e.currentTarget.value));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (!spacesOptions.length) {
|
|
388
|
+
return /*#__PURE__*/_react.default.createElement(_Feedback.default, {
|
|
389
|
+
tone: "critical"
|
|
390
|
+
}, /*#__PURE__*/_react.default.createElement("code", null, "__experimental_spaces"), " not found in ", /*#__PURE__*/_react.default.createElement("code", null, "sanity.json"));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
var payloadCount = payload.length;
|
|
394
|
+
var firstSvgIndex = payload.findIndex(_ref => {
|
|
395
|
+
var doc = _ref.doc;
|
|
396
|
+
return doc.extension === 'svg';
|
|
397
|
+
});
|
|
398
|
+
var selectedDocumentsCount = payload.filter(item => item.include && !(0, _helpers.typeIsAsset)(item.doc._type)).length;
|
|
399
|
+
var selectedAssetsCount = payload.filter(item => item.include && (0, _helpers.typeIsAsset)(item.doc._type)).length;
|
|
400
|
+
var selectedTotal = selectedDocumentsCount + selectedAssetsCount;
|
|
401
|
+
var destinationTitle = (_destination$title = destination === null || destination === void 0 ? void 0 : destination.title) !== null && _destination$title !== void 0 ? _destination$title : destination === null || destination === void 0 ? void 0 : destination.name;
|
|
402
|
+
var hasMultipleProjectIds = new Set(spacesOptions.map(space => {
|
|
403
|
+
var _space$api;
|
|
404
|
+
|
|
405
|
+
return space === null || space === void 0 ? void 0 : (_space$api = space.api) === null || _space$api === void 0 ? void 0 : _space$api.projectId;
|
|
406
|
+
}).filter(Boolean)).size > 1;
|
|
407
|
+
var headingText = [selectedTotal, "/", payloadCount, "Documents and Assets selected"].join(" ");
|
|
408
|
+
|
|
409
|
+
var buttonText = _react.default.useMemo(() => {
|
|
410
|
+
var text = ["Duplicate"];
|
|
411
|
+
|
|
412
|
+
if (selectedDocumentsCount > 1) {
|
|
413
|
+
text.push(selectedDocumentsCount, selectedDocumentsCount === 1 ? "Document" : "Documents");
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (selectedAssetsCount > 1) {
|
|
417
|
+
text.push("and", selectedAssetsCount, selectedAssetsCount === 1 ? "Asset" : "Assets");
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (originClient.config().projectId !== destination.api.projectId) {
|
|
421
|
+
text.push("between Projects");
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
text.push("to", destinationTitle);
|
|
425
|
+
return text.join(" ");
|
|
426
|
+
}, [selectedDocumentsCount, selectedAssetsCount, destinationTitle]);
|
|
427
|
+
|
|
428
|
+
return /*#__PURE__*/_react.default.createElement(_ui.Container, {
|
|
429
|
+
width: 1
|
|
430
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Card, null, /*#__PURE__*/_react.default.createElement(_ui.Stack, null, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
431
|
+
borderBottom: true,
|
|
432
|
+
padding: 4,
|
|
433
|
+
style: _helpers.stickyStyles
|
|
434
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
435
|
+
space: 4
|
|
436
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
|
|
437
|
+
space: 3
|
|
438
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
439
|
+
style: {
|
|
440
|
+
flex: 1
|
|
441
|
+
},
|
|
442
|
+
space: 3
|
|
443
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Label, null, "Duplicate from"), /*#__PURE__*/_react.default.createElement(_ui.Select, {
|
|
444
|
+
readOnly: true,
|
|
445
|
+
value: (_spacesOptions$find = spacesOptions.find(space => space.disabled)) === null || _spacesOptions$find === void 0 ? void 0 : _spacesOptions$find.name
|
|
446
|
+
}, spacesOptions.filter(space => space.disabled).map(space => {
|
|
447
|
+
var _space$title;
|
|
448
|
+
|
|
449
|
+
return /*#__PURE__*/_react.default.createElement("option", {
|
|
450
|
+
key: space.name,
|
|
451
|
+
value: space.name,
|
|
452
|
+
disabled: space.disabled
|
|
453
|
+
}, (_space$title = space.title) !== null && _space$title !== void 0 ? _space$title : space.name, hasMultipleProjectIds ? " (".concat(space.api.projectId, ")") : "");
|
|
454
|
+
}))), /*#__PURE__*/_react.default.createElement(_ui.Box, {
|
|
455
|
+
padding: 4,
|
|
456
|
+
paddingTop: 5,
|
|
457
|
+
paddingBottom: 0
|
|
458
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Text, {
|
|
459
|
+
size: 3
|
|
460
|
+
}, /*#__PURE__*/_react.default.createElement(_icons.ArrowRightIcon, null))), /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
461
|
+
style: {
|
|
462
|
+
flex: 1
|
|
463
|
+
},
|
|
464
|
+
space: 3
|
|
465
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Label, null, "To Destination"), /*#__PURE__*/_react.default.createElement(_ui.Select, {
|
|
466
|
+
onChange: handleChange
|
|
467
|
+
}, spacesOptions.map(space => {
|
|
468
|
+
var _space$title2;
|
|
469
|
+
|
|
470
|
+
return /*#__PURE__*/_react.default.createElement("option", {
|
|
471
|
+
key: space.name,
|
|
472
|
+
value: space.name,
|
|
473
|
+
disabled: space.disabled
|
|
474
|
+
}, (_space$title2 = space.title) !== null && _space$title2 !== void 0 ? _space$title2 : space.name, hasMultipleProjectIds ? " (".concat(space.api.projectId, ")") : "", space.disabled ? " (Current)" : "");
|
|
475
|
+
})))), isDuplicating && /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
476
|
+
border: true,
|
|
477
|
+
radius: 2
|
|
478
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
479
|
+
style: {
|
|
480
|
+
width: '100%',
|
|
481
|
+
transform: "scaleX(".concat(progress[0] / progress[1], ")"),
|
|
482
|
+
transformOrigin: 'left',
|
|
483
|
+
transition: 'transform .2s ease',
|
|
484
|
+
boxSizing: 'border-box'
|
|
485
|
+
},
|
|
486
|
+
padding: 1,
|
|
487
|
+
tone: "positive"
|
|
488
|
+
})), payload.length > 0 && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.Label, null, headingText), /*#__PURE__*/_react.default.createElement(_SelectButtons.default, {
|
|
489
|
+
payload: payload,
|
|
490
|
+
setPayload: setPayload
|
|
491
|
+
})))), (message === null || message === void 0 ? void 0 : message.text) && /*#__PURE__*/_react.default.createElement(_ui.Box, {
|
|
492
|
+
paddingX: 4,
|
|
493
|
+
paddingTop: 4
|
|
494
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
495
|
+
padding: 3,
|
|
496
|
+
radius: 2,
|
|
497
|
+
shadow: 1,
|
|
498
|
+
tone: (_message$tone = message === null || message === void 0 ? void 0 : message.tone) !== null && _message$tone !== void 0 ? _message$tone : 'transparent'
|
|
499
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Text, {
|
|
500
|
+
size: 1
|
|
501
|
+
}, message.text))), payload.length > 0 && /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
502
|
+
padding: 4,
|
|
503
|
+
space: 3
|
|
504
|
+
}, payload.map((_ref2, index) => {
|
|
505
|
+
var doc = _ref2.doc,
|
|
506
|
+
include = _ref2.include,
|
|
507
|
+
status = _ref2.status;
|
|
508
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
|
|
509
|
+
key: doc._id
|
|
510
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Flex, {
|
|
511
|
+
align: "center"
|
|
512
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Checkbox, {
|
|
513
|
+
checked: include,
|
|
514
|
+
onChange: () => handleCheckbox(doc._id)
|
|
515
|
+
}), /*#__PURE__*/_react.default.createElement(_ui.Box, {
|
|
516
|
+
style: {
|
|
517
|
+
flex: 1
|
|
518
|
+
},
|
|
519
|
+
paddingX: 3
|
|
520
|
+
}, /*#__PURE__*/_react.default.createElement(_preview.default, {
|
|
521
|
+
value: doc,
|
|
522
|
+
type: _schema.default.get(doc._type)
|
|
523
|
+
})), /*#__PURE__*/_react.default.createElement(_StatusBadge.default, {
|
|
524
|
+
status: status,
|
|
525
|
+
isAsset: (0, _helpers.typeIsAsset)(doc._type)
|
|
526
|
+
})), (doc === null || doc === void 0 ? void 0 : doc.extension) === 'svg' && index === firstSvgIndex && /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
527
|
+
padding: 3,
|
|
528
|
+
radius: 2,
|
|
529
|
+
shadow: 1,
|
|
530
|
+
tone: "caution"
|
|
531
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Text, {
|
|
532
|
+
size: 1
|
|
533
|
+
}, "Due to how SVGs are sanitized after first uploaded, duplicated SVG assets may have new", ' ', /*#__PURE__*/_react.default.createElement("code", null, "_id"), "'s at the destination. The newly generated ", /*#__PURE__*/_react.default.createElement("code", null, "_id"), ' ', "will be the same in each duplication, but it will never be the same", ' ', /*#__PURE__*/_react.default.createElement("code", null, "_id"), " as the first time this Asset was uploaded. References to the asset will be updated to use the new ", /*#__PURE__*/_react.default.createElement("code", null, "_id"), ".")));
|
|
534
|
+
})), /*#__PURE__*/_react.default.createElement(_ui.Stack, {
|
|
535
|
+
space: 2,
|
|
536
|
+
padding: 4,
|
|
537
|
+
paddingTop: 0
|
|
538
|
+
}, hasReferences && /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
539
|
+
fontSize: 2,
|
|
540
|
+
padding: 4,
|
|
541
|
+
tone: "positive",
|
|
542
|
+
mode: "ghost",
|
|
543
|
+
icon: _icons.SearchIcon,
|
|
544
|
+
onClick: handleReferences,
|
|
545
|
+
text: "Gather References",
|
|
546
|
+
disabled: isDuplicating || !selectedTotal || isGathering
|
|
547
|
+
}), /*#__PURE__*/_react.default.createElement(_ui.Button, {
|
|
548
|
+
fontSize: 2,
|
|
549
|
+
padding: 4,
|
|
550
|
+
tone: "positive",
|
|
551
|
+
icon: _icons.LaunchIcon,
|
|
552
|
+
onClick: handleDuplicate,
|
|
553
|
+
text: buttonText,
|
|
554
|
+
disabled: isDuplicating || !selectedTotal || isGathering
|
|
555
|
+
}))))));
|
|
556
|
+
}
|
|
557
|
+
//# sourceMappingURL=DuplicatorTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/DuplicatorTool.tsx"],"names":["DuplicatorTool","props","docs","token","originClient","sanityClient","withConfig","clientConfig","spacesOptions","config","__experimental_spaces","length","map","space","disabled","api","dataset","find","destination","setDestination","message","setMessage","item","doc","include","status","payload","setPayload","hasReferences","setHasReferences","isDuplicating","setIsDuplicating","isGathering","setIsGathering","progress","setProgress","expr","initialRefs","initialPayload","forEach","push","docCount","refsCount","tone","text","updatePayloadStatuses","newPayload","payloadActual","name","payloadIds","_id","destinationClient","projectId","destinationData","fetch","updatedPayload","existingDoc","_updatedAt","Date","handleCheckbox","handleReferences","docIds","payloadDocs","payloadShaped","handleDuplicate","assetsCount","filter","_type","currentProgress","transactionDocs","svgMaps","fetchDoc","uploadType","split","pop","replace","downloadUrl","url","downloadConfig","headers","Authorization","then","res","assetData","blob","options","filename","originalFilename","assetDoc","assets","upload","extension","old","new","result","Promise","resolve","reject","payloadIncludedDocs","err","console","error","Error","transactionDocsMapped","references","ref","newRefValue","asset","value","refPath","path","join","transaction","createOrReplace","commit","catch","details","description","handleChange","e","currentTarget","payloadCount","firstSvgIndex","findIndex","selectedDocumentsCount","selectedAssetsCount","selectedTotal","destinationTitle","title","hasMultipleProjectIds","Set","Boolean","size","headingText","buttonText","React","useMemo","stickyStyles","flex","width","transform","transformOrigin","transition","boxSizing","index","schema","get","SearchIcon","LaunchIcon"],"mappings":"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","sourcesContent":["/* eslint-disable react/jsx-no-bind */\nimport React, {useState, useEffect} from 'react'\nimport mapLimit from 'async/mapLimit'\nimport asyncify from 'async/asyncify'\nimport {extract, extractWithPath} from '@sanity/mutator'\nimport {dset} from 'dset'\nimport {Card, Container, Text, Box, Button, Label, Stack, Select, Flex, Checkbox} from '@sanity/ui'\nimport {ArrowRightIcon, SearchIcon, LaunchIcon} from '@sanity/icons'\nimport sanityClient from 'part:@sanity/base/client'\nimport Preview from 'part:@sanity/base/preview'\nimport schema from 'part:@sanity/base/schema'\nimport config from 'config:sanity'\n\nimport {typeIsAsset, stickyStyles, createInitialMessage} from '../helpers'\nimport {getDocumentsInArray} from '../helpers/getDocumentsInArray'\nimport SelectButtons from './SelectButtons'\nimport StatusBadge from './StatusBadge'\nimport Feedback from './Feedback'\nimport {SanityDocument} from '../types'\nimport {clientConfig} from '../helpers/clientConfig'\n\ntype DuplicatorToolProps = {\n docs: SanityDocument[]\n token: string\n}\n\nexport default function DuplicatorTool(props: DuplicatorToolProps) {\n const {docs, token} = props\n\n // Prepare origin (this Studio) client\n // In function-scope so it is up to date on every render\n const originClient = sanityClient.withConfig(clientConfig)\n\n // Create list of dataset options\n // and set initial value of dropdown\n const spacesOptions = config?.__experimental_spaces?.length\n ? config.__experimental_spaces.map((space) => ({\n ...space,\n disabled: space.api.dataset === originClient.config().dataset,\n }))\n : []\n\n const [destination, setDestination] = useState(\n spacesOptions.length ? spacesOptions.find((space) => !space.disabled) : {}\n )\n const [message, setMessage] = useState({})\n const [payload, setPayload] = useState(\n docs.length\n ? docs.map((item) => ({\n doc: item,\n include: true,\n status: null,\n }))\n : []\n )\n const [hasReferences, setHasReferences] = useState(false)\n const [isDuplicating, setIsDuplicating] = useState(false)\n const [isGathering, setIsGathering] = useState(false)\n const [progress, setProgress] = useState([0, 0])\n\n // Check for References and update message\n useEffect(() => {\n const expr = `.._ref`\n const initialRefs = []\n const initialPayload = []\n\n docs.forEach((doc) => {\n initialRefs.push(...extract(expr, doc))\n initialPayload.push({include: true, doc})\n })\n\n setPayload(initialPayload)\n\n const docCount = docs.length\n const refsCount = initialRefs.length\n\n if (initialRefs.length) {\n setHasReferences(true)\n\n setMessage({\n tone: `caution`,\n text: createInitialMessage(docCount, refsCount),\n })\n }\n }, [docs])\n\n // Re-check payload on destination when value changes\n // (On initial render + select change)\n useEffect(() => {\n updatePayloadStatuses()\n }, [destination, docs])\n\n // Check if payload documents exist at destination\n async function updatePayloadStatuses(newPayload = []) {\n const payloadActual = newPayload.length ? newPayload : payload\n\n if (!payloadActual.length || !destination?.name) {\n return\n }\n\n const payloadIds = payloadActual.map(({doc}) => doc._id)\n const destinationClient = sanityClient.withConfig({\n ...clientConfig,\n dataset: destination.api.dataset,\n projectId: destination.api.projectId,\n })\n const destinationData = await destinationClient.fetch(\n `*[_id in $payloadIds]{ _id, _updatedAt }`,\n {payloadIds}\n )\n\n const updatedPayload = payloadActual.map((item) => {\n const existingDoc = destinationData.find((doc) => doc._id === item.doc._id)\n\n if (existingDoc?._updatedAt && item?.doc?._updatedAt) {\n if (existingDoc._updatedAt === item.doc._updatedAt) {\n // Exact same document exists at destination\n // We don't compare by _rev because that is updated in a transaction\n item.status = `EXISTS`\n } else if (existingDoc._updatedAt && item.doc._updatedAt) {\n item.status =\n new Date(existingDoc._updatedAt) > new Date(item.doc._updatedAt)\n ? // Document at destination is newer\n `OVERWRITE`\n : // Document at destination is older\n `UPDATE`\n }\n } else {\n item.status = 'CREATE'\n }\n\n return item\n })\n\n setPayload(updatedPayload)\n }\n\n function handleCheckbox(_id) {\n const updatedPayload = payload.map((item) => {\n if (item.doc._id === _id) {\n item.include = !item.include\n }\n\n return item\n })\n\n setPayload(updatedPayload)\n }\n\n // Find and recursively follow references beginning with this document\n async function handleReferences() {\n setIsGathering(true)\n const docIds = docs.map((doc) => doc._id)\n\n const payloadDocs = await getDocumentsInArray(docIds, originClient, null)\n\n // Shape it up\n const payloadShaped = payloadDocs.map((doc) => ({\n doc,\n // Include this in the transaction?\n include: true,\n // Does it exist at the destination?\n status: '',\n }))\n\n setPayload(payloadShaped)\n updatePayloadStatuses(payloadShaped)\n setIsGathering(false)\n }\n\n // Duplicate payload to destination dataset\n async function handleDuplicate() {\n setIsDuplicating(true)\n\n const assetsCount = payload.filter(({doc, include}) => include && typeIsAsset(doc._type)).length\n let currentProgress = 0\n setProgress([currentProgress, assetsCount])\n\n setMessage({text: 'Duplicating...'})\n\n const destinationClient = sanityClient.withConfig({\n ...clientConfig,\n dataset: destination.api.dataset,\n projectId: destination.api.projectId,\n })\n\n const transactionDocs = []\n const svgMaps = []\n\n // Upload assets and then add to transaction\n async function fetchDoc(doc) {\n if (typeIsAsset(doc._type)) {\n // Download and upload asset\n // Get the *original* image with this dlRaw param to create the same determenistic _id\n const uploadType = doc._type.split('.').pop().replace('Asset', '')\n const downloadUrl = uploadType === 'image' ? `${doc.url}?dlRaw=true` : doc.url\n const downloadConfig =\n uploadType === 'image' ? {headers: {Authorization: token ? `Bearer ${token}` : ``}} : {}\n\n await fetch(downloadUrl, downloadConfig).then(async (res) => {\n const assetData = await res.blob()\n\n const options = {filename: doc.originalFilename}\n const assetDoc = await destinationClient.assets.upload(uploadType, assetData, options)\n\n // SVG _id's need remapping before transaction\n if (doc?.extension === 'svg') {\n svgMaps.push({old: doc._id, new: assetDoc._id})\n }\n\n transactionDocs.push(assetDoc)\n })\n\n currentProgress += 1\n setMessage({\n text: `Duplicating ${currentProgress}/${assetsCount} ${\n assetsCount === 1 ? `Assets` : `Assets`\n }`,\n })\n\n return setProgress([currentProgress, assetsCount])\n }\n\n return transactionDocs.push(doc)\n }\n\n // Promises are limited to three at once\n const result = new Promise((resolve, reject) => {\n const payloadIncludedDocs = payload.filter((item) => item.include).map((item) => item.doc)\n\n mapLimit(payloadIncludedDocs, 3, asyncify(fetchDoc), (err) => {\n if (err) {\n setIsDuplicating(false)\n setMessage({tone: 'critical', text: `Duplication Failed`})\n console.error(err)\n reject(new Error('Duplication Failed'))\n }\n\n resolve()\n })\n })\n\n await result\n\n // Remap SVG references to new _id's\n const transactionDocsMapped = transactionDocs.map((doc) => {\n const expr = `.._ref`\n const references = extractWithPath(expr, doc)\n\n if (!references.length) {\n return doc\n }\n\n // For every found _ref, search for an SVG asset _id and update\n references.forEach((ref) => {\n const newRefValue = svgMaps.find((asset) => asset.old === ref.value)?.new\n\n if (newRefValue) {\n const refPath = ref.path.join('.')\n\n dset(doc, refPath, newRefValue)\n }\n })\n\n return doc\n })\n\n // Create transaction\n const transaction = destinationClient.transaction()\n\n transactionDocsMapped.forEach((doc) => {\n transaction.createOrReplace(doc)\n })\n\n await transaction\n .commit()\n .then((res) => {\n setMessage({tone: 'positive', text: 'Duplication complete!'})\n\n updatePayloadStatuses()\n })\n .catch((err) => {\n setMessage({tone: 'critical', text: err.details.description})\n })\n\n setIsDuplicating(false)\n setProgress(0)\n }\n\n function handleChange(e) {\n setDestination(spacesOptions.find((space) => space.name === e.currentTarget.value))\n }\n\n if (!spacesOptions.length) {\n return (\n <Feedback tone=\"critical\">\n <code>__experimental_spaces</code> not found in <code>sanity.json</code>\n </Feedback>\n )\n }\n\n const payloadCount = payload.length\n const firstSvgIndex = payload.findIndex(({doc}) => doc.extension === 'svg')\n const selectedDocumentsCount = payload.filter(\n (item) => item.include && !typeIsAsset(item.doc._type)\n ).length\n const selectedAssetsCount = payload.filter(\n (item) => item.include && typeIsAsset(item.doc._type)\n ).length\n const selectedTotal = selectedDocumentsCount + selectedAssetsCount\n const destinationTitle = destination?.title ?? destination?.name\n const hasMultipleProjectIds =\n new Set(spacesOptions.map((space) => space?.api?.projectId).filter(Boolean)).size > 1\n\n const headingText = [selectedTotal, `/`, payloadCount, `Documents and Assets selected`].join(` `)\n\n const buttonText = React.useMemo(() => {\n let text = [`Duplicate`]\n\n if (selectedDocumentsCount > 1) {\n text.push(selectedDocumentsCount, selectedDocumentsCount === 1 ? `Document` : `Documents`)\n }\n\n if (selectedAssetsCount > 1) {\n text.push(`and`, selectedAssetsCount, selectedAssetsCount === 1 ? `Asset` : `Assets`)\n }\n\n if (originClient.config().projectId !== destination.api.projectId) {\n text.push(`between Projects`)\n }\n\n text.push(`to`, destinationTitle)\n\n return text.join(` `)\n }, [selectedDocumentsCount, selectedAssetsCount, destinationTitle])\n\n return (\n <Container width={1}>\n <Card>\n <Stack>\n <>\n <Card borderBottom padding={4} style={stickyStyles}>\n <Stack space={4}>\n <Flex space={3}>\n <Stack style={{flex: 1}} space={3}>\n <Label>Duplicate from</Label>\n <Select readOnly value={spacesOptions.find((space) => space.disabled)?.name}>\n {spacesOptions\n .filter((space) => space.disabled)\n .map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.api.projectId})` : ``}\n </option>\n ))}\n </Select>\n </Stack>\n <Box padding={4} paddingTop={5} paddingBottom={0}>\n <Text size={3}>\n <ArrowRightIcon />\n </Text>\n </Box>\n <Stack style={{flex: 1}} space={3}>\n <Label>To Destination</Label>\n <Select onChange={handleChange}>\n {spacesOptions.map((space) => (\n <option key={space.name} value={space.name} disabled={space.disabled}>\n {space.title ?? space.name}\n {hasMultipleProjectIds ? ` (${space.api.projectId})` : ``}\n {space.disabled ? ` (Current)` : ``}\n </option>\n ))}\n </Select>\n </Stack>\n </Flex>\n\n {isDuplicating && (\n <Card border radius={2}>\n <Card\n style={{\n width: '100%',\n transform: `scaleX(${progress[0] / progress[1]})`,\n transformOrigin: 'left',\n transition: 'transform .2s ease',\n boxSizing: 'border-box',\n }}\n padding={1}\n tone=\"positive\"\n />\n </Card>\n )}\n {payload.length > 0 && (\n <>\n <Label>{headingText}</Label>\n <SelectButtons payload={payload} setPayload={setPayload} />\n </>\n )}\n </Stack>\n </Card>\n {message?.text && (\n <Box paddingX={4} paddingTop={4}>\n <Card padding={3} radius={2} shadow={1} tone={message?.tone ?? 'transparent'}>\n <Text size={1}>{message.text}</Text>\n </Card>\n </Box>\n )}\n {payload.length > 0 && (\n <Stack padding={4} space={3}>\n {payload.map(({doc, include, status}, index) => (\n <React.Fragment key={doc._id}>\n <Flex align=\"center\">\n <Checkbox checked={include} onChange={() => handleCheckbox(doc._id)} />\n <Box style={{flex: 1}} paddingX={3}>\n <Preview value={doc} type={schema.get(doc._type)} />\n </Box>\n <StatusBadge status={status} isAsset={typeIsAsset(doc._type)} />\n </Flex>\n {doc?.extension === 'svg' && index === firstSvgIndex && (\n <Card padding={3} radius={2} shadow={1} tone=\"caution\">\n <Text size={1}>\n Due to how SVGs are sanitized after first uploaded, duplicated SVG assets may have new{' '}\n <code>_id</code>'s at the destination. The newly generated <code>_id</code>{' '}\n will be the same in each duplication, but it will never be the same{' '}\n <code>_id</code> as the first time this Asset was uploaded. References to the asset will be updated to use the new <code>_id</code>.\n </Text>\n </Card>\n )}\n </React.Fragment>\n ))}\n </Stack>\n )}\n <Stack space={2} padding={4} paddingTop={0}>\n {hasReferences && (\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n mode=\"ghost\"\n icon={SearchIcon}\n onClick={handleReferences}\n text=\"Gather References\"\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n )}\n <Button\n fontSize={2}\n padding={4}\n tone=\"positive\"\n icon={LaunchIcon}\n onClick={handleDuplicate}\n text={buttonText}\n disabled={isDuplicating || !selectedTotal || isGathering}\n />\n </Stack>\n </>\n </Stack>\n </Card>\n </Container>\n )\n}\n"],"file":"DuplicatorTool.js"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = Feedback;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _ui = require("@sanity/ui");
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
function Feedback(props) {
|
|
15
|
+
var children = props.children,
|
|
16
|
+
_props$tone = props.tone,
|
|
17
|
+
tone = _props$tone === void 0 ? "caution" : _props$tone;
|
|
18
|
+
return /*#__PURE__*/_react.default.createElement(_ui.Card, {
|
|
19
|
+
padding: 3,
|
|
20
|
+
radius: 2,
|
|
21
|
+
shadow: 1,
|
|
22
|
+
tone: tone
|
|
23
|
+
}, /*#__PURE__*/_react.default.createElement(_ui.Text, {
|
|
24
|
+
size: 1
|
|
25
|
+
}, children));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=Feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Feedback.tsx"],"names":["Feedback","props","children","tone"],"mappings":";;;;;;;AAAA;;AACA;;;;AAQe,SAASA,QAAT,CAAkBC,KAAlB,EAAwC;AACrD,MAAOC,QAAP,GAAqCD,KAArC,CAAOC,QAAP;AAAA,oBAAqCD,KAArC,CAAiBE,IAAjB;AAAA,MAAiBA,IAAjB;AAEA,sBACE,6BAAC,QAAD;AAAM,IAAA,OAAO,EAAE,CAAf;AAAkB,IAAA,MAAM,EAAE,CAA1B;AAA6B,IAAA,MAAM,EAAE,CAArC;AAAwC,IAAA,IAAI,EAAEA;AAA9C,kBACE,6BAAC,QAAD;AAAM,IAAA,IAAI,EAAE;AAAZ,KAAgBD,QAAhB,CADF,CADF;AAKD","sourcesContent":["import React from 'react'\nimport {Card, Text} from '@sanity/ui'\nimport type {BadgeTone} from '@sanity/ui'\n\ntype FeedbackProps = {\n children?: React.ReactNode\n tone?: BadgeTone\n}\n\nexport default function Feedback(props: FeedbackProps) {\n const {children, tone = `caution`} = props\n\n return (\n <Card padding={3} radius={2} shadow={1} tone={tone}>\n <Text size={1}>{children}</Text>\n </Card>\n )\n}\n"],"file":"Feedback.js"}
|