Introduces 'draft mode' tags, so user doesn't need to hit Enter to store
This commit is contained in:
parent
48d65ce520
commit
4373abf54b
|
@ -9,7 +9,6 @@ const Autocomplete = props => {
|
|||
|
||||
const onInputValueChange = ({ inputValue }) => {
|
||||
if (inputValue.length > 0) {
|
||||
// Set suggestions to prefix matches...
|
||||
const prefixMatches = props.vocabulary.filter(item => {
|
||||
return item.toLowerCase().startsWith(inputValue.toLowerCase());
|
||||
});
|
||||
|
@ -61,6 +60,7 @@ const Autocomplete = props => {
|
|||
<div {...getComboboxProps()}>
|
||||
<input
|
||||
{...getInputProps({ onKeyDown })}
|
||||
onChange={evt => props.onChange && props.onChange(evt)}
|
||||
placeholder={props.placeholder}
|
||||
defaultValue={props.initialValue}
|
||||
/>
|
||||
|
|
|
@ -5,14 +5,25 @@ import { CloseIcon } from '../../../Icons';
|
|||
import i18n from '../../../i18n';
|
||||
import Autocomplete from '../Autocomplete';
|
||||
|
||||
const getDraftTag = existingDraft =>
|
||||
existingDraft ? existingDraft : {
|
||||
type: 'TextualBody', value: '', purpose: 'tagging', draft: true
|
||||
};
|
||||
|
||||
/** The basic freetext tag control from original Recogito **/
|
||||
const TagWidget = props => {
|
||||
|
||||
const [ showDelete, setShowDelete ] = useState(false);
|
||||
// All tags (draft + non-draft)
|
||||
const all = props.annotation ?
|
||||
props.annotation.bodies.filter(b => b.type === 'TextualBody' && b.purpose === 'tagging') : [];
|
||||
|
||||
// Every body with a 'tagging' purpose is considered a tag
|
||||
const tagBodies = props.annotation ?
|
||||
props.annotation.bodies.filter(b => b.purpose === 'tagging') : [];
|
||||
// Last draft tag goes into the input field
|
||||
const draftTag = getDraftTag(all.slice().reverse().find(b => b.draft));
|
||||
|
||||
// All except draft tag
|
||||
const tags = all.filter(b => b != draftTag);
|
||||
|
||||
const [ showDelete, setShowDelete ] = useState(false);
|
||||
|
||||
const toggle = tag => _ => {
|
||||
if (showDelete === tag) // Removes delete button
|
||||
|
@ -26,16 +37,31 @@ const TagWidget = props => {
|
|||
props.onRemoveBody(tag);
|
||||
}
|
||||
|
||||
const onDraftChange = evt => {
|
||||
const prev = draftTag.value.trim();
|
||||
const updated = evt.target.value.trim();
|
||||
|
||||
if (prev.length === 0 && updated.length > 0) {
|
||||
props.onAppendBody({ ...draftTag, value: updated });
|
||||
} else if (prev.length > 0 && updated.length === 0) {
|
||||
props.onRemoveBody(draftTag);
|
||||
} else {
|
||||
props.onUpdateBody(draftTag, { ...draftTag, value: updated });
|
||||
}
|
||||
}
|
||||
|
||||
const onSubmit = tag => {
|
||||
props.onAppendBody({ type: 'TextualBody', purpose: 'tagging', value: tag.trim() });
|
||||
// Just 'undraft' the current draft tag
|
||||
const { draft, ...undrafted } = draftTag;
|
||||
props.onUpdateBody(draftTag, undrafted);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="r6o-widget tag">
|
||||
<div>
|
||||
{ tagBodies.length > 0 &&
|
||||
{ tags.length > 0 &&
|
||||
<ul className="r6o-taglist">
|
||||
{ tagBodies.map(tag =>
|
||||
{ tags.map(tag =>
|
||||
<li key={tag.value} onClick={toggle(tag.value)}>
|
||||
<span className="label">{tag.value}</span>
|
||||
|
||||
|
@ -57,6 +83,8 @@ const TagWidget = props => {
|
|||
{!props.readOnly &&
|
||||
<Autocomplete
|
||||
placeholder={i18n.t('Add tag...')}
|
||||
initialValue={draftTag.value}
|
||||
onChange={onDraftChange}
|
||||
onSubmit={onSubmit}
|
||||
vocabulary={props.vocabulary || []} />
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue