Projekt

Obecné

Profil

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