Projekt

Obecné

Profil

Stáhnout (8.32 KB) Statistiky
| Větev: | Tag: | Revize:
1
import React, { createContext, useEffect, useState } from 'react';
2
import { AnnotationInfo, ETagType, SubTagInfo, TagInfo, TagInstanceInfo } from '../api';
3
import { Tag } from '../components/types/tag';
4
import { annotationController } from '../controllers';
5
import { GetSelectionInfo } from '../utils/selectionUtils';
6

    
7
/**
8
 * Interface of an annotation context provider.
9
 */
10
interface IAnnotationContextProvider {
11
    /**
12
     * Tags managed by the context.
13
     */
14
    tags: TagInstanceInfo[] | null;
15

    
16
    /**
17
     * Sets new tags.
18
     * @param newTags An array of new tags.
19
     */
20
    setTags: (newTags: TagInstanceInfo[] | null) => void;
21

    
22
    /**
23
     * Adds occurrence to an annotation.
24
     * @param tag Tag whose occurrence should be added.
25
     */
26
    addOccurrence: (tag: Tag) => void;
27

    
28
    /**
29
     * Changes visibility of an annotation.
30
     * @param tag Tag whose visibility should be changed.
31
     */
32
    changeVisibility: (tag: Tag) => void;
33

    
34
    /**
35
     * Deletes an occurrence of an annotation.
36
     * @param occurrence Occurrence that should be deleted.
37
     */
38
    deleteOccurrence: (occurrence: TagInstanceInfo) => void;
39

    
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
    changePosition: (occurrence: TagInstanceInfo, newValue: number) => void;
46

    
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
    changeLength: (occurrence: TagInstanceInfo, newValue: number) => void;
53

    
54
    annotation: AnnotationInfo | null;
55
    mappedTags: Tag[] | null;
56
    refreshAnnotation: () => void;
57

    
58
    markSelectedText: (
59
        tagId: string,
60
        subtagId: string | null,
61
        instanceID: string | null
62
    ) => void;
63
}
64

    
65
/**
66
 * The annotation context that manages active annotations.
67
 */
68
export const AnnotationContext = createContext<IAnnotationContextProvider>({
69
    /**
70
     * Default tags.
71
     */
72
    tags: null,
73

    
74
    /**
75
     * Default implementation of setTags method.
76
     * @param v Array of new tags.
77
     */
78
    setTags: (v) => {
79
        return;
80
    },
81

    
82
    /**
83
     * Default implementation of addOccurrence method.
84
     * @param tag The tag with new occurrence.
85
     */
86
    addOccurrence: (tag: Tag) => {
87
        return;
88
    },
89

    
90
    /**
91
     * Default implementation of changeVisibility method.
92
     * @param tag The tag whose visibility should be changed.
93
     */
94
    changeVisibility: (tag: Tag) => {
95
        return;
96
    },
97

    
98
    /**
99
     * Default implementation of deleteOccurrence method.
100
     * @param occurrence Occurrence that should be deleted.
101
     */
102
    deleteOccurrence: (occurrence: TagInstanceInfo) => {
103
        return;
104
    },
105

    
106
    /**
107
     * Default implementation of changePosition method.
108
     * @param occurrence Occurrence whose position should be changed.
109
     * @param newValue A new position.
110
     */
111
    changePosition: (occurrence: TagInstanceInfo, newValue: number) => {
112
        return;
113
    },
114

    
115
    /**
116
     * Default implementation of changeLength method.
117
     * @param occurrence Occurrence whose length should be changed.
118
     * @param newValue A new length.
119
     */
120
    changeLength: (occurrence: TagInstanceInfo, newValue: number) => {
121
        return;
122
    },
123

    
124
    annotation: null,
125
    mappedTags: null,
126
    refreshAnnotation: () => {
127
        return;
128
    },
129

    
130
    markSelectedText: () => {
131
        return;
132
    },
133
});
134

    
135
/**
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
const AnnotationProvider = (props: {
141
    children: React.ReactNode;
142
    annotationId: string;
143
}) => {
144
    const [annotation, setAnnotation] = useState<AnnotationInfo | null>(null);
145

    
146
    /**
147
     * Tags managed by the context.
148
     */
149
    const [tags, setTags] = useState<TagInstanceInfo[] | null>(null);
150

    
151
    const [mappedTags, setMappedTags] = useState<Tag[] | null>(null);
152

    
153
    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
        console.log('res');
185
        console.log(res);
186

    
187
        await refreshAnnotation();
188
    }
189

    
190
    /**
191
     * Default implementation of addOccurrence method.
192
     * @param tag The tag with new occurrence.
193
     */
194
    const addOccurrence = async (tag: Tag) => {
195
        await markSelectedText(tag.tagId, tag.subtagId ?? null, tag.instanceId);
196
    };
197

    
198
    /**
199
     * Changes visibility of an annotation.
200
     * @param tag Tag whose visibility should be changed.
201
     */
202
    const changeVisibility = (tag: Tag) => {
203
        //TODO: Implement method (should use objects from server API)
204
    };
205

    
206
    /**
207
     * Deletes an occurrence of an annotation.
208
     * @param occurrence Occurrence that should be deleted.
209
     */
210
    const deleteOccurrence = (occurrence: TagInstanceInfo) => {
211
        //TODO: Implement method (should use objects from server API)
212
    };
213

    
214
    /**
215
     * Changes a position of an occurrence of an annotation.
216
     * @param occurrence Occurrence whose position should be changed.
217
     * @param newValue New value of the position.
218
     */
219
    const changePosition = (occurrence: TagInstanceInfo, newValue: number) => {
220
        //TODO: Implement method (should use objects from server API)
221
    };
222

    
223
    /**
224
     * Changes a length of an occurrence of an annotation.
225
     * @param occurrence Occurrence whose length should be changed.
226
     * @param newValue New value of the length.
227
     */
228
    const changeLength = (occurrence: TagInstanceInfo, newValue: number) => {
229
        //TODO: Implement method (should use objects from server API)
230
    };
231

    
232
    const remapAnnotations = (data: AnnotationInfo) => {
233
        let map = new Map<string, Tag>();
234
        data.tagInstances?.forEach((tagInstance) => {
235
            if (map.has(tagInstance.instance ?? '-')) {
236
                let tag = map.get(tagInstance.instance ?? '-');
237
                tag!.occurrences = [...tag!.occurrences, tagInstance];
238
            } else {
239
                map.set(tagInstance.instance ?? '-', {
240
                    tagName: tagInstance.tagName ?? '',
241
                    subtagName: tagInstance.subTagName ?? null,
242
                    category: tagInstance.tagCategoryName ?? '',
243
                    visible: true,
244
                    occurrences: [tagInstance],
245
                    tagId: tagInstance.tagId ?? '',
246
                    instanceId: tagInstance.instance ?? '',
247
                    subtagId: tagInstance.subTagId ?? null,
248
                });
249
            }
250
        });
251

    
252
        setMappedTags(Array.from(map.values()));
253
    };
254

    
255
    async function refreshAnnotation() {
256
        const data = await annotationController.annotationAnnotationIdGet(
257
            props.annotationId
258
        );
259

    
260
        remapAnnotations(data.data);
261
        setAnnotation(data.data ?? null);
262
    }
263

    
264
    /**
265
     * Initializes the context.
266
     */
267
    useEffect(() => {
268
        refreshAnnotation();
269
    }, [props.annotationId]);
270

    
271
    return (
272
        <AnnotationContext.Provider
273
            value={{
274
                tags,
275
                setTags,
276
                addOccurrence,
277
                changeVisibility,
278
                deleteOccurrence,
279
                changeLength,
280
                changePosition,
281
                refreshAnnotation,
282
                annotation,
283
                mappedTags,
284
                markSelectedText,
285
            }}
286
        >
287
            {props.children}
288
        </AnnotationContext.Provider>
289
    );
290
};
291

    
292
export default AnnotationProvider;
(1-1/3)