@wordpress/core-data 4.8.0 → 4.11.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/CHANGELOG.md +6 -0
- package/README.md +56 -56
- package/build/actions.js.map +1 -1
- package/build/batch/create-batch.js +1 -1
- package/build/batch/create-batch.js.map +1 -1
- package/build/batch/default-processor.js +13 -7
- package/build/batch/default-processor.js.map +1 -1
- package/build/entities.js.map +1 -1
- package/build/entity-provider.js.map +1 -1
- package/build/hooks/use-entity-record.js.map +1 -1
- package/build/hooks/use-query-select.js.map +1 -1
- package/build/hooks/use-resource-permissions.js +94 -0
- package/build/hooks/use-resource-permissions.js.map +1 -0
- package/build/index.js +28 -1
- package/build/index.js.map +1 -1
- package/build/queried-data/selectors.js.map +1 -1
- package/build/reducer.js +4 -1
- package/build/reducer.js.map +1 -1
- package/build/resolvers.js +4 -14
- package/build/resolvers.js.map +1 -1
- package/build/selectors.js +45 -8
- package/build/selectors.js.map +1 -1
- package/build/utils/forward-resolver.js.map +1 -1
- package/build/utils/on-sub-key.js.map +1 -1
- package/build/utils/with-weak-map-cache.js +1 -7
- package/build/utils/with-weak-map-cache.js.map +1 -1
- package/build-module/actions.js.map +1 -1
- package/build-module/batch/create-batch.js +2 -2
- package/build-module/batch/create-batch.js.map +1 -1
- package/build-module/batch/default-processor.js +12 -5
- package/build-module/batch/default-processor.js.map +1 -1
- package/build-module/entities.js.map +1 -1
- package/build-module/entity-provider.js.map +1 -1
- package/build-module/hooks/use-entity-record.js.map +1 -1
- package/build-module/hooks/use-query-select.js.map +1 -1
- package/build-module/hooks/use-resource-permissions.js +82 -0
- package/build-module/hooks/use-resource-permissions.js.map +1 -0
- package/build-module/index.js +3 -0
- package/build-module/index.js.map +1 -1
- package/build-module/queried-data/selectors.js.map +1 -1
- package/build-module/reducer.js +5 -2
- package/build-module/reducer.js.map +1 -1
- package/build-module/resolvers.js +5 -15
- package/build-module/resolvers.js.map +1 -1
- package/build-module/selectors.js +40 -4
- package/build-module/selectors.js.map +1 -1
- package/build-module/utils/forward-resolver.js.map +1 -1
- package/build-module/utils/on-sub-key.js.map +1 -1
- package/build-module/utils/with-weak-map-cache.js +1 -6
- package/build-module/utils/with-weak-map-cache.js.map +1 -1
- package/package.json +11 -11
- package/src/actions.js +389 -372
- package/src/batch/create-batch.js +2 -2
- package/src/batch/default-processor.js +10 -5
- package/src/entities.ts +16 -17
- package/src/entity-provider.js +4 -6
- package/src/entity-types/attachment.ts +4 -3
- package/src/entity-types/comment.ts +4 -3
- package/src/entity-types/entities.ts +5 -2
- package/src/entity-types/index.ts +114 -20
- package/src/entity-types/menu-location.ts +4 -3
- package/src/entity-types/nav-menu-item.ts +4 -3
- package/src/entity-types/nav-menu.ts +3 -3
- package/src/entity-types/page.ts +3 -3
- package/src/entity-types/plugin.ts +3 -3
- package/src/entity-types/post.ts +3 -3
- package/src/entity-types/settings.ts +3 -3
- package/src/entity-types/sidebar.ts +4 -3
- package/src/entity-types/taxonomy.ts +4 -3
- package/src/entity-types/theme.ts +3 -3
- package/src/entity-types/type.ts +3 -3
- package/src/entity-types/user.ts +3 -3
- package/src/entity-types/widget-type.ts +4 -3
- package/src/entity-types/widget.ts +3 -3
- package/src/entity-types/wp-template-part.ts +4 -3
- package/src/entity-types/wp-template.ts +4 -3
- package/src/fetch/test/__experimental-fetch-link-suggestions.js +2 -4
- package/src/hooks/test/use-query-select.js +4 -2
- package/src/hooks/test/use-resource-permissions.js +115 -0
- package/src/hooks/use-entity-record.ts +0 -1
- package/src/hooks/use-query-select.ts +26 -24
- package/src/hooks/use-resource-permissions.ts +120 -0
- package/src/index.js +3 -0
- package/src/locks/test/selectors.js +2 -1
- package/src/queried-data/selectors.js +2 -8
- package/src/reducer.js +9 -2
- package/src/resolvers.js +344 -326
- package/src/selectors.ts +347 -194
- package/src/test/reducer.js +5 -4
- package/src/test/resolvers.js +1 -3
- package/src/test/selectors.js +1 -2
- package/src/utils/forward-resolver.js +6 -5
- package/src/utils/on-sub-key.js +20 -20
- package/src/utils/with-weak-map-cache.js +1 -6
package/src/actions.js
CHANGED
|
@@ -221,71 +221,73 @@ export function receiveEmbedPreview( url, preview ) {
|
|
|
221
221
|
* @param {boolean} [options.throwOnError=false] If false, this action suppresses all
|
|
222
222
|
* the exceptions. Defaults to false.
|
|
223
223
|
*/
|
|
224
|
-
export const deleteEntityRecord =
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
STORE_NAME,
|
|
241
|
-
[ 'entities', 'records', kind, name, recordId ],
|
|
242
|
-
{ exclusive: true }
|
|
243
|
-
);
|
|
224
|
+
export const deleteEntityRecord =
|
|
225
|
+
(
|
|
226
|
+
kind,
|
|
227
|
+
name,
|
|
228
|
+
recordId,
|
|
229
|
+
query,
|
|
230
|
+
{ __unstableFetch = apiFetch, throwOnError = false } = {}
|
|
231
|
+
) =>
|
|
232
|
+
async ( { dispatch } ) => {
|
|
233
|
+
const configs = await dispatch( getOrLoadEntitiesConfig( kind ) );
|
|
234
|
+
const entityConfig = find( configs, { kind, name } );
|
|
235
|
+
let error;
|
|
236
|
+
let deletedRecord = false;
|
|
237
|
+
if ( ! entityConfig || entityConfig?.__experimentalNoFetch ) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
244
240
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
recordId,
|
|
251
|
-
} );
|
|
241
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
242
|
+
STORE_NAME,
|
|
243
|
+
[ 'entities', 'records', kind, name, recordId ],
|
|
244
|
+
{ exclusive: true }
|
|
245
|
+
);
|
|
252
246
|
|
|
253
|
-
let hasError = false;
|
|
254
247
|
try {
|
|
255
|
-
|
|
248
|
+
dispatch( {
|
|
249
|
+
type: 'DELETE_ENTITY_RECORD_START',
|
|
250
|
+
kind,
|
|
251
|
+
name,
|
|
252
|
+
recordId,
|
|
253
|
+
} );
|
|
254
|
+
|
|
255
|
+
let hasError = false;
|
|
256
|
+
try {
|
|
257
|
+
let path = `${ entityConfig.baseURL }/${ recordId }`;
|
|
258
|
+
|
|
259
|
+
if ( query ) {
|
|
260
|
+
path = addQueryArgs( path, query );
|
|
261
|
+
}
|
|
256
262
|
|
|
257
|
-
|
|
258
|
-
|
|
263
|
+
deletedRecord = await __unstableFetch( {
|
|
264
|
+
path,
|
|
265
|
+
method: 'DELETE',
|
|
266
|
+
} );
|
|
267
|
+
|
|
268
|
+
await dispatch( removeItems( kind, name, recordId, true ) );
|
|
269
|
+
} catch ( _error ) {
|
|
270
|
+
hasError = true;
|
|
271
|
+
error = _error;
|
|
259
272
|
}
|
|
260
273
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
274
|
+
dispatch( {
|
|
275
|
+
type: 'DELETE_ENTITY_RECORD_FINISH',
|
|
276
|
+
kind,
|
|
277
|
+
name,
|
|
278
|
+
recordId,
|
|
279
|
+
error,
|
|
264
280
|
} );
|
|
265
281
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
error = _error;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
dispatch( {
|
|
273
|
-
type: 'DELETE_ENTITY_RECORD_FINISH',
|
|
274
|
-
kind,
|
|
275
|
-
name,
|
|
276
|
-
recordId,
|
|
277
|
-
error,
|
|
278
|
-
} );
|
|
282
|
+
if ( hasError && throwOnError ) {
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
279
285
|
|
|
280
|
-
|
|
281
|
-
|
|
286
|
+
return deletedRecord;
|
|
287
|
+
} finally {
|
|
288
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
282
289
|
}
|
|
283
|
-
|
|
284
|
-
return deletedRecord;
|
|
285
|
-
} finally {
|
|
286
|
-
dispatch.__unstableReleaseStoreLock( lock );
|
|
287
|
-
}
|
|
288
|
-
};
|
|
290
|
+
};
|
|
289
291
|
|
|
290
292
|
/**
|
|
291
293
|
* Returns an action object that triggers an
|
|
@@ -300,87 +302,91 @@ export const deleteEntityRecord = (
|
|
|
300
302
|
*
|
|
301
303
|
* @return {Object} Action object.
|
|
302
304
|
*/
|
|
303
|
-
export const editEntityRecord =
|
|
304
|
-
kind,
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
305
|
+
export const editEntityRecord =
|
|
306
|
+
( kind, name, recordId, edits, options = {} ) =>
|
|
307
|
+
( { select, dispatch } ) => {
|
|
308
|
+
const entityConfig = select.getEntityConfig( kind, name );
|
|
309
|
+
if ( ! entityConfig ) {
|
|
310
|
+
throw new Error(
|
|
311
|
+
`The entity being edited (${ kind }, ${ name }) does not have a loaded config.`
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
const { transientEdits = {}, mergedEdits = {} } = entityConfig;
|
|
315
|
+
const record = select.getRawEntityRecord( kind, name, recordId );
|
|
316
|
+
const editedRecord = select.getEditedEntityRecord(
|
|
317
|
+
kind,
|
|
318
|
+
name,
|
|
319
|
+
recordId
|
|
314
320
|
);
|
|
315
|
-
}
|
|
316
|
-
const { transientEdits = {}, mergedEdits = {} } = entityConfig;
|
|
317
|
-
const record = select.getRawEntityRecord( kind, name, recordId );
|
|
318
|
-
const editedRecord = select.getEditedEntityRecord( kind, name, recordId );
|
|
319
321
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
322
|
+
const edit = {
|
|
323
|
+
kind,
|
|
324
|
+
name,
|
|
325
|
+
recordId,
|
|
326
|
+
// Clear edits when they are equal to their persisted counterparts
|
|
327
|
+
// so that the property is not considered dirty.
|
|
328
|
+
edits: Object.keys( edits ).reduce( ( acc, key ) => {
|
|
329
|
+
const recordValue = record[ key ];
|
|
330
|
+
const editedRecordValue = editedRecord[ key ];
|
|
331
|
+
const value = mergedEdits[ key ]
|
|
332
|
+
? { ...editedRecordValue, ...edits[ key ] }
|
|
333
|
+
: edits[ key ];
|
|
334
|
+
acc[ key ] = isEqual( recordValue, value ) ? undefined : value;
|
|
335
|
+
return acc;
|
|
336
|
+
}, {} ),
|
|
337
|
+
transientEdits,
|
|
338
|
+
};
|
|
339
|
+
dispatch( {
|
|
340
|
+
type: 'EDIT_ENTITY_RECORD',
|
|
341
|
+
...edit,
|
|
342
|
+
meta: {
|
|
343
|
+
undo: ! options.undoIgnore && {
|
|
344
|
+
...edit,
|
|
345
|
+
// Send the current values for things like the first undo stack entry.
|
|
346
|
+
edits: Object.keys( edits ).reduce( ( acc, key ) => {
|
|
347
|
+
acc[ key ] = editedRecord[ key ];
|
|
348
|
+
return acc;
|
|
349
|
+
}, {} ),
|
|
350
|
+
},
|
|
348
351
|
},
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
+
} );
|
|
353
|
+
};
|
|
352
354
|
|
|
353
355
|
/**
|
|
354
356
|
* Action triggered to undo the last edit to
|
|
355
357
|
* an entity record, if any.
|
|
356
358
|
*/
|
|
357
|
-
export const undo =
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
359
|
+
export const undo =
|
|
360
|
+
() =>
|
|
361
|
+
( { select, dispatch } ) => {
|
|
362
|
+
const undoEdit = select.getUndoEdit();
|
|
363
|
+
if ( ! undoEdit ) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
dispatch( {
|
|
367
|
+
type: 'EDIT_ENTITY_RECORD',
|
|
368
|
+
...undoEdit,
|
|
369
|
+
meta: { isUndo: true },
|
|
370
|
+
} );
|
|
371
|
+
};
|
|
368
372
|
|
|
369
373
|
/**
|
|
370
374
|
* Action triggered to redo the last undoed
|
|
371
375
|
* edit to an entity record, if any.
|
|
372
376
|
*/
|
|
373
|
-
export const redo =
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
377
|
+
export const redo =
|
|
378
|
+
() =>
|
|
379
|
+
( { select, dispatch } ) => {
|
|
380
|
+
const redoEdit = select.getRedoEdit();
|
|
381
|
+
if ( ! redoEdit ) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
dispatch( {
|
|
385
|
+
type: 'EDIT_ENTITY_RECORD',
|
|
386
|
+
...redoEdit,
|
|
387
|
+
meta: { isRedo: true },
|
|
388
|
+
} );
|
|
389
|
+
};
|
|
384
390
|
|
|
385
391
|
/**
|
|
386
392
|
* Forces the creation of a new undo level.
|
|
@@ -405,204 +411,215 @@ export function __unstableCreateUndoLevel() {
|
|
|
405
411
|
* @param {boolean} [options.throwOnError=false] If false, this action suppresses all
|
|
406
412
|
* the exceptions. Defaults to false.
|
|
407
413
|
*/
|
|
408
|
-
export const saveEntityRecord =
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const recordId = record[ entityIdKey ];
|
|
425
|
-
|
|
426
|
-
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
427
|
-
STORE_NAME,
|
|
428
|
-
[ 'entities', 'records', kind, name, recordId || uuid() ],
|
|
429
|
-
{ exclusive: true }
|
|
430
|
-
);
|
|
431
|
-
|
|
432
|
-
try {
|
|
433
|
-
// Evaluate optimized edits.
|
|
434
|
-
// (Function edits that should be evaluated on save to avoid expensive computations on every edit.)
|
|
435
|
-
for ( const [ key, value ] of Object.entries( record ) ) {
|
|
436
|
-
if ( typeof value === 'function' ) {
|
|
437
|
-
const evaluatedValue = value(
|
|
438
|
-
select.getEditedEntityRecord( kind, name, recordId )
|
|
439
|
-
);
|
|
440
|
-
dispatch.editEntityRecord(
|
|
441
|
-
kind,
|
|
442
|
-
name,
|
|
443
|
-
recordId,
|
|
444
|
-
{
|
|
445
|
-
[ key ]: evaluatedValue,
|
|
446
|
-
},
|
|
447
|
-
{ undoIgnore: true }
|
|
448
|
-
);
|
|
449
|
-
record[ key ] = evaluatedValue;
|
|
450
|
-
}
|
|
414
|
+
export const saveEntityRecord =
|
|
415
|
+
(
|
|
416
|
+
kind,
|
|
417
|
+
name,
|
|
418
|
+
record,
|
|
419
|
+
{
|
|
420
|
+
isAutosave = false,
|
|
421
|
+
__unstableFetch = apiFetch,
|
|
422
|
+
throwOnError = false,
|
|
423
|
+
} = {}
|
|
424
|
+
) =>
|
|
425
|
+
async ( { select, resolveSelect, dispatch } ) => {
|
|
426
|
+
const configs = await dispatch( getOrLoadEntitiesConfig( kind ) );
|
|
427
|
+
const entityConfig = find( configs, { kind, name } );
|
|
428
|
+
if ( ! entityConfig || entityConfig?.__experimentalNoFetch ) {
|
|
429
|
+
return;
|
|
451
430
|
}
|
|
431
|
+
const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
|
|
432
|
+
const recordId = record[ entityIdKey ];
|
|
433
|
+
|
|
434
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
435
|
+
STORE_NAME,
|
|
436
|
+
[ 'entities', 'records', kind, name, recordId || uuid() ],
|
|
437
|
+
{ exclusive: true }
|
|
438
|
+
);
|
|
452
439
|
|
|
453
|
-
dispatch( {
|
|
454
|
-
type: 'SAVE_ENTITY_RECORD_START',
|
|
455
|
-
kind,
|
|
456
|
-
name,
|
|
457
|
-
recordId,
|
|
458
|
-
isAutosave,
|
|
459
|
-
} );
|
|
460
|
-
let updatedRecord;
|
|
461
|
-
let error;
|
|
462
|
-
let hasError = false;
|
|
463
440
|
try {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
441
|
+
// Evaluate optimized edits.
|
|
442
|
+
// (Function edits that should be evaluated on save to avoid expensive computations on every edit.)
|
|
443
|
+
for ( const [ key, value ] of Object.entries( record ) ) {
|
|
444
|
+
if ( typeof value === 'function' ) {
|
|
445
|
+
const evaluatedValue = value(
|
|
446
|
+
select.getEditedEntityRecord( kind, name, recordId )
|
|
447
|
+
);
|
|
448
|
+
dispatch.editEntityRecord(
|
|
449
|
+
kind,
|
|
450
|
+
name,
|
|
451
|
+
recordId,
|
|
452
|
+
{
|
|
453
|
+
[ key ]: evaluatedValue,
|
|
454
|
+
},
|
|
455
|
+
{ undoIgnore: true }
|
|
456
|
+
);
|
|
457
|
+
record[ key ] = evaluatedValue;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
dispatch( {
|
|
462
|
+
type: 'SAVE_ENTITY_RECORD_START',
|
|
468
463
|
kind,
|
|
469
464
|
name,
|
|
470
|
-
recordId
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
);
|
|
485
|
-
// Autosaves need all expected fields to be present.
|
|
486
|
-
// So we fallback to the previous autosave and then
|
|
487
|
-
// to the actual persisted entity if the edits don't
|
|
488
|
-
// have a value.
|
|
489
|
-
let data = { ...persistedRecord, ...autosavePost, ...record };
|
|
490
|
-
data = Object.keys( data ).reduce(
|
|
491
|
-
( acc, key ) => {
|
|
492
|
-
if (
|
|
493
|
-
[ 'title', 'excerpt', 'content' ].includes( key )
|
|
494
|
-
) {
|
|
495
|
-
acc[ key ] = data[ key ];
|
|
496
|
-
}
|
|
497
|
-
return acc;
|
|
498
|
-
},
|
|
499
|
-
{
|
|
500
|
-
status:
|
|
501
|
-
data.status === 'auto-draft'
|
|
502
|
-
? 'draft'
|
|
503
|
-
: data.status,
|
|
504
|
-
}
|
|
465
|
+
recordId,
|
|
466
|
+
isAutosave,
|
|
467
|
+
} );
|
|
468
|
+
let updatedRecord;
|
|
469
|
+
let error;
|
|
470
|
+
let hasError = false;
|
|
471
|
+
try {
|
|
472
|
+
const path = `${ entityConfig.baseURL }${
|
|
473
|
+
recordId ? '/' + recordId : ''
|
|
474
|
+
}`;
|
|
475
|
+
const persistedRecord = select.getRawEntityRecord(
|
|
476
|
+
kind,
|
|
477
|
+
name,
|
|
478
|
+
recordId
|
|
505
479
|
);
|
|
506
|
-
updatedRecord = await __unstableFetch( {
|
|
507
|
-
path: `${ path }/autosaves`,
|
|
508
|
-
method: 'POST',
|
|
509
|
-
data,
|
|
510
|
-
} );
|
|
511
480
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
481
|
+
if ( isAutosave ) {
|
|
482
|
+
// Most of this autosave logic is very specific to posts.
|
|
483
|
+
// This is fine for now as it is the only supported autosave,
|
|
484
|
+
// but ideally this should all be handled in the back end,
|
|
485
|
+
// so the client just sends and receives objects.
|
|
486
|
+
const currentUser = select.getCurrentUser();
|
|
487
|
+
const currentUserId = currentUser
|
|
488
|
+
? currentUser.id
|
|
489
|
+
: undefined;
|
|
490
|
+
const autosavePost = await resolveSelect.getAutosave(
|
|
491
|
+
persistedRecord.type,
|
|
492
|
+
persistedRecord.id,
|
|
493
|
+
currentUserId
|
|
494
|
+
);
|
|
495
|
+
// Autosaves need all expected fields to be present.
|
|
496
|
+
// So we fallback to the previous autosave and then
|
|
497
|
+
// to the actual persisted entity if the edits don't
|
|
498
|
+
// have a value.
|
|
499
|
+
let data = {
|
|
517
500
|
...persistedRecord,
|
|
518
|
-
...
|
|
519
|
-
...
|
|
501
|
+
...autosavePost,
|
|
502
|
+
...record,
|
|
520
503
|
};
|
|
521
|
-
|
|
504
|
+
data = Object.keys( data ).reduce(
|
|
522
505
|
( acc, key ) => {
|
|
523
|
-
// These properties are persisted in autosaves.
|
|
524
506
|
if (
|
|
525
507
|
[ 'title', 'excerpt', 'content' ].includes(
|
|
526
508
|
key
|
|
527
509
|
)
|
|
528
510
|
) {
|
|
529
|
-
acc[ key ] =
|
|
530
|
-
} else if ( key === 'status' ) {
|
|
531
|
-
// Status is only persisted in autosaves when going from
|
|
532
|
-
// "auto-draft" to "draft".
|
|
533
|
-
acc[ key ] =
|
|
534
|
-
persistedRecord.status === 'auto-draft' &&
|
|
535
|
-
newRecord.status === 'draft'
|
|
536
|
-
? newRecord.status
|
|
537
|
-
: persistedRecord.status;
|
|
538
|
-
} else {
|
|
539
|
-
// These properties are not persisted in autosaves.
|
|
540
|
-
acc[ key ] = persistedRecord[ key ];
|
|
511
|
+
acc[ key ] = data[ key ];
|
|
541
512
|
}
|
|
542
513
|
return acc;
|
|
543
514
|
},
|
|
544
|
-
{
|
|
515
|
+
{
|
|
516
|
+
status:
|
|
517
|
+
data.status === 'auto-draft'
|
|
518
|
+
? 'draft'
|
|
519
|
+
: data.status,
|
|
520
|
+
}
|
|
545
521
|
);
|
|
522
|
+
updatedRecord = await __unstableFetch( {
|
|
523
|
+
path: `${ path }/autosaves`,
|
|
524
|
+
method: 'POST',
|
|
525
|
+
data,
|
|
526
|
+
} );
|
|
527
|
+
|
|
528
|
+
// An autosave may be processed by the server as a regular save
|
|
529
|
+
// when its update is requested by the author and the post had
|
|
530
|
+
// draft or auto-draft status.
|
|
531
|
+
if ( persistedRecord.id === updatedRecord.id ) {
|
|
532
|
+
let newRecord = {
|
|
533
|
+
...persistedRecord,
|
|
534
|
+
...data,
|
|
535
|
+
...updatedRecord,
|
|
536
|
+
};
|
|
537
|
+
newRecord = Object.keys( newRecord ).reduce(
|
|
538
|
+
( acc, key ) => {
|
|
539
|
+
// These properties are persisted in autosaves.
|
|
540
|
+
if (
|
|
541
|
+
[ 'title', 'excerpt', 'content' ].includes(
|
|
542
|
+
key
|
|
543
|
+
)
|
|
544
|
+
) {
|
|
545
|
+
acc[ key ] = newRecord[ key ];
|
|
546
|
+
} else if ( key === 'status' ) {
|
|
547
|
+
// Status is only persisted in autosaves when going from
|
|
548
|
+
// "auto-draft" to "draft".
|
|
549
|
+
acc[ key ] =
|
|
550
|
+
persistedRecord.status ===
|
|
551
|
+
'auto-draft' &&
|
|
552
|
+
newRecord.status === 'draft'
|
|
553
|
+
? newRecord.status
|
|
554
|
+
: persistedRecord.status;
|
|
555
|
+
} else {
|
|
556
|
+
// These properties are not persisted in autosaves.
|
|
557
|
+
acc[ key ] = persistedRecord[ key ];
|
|
558
|
+
}
|
|
559
|
+
return acc;
|
|
560
|
+
},
|
|
561
|
+
{}
|
|
562
|
+
);
|
|
563
|
+
dispatch.receiveEntityRecords(
|
|
564
|
+
kind,
|
|
565
|
+
name,
|
|
566
|
+
newRecord,
|
|
567
|
+
undefined,
|
|
568
|
+
true
|
|
569
|
+
);
|
|
570
|
+
} else {
|
|
571
|
+
dispatch.receiveAutosaves(
|
|
572
|
+
persistedRecord.id,
|
|
573
|
+
updatedRecord
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
} else {
|
|
577
|
+
let edits = record;
|
|
578
|
+
if ( entityConfig.__unstablePrePersist ) {
|
|
579
|
+
edits = {
|
|
580
|
+
...edits,
|
|
581
|
+
...entityConfig.__unstablePrePersist(
|
|
582
|
+
persistedRecord,
|
|
583
|
+
edits
|
|
584
|
+
),
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
updatedRecord = await __unstableFetch( {
|
|
588
|
+
path,
|
|
589
|
+
method: recordId ? 'PUT' : 'POST',
|
|
590
|
+
data: edits,
|
|
591
|
+
} );
|
|
546
592
|
dispatch.receiveEntityRecords(
|
|
547
593
|
kind,
|
|
548
594
|
name,
|
|
549
|
-
|
|
595
|
+
updatedRecord,
|
|
550
596
|
undefined,
|
|
551
|
-
true
|
|
552
|
-
|
|
553
|
-
} else {
|
|
554
|
-
dispatch.receiveAutosaves(
|
|
555
|
-
persistedRecord.id,
|
|
556
|
-
updatedRecord
|
|
597
|
+
true,
|
|
598
|
+
edits
|
|
557
599
|
);
|
|
558
600
|
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
edits = {
|
|
563
|
-
...edits,
|
|
564
|
-
...entityConfig.__unstablePrePersist(
|
|
565
|
-
persistedRecord,
|
|
566
|
-
edits
|
|
567
|
-
),
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
updatedRecord = await __unstableFetch( {
|
|
571
|
-
path,
|
|
572
|
-
method: recordId ? 'PUT' : 'POST',
|
|
573
|
-
data: edits,
|
|
574
|
-
} );
|
|
575
|
-
dispatch.receiveEntityRecords(
|
|
576
|
-
kind,
|
|
577
|
-
name,
|
|
578
|
-
updatedRecord,
|
|
579
|
-
undefined,
|
|
580
|
-
true,
|
|
581
|
-
edits
|
|
582
|
-
);
|
|
601
|
+
} catch ( _error ) {
|
|
602
|
+
hasError = true;
|
|
603
|
+
error = _error;
|
|
583
604
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
recordId,
|
|
593
|
-
error,
|
|
594
|
-
isAutosave,
|
|
595
|
-
} );
|
|
605
|
+
dispatch( {
|
|
606
|
+
type: 'SAVE_ENTITY_RECORD_FINISH',
|
|
607
|
+
kind,
|
|
608
|
+
name,
|
|
609
|
+
recordId,
|
|
610
|
+
error,
|
|
611
|
+
isAutosave,
|
|
612
|
+
} );
|
|
596
613
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
614
|
+
if ( hasError && throwOnError ) {
|
|
615
|
+
throw error;
|
|
616
|
+
}
|
|
600
617
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
};
|
|
618
|
+
return updatedRecord;
|
|
619
|
+
} finally {
|
|
620
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
621
|
+
}
|
|
622
|
+
};
|
|
606
623
|
|
|
607
624
|
/**
|
|
608
625
|
* Runs multiple core-data actions at the same time using one API request.
|
|
@@ -626,41 +643,43 @@ export const saveEntityRecord = (
|
|
|
626
643
|
* @return {(thunkArgs: Object) => Promise} A promise that resolves to an array containing the return
|
|
627
644
|
* values of each function given in `requests`.
|
|
628
645
|
*/
|
|
629
|
-
export const __experimentalBatch =
|
|
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
|
-
|
|
646
|
+
export const __experimentalBatch =
|
|
647
|
+
( requests ) =>
|
|
648
|
+
async ( { dispatch } ) => {
|
|
649
|
+
const batch = createBatch();
|
|
650
|
+
const api = {
|
|
651
|
+
saveEntityRecord( kind, name, record, options ) {
|
|
652
|
+
return batch.add( ( add ) =>
|
|
653
|
+
dispatch.saveEntityRecord( kind, name, record, {
|
|
654
|
+
...options,
|
|
655
|
+
__unstableFetch: add,
|
|
656
|
+
} )
|
|
657
|
+
);
|
|
658
|
+
},
|
|
659
|
+
saveEditedEntityRecord( kind, name, recordId, options ) {
|
|
660
|
+
return batch.add( ( add ) =>
|
|
661
|
+
dispatch.saveEditedEntityRecord( kind, name, recordId, {
|
|
662
|
+
...options,
|
|
663
|
+
__unstableFetch: add,
|
|
664
|
+
} )
|
|
665
|
+
);
|
|
666
|
+
},
|
|
667
|
+
deleteEntityRecord( kind, name, recordId, query, options ) {
|
|
668
|
+
return batch.add( ( add ) =>
|
|
669
|
+
dispatch.deleteEntityRecord( kind, name, recordId, query, {
|
|
670
|
+
...options,
|
|
671
|
+
__unstableFetch: add,
|
|
672
|
+
} )
|
|
673
|
+
);
|
|
674
|
+
},
|
|
675
|
+
};
|
|
676
|
+
const resultPromises = requests.map( ( request ) => request( api ) );
|
|
677
|
+
const [ , ...results ] = await Promise.all( [
|
|
678
|
+
batch.run(),
|
|
679
|
+
...resultPromises,
|
|
680
|
+
] );
|
|
681
|
+
return results;
|
|
656
682
|
};
|
|
657
|
-
const resultPromises = requests.map( ( request ) => request( api ) );
|
|
658
|
-
const [ , ...results ] = await Promise.all( [
|
|
659
|
-
batch.run(),
|
|
660
|
-
...resultPromises,
|
|
661
|
-
] );
|
|
662
|
-
return results;
|
|
663
|
-
};
|
|
664
683
|
|
|
665
684
|
/**
|
|
666
685
|
* Action triggered to save an entity record's edits.
|
|
@@ -670,30 +689,27 @@ export const __experimentalBatch = ( requests ) => async ( { dispatch } ) => {
|
|
|
670
689
|
* @param {Object} recordId ID of the record.
|
|
671
690
|
* @param {Object} options Saving options.
|
|
672
691
|
*/
|
|
673
|
-
export const saveEditedEntityRecord =
|
|
674
|
-
kind,
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
|
|
692
|
+
export const saveEditedEntityRecord =
|
|
693
|
+
( kind, name, recordId, options ) =>
|
|
694
|
+
async ( { select, dispatch } ) => {
|
|
695
|
+
if ( ! select.hasEditsForEntityRecord( kind, name, recordId ) ) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
const configs = await dispatch( getOrLoadEntitiesConfig( kind ) );
|
|
699
|
+
const entityConfig = find( configs, { kind, name } );
|
|
700
|
+
if ( ! entityConfig ) {
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY;
|
|
688
704
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
};
|
|
705
|
+
const edits = select.getEntityRecordNonTransientEdits(
|
|
706
|
+
kind,
|
|
707
|
+
name,
|
|
708
|
+
recordId
|
|
709
|
+
);
|
|
710
|
+
const record = { [ entityIdKey ]: recordId, ...edits };
|
|
711
|
+
return await dispatch.saveEntityRecord( kind, name, record, options );
|
|
712
|
+
};
|
|
697
713
|
|
|
698
714
|
/**
|
|
699
715
|
* Action triggered to save only specified properties for the entity.
|
|
@@ -704,29 +720,30 @@ export const saveEditedEntityRecord = (
|
|
|
704
720
|
* @param {Array} itemsToSave List of entity properties to save.
|
|
705
721
|
* @param {Object} options Saving options.
|
|
706
722
|
*/
|
|
707
|
-
export const __experimentalSaveSpecifiedEntityEdits =
|
|
708
|
-
kind,
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
options
|
|
713
|
-
) => async ( { select, dispatch } ) => {
|
|
714
|
-
if ( ! select.hasEditsForEntityRecord( kind, name, recordId ) ) {
|
|
715
|
-
return;
|
|
716
|
-
}
|
|
717
|
-
const edits = select.getEntityRecordNonTransientEdits(
|
|
718
|
-
kind,
|
|
719
|
-
name,
|
|
720
|
-
recordId
|
|
721
|
-
);
|
|
722
|
-
const editsToSave = {};
|
|
723
|
-
for ( const edit in edits ) {
|
|
724
|
-
if ( itemsToSave.some( ( item ) => item === edit ) ) {
|
|
725
|
-
editsToSave[ edit ] = edits[ edit ];
|
|
723
|
+
export const __experimentalSaveSpecifiedEntityEdits =
|
|
724
|
+
( kind, name, recordId, itemsToSave, options ) =>
|
|
725
|
+
async ( { select, dispatch } ) => {
|
|
726
|
+
if ( ! select.hasEditsForEntityRecord( kind, name, recordId ) ) {
|
|
727
|
+
return;
|
|
726
728
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
729
|
+
const edits = select.getEntityRecordNonTransientEdits(
|
|
730
|
+
kind,
|
|
731
|
+
name,
|
|
732
|
+
recordId
|
|
733
|
+
);
|
|
734
|
+
const editsToSave = {};
|
|
735
|
+
for ( const edit in edits ) {
|
|
736
|
+
if ( itemsToSave.some( ( item ) => item === edit ) ) {
|
|
737
|
+
editsToSave[ edit ] = edits[ edit ];
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return await dispatch.saveEntityRecord(
|
|
741
|
+
kind,
|
|
742
|
+
name,
|
|
743
|
+
editsToSave,
|
|
744
|
+
options
|
|
745
|
+
);
|
|
746
|
+
};
|
|
730
747
|
|
|
731
748
|
/**
|
|
732
749
|
* Returns an action object used in signalling that Upload permissions have been received.
|