Projekt

Obecné

Profil

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