@ia2coop/ia2-annotation-tool
Version:
Annotation tool components library for IA² Project
413 lines (366 loc) • 15.5 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.configuredStore = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/slicedToArray"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectSpread2"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/toConsumableArray"));
var _ia2ReactTextAnnotate = require("@ia2coop/ia2-react-text-annotate");
var _react = _interopRequireWildcard(require("react"));
var _reactRedux = require("react-redux");
var _redux = require("redux");
var _toolkit = require("@reduxjs/toolkit");
var _reduxUndo = require("redux-undo");
var _core = require("@material-ui/core");
var _Redo = _interopRequireDefault(require("@material-ui/icons/Redo"));
var _Undo = _interopRequireDefault(require("@material-ui/icons/Undo"));
var _anonymizerSlice = _interopRequireWildcard(require("./anonymizerSlice"));
var _Instructions = _interopRequireDefault(require("../Instructions"));
var _MultipleEntitiesSelector = _interopRequireDefault(require("../MultipleEntitiesSelector"));
var _EditorModule = _interopRequireDefault(require("./Editor.module.css"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
var createRootReducer = function createRootReducer() {
return (0, _redux.combineReducers)({
anonymizer: _anonymizerSlice.default
});
};
var rootReducer = createRootReducer();
var middleware = (0, _toConsumableArray2.default)((0, _toolkit.getDefaultMiddleware)());
var configuredStore = function configuredStore(initialState) {
var store = (0, _toolkit.configureStore)({
reducer: rootReducer,
middleware: middleware,
preloadedState: initialState
});
return store;
};
exports.configuredStore = configuredStore;
var useStyles = (0, _core.makeStyles)(function (theme) {
var _container, _selector, _, _rightActions;
return (0, _core.createStyles)({
container: (_container = {
display: "flex",
flexDirection: "column",
minWidth: theme.spacing(85)
}, (0, _defineProperty2.default)(_container, theme.breakpoints.up("lg"), {
marginRight: theme.spacing(40),
marginLeft: theme.spacing(40)
}), (0, _defineProperty2.default)(_container, theme.breakpoints.down("lg"), {
marginRight: theme.spacing(20),
marginLeft: theme.spacing(20)
}), (0, _defineProperty2.default)(_container, theme.breakpoints.down("md"), {
marginRight: theme.spacing(8),
marginLeft: theme.spacing(8)
}), _container),
selectInput: {
display: "flex",
flexDirection: "row",
backgroundColor: theme.palette.common.white,
borderRadius: theme.spacing(10),
color: theme.palette.secondary.main,
padding: theme.spacing(1, 3),
fontSize: "medium",
fontWeight: "bold",
"&:hover, &:focus": {
color: theme.palette.primary.main,
borderRadius: theme.spacing(10)
}
},
selectIcon: {
color: theme.palette.primary.main,
paddingRight: theme.spacing(2)
},
selector: (_selector = {}, (0, _defineProperty2.default)(_selector, theme.breakpoints.down("lg"), {
width: theme.spacing(30)
}), (0, _defineProperty2.default)(_selector, theme.breakpoints.up("lg"), {
width: theme.spacing(50)
}), _selector),
tagDescription: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
whiteSpace: "nowrap",
textOverflow: "ellipsis",
overflow: "hidden"
},
tagTitle: {
marginRight: theme.spacing(1)
},
selectorContainer: {
flexGrow: 1,
marginRight: theme.spacing(2),
alignItems: "center",
display: "flex",
flexDirection: "column"
},
selectorIcon: {
color: theme.palette.primary.main,
paddingRight: theme.spacing(1)
},
root: {
"& > *": (_ = {
marginBottom: theme.spacing(4),
height: theme.spacing(50)
}, (0, _defineProperty2.default)(_, theme.breakpoints.down("lg"), {
height: theme.spacing(20)
}), (0, _defineProperty2.default)(_, theme.breakpoints.down("md"), {
height: theme.spacing(16)
}), _)
},
rightActions: (_rightActions = {
right: 0,
position: "absolute"
}, (0, _defineProperty2.default)(_rightActions, theme.breakpoints.up("lg"), {
transform: "translateX(-350px)"
}), (0, _defineProperty2.default)(_rightActions, theme.breakpoints.down("lg"), {
transform: "translateX(-230px)"
}), (0, _defineProperty2.default)(_rightActions, theme.breakpoints.down("md"), {
transform: "translateX(-100px)"
}), _rightActions)
});
});
var Editor = function Editor(_ref) {
var _tags$;
var style = _ref.style,
annotations = _ref.annotations,
tags = _ref.tags,
text = _ref.text,
multipleSelectionEnable = _ref.multipleSelectionEnable,
onMultipleSelection = _ref.onMultipleSelection;
var _useSelector = (0, _reactRedux.useSelector)(_anonymizerSlice.selectAnonymizer),
present = _useSelector.present,
future = _useSelector.future,
past = _useSelector.past;
var dispatch = (0, _reactRedux.useDispatch)();
var classes = useStyles();
(0, _react.useEffect)(function () {
dispatch((0, _anonymizerSlice.updateTags)(tags));
var annotationsMap = annotations.map(function (ent) {
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, ent), {}, {
class: ent.should_anonymized ? _EditorModule.default.anonymousmark : _EditorModule.default.mark
});
});
dispatch((0, _anonymizerSlice.updateAnalysisSuccess)({
ents: annotationsMap,
text: text
}));
dispatch((0, _anonymizerSlice.updateSelectTag)(tags[0].name));
}, [dispatch, annotations, tags, text]);
var _useState = (0, _react.useState)((_tags$ = tags[0]) === null || _tags$ === void 0 ? void 0 : _tags$.name),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
selectedTag = _useState2[0],
setSelectedTag = _useState2[1];
var renderMultipleEntitiesSelector = function renderMultipleEntitiesSelector() {
return /*#__PURE__*/_react.default.createElement(_MultipleEntitiesSelector.default, {
onMultipleSelection: onMultipleSelection
});
};
var handleTagSelection = function handleTagSelection(event) {
dispatch((0, _anonymizerSlice.updateSelectTag)(event.target.value));
setSelectedTag(event.target.value);
};
var onUndo = function onUndo() {
dispatch(_reduxUndo.ActionCreators.undo());
};
var onRedo = function onRedo() {
dispatch(_reduxUndo.ActionCreators.redo());
};
var renderUndoRedo = function renderUndoRedo() {
var dispatchPrevios = 3;
var canUndo = past.length > dispatchPrevios;
var canRedo = future.length > 0;
return /*#__PURE__*/_react.default.createElement(_core.Box, {
className: classes.rightActions
}, /*#__PURE__*/_react.default.createElement(_core.IconButton, {
"aria-label": "undo",
onClick: onUndo,
disabled: !canUndo
}, /*#__PURE__*/_react.default.createElement(_Undo.default, null)), /*#__PURE__*/_react.default.createElement(_core.IconButton, {
"aria-label": "redo",
onClick: onRedo,
disabled: !canRedo
}, /*#__PURE__*/_react.default.createElement(_Redo.default, null)));
};
var renderSelect = function renderSelect() {
return /*#__PURE__*/_react.default.createElement(_core.FormControl, {
className: classes.selectorContainer,
color: "secondary"
}, /*#__PURE__*/_react.default.createElement(_core.Select, {
label: "TAG",
fullWidth: true,
labelId: "tag",
id: "tag",
value: selectedTag,
onChange: function onChange(event) {
return handleTagSelection(event);
},
className: classes.selector,
defaultValue: "",
color: "secondary",
classes: {
icon: classes.selectorIcon,
select: classes.selectInput
},
disableUnderline: true,
style: {
display: "flex",
alignSelf: "flex-end",
margin: "24px"
}
}, present.tags.map(function (tag) {
return /*#__PURE__*/_react.default.createElement(_core.MenuItem, {
key: tag.id,
value: tag.name,
id: tag.id
}, /*#__PURE__*/_react.default.createElement(_core.Typography, {
component: "h1",
variant: "subtitle1",
className: classes.tagTitle
}, tag.name), /*#__PURE__*/_react.default.createElement(_core.Typography, {
component: "h1",
variant: "subtitle1",
className: classes.tagDescription
}, tag.description));
})));
};
var handleEntitySelection = function handleEntitySelection(value, span) {
// Check if annotations exist in deleteAnnotations array
if (present.deleteAnnotations.some(function (annot) {
return annot.start === span.start && annot.end === span.end && annot.tag === span.tag;
})) {
// Remove a delete annotation and update annotations by show in editor
dispatch((0, _anonymizerSlice.removeDeleteAnnotations)(span));
dispatch((0, _anonymizerSlice.updateAnnotations)((0, _toConsumableArray2.default)(present.annotations.concat([span]))));
} else {
// Update new annotations by show in editor
dispatch((0, _anonymizerSlice.updateNewAnnotations)([span]));
}
};
var handleDelete = function handleDelete(index, value) {
// Check if annotations exist in newAnnotations array
if (present.newAnnotations.some(function (annot) {
return annot.start === value.start && annot.end === value.end;
})) {
dispatch((0, _anonymizerSlice.removeNewAnnotations)(value));
} else {
// Add a delete annotation and update annotations by don't show in editor
dispatch((0, _anonymizerSlice.updateDeleteAnnotations)([present.annotations[index]]));
dispatch((0, _anonymizerSlice.updateAnnotations)([].concat((0, _toConsumableArray2.default)(present.annotations.slice(0, index)), (0, _toConsumableArray2.default)(present.annotations.slice(index + 1)))));
}
return null;
};
var _handleClick = function handleClick(index, value) {
handleDelete(index, value);
};
return /*#__PURE__*/_react.default.createElement(_core.Box, null, /*#__PURE__*/_react.default.createElement("div", {
className: classes.container
}, /*#__PURE__*/_react.default.createElement(_Instructions.default, {
title: "Selecciona una etiqueta",
subtitle: "Luego elimina, agrega o corrige las entidades identificadas. IA\xB2 detecta las etiquetas y realizar\xE1 las siguientes acciones con cada una seg\xFAn su color:" // Hardcodeados los colores y los textos, pensar si no hacer un servicio de backend,que brinde los colores y los textos
,
legends: [{
id: 1,
color: "#00D6A1",
description: "Anonimizar"
}, {
id: 2,
color: "#ffca00",
description: "No anonimizar"
}]
}, /*#__PURE__*/_react.default.createElement("div", {
className: classes.selectorContainer
}, renderSelect(), multipleSelectionEnable && renderMultipleEntitiesSelector())), /*#__PURE__*/_react.default.createElement("div", {
className: classes.root
}, renderUndoRedo(), /*#__PURE__*/_react.default.createElement(_core.Paper, {
elevation: 5
}, /*#__PURE__*/_react.default.createElement(_ia2ReactTextAnnotate.TextAnnotator, {
tabIndex: 0,
editableContent: true,
doubleTaggingOff: true,
style: style,
content: present.text,
value: present.annotations.concat(present.newAnnotations),
onChange: function onChange(value, span) {
return handleEntitySelection(value, span);
},
getSpan: function getSpan(span) {
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, span), {}, {
should_anonymized: present.selectTag.should_anonimyzation,
human_marked_ocurrency: true,
tag: selectedTag,
class: present.selectTag.should_anonimyzation ? _EditorModule.default.anonymousmark : _EditorModule.default.mark
});
},
markStyle: _EditorModule.default,
markClass: _EditorModule.default.mark,
handleClick: function handleClick(index, value) {
return _handleClick(index, value);
},
withCompletedWordSelection: true
})))));
};
Editor.defaultProps = {
style: {},
annotations: [],
tags: [],
multipleSelectionEnable: false,
onMultipleSelection: function onMultipleSelection() {
return true;
}
};
var WrappedEditor = function WrappedEditor(_ref2) {
var style = _ref2.style,
annotations = _ref2.annotations,
tags = _ref2.tags,
text = _ref2.text,
onAnnotationsChange = _ref2.onAnnotationsChange,
multipleSelectionEnable = _ref2.multipleSelectionEnable,
onMultipleSelection = _ref2.onMultipleSelection;
var store = configuredStore();
(0, _react.useEffect)(function () {
var subscribeAnnotations = function subscribeAnnotations() {
var currentD;
var currentNa;
return store.subscribe(function () {
var prevD = currentD;
var prevNa = currentNa;
currentNa = store.getState().anonymizer.newAnnotations;
currentD = store.getState().anonymizer.deleteAnnotations;
if (prevD !== currentD || prevNa !== currentNa) {
onAnnotationsChange(currentD, currentNa);
}
});
};
var unsubscribe = subscribeAnnotations();
return function () {
return unsubscribe();
};
}, [onAnnotationsChange, store]);
return /*#__PURE__*/_react.default.createElement(_reactRedux.Provider, {
store: store
}, /*#__PURE__*/_react.default.createElement(Editor, {
style: style,
text: text,
tags: tags,
annotations: annotations,
multipleSelectionEnable: multipleSelectionEnable,
onMultipleSelection: onMultipleSelection
}));
};
WrappedEditor.defaultProps = {
style: {},
annotations: [],
tags: [],
multipleSelectionEnable: false,
onMultipleSelection: function onMultipleSelection() {
return true;
},
onAnnotationsChange: function onAnnotationsChange() {
return true;
}
};
var _default = WrappedEditor;
exports.default = _default;