Revised widget API for batch body modifications
This commit is contained in:
parent
9cb80ca6a4
commit
e84bebc9b9
|
@ -91,43 +91,29 @@ export default class Editor extends Component {
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Shorthand **/
|
/** Shorthand **/
|
||||||
updateCurrentAnnotation = (diff, saveImmediately) => {
|
updateCurrentAnnotation = (diff, saveImmediately) => this.setState({
|
||||||
this.setState({
|
currentAnnotation: this.state.currentAnnotation.clone(diff)
|
||||||
currentAnnotation: this.state.currentAnnotation.clone(diff)
|
}, () => {
|
||||||
}, () => {
|
if (saveImmediately)
|
||||||
if (saveImmediately)
|
this.onOk();
|
||||||
this.onOk();
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
onAppendBody = (body, saveImmediately) => this.updateCurrentAnnotation({
|
||||||
* Appends a body to the current annotation. For convenience: also
|
body: [
|
||||||
* takes an array of bodies as argument.
|
...this.state.currentAnnotation.bodies,
|
||||||
* @param bodyOrBodies the body or list of bodies to append
|
{ ...body, ...this.creationMeta(body) }
|
||||||
* @param saveImmediately set to true to save & close immediately
|
]
|
||||||
*/
|
}, saveImmediately);
|
||||||
onAppendBody = (bodyOrBodies, saveImmediately) => {
|
|
||||||
const toAppend = toArray(bodyOrBodies).map(b =>
|
|
||||||
({ ...b, ...this.creationMeta(b) }));
|
|
||||||
|
|
||||||
this.updateCurrentAnnotation({
|
onUpdateBody = (previous, updated, saveImmediately) => this.updateCurrentAnnotation({
|
||||||
body: [ ...this.state.currentAnnotation.bodies, ...toAppend ]
|
body: this.state.currentAnnotation.bodies.map(body =>
|
||||||
}, saveImmediately);
|
body === previous ? { ...updated, ...this.creationMeta(updated) } : body)
|
||||||
}
|
}, saveImmediately);
|
||||||
|
|
||||||
/**
|
onRemoveBody = (body, saveImmediately) => this.updateCurrentAnnotation({
|
||||||
* Updates a previous body with the given body.
|
body: this.state.currentAnnotation.bodies.filter(b => b !== body)
|
||||||
* @param previous the body to replace
|
}, saveImmediately);
|
||||||
* @param updated the body to replace with
|
|
||||||
* @param saveImmediately set to true to save & close immediately
|
|
||||||
*/
|
|
||||||
onUpdateBody = (previous, updated, saveImmediately) => {
|
|
||||||
this.updateCurrentAnnotation({
|
|
||||||
body: this.state.currentAnnotation.bodies.map(body =>
|
|
||||||
body === previous ? { ...updated, ...this.creationMeta(updated) } : body)
|
|
||||||
}, saveImmediately);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For convenience: an 'append or update' shorthand.
|
* For convenience: an 'append or update' shorthand.
|
||||||
|
@ -150,18 +136,76 @@ export default class Editor extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given body from the current annotation. For
|
* Advanced method for applying a batch of body changes
|
||||||
* convenience: also takes an array of bodies as argument.
|
* in one go (append, remove update), optionally saving
|
||||||
* @param bodyOrBodies the body or list of bodies to remove
|
* immediately afterwards. The argument is an array of
|
||||||
* @param saveImmediately set to true to save & close immediately
|
* diff objects with the following structure:
|
||||||
|
*
|
||||||
|
* [
|
||||||
|
* { action: 'append', body: bodyToAppend },
|
||||||
|
* { action: 'update', previous: prevBody, updated: updatedBody }
|
||||||
|
* { action: 'remove', body: bodyToRemove },
|
||||||
|
*
|
||||||
|
* // Normal upsert, previous is optional
|
||||||
|
* { action: 'upsert', previous: prevBody, updated: updatedBody }
|
||||||
|
*
|
||||||
|
* // Auto-upsert based on purpose
|
||||||
|
* { action: 'upsert', body: bodyToUpser }
|
||||||
|
* ]
|
||||||
*/
|
*/
|
||||||
onRemoveBody = (bodyOrBodies, saveImmediately) => {
|
onBatchModify = (diffs, saveImmediately) => {
|
||||||
const toRemove = toArray(bodyOrBodies);
|
// First, find previous bodies for auto upserts
|
||||||
|
const autoUpserts = diffs
|
||||||
|
.filter(d => d.action === 'upsert' && d.body)
|
||||||
|
.map(d => ({
|
||||||
|
previous: this.state.currentAnnotation.bodies.find(b => b.purpose === d.body.purpose),
|
||||||
|
updated: { ...d.body, ...this.creationMeta(d.body)}
|
||||||
|
}));
|
||||||
|
|
||||||
this.updateCurrentAnnotation({
|
const toRemove = diffs
|
||||||
body: this.state.currentAnnotation.bodies.filter(b => !toRemove.includes(b))
|
.filter(d => d.action === 'remove')
|
||||||
}, saveImmediately);
|
.map(d => d.body);
|
||||||
|
|
||||||
|
const toAppend = [
|
||||||
|
...diffs
|
||||||
|
.filter(d => (d.action === 'append') || (d.action === 'upsert' && d.updated && !d.previous))
|
||||||
|
.map(d => ({ ...d.body, ...this.creationMeta(d.body) })),
|
||||||
|
|
||||||
|
...autoUpserts
|
||||||
|
.filter(d => !d.previous)
|
||||||
|
.map(d => d.updated)
|
||||||
|
];
|
||||||
|
|
||||||
|
const toUpdate = [
|
||||||
|
...diffs
|
||||||
|
.filter(d => (d.action === 'update') || (d.action === 'upsert' && d.updated && d.previous))
|
||||||
|
.map(d => ({
|
||||||
|
previous: d.previous,
|
||||||
|
updated: { ...d.updated, ...this.creationMeta(d.updated) }
|
||||||
|
})),
|
||||||
|
|
||||||
|
...autoUpserts
|
||||||
|
.filter(d => d.previous)
|
||||||
|
];
|
||||||
|
|
||||||
|
const updatedBodies = [
|
||||||
|
// Current bodies
|
||||||
|
...this.state.currentAnnotation.bodies
|
||||||
|
// Remvoe
|
||||||
|
.filter(b => !toRemove.includes(b))
|
||||||
|
|
||||||
|
// Update
|
||||||
|
.map(b => {
|
||||||
|
const { updated } = toUpdate.find(t => t.previous === b);
|
||||||
|
return updated ? updated : body;
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Append
|
||||||
|
...toAppend
|
||||||
|
]
|
||||||
|
|
||||||
|
this.updateCurrentAnnotation({ body: updatedBodies }, saveImmediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue