labo-components
Version:
207 lines (184 loc) • 6.45 kB
JSX
import React from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import IDUtil from "../../../util/IDUtil";
import Classification from "./Types/Classification";
import Comment from "./Types/Comment";
import Link from "./Types/Link";
import Metadata from "./Types/Metadata";
import TypeHeader from "./TypeHeader";
import ClassificationEditor from "./ClassificationForm";
import CommentEditor from "./CommentForm";
import LinkForm from "./LinkForm";
import MetadataForm from "./MetadataForm";
import { ANNOTATION_TYPE } from "../../../util/AnnotationConstants";
export default class AnnotationType extends React.PureComponent {
constructor(props) {
super(props);
// initial state
this.state = {
showForm: this.props.showForm,
};
}
// Delete the given annotations using the annotationClient
deleteAnnotation = (annotation) => {
// Get index of given annotation
let index = -1;
if (
!this.props.annotations.some((a, i) => {
if (a.annotationId == annotation.annotationId) {
index = i;
return true;
}
return false;
})
) {
console.error("Annotation not in list, can not be deleted");
return;
}
// Get motivation/ type
this.props.annotationClient.removeBodyElement(
this.props.type,
index,
true,
true,
this.props.targetAnnotation
);
};
/* ---------------------------------- UI FUNCTIONS -------------------------------- */
// Create a target annotation for the current target
// This way there is a body to which we can add the type annotations
createTargetAnnotation = () => {
// create new annotation
const annotation = this.props.annotationClient.newAnnotation(
this.props.target,
false
);
if (annotation) {
this.props.annotationClient.edit(annotation);
this.props.annotationClient.save();
}
};
// Toggle form visibility
// Optionally create a target (root) annotation
toggleForm = () => {
this.setState({ showForm: !this.state.showForm }, () => {
// if we show the form, check for a target annotation
// if it does not exist yet; create one
if (!this.props.targetAnnotation) {
this.createTargetAnnotation();
}
});
};
// /* ---------------------------------- RENDER FUNCTIONS -------------------------------- */
// Render an annotation, based on the given type
renderAnnotation = (
type,
annotation,
key,
targetAnnotation,
annotationClient
) => {
const defaultProps = {
key,
delete: this.deleteAnnotation,
annotationClient,
targetAnnotation,
};
switch (type) {
case ANNOTATION_TYPE.CLASSIFICATION:
return (
<Classification
classification={annotation}
{...defaultProps}
/>
);
case ANNOTATION_TYPE.COMMENT:
return <Comment comment={annotation} {...defaultProps} />;
case ANNOTATION_TYPE.LINK:
return <Link link={annotation} {...defaultProps} />;
case ANNOTATION_TYPE.METADATA:
return <Metadata metadata={annotation} {...defaultProps} />;
default:
return <span key={key}>{type} - not implemented.</span>;
}
};
// Render the form for the given annotation type
renderForm(type, annotation, annotationClient, deleteAnnotation) {
const props = {
annotationClient,
annotation,
deleteAnnotation,
};
switch (type) {
case ANNOTATION_TYPE.CLASSIFICATION:
return <ClassificationEditor {...props} />;
case ANNOTATION_TYPE.COMMENT:
return <CommentEditor {...props} />;
case ANNOTATION_TYPE.LINK:
return <LinkForm {...props} />;
case ANNOTATION_TYPE.METADATA:
return <MetadataForm onSave={this.toggleForm} {...props} />;
default:
return <span>{type} - not implemented.</span>;
}
}
render() {
const type = this.props.type;
// type header
const header = (
<TypeHeader
type={type}
showForm={this.state.showForm}
toggleForm={this.toggleForm}
/>
);
// the annotation content
const annotations = (
<div className={"type-annotations"}>
{this.props.annotations.map((annotation, index) =>
this.renderAnnotation(
type,
annotation,
index,
this.props.targetAnnotation,
this.props.annotationClient
)
)}
</div>
);
// type specific form
const form =
this.state.showForm && this.props.targetAnnotation ? (
<div className="annotation-form">
{this.renderForm(
type,
this.props.targetAnnotation,
this.props.annotationClient,
this.deleteAnnotation
)}
</div>
) : null;
return (
<div
className={classNames(
IDUtil.cssClassName("annotation-type"),
"type-" + type,
{ "has-content": this.props.annotations.length > 0 }
)}
>
{header}
{form}
{annotations}
</div>
);
}
}
AnnotationType.propTypes = {
type: PropTypes.string.isRequired,
target: PropTypes.string.isRequired,
targetAnnotation: PropTypes.object,
annotationClient: PropTypes.object.isRequired,
annotations: PropTypes.array.isRequired,
showForm: PropTypes.bool.isRequired,
};