mirador-annotation-editor-video 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/src/index.js +1 -1
- package/es/IIIFUtils.js +1 -1
- package/es/annotationForm/MultiTagsInput.js +3 -7
- package/es/annotationForm/MultipleBodyTemplate.js +33 -3
- package/es/annotationForm/TextCommentInput.js +8 -4
- package/package.json +1 -1
- package/src/IIIFUtils.js +4 -4
- package/src/annotationForm/MultiTagsInput.js +3 -8
- package/src/annotationForm/MultipleBodyTemplate.js +35 -3
- package/src/annotationForm/TextCommentInput.js +6 -3
package/demo/src/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const config = {
|
|
|
15
15
|
content: '<h4>Comment2</h4><p>comment content</p>',
|
|
16
16
|
}],
|
|
17
17
|
exportLocalStorageAnnotations: false, // display annotation JSON export button
|
|
18
|
-
tagsSuggestions: ['Mirador', 'Awesome', 'Viewer', 'IIIF'],
|
|
18
|
+
tagsSuggestions: ['Mirador', 'Awesome', 'Viewer', 'IIIF', 'Template'],
|
|
19
19
|
},
|
|
20
20
|
annotations: {
|
|
21
21
|
htmlSanitizationRuleSet: 'liberal',
|
package/es/IIIFUtils.js
CHANGED
|
@@ -60,7 +60,7 @@ const convertAnnotationStateToBeSaved = async (annotationState, canvas, windowId
|
|
|
60
60
|
purpose: 'tagging',
|
|
61
61
|
type: 'TextualBody',
|
|
62
62
|
value: tag.value,
|
|
63
|
-
id: tag.
|
|
63
|
+
id: tag.value
|
|
64
64
|
})));
|
|
65
65
|
}
|
|
66
66
|
if (isAnnotationExportableToImage(annotationStateForSaving.maeData)) {
|
|
@@ -12,8 +12,8 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
12
12
|
/**
|
|
13
13
|
* MultiTagsInput component
|
|
14
14
|
* @param t
|
|
15
|
-
* @param tags
|
|
16
|
-
* @param tagsSuggestions
|
|
15
|
+
* @param tags as [{ label: string, value: string }]
|
|
16
|
+
* @param tagsSuggestions as [{ label: string, value: string }]
|
|
17
17
|
* @param setTags
|
|
18
18
|
* @returns {Element}
|
|
19
19
|
* @constructor
|
|
@@ -24,15 +24,11 @@ function MultiTagsInput({
|
|
|
24
24
|
tags,
|
|
25
25
|
tagsSuggestions
|
|
26
26
|
}) {
|
|
27
|
-
const mappedSuggestionsTags = tagsSuggestions.map(suggestion => ({
|
|
28
|
-
label: suggestion,
|
|
29
|
-
value: suggestion
|
|
30
|
-
}));
|
|
31
27
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_material.Typography, {
|
|
32
28
|
variant: "formSectionTitle"
|
|
33
29
|
}, t('tags')), /*#__PURE__*/_react.default.createElement(_creatable.default, {
|
|
34
30
|
isMulti: true,
|
|
35
|
-
options:
|
|
31
|
+
options: tagsSuggestions,
|
|
36
32
|
value: tags,
|
|
37
33
|
onChange: setTags,
|
|
38
34
|
closeMenuOnSelect: false,
|
|
@@ -52,8 +52,8 @@ function MultipleBodyTemplate({
|
|
|
52
52
|
// We support only one textual body
|
|
53
53
|
maeAnnotation.maeData.textBody = maeAnnotation.body.find(body => body.purpose === 'describing');
|
|
54
54
|
maeAnnotation.maeData.tags = maeAnnotation.body.filter(body => body.purpose === 'tagging').map(tag => ({
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
label: tag.value,
|
|
56
|
+
value: tag.value
|
|
57
57
|
}));
|
|
58
58
|
}
|
|
59
59
|
const [annotationState, setAnnotationState] = (0, _react.useState)(maeAnnotation);
|
|
@@ -100,6 +100,35 @@ function MultipleBodyTemplate({
|
|
|
100
100
|
(0, _KonvaUtils.resizeKonvaStage)(windowId, playerReferences.getMediaTrueWidth(), playerReferences.getMediaTrueHeight(), 1 / playerReferences.getScale());
|
|
101
101
|
saveAnnotation(annotationState);
|
|
102
102
|
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* When the user selects a template, we change text comment and try to add the tag with same name
|
|
106
|
+
* @param selectedTemplate
|
|
107
|
+
*/
|
|
108
|
+
const onChangeTemplate = selectedTemplate => {
|
|
109
|
+
const associatedTag = mappedSuggestionsTags.find(tag => tag.value === selectedTemplate.label);
|
|
110
|
+
if (associatedTag) {
|
|
111
|
+
if (!annotationState.maeData.tags.find(tag => tag.value === associatedTag.value)) {
|
|
112
|
+
setAnnotationState({
|
|
113
|
+
...annotationState,
|
|
114
|
+
maeData: {
|
|
115
|
+
...annotationState.maeData,
|
|
116
|
+
tags: [...annotationState.maeData.tags, associatedTag],
|
|
117
|
+
textBody: {
|
|
118
|
+
...annotationState.maeData.textBody,
|
|
119
|
+
value: selectedTemplate.value
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
updateAnnotationTextualBodyValue(selectedTemplate.value);
|
|
127
|
+
};
|
|
128
|
+
const mappedSuggestionsTags = tagsSuggestions.map(suggestion => ({
|
|
129
|
+
label: suggestion,
|
|
130
|
+
value: suggestion
|
|
131
|
+
}));
|
|
103
132
|
return /*#__PURE__*/_react.default.createElement(_material.Grid, {
|
|
104
133
|
container: true,
|
|
105
134
|
direction: "column",
|
|
@@ -110,6 +139,7 @@ function MultipleBodyTemplate({
|
|
|
110
139
|
commentTemplates: commentTemplate,
|
|
111
140
|
comment: annotationState.maeData.textBody.value,
|
|
112
141
|
setComment: updateAnnotationTextualBodyValue,
|
|
142
|
+
onChangeTemplate: onChangeTemplate,
|
|
113
143
|
t: t
|
|
114
144
|
})), /*#__PURE__*/_react.default.createElement(_material.Grid, {
|
|
115
145
|
item: true
|
|
@@ -117,7 +147,7 @@ function MultipleBodyTemplate({
|
|
|
117
147
|
t: t,
|
|
118
148
|
tags: annotationState.maeData.tags,
|
|
119
149
|
setTags: setTags,
|
|
120
|
-
tagsSuggestions:
|
|
150
|
+
tagsSuggestions: mappedSuggestionsTags
|
|
121
151
|
})), /*#__PURE__*/_react.default.createElement(_material.Grid, {
|
|
122
152
|
item: true
|
|
123
153
|
}, /*#__PURE__*/_react.default.createElement(_TargetFormSection.default, {
|
|
@@ -15,12 +15,14 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
15
15
|
* @param commentTemplates - The list of comment templates
|
|
16
16
|
* @param comment - The current comment
|
|
17
17
|
* @param setComment - Function to set the comment
|
|
18
|
+
* @param onChangeTemplate - Function to handle template selection
|
|
18
19
|
* @param t - Translation function
|
|
19
20
|
* @constructor
|
|
20
21
|
*/
|
|
21
22
|
function TextCommentInput({
|
|
22
|
-
commentTemplates,
|
|
23
23
|
comment,
|
|
24
|
+
commentTemplates,
|
|
25
|
+
onChangeTemplate,
|
|
24
26
|
setComment,
|
|
25
27
|
t
|
|
26
28
|
}) {
|
|
@@ -37,13 +39,14 @@ function TextCommentInput({
|
|
|
37
39
|
}, /*#__PURE__*/_react.default.createElement(_creatable.default, {
|
|
38
40
|
options: commentTemplates.map(template => ({
|
|
39
41
|
label: template.title,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
title: template.content,
|
|
43
|
+
// Add title attribute for tooltip
|
|
44
|
+
value: template.content
|
|
42
45
|
})),
|
|
43
46
|
placeholder: t('useTemplate'),
|
|
44
47
|
onChange: selectedOption => {
|
|
45
48
|
if (selectedOption) {
|
|
46
|
-
|
|
49
|
+
onChangeTemplate(selectedOption);
|
|
47
50
|
}
|
|
48
51
|
},
|
|
49
52
|
isClearable: true,
|
|
@@ -66,6 +69,7 @@ TextCommentInput.propTypes = {
|
|
|
66
69
|
comment: _propTypes.default.string.isRequired,
|
|
67
70
|
// eslint-disable-next-line react/forbid-prop-types
|
|
68
71
|
commentTemplates: _propTypes.default.arrayOf(_propTypes.default.object).isRequired,
|
|
72
|
+
onChangeTemplate: _propTypes.default.func.isRequired,
|
|
69
73
|
setComment: _propTypes.default.func.isRequired,
|
|
70
74
|
t: _propTypes.default.func.isRequired
|
|
71
75
|
};
|
package/package.json
CHANGED
package/src/IIIFUtils.js
CHANGED
|
@@ -73,7 +73,7 @@ export const convertAnnotationStateToBeSaved = async (
|
|
|
73
73
|
purpose: 'tagging',
|
|
74
74
|
type: 'TextualBody',
|
|
75
75
|
value: tag.value,
|
|
76
|
-
id: tag.
|
|
76
|
+
id: tag.value,
|
|
77
77
|
})));
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -155,9 +155,9 @@ export const getIIIFTargetFromMaeData = (
|
|
|
155
155
|
};
|
|
156
156
|
|
|
157
157
|
const isSimpleTarget = (shapes) => shapes.length === 1
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
&& shapes[0].type === SHAPES_TOOL.RECTANGLE
|
|
159
|
+
&& shapes[0].strokeColor === TARGET_TOOL_STATE.strokeColor
|
|
160
|
+
&& shapes[0].fillColor === TARGET_TOOL_STATE.fillColor;
|
|
161
161
|
|
|
162
162
|
/**
|
|
163
163
|
* Get the IIIF target from a Konva annotation (Drawing template)
|
|
@@ -6,8 +6,8 @@ import CreatableSelect from 'react-select/creatable';
|
|
|
6
6
|
/**
|
|
7
7
|
* MultiTagsInput component
|
|
8
8
|
* @param t
|
|
9
|
-
* @param tags
|
|
10
|
-
* @param tagsSuggestions
|
|
9
|
+
* @param tags as [{ label: string, value: string }]
|
|
10
|
+
* @param tagsSuggestions as [{ label: string, value: string }]
|
|
11
11
|
* @param setTags
|
|
12
12
|
* @returns {Element}
|
|
13
13
|
* @constructor
|
|
@@ -18,11 +18,6 @@ export function MultiTagsInput({
|
|
|
18
18
|
tags,
|
|
19
19
|
tagsSuggestions,
|
|
20
20
|
}) {
|
|
21
|
-
const mappedSuggestionsTags = tagsSuggestions.map((suggestion) => ({
|
|
22
|
-
label: suggestion,
|
|
23
|
-
value: suggestion,
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
21
|
return (
|
|
27
22
|
<>
|
|
28
23
|
<Typography variant="formSectionTitle">
|
|
@@ -30,7 +25,7 @@ export function MultiTagsInput({
|
|
|
30
25
|
</Typography>
|
|
31
26
|
<CreatableSelect
|
|
32
27
|
isMulti
|
|
33
|
-
options={
|
|
28
|
+
options={tagsSuggestions}
|
|
34
29
|
value={tags}
|
|
35
30
|
onChange={setTags}
|
|
36
31
|
closeMenuOnSelect={false}
|
|
@@ -50,8 +50,8 @@ export default function MultipleBodyTemplate(
|
|
|
50
50
|
maeAnnotation.maeData.textBody = maeAnnotation.body.find((body) => body.purpose === 'describing');
|
|
51
51
|
maeAnnotation.maeData.tags = maeAnnotation.body.filter((body) => body.purpose === 'tagging')
|
|
52
52
|
.map((tag) => ({
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
label: tag.value,
|
|
54
|
+
value: tag.value,
|
|
55
55
|
}));
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -105,6 +105,37 @@ export default function MultipleBodyTemplate(
|
|
|
105
105
|
saveAnnotation(annotationState);
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
/**
|
|
109
|
+
* When the user selects a template, we change text comment and try to add the tag with same name
|
|
110
|
+
* @param selectedTemplate
|
|
111
|
+
*/
|
|
112
|
+
const onChangeTemplate = (selectedTemplate) => {
|
|
113
|
+
const associatedTag = mappedSuggestionsTags.find((tag) => tag.value === selectedTemplate.label);
|
|
114
|
+
if (associatedTag) {
|
|
115
|
+
if (!annotationState.maeData.tags.find((tag) => tag.value === associatedTag.value)) {
|
|
116
|
+
setAnnotationState({
|
|
117
|
+
...annotationState,
|
|
118
|
+
maeData: {
|
|
119
|
+
...annotationState.maeData,
|
|
120
|
+
tags: [...annotationState.maeData.tags, associatedTag],
|
|
121
|
+
textBody: {
|
|
122
|
+
...annotationState.maeData.textBody,
|
|
123
|
+
value: selectedTemplate.value,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
updateAnnotationTextualBodyValue(selectedTemplate.value);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const mappedSuggestionsTags = tagsSuggestions.map((suggestion) => ({
|
|
135
|
+
label: suggestion,
|
|
136
|
+
value: suggestion,
|
|
137
|
+
}));
|
|
138
|
+
|
|
108
139
|
return (
|
|
109
140
|
<Grid container direction="column" spacing={2}>
|
|
110
141
|
<Grid item>
|
|
@@ -112,6 +143,7 @@ export default function MultipleBodyTemplate(
|
|
|
112
143
|
commentTemplates={commentTemplate}
|
|
113
144
|
comment={annotationState.maeData.textBody.value}
|
|
114
145
|
setComment={updateAnnotationTextualBodyValue}
|
|
146
|
+
onChangeTemplate={onChangeTemplate}
|
|
115
147
|
t={t}
|
|
116
148
|
/>
|
|
117
149
|
</Grid>
|
|
@@ -120,7 +152,7 @@ export default function MultipleBodyTemplate(
|
|
|
120
152
|
t={t}
|
|
121
153
|
tags={annotationState.maeData.tags}
|
|
122
154
|
setTags={setTags}
|
|
123
|
-
tagsSuggestions={
|
|
155
|
+
tagsSuggestions={mappedSuggestionsTags}
|
|
124
156
|
/>
|
|
125
157
|
</Grid>
|
|
126
158
|
<Grid item>
|
|
@@ -9,12 +9,14 @@ import TextEditor from '../TextEditor';
|
|
|
9
9
|
* @param commentTemplates - The list of comment templates
|
|
10
10
|
* @param comment - The current comment
|
|
11
11
|
* @param setComment - Function to set the comment
|
|
12
|
+
* @param onChangeTemplate - Function to handle template selection
|
|
12
13
|
* @param t - Translation function
|
|
13
14
|
* @constructor
|
|
14
15
|
*/
|
|
15
16
|
export function TextCommentInput({
|
|
16
|
-
commentTemplates,
|
|
17
17
|
comment,
|
|
18
|
+
commentTemplates,
|
|
19
|
+
onChangeTemplate,
|
|
18
20
|
setComment,
|
|
19
21
|
t,
|
|
20
22
|
}) {
|
|
@@ -30,13 +32,13 @@ export function TextCommentInput({
|
|
|
30
32
|
<CreatableSelect
|
|
31
33
|
options={commentTemplates.map((template) => ({
|
|
32
34
|
label: template.title,
|
|
33
|
-
value: template.content,
|
|
34
35
|
title: template.content, // Add title attribute for tooltip
|
|
36
|
+
value: template.content,
|
|
35
37
|
}))}
|
|
36
38
|
placeholder={t('useTemplate')}
|
|
37
39
|
onChange={(selectedOption) => {
|
|
38
40
|
if (selectedOption) {
|
|
39
|
-
|
|
41
|
+
onChangeTemplate(selectedOption);
|
|
40
42
|
}
|
|
41
43
|
}}
|
|
42
44
|
isClearable
|
|
@@ -67,6 +69,7 @@ TextCommentInput.propTypes = {
|
|
|
67
69
|
comment: PropTypes.string.isRequired,
|
|
68
70
|
// eslint-disable-next-line react/forbid-prop-types
|
|
69
71
|
commentTemplates: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
72
|
+
onChangeTemplate: PropTypes.func.isRequired,
|
|
70
73
|
setComment: PropTypes.func.isRequired,
|
|
71
74
|
t: PropTypes.func.isRequired,
|
|
72
75
|
};
|