Projekt

Obecné

Profil

Stáhnout (9.07 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
            return;
183
        }
184
185
        const id = subtagId ?? tagId;
186
        const type: ETagType = subtagId == null ? ETagType.Tag : ETagType.Subtag;
187 dee53692 Jaroslav Hrubý
        const res = await annotationController
188
            .annotationAnnotationIdPost(props.annotationId, {
189 4bc99591 Lukáš Vlček
                id: id,
190
                instanceId,
191
                type,
192
                position: selectionInfo.startPositionOriginalDocument,
193
                length: selectionInfo.selectionLengthOriginalDocument,
194 dee53692 Jaroslav Hrubý
            })
195 5ef75299 Lukáš Vlček
            .catch((e) =>
196
                ShowToast('Tato část textu je již touto značkou anotována', 'warning')
197
            );
198 4bc99591 Lukáš Vlček
199
        await refreshAnnotation();
200
    }
201
202 acb8a961 Dominik Poch
    /**
203
     * Default implementation of addOccurrence method.
204
     * @param tag The tag with new occurrence.
205
     */
206 4bc99591 Lukáš Vlček
    const addOccurrence = async (tag: Tag) => {
207
        await markSelectedText(tag.tagId, tag.subtagId ?? null, tag.instanceId);
208 acb8a961 Dominik Poch
    };
209
210
    /**
211
     * Changes visibility of an annotation.
212
     * @param tag Tag whose visibility should be changed.
213
     */
214
    const changeVisibility = (tag: Tag) => {
215
        //TODO: Implement method (should use objects from server API)
216
    };
217
218
    /**
219
     * Deletes an occurrence of an annotation.
220
     * @param occurrence Occurrence that should be deleted.
221
     */
222 9fdb7d55 Lukáš Vlček
    const deleteOccurrence = async (occurrence: TagInstanceInfo) => {
223
        if (!occurrence.occurenceId) {
224
            console.log('invalid occurrence');
225
            return;
226
        }
227
228 dee53692 Jaroslav Hrubý
        ShowConfirmDelete(() => {
229
            annotationController
230
                .annotationAnnotationIdOccurenceIdDelete(
231
                    props.annotationId,
232
                    occurrence.occurenceId ?? ''
233
                )
234
                .then(() => refreshAnnotation());
235
        }, 'značku');
236 acb8a961 Dominik Poch
    };
237
238
    /**
239
     * Changes a position of an occurrence of an annotation.
240
     * @param occurrence Occurrence whose position should be changed.
241
     * @param newValue New value of the position.
242
     */
243 9a41c02f Dominik Poch
    const changePosition = (occurrence: TagInstanceInfo, newValue: number) => {
244 acb8a961 Dominik Poch
        //TODO: Implement method (should use objects from server API)
245
    };
246
247
    /**
248
     * Changes a length of an occurrence of an annotation.
249
     * @param occurrence Occurrence whose length should be changed.
250
     * @param newValue New value of the length.
251
     */
252 9a41c02f Dominik Poch
    const changeLength = (occurrence: TagInstanceInfo, newValue: number) => {
253 acb8a961 Dominik Poch
        //TODO: Implement method (should use objects from server API)
254
    };
255
256 9a41c02f Dominik Poch
    const remapAnnotations = (data: AnnotationInfo) => {
257 4bc99591 Lukáš Vlček
        let map = new Map<string, Tag>();
258 9a41c02f Dominik Poch
        data.tagInstances?.forEach((tagInstance) => {
259 4bc99591 Lukáš Vlček
            if (map.has(tagInstance.instance ?? '-')) {
260
                let tag = map.get(tagInstance.instance ?? '-');
261 9a41c02f Dominik Poch
                tag!.occurrences = [...tag!.occurrences, tagInstance];
262
            } else {
263 4bc99591 Lukáš Vlček
                map.set(tagInstance.instance ?? '-', {
264
                    tagName: tagInstance.tagName ?? '',
265
                    subtagName: tagInstance.subTagName ?? null,
266 9a41c02f Dominik Poch
                    category: tagInstance.tagCategoryName ?? '',
267
                    visible: true,
268
                    occurrences: [tagInstance],
269 4bc99591 Lukáš Vlček
                    tagId: tagInstance.tagId ?? '',
270
                    instanceId: tagInstance.instance ?? '',
271
                    subtagId: tagInstance.subTagId ?? null,
272 9a41c02f Dominik Poch
                });
273
            }
274
        });
275
276
        setMappedTags(Array.from(map.values()));
277
    };
278
279 7652cf88 Lukáš Vlček
    async function refreshAnnotation() {
280
        const data = await annotationController.annotationAnnotationIdGet(
281
            props.annotationId
282
        );
283
284 9a41c02f Dominik Poch
        remapAnnotations(data.data);
285 7652cf88 Lukáš Vlček
        setAnnotation(data.data ?? null);
286 dee53692 Jaroslav Hrubý
        setSubmitting(false);
287 7652cf88 Lukáš Vlček
    }
288
289 acb8a961 Dominik Poch
    /**
290
     * Initializes the context.
291
     */
292 c057279b Lukáš Vlček
    useEffect(() => {
293 7652cf88 Lukáš Vlček
        refreshAnnotation();
294 7595035c Lukáš Vlček
    }, [props.annotationId]);
295 c057279b Lukáš Vlček
296
    return (
297
        <AnnotationContext.Provider
298
            value={{
299
                tags,
300 dee53692 Jaroslav Hrubý
                submitting,
301 c057279b Lukáš Vlček
                setTags,
302
                addOccurrence,
303
                changeVisibility,
304
                deleteOccurrence,
305
                changeLength,
306
                changePosition,
307 7652cf88 Lukáš Vlček
                refreshAnnotation,
308
                annotation,
309 9a41c02f Dominik Poch
                mappedTags,
310 4bc99591 Lukáš Vlček
                markSelectedText,
311 c057279b Lukáš Vlček
            }}
312
        >
313
            {props.children}
314
        </AnnotationContext.Provider>
315
    );
316
};
317
318
export default AnnotationProvider;