Projekt

Obecné

Profil

Stáhnout (9.17 KB) Statistiky
| Větev: | Tag: | Revize:
1 acb8a961 Dominik Poch
import React, { createContext, useEffect, useState } from 'react';
2 bcbaa7d3 Dominik Poch
import {
3
    AnnotationInfo,
4
    ETagSentiment,
5
    ETagType,
6
    SubTagInfo,
7
    TagInfo,
8
    TagInstanceInfo,
9
} from '../api';
10 9a41c02f Dominik Poch
import { Tag } from '../components/types/tag';
11 7652cf88 Lukáš Vlček
import { annotationController } from '../controllers';
12 4bc99591 Lukáš Vlček
import { GetSelectionInfo } from '../utils/selectionUtils';
13 c057279b Lukáš Vlček
14 acb8a961 Dominik Poch
/**
15
 * Interface of an annotation context provider.
16
 */
17 c057279b Lukáš Vlček
interface IAnnotationContextProvider {
18 acb8a961 Dominik Poch
    /**
19
     * Tags managed by the context.
20
     */
21 c057279b Lukáš Vlček
    tags: TagInstanceInfo[] | null;
22 acb8a961 Dominik Poch
23
    /**
24
     * Sets new tags.
25
     * @param newTags An array of new tags.
26
     */
27 c057279b Lukáš Vlček
    setTags: (newTags: TagInstanceInfo[] | null) => void;
28 acb8a961 Dominik Poch
29
    /**
30
     * Adds occurrence to an annotation.
31
     * @param tag Tag whose occurrence should be added.
32
     */
33 c73aecde Dominik Poch
    addOccurrence: (tag: Tag) => void;
34 acb8a961 Dominik Poch
35
    /**
36
     * Deletes an occurrence of an annotation.
37
     * @param occurrence Occurrence that should be deleted.
38
     */
39 9a41c02f Dominik Poch
    deleteOccurrence: (occurrence: TagInstanceInfo) => void;
40 acb8a961 Dominik Poch
41
    /**
42
     * Changes a position of an occurrence of an annotation.
43
     * @param occurrence Occurrence whose position should be changed.
44
     * @param newValue New value of the position.
45
     */
46 9a41c02f Dominik Poch
    changePosition: (occurrence: TagInstanceInfo, newValue: number) => void;
47 acb8a961 Dominik Poch
48
    /**
49
     * Changes a length of an occurrence of an annotation.
50
     * @param occurrence Occurrence whose length should be changed.
51
     * @param newValue New value of the length.
52
     */
53 9a41c02f Dominik Poch
    changeLength: (occurrence: TagInstanceInfo, newValue: number) => void;
54 7652cf88 Lukáš Vlček
55 bcbaa7d3 Dominik Poch
    /**
56
     * Changes sentiment of an annotation.
57
     * @param occurrence Occurrence whose sentiment should be changed.
58
     * @param newValue New value of the sentiment.
59
     */
60
    changeSentiment: (occurrence: TagInstanceInfo, newValue: ETagSentiment) => void;
61
62 7652cf88 Lukáš Vlček
    annotation: AnnotationInfo | null;
63 9a41c02f Dominik Poch
    mappedTags: Tag[] | null;
64 7652cf88 Lukáš Vlček
    refreshAnnotation: () => void;
65 4bc99591 Lukáš Vlček
66
    markSelectedText: (
67
        tagId: string,
68
        subtagId: string | null,
69
        instanceID: string | null
70
    ) => void;
71 c057279b Lukáš Vlček
}
72
73 acb8a961 Dominik Poch
/**
74
 * The annotation context that manages active annotations.
75
 */
76 c057279b Lukáš Vlček
export const AnnotationContext = createContext<IAnnotationContextProvider>({
77 acb8a961 Dominik Poch
    /**
78
     * Default tags.
79
     */
80 c057279b Lukáš Vlček
    tags: null,
81 acb8a961 Dominik Poch
82
    /**
83
     * Default implementation of setTags method.
84
     * @param v Array of new tags.
85
     */
86 c057279b Lukáš Vlček
    setTags: (v) => {
87
        return;
88
    },
89 acb8a961 Dominik Poch
90
    /**
91
     * Default implementation of addOccurrence method.
92
     * @param tag The tag with new occurrence.
93
     */
94 c73aecde Dominik Poch
    addOccurrence: (tag: Tag) => {
95 c057279b Lukáš Vlček
        return;
96
    },
97 acb8a961 Dominik Poch
98
    /**
99
     * Default implementation of deleteOccurrence method.
100
     * @param occurrence Occurrence that should be deleted.
101
     */
102 9a41c02f Dominik Poch
    deleteOccurrence: (occurrence: TagInstanceInfo) => {
103 c057279b Lukáš Vlček
        return;
104
    },
105 acb8a961 Dominik Poch
106
    /**
107
     * Default implementation of changePosition method.
108
     * @param occurrence Occurrence whose position should be changed.
109
     * @param newValue A new position.
110
     */
111 9a41c02f Dominik Poch
    changePosition: (occurrence: TagInstanceInfo, newValue: number) => {
112 c057279b Lukáš Vlček
        return;
113
    },
114 acb8a961 Dominik Poch
115
    /**
116
     * Default implementation of changeLength method.
117
     * @param occurrence Occurrence whose length should be changed.
118
     * @param newValue A new length.
119
     */
120 9a41c02f Dominik Poch
    changeLength: (occurrence: TagInstanceInfo, newValue: number) => {
121 c057279b Lukáš Vlček
        return;
122
    },
123 7652cf88 Lukáš Vlček
124 bcbaa7d3 Dominik Poch
    /**
125
     * Changes sentiment of an annotation.
126
     * @param occurrence Occurrence whose sentiment should be changed.
127
     * @param newValue New value of the sentiment.
128
     */
129
    changeSentiment: (occurrence: TagInstanceInfo, newValue: ETagSentiment) => {
130
        return;
131
    },
132
133 7652cf88 Lukáš Vlček
    annotation: null,
134 9a41c02f Dominik Poch
    mappedTags: null,
135 7652cf88 Lukáš Vlček
    refreshAnnotation: () => {
136
        return;
137
    },
138 4bc99591 Lukáš Vlček
139
    markSelectedText: () => {
140
        return;
141
    },
142 c057279b Lukáš Vlček
});
143
144 acb8a961 Dominik Poch
/**
145
 * Provider of the annotation context.
146
 * @param props Children that should have access to the annotation context.
147
 * @returns Prepared html of the provider.
148
 */
149 7595035c Lukáš Vlček
const AnnotationProvider = (props: {
150
    children: React.ReactNode;
151
    annotationId: string;
152
}) => {
153 7652cf88 Lukáš Vlček
    const [annotation, setAnnotation] = useState<AnnotationInfo | null>(null);
154
155 acb8a961 Dominik Poch
    /**
156
     * Tags managed by the context.
157
     */
158 c057279b Lukáš Vlček
    const [tags, setTags] = useState<TagInstanceInfo[] | null>(null);
159
160 9a41c02f Dominik Poch
    const [mappedTags, setMappedTags] = useState<Tag[] | null>(null);
161
162 4bc99591 Lukáš Vlček
    async function markSelectedText(
163
        tagId: string,
164
        subtagId: string | null,
165
        instanceId: string | null
166
    ) {
167
        if (!annotation) {
168
            console.log('annotation not found');
169
            return;
170
        }
171
172
        const selectionInfo = GetSelectionInfo(annotation);
173
        if (!selectionInfo) {
174
            console.log(
175
                'not able to continue, selection processing not completed successfully'
176
            );
177
            return;
178
        }
179
180
        const id = subtagId ?? tagId;
181
        const type: ETagType = subtagId == null ? ETagType.Tag : ETagType.Subtag;
182
183
        const res = await annotationController.annotationAnnotationIdPost(
184
            props.annotationId,
185
            {
186
                id: id,
187
                instanceId,
188
                type,
189
                position: selectionInfo.startPositionOriginalDocument,
190
                length: selectionInfo.selectionLengthOriginalDocument,
191
            }
192
        );
193
194
        await refreshAnnotation();
195
    }
196
197 acb8a961 Dominik Poch
    /**
198
     * Default implementation of addOccurrence method.
199
     * @param tag The tag with new occurrence.
200
     */
201 4bc99591 Lukáš Vlček
    const addOccurrence = async (tag: Tag) => {
202
        await markSelectedText(tag.tagId, tag.subtagId ?? null, tag.instanceId);
203 acb8a961 Dominik Poch
    };
204
205
    /**
206
     * Deletes an occurrence of an annotation.
207
     * @param occurrence Occurrence that should be deleted.
208
     */
209 9fdb7d55 Lukáš Vlček
    const deleteOccurrence = async (occurrence: TagInstanceInfo) => {
210
        if (!occurrence.occurenceId) {
211
            console.log('invalid occurrence');
212
            return;
213
        }
214
215
        const deleteRes =
216
            await annotationController.annotationAnnotationIdOccurenceIdDelete(
217
                props.annotationId,
218
                occurrence.occurenceId
219
            );
220
221
        await refreshAnnotation();
222 acb8a961 Dominik Poch
    };
223
224
    /**
225
     * Changes a position of an occurrence of an annotation.
226
     * @param occurrence Occurrence whose position should be changed.
227
     * @param newValue New value of the position.
228
     */
229 9a41c02f Dominik Poch
    const changePosition = (occurrence: TagInstanceInfo, newValue: number) => {
230 acb8a961 Dominik Poch
        //TODO: Implement method (should use objects from server API)
231
    };
232
233
    /**
234
     * Changes a length of an occurrence of an annotation.
235
     * @param occurrence Occurrence whose length should be changed.
236
     * @param newValue New value of the length.
237
     */
238 9a41c02f Dominik Poch
    const changeLength = (occurrence: TagInstanceInfo, newValue: number) => {
239 acb8a961 Dominik Poch
        //TODO: Implement method (should use objects from server API)
240
    };
241
242 bcbaa7d3 Dominik Poch
    /**
243
     * Changes sentiment of an annotation.
244
     * @param occurrence Occurrence whose sentiment should be changed.
245
     * @param newValue New value of the sentiment.
246
     */
247
    const changeSentiment = async (
248
        occurrence: TagInstanceInfo,
249
        newValue: ETagSentiment
250
    ) => {
251
        if (!occurrence.instance) {
252
            console.log('invalid instance');
253
            return;
254
        }
255
256
        const putRes =
257
            await annotationController.annotationAnnotationIdInstanceIdSentimentPut(
258
                props.annotationId,
259
                occurrence.instance,
260
                { sentiment: newValue }
261
            );
262
263
        await refreshAnnotation();
264
    };
265
266 9a41c02f Dominik Poch
    const remapAnnotations = (data: AnnotationInfo) => {
267 4bc99591 Lukáš Vlček
        let map = new Map<string, Tag>();
268 9a41c02f Dominik Poch
        data.tagInstances?.forEach((tagInstance) => {
269 4bc99591 Lukáš Vlček
            if (map.has(tagInstance.instance ?? '-')) {
270
                let tag = map.get(tagInstance.instance ?? '-');
271 9a41c02f Dominik Poch
                tag!.occurrences = [...tag!.occurrences, tagInstance];
272
            } else {
273 4bc99591 Lukáš Vlček
                map.set(tagInstance.instance ?? '-', {
274
                    tagName: tagInstance.tagName ?? '',
275
                    subtagName: tagInstance.subTagName ?? null,
276 9a41c02f Dominik Poch
                    category: tagInstance.tagCategoryName ?? '',
277
                    occurrences: [tagInstance],
278 4bc99591 Lukáš Vlček
                    tagId: tagInstance.tagId ?? '',
279
                    instanceId: tagInstance.instance ?? '',
280
                    subtagId: tagInstance.subTagId ?? null,
281 9a41c02f Dominik Poch
                });
282
            }
283
        });
284
285
        setMappedTags(Array.from(map.values()));
286
    };
287
288 7652cf88 Lukáš Vlček
    async function refreshAnnotation() {
289
        const data = await annotationController.annotationAnnotationIdGet(
290
            props.annotationId
291
        );
292
293 9a41c02f Dominik Poch
        remapAnnotations(data.data);
294 7652cf88 Lukáš Vlček
        setAnnotation(data.data ?? null);
295
    }
296
297 acb8a961 Dominik Poch
    /**
298
     * Initializes the context.
299
     */
300 c057279b Lukáš Vlček
    useEffect(() => {
301 7652cf88 Lukáš Vlček
        refreshAnnotation();
302 7595035c Lukáš Vlček
    }, [props.annotationId]);
303 c057279b Lukáš Vlček
304
    return (
305
        <AnnotationContext.Provider
306
            value={{
307
                tags,
308
                setTags,
309
                addOccurrence,
310
                deleteOccurrence,
311
                changeLength,
312
                changePosition,
313 bcbaa7d3 Dominik Poch
                changeSentiment,
314 7652cf88 Lukáš Vlček
                refreshAnnotation,
315
                annotation,
316 9a41c02f Dominik Poch
                mappedTags,
317 4bc99591 Lukáš Vlček
                markSelectedText,
318 c057279b Lukáš Vlček
            }}
319
        >
320
            {props.children}
321
        </AnnotationContext.Provider>
322
    );
323
};
324
325
export default AnnotationProvider;