Projekt

Obecné

Profil

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