import React from "react"; import { connect } from "react-redux"; import { Button, Tooltip, InputGroup, Dialog, Classes, Colors, } from "@blueprintjs/core"; @connect((state) => ({ universe: state.universe, idhash: state.config?.parameters?.["annotations-user-data-idhash"] ?? null, annotations: state.annotations, obsAnnotations: state.universe.obsAnnotations, saveInProgress: state.autosave?.saveInProgress ?? false, lastSavedObsAnnotations: state.autosave?.lastSavedObsAnnotations, error: state.autosave?.error, writableCategoriesEnabled: state.config?.parameters?.["annotations"] ?? false, })) class FilenameDialog extends React.Component { constructor(props) { super(props); this.state = { filenameText: "", }; } dismissFilenameDialog = () => {}; handleCreateFilename = () => { const { dispatch } = this.props; const { filenameText } = this.state; dispatch({ type: "set annotations collection name", data: filenameText, }); }; filenameError = () => { const legalNames = /^\w+$/; const { filenameText } = this.state; let err = false; if (filenameText === "") { err = "empty_string"; } else if (!legalNames.test(filenameText)) { /* IMPORTANT: this test must ultimately match the test applied by the backend, which is designed to ensure a safe file name can be created from the data collection name. If you change this, you will also need to change the validation code in the backend, or it will have no effect. */ err = "characters"; } return err; }; filenameErrorMessage = () => { const err = this.filenameError(); let markup = null; if (err === "empty_string") { markup = ( Name cannot be blank ); } else if (err === "characters") { markup = ( Only alphanumeric and underscore allowed ); } return markup; }; render() { const { writableCategoriesEnabled, annotations, idhash } = this.props; const { filenameText } = this.state; return writableCategoriesEnabled && !annotations.dataCollectionNameIsReadOnly && !annotations.dataCollectionName ? (
{ e.preventDefault(); this.handleCreateFilename(); }} >

Name your annotations collection:

this.setState({ filenameText: e.target.value }) } leftIcon="tag" />

{this.filenameErrorMessage(filenameText)}

Your annotations are stored in this file: {filenameText}-{idhash}.csv

(We added a unique ID to your filename)

) : null; } } export default FilenameDialog;