UNPKG

labo-components

Version:
207 lines (184 loc) 6.45 kB
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, };