Made overrideId work for long delays
This commit is contained in:
parent
5554a54df8
commit
2ca27b285d
|
@ -14,8 +14,6 @@ export default class TextAnnotator extends Component {
|
||||||
state = {
|
state = {
|
||||||
selectionBounds: null,
|
selectionBounds: null,
|
||||||
selectedAnnotation: null,
|
selectedAnnotation: null,
|
||||||
|
|
||||||
showRelationEditor: false,
|
|
||||||
selectedRelation: null,
|
selectedRelation: null,
|
||||||
|
|
||||||
applyTemplate: null,
|
applyTemplate: null,
|
||||||
|
@ -77,22 +75,59 @@ export default class TextAnnotator extends Component {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience method that allows the external application to
|
* A convenience method that allows the external application to
|
||||||
* override the autogenerated Id.
|
* override the autogenerated Id for an annotation.
|
||||||
*
|
*
|
||||||
* Usually, the override will happen almost immediately after
|
* Usually, the override will happen almost immediately after
|
||||||
* the annotation is created. But we need to be defensive and assume
|
* the annotation is created. But we need to be defensive and assume
|
||||||
* that the override might come in with considerable delay, thus
|
* that the override might come in with considerable delay, thus
|
||||||
* the user might have made further edits already.
|
* the user might have made further edits already.
|
||||||
|
*
|
||||||
|
* A key challenge here is that there may be dependencies between
|
||||||
|
* the original annotation and relations that were created meanwhile.
|
||||||
*/
|
*/
|
||||||
overrideId = originalId => forcedId => {
|
overrideAnnotationId = originalAnnotation => forcedId => {
|
||||||
// Force the editors to close, otherwise their annotations will be orphaned
|
const { id } = originalAnnotation;
|
||||||
|
|
||||||
|
// After the annotation update, we need to update dependencies
|
||||||
|
// on the annotation layer, if any
|
||||||
|
const updateDependentRelations = updatedAnnotation => {
|
||||||
|
// Wait until the highlighter update has come into effect
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this.relationsLayer.overrideTargetAnnotation(originalAnnotation, updatedAnnotation);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Force the editors to close first, otherwise their annotations will be orphaned
|
||||||
if (this.state.selectedAnnotation || this.state.selectedRelation) {
|
if (this.state.selectedAnnotation || this.state.selectedRelation) {
|
||||||
|
this.relationsLayer.resetDrawing();
|
||||||
this.setState({
|
this.setState({
|
||||||
selectedAnnotation: null,
|
selectedAnnotation: null,
|
||||||
selectedRelation: null
|
selectedRelation: null
|
||||||
}, () => this.highlighter.overrideId(originalId, forcedId));
|
}, () => {
|
||||||
|
const updated = this.highlighter.overrideId(id, forcedId);
|
||||||
|
updateDependentRelations(updated);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.highlighter.overrideId(originalId, forcedId);
|
const updated = this.highlighter.overrideId(id, forcedId);
|
||||||
|
updateDependentRelations(updated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience method that allows the external application to
|
||||||
|
* override the autogenerated Id for a relation.
|
||||||
|
*
|
||||||
|
* This operation is less problematic than .overrideAnnotation().
|
||||||
|
* We just need to make sure the RelationEditor is closed, so that
|
||||||
|
* the annotation doesn't become orphaned. Otherwise, there are
|
||||||
|
* no dependencies.
|
||||||
|
*/
|
||||||
|
overrideRelationId = originalId => forcedId => {
|
||||||
|
if (this.state.selectedRelation) {
|
||||||
|
this.setState({ selectedRelation: null }, () =>
|
||||||
|
this.relationsLayer.overrideId(originalId, forcedId));
|
||||||
|
} else {
|
||||||
|
this.relationsLayer.overrideId(originalId, forcedId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +142,7 @@ export default class TextAnnotator extends Component {
|
||||||
if (previous)
|
if (previous)
|
||||||
this.props[method](annotation.clone(), previous.clone());
|
this.props[method](annotation.clone(), previous.clone());
|
||||||
else
|
else
|
||||||
this.props[method](annotation.clone(), this.overrideId(annotation.id));
|
this.props[method](annotation.clone(), this.overrideAnnotationId(annotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
onDeleteAnnotation = annotation => {
|
onDeleteAnnotation = annotation => {
|
||||||
|
@ -133,7 +168,7 @@ export default class TextAnnotator extends Component {
|
||||||
|
|
||||||
// Shorthand
|
// Shorthand
|
||||||
closeRelationsEditor = () => {
|
closeRelationsEditor = () => {
|
||||||
this.setState({ showRelationEditor: false });
|
this.setState({ selectedRelation: null });
|
||||||
this.relationsLayer.resetDrawing();
|
this.relationsLayer.resetDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +178,6 @@ export default class TextAnnotator extends Component {
|
||||||
*/
|
*/
|
||||||
onEditRelation = relation => {
|
onEditRelation = relation => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showRelationEditor: true,
|
|
||||||
selectedRelation: relation
|
selectedRelation: relation
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -158,13 +192,8 @@ export default class TextAnnotator extends Component {
|
||||||
// otherwise, fire 'update'
|
// otherwise, fire 'update'
|
||||||
const isNew = previous.annotation.bodies.length === 0;
|
const isNew = previous.annotation.bodies.length === 0;
|
||||||
|
|
||||||
// A convenience method that allows the external application to
|
|
||||||
// override the autogenerated Id
|
|
||||||
const overrideId = originalId => forcedId =>
|
|
||||||
this.relationsLayer.overrideId(originalId, forcedId);
|
|
||||||
|
|
||||||
if (isNew)
|
if (isNew)
|
||||||
this.props.onAnnotationCreated(relation.annotation.clone(), overrideId(relation.annotation.id));
|
this.props.onAnnotationCreated(relation.annotation.clone(), this.overrideRelationId(relation.annotation.id));
|
||||||
else
|
else
|
||||||
this.props.onAnnotationUpdated(relation.annotation.clone(), previous.annotation.clone());
|
this.props.onAnnotationUpdated(relation.annotation.clone(), previous.annotation.clone());
|
||||||
}
|
}
|
||||||
|
@ -214,7 +243,7 @@ export default class TextAnnotator extends Component {
|
||||||
this.relationsLayer.readOnly = false;
|
this.relationsLayer.readOnly = false;
|
||||||
this.relationsLayer.startDrawing();
|
this.relationsLayer.startDrawing();
|
||||||
} else {
|
} else {
|
||||||
this.setState({ showRelationEditor: false });
|
this.setState({ selectedRelation: null });
|
||||||
|
|
||||||
this.selectionHandler.enabled = true;
|
this.selectionHandler.enabled = true;
|
||||||
|
|
||||||
|
@ -247,7 +276,7 @@ export default class TextAnnotator extends Component {
|
||||||
</Editor>
|
</Editor>
|
||||||
}
|
}
|
||||||
|
|
||||||
{ this.state.showRelationEditor &&
|
{ this.state.selectedRelation &&
|
||||||
<RelationEditor
|
<RelationEditor
|
||||||
relation={this.state.selectedRelation}
|
relation={this.state.selectedRelation}
|
||||||
onRelationCreated={this.onCreateOrUpdateRelation}
|
onRelationCreated={this.onCreateOrUpdateRelation}
|
||||||
|
|
|
@ -95,10 +95,8 @@ export default class Highlighter {
|
||||||
*
|
*
|
||||||
* @returns the updated annotation for convenience
|
* @returns the updated annotation for convenience
|
||||||
*/
|
*/
|
||||||
overrideId = (annotationOrId, forcedId) => {
|
overrideId = (originalId, forcedId) => {
|
||||||
const id = annotationOrId.id ? annotationOrId.id : annotationOrId;
|
const allSpans = document.querySelectorAll(`.r6o-annotation[data-id="${originalId}"]`);
|
||||||
|
|
||||||
const allSpans = document.querySelectorAll(`.r6o-annotation[data-id="${id}"]`);
|
|
||||||
const annotation = allSpans[0].annotation;
|
const annotation = allSpans[0].annotation;
|
||||||
|
|
||||||
const updatedAnnotation = annotation.clone({ id : forcedId });
|
const updatedAnnotation = annotation.clone({ id : forcedId });
|
||||||
|
|
|
@ -93,16 +93,23 @@ export default class RelationsLayer extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
overrideId = (annotationOrId, forcedId) => {
|
/** Overrides the ID for an existing relation **/
|
||||||
const id = annotationOrId.id ? annotationOrId.id : annotationOrId;
|
overrideRelationId = (originalId, forcedId) => {
|
||||||
const conn = this.connections.find(c => c.annotation.id == id);
|
const conn = this.connections.find(c => c.annotation.id == originalId);
|
||||||
|
|
||||||
const updatedAnnotation = conn.annotation.clone({ id : forcedId });
|
const updatedAnnotation = conn.annotation.clone({ id : forcedId });
|
||||||
conn.annotation = updatedAnnotation;
|
conn.annotation = updatedAnnotation;
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Overrides the given source or target annotation **/
|
||||||
|
overrideTargetAnnotation = (originalAnnotation, forcedAnnotation) => {
|
||||||
|
const affectedFrom = this.connections.filter(c => c.fromNode.annotation == originalAnnotation);
|
||||||
|
affectedFrom.forEach(c => c.fromNode.annotation = forcedAnnotation);
|
||||||
|
|
||||||
|
const affectedTo = this.connections.filter(c => c.toNode.annotation == originalAnnotation);
|
||||||
|
affectedTo.forEach(c => c.toNode.annotation = forcedAnnotation);
|
||||||
|
}
|
||||||
|
|
||||||
getAllRelations = () => {
|
getAllRelations = () => {
|
||||||
return this.connections.map(c => c.annotation);
|
return this.connections.map(c => c.annotation);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue