commit
730b3960cb
|
@ -13,6 +13,7 @@
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"node-polyglot": "^2.4.0",
|
"node-polyglot": "^2.4.0",
|
||||||
"react-autosize-textarea": "^7.1.0",
|
"react-autosize-textarea": "^7.1.0",
|
||||||
|
"react-draggable": "^4.4.3",
|
||||||
"react-select": "^4.3.1",
|
"react-select": "^4.3.1",
|
||||||
"react-transition-group": "^4.4.2",
|
"react-transition-group": "^4.4.2",
|
||||||
"timeago-react": "^3.0.2",
|
"timeago-react": "^3.0.2",
|
||||||
|
@ -1641,6 +1642,11 @@
|
||||||
"fsevents": "~2.1.1"
|
"fsevents": "~2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/classnames": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||||
|
},
|
||||||
"node_modules/cliui": {
|
"node_modules/cliui": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||||
|
@ -2956,6 +2962,15 @@
|
||||||
"react": "^16.14.0"
|
"react": "^16.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-draggable": {
|
||||||
|
"version": "4.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz",
|
||||||
|
"integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==",
|
||||||
|
"dependencies": {
|
||||||
|
"classnames": "^2.2.5",
|
||||||
|
"prop-types": "^15.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-input-autosize": {
|
"node_modules/react-input-autosize": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz",
|
||||||
|
@ -4903,6 +4918,11 @@
|
||||||
"readdirp": "~3.2.0"
|
"readdirp": "~3.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"classnames": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||||
|
},
|
||||||
"cliui": {
|
"cliui": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||||
|
@ -5881,6 +5901,15 @@
|
||||||
"scheduler": "^0.19.1"
|
"scheduler": "^0.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-draggable": {
|
||||||
|
"version": "4.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz",
|
||||||
|
"integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==",
|
||||||
|
"requires": {
|
||||||
|
"classnames": "^2.2.5",
|
||||||
|
"prop-types": "^15.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-input-autosize": {
|
"react-input-autosize": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz",
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"node-polyglot": "^2.4.0",
|
"node-polyglot": "^2.4.0",
|
||||||
"react-autosize-textarea": "^7.1.0",
|
"react-autosize-textarea": "^7.1.0",
|
||||||
|
"react-draggable": "^4.4.3",
|
||||||
"react-select": "^4.3.1",
|
"react-select": "^4.3.1",
|
||||||
"react-transition-group": "^4.4.2",
|
"react-transition-group": "^4.4.2",
|
||||||
"timeago-react": "^3.0.2",
|
"timeago-react": "^3.0.2",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
import Draggable from 'react-draggable';
|
||||||
import { getWidget, DEFAULT_WIDGETS } from './widgets';
|
import { getWidget, DEFAULT_WIDGETS } from './widgets';
|
||||||
import { TrashIcon } from '../Icons';
|
import { TrashIcon } from '../Icons';
|
||||||
import setPosition from './setPosition';
|
import setPosition from './setPosition';
|
||||||
|
@ -22,6 +23,8 @@ const Editor = props => {
|
||||||
// The current state of the edited annotation vs. original
|
// The current state of the edited annotation vs. original
|
||||||
const [ currentAnnotation, setCurrentAnnotation ] = useState();
|
const [ currentAnnotation, setCurrentAnnotation ] = useState();
|
||||||
|
|
||||||
|
const [ dragged, setDragged ] = useState(false);
|
||||||
|
|
||||||
// Reference to the DOM element, so we can set position
|
// Reference to the DOM element, so we can set position
|
||||||
const element = useRef();
|
const element = useRef();
|
||||||
|
|
||||||
|
@ -46,14 +49,16 @@ const Editor = props => {
|
||||||
const initResizeObserver = () => {
|
const initResizeObserver = () => {
|
||||||
if (window?.ResizeObserver) {
|
if (window?.ResizeObserver) {
|
||||||
const resizeObserver = new ResizeObserver(() => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
setPosition(props.wrapperEl, element.current, props.selectedElement);
|
if (!dragged)
|
||||||
|
setPosition(props.wrapperEl, element.current, props.selectedElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
resizeObserver.observe(props.wrapperEl);
|
resizeObserver.observe(props.wrapperEl);
|
||||||
return () => resizeObserver.disconnect();
|
return () => resizeObserver.disconnect();
|
||||||
} else {
|
} else {
|
||||||
// Fire setPosition *only* for devices that don't support ResizeObserver
|
// Fire setPosition *only* for devices that don't support ResizeObserver
|
||||||
setPosition(props.wrapperEl, element.current, props.selectedElement);
|
if (!dragged)
|
||||||
|
setPosition(props.wrapperEl, element.current, props.selectedElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,51 +169,57 @@ const Editor = props => {
|
||||||
!widgets.some(isReadOnlyWidget); // every widget is deletable
|
!widgets.some(isReadOnlyWidget); // every widget is deletable
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={element} className="r6o-editor">
|
<Draggable
|
||||||
<div className="r6o-arrow" />
|
cancel=".r6o-btn, .r6o-nodrag"
|
||||||
<div className="r6o-editor-inner">
|
onDrag={() => setDragged(true)}>
|
||||||
{widgets.map(widget =>
|
|
||||||
React.cloneElement(widget, {
|
<div ref={element} className={dragged ? 'r6o-editor dragged' : 'r6o-editor'}>
|
||||||
annotation : currentAnnotation,
|
<div className="r6o-arrow" />
|
||||||
readOnly : props.readOnly,
|
<div className="r6o-editor-inner">
|
||||||
env: props.env,
|
{widgets.map(widget =>
|
||||||
onAppendBody,
|
React.cloneElement(widget, {
|
||||||
onUpdateBody,
|
annotation : currentAnnotation,
|
||||||
onRemoveBody,
|
readOnly : props.readOnly,
|
||||||
onUpsertBody,
|
env: props.env,
|
||||||
onSetProperty,
|
onAppendBody,
|
||||||
onSaveAndClose: onOk
|
onUpdateBody,
|
||||||
})
|
onRemoveBody,
|
||||||
)}
|
onUpsertBody,
|
||||||
|
onSetProperty,
|
||||||
{ props.readOnly ? (
|
onSaveAndClose: onOk
|
||||||
<div className="r6o-footer">
|
})
|
||||||
<button
|
)}
|
||||||
className="r6o-btn"
|
|
||||||
onClick={onCancel}>{i18n.t('Close')}</button>
|
{ props.readOnly ? (
|
||||||
</div>
|
<div className="r6o-footer">
|
||||||
) : (
|
<button
|
||||||
<div className="r6o-footer">
|
className="r6o-btn"
|
||||||
{ hasDelete && (
|
onClick={onCancel}>{i18n.t('Close')}</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="r6o-footer">
|
||||||
|
{ hasDelete && (
|
||||||
|
<button
|
||||||
|
className="r6o-btn left delete-annotation"
|
||||||
|
title={i18n.t('Delete')}
|
||||||
|
onClick={onDelete}>
|
||||||
|
<TrashIcon width={12} />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="r6o-btn left delete-annotation"
|
className="r6o-btn outline"
|
||||||
title={i18n.t('Delete')}
|
onClick={onCancel}>{i18n.t('Cancel')}</button>
|
||||||
onClick={onDelete}>
|
|
||||||
<TrashIcon width={12} />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="r6o-btn outline"
|
className="r6o-btn "
|
||||||
onClick={onCancel}>{i18n.t('Cancel')}</button>
|
onClick={onOk}>{i18n.t('Ok')}</button>
|
||||||
|
</div>
|
||||||
<button
|
)}
|
||||||
className="r6o-btn "
|
</div>
|
||||||
onClick={onOk}>{i18n.t('Ok')}</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
</Draggable>
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ const Comment = props => {
|
||||||
/> }
|
/> }
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={isMenuVisible ? "r6o-icon r6o-arrow-down r6o-menu-open" : "r6o-icon r6o-arrow-down"}
|
className={isMenuVisible ? "r6o-icon r6o-arrow-down r6o-nodrag r6o-menu-open" : "r6o-icon r6o-arrow-down r6o-nodrag"}
|
||||||
onClick={() => setIsMenuVisible(!isMenuVisible)}>
|
onClick={() => setIsMenuVisible(!isMenuVisible)}>
|
||||||
<ChevronDownIcon width={12} />
|
<ChevronDownIcon width={12} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@ const DropdownMenu = props => {
|
||||||
useClickOutside(ref, () => props.onClickOutside());
|
useClickOutside(ref, () => props.onClickOutside());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul ref={ref} className="r6o-comment-dropdown-menu">
|
<ul ref={ref} className="r6o-comment-dropdown-menu r6o-nodrag">
|
||||||
<li onClick={props.onEdit}>{i18n.t('Edit')}</li>
|
<li onClick={props.onEdit}>{i18n.t('Edit')}</li>
|
||||||
<li onClick={props.onDelete}>{i18n.t('Delete')}</li>
|
<li onClick={props.onDelete}>{i18n.t('Delete')}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default class TextEntryField extends Component {
|
||||||
return (
|
return (
|
||||||
<TextareaAutosize
|
<TextareaAutosize
|
||||||
ref={this.onRender}
|
ref={this.onRender}
|
||||||
className="r6o-editable-text"
|
className={this.props.editable ? 'r6o-editable-text r6o-nodrag' : 'r6o-editable-text'}
|
||||||
value={this.props.content}
|
value={this.props.content}
|
||||||
placeholder={this.props.placeholder || i18n.t('Add a comment...')}
|
placeholder={this.props.placeholder || i18n.t('Add a comment...')}
|
||||||
disabled={!this.props.editable}
|
disabled={!this.props.editable}
|
||||||
|
|
|
@ -59,7 +59,7 @@ const TagWidget = props => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="r6o-widget r6o-tag">
|
<div className="r6o-widget r6o-tag r6o-nodrag">
|
||||||
{ tags.length > 0 &&
|
{ tags.length > 0 &&
|
||||||
<ul className="r6o-taglist">
|
<ul className="r6o-taglist">
|
||||||
{ tags.map(tag =>
|
{ tags.map(tag =>
|
||||||
|
|
|
@ -116,6 +116,10 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.r6o-editor.dragged .r6o-arrow {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
.r6o-purposedropdown {
|
.r6o-purposedropdown {
|
||||||
width: 150px;
|
width: 150px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
Loading…
Reference in New Issue