Projekt

Obecné

Profil

Stáhnout (8.33 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { Col, Container, Row, Stack } from 'react-bootstrap';
2
import { Tag } from '../types/tag';
3
import { ChangeEvent, useContext, useState } from 'react';
4
import 'antd/dist/antd.css';
5
import { Button, Input, Select } from 'antd';
6
import {
7
    PlusOutlined,
8
    DownOutlined,
9
    DeleteOutlined,
10
    TagOutlined,
11
} from '@ant-design/icons';
12
import { AnnotationContext } from '../../contexts/AnnotationContext';
13
import { ETagSentiment, TagInstanceInfo } from '../../api';
14

    
15
const { Option } = Select;
16

    
17
/**
18
 * Creates a single item in an annotation panel.
19
 * @param props Properties should contain a tag that will be shown in this annotation.
20
 * @returns The item that represents an annotation.
21
 */
22
export function AnnotationItem(props: { tag: Tag }) {
23
    const { markSelectedText } = useContext(AnnotationContext);
24

    
25
    /**
26
     * Should properties of this annotation be visible?
27
     */
28
    const [visibleProperties, setVisibleProperties] = useState(false);
29

    
30
    /**
31
     * Context that manages annotations.
32
     */
33
    const {
34
        addOccurrence,
35
        deleteOccurrence,
36
        changePosition,
37
        changeNote,
38
        changeSentiment,
39
        changeLength,
40
    } = useContext(AnnotationContext);
41

    
42
    /**
43
     * Adds new occurrence of this annotation to the context.
44
     */
45
    const onAddOccurrence = () => {
46
        addOccurrence(props.tag);
47
    };
48

    
49
    /**
50
     * Removes an occurrence of this annotation from the context.
51
     * @param occurrence The occurrence that should be removed.
52
     */
53
    const onDeleteOccurrence = (occurrence: TagInstanceInfo) => (e: any) => {
54
        deleteOccurrence(occurrence);
55
    };
56

    
57
    /**
58
     * Changes a position of an occurrence of this annotation in the context.
59
     * @param occurrence The occurrence that should be changed.
60
     */
61
    const onChangePosition =
62
        (occurrence: TagInstanceInfo) => (e: ChangeEvent<HTMLInputElement>) => {
63
            changePosition(occurrence, Number(e.currentTarget.value));
64
        };
65

    
66
    /**
67
     * Changes a length of an occurrence of this annotation in the context.
68
     * @param occurrence The occurrence that should be changed.
69
     */
70
    const onChangeLength =
71
        (occurrence: TagInstanceInfo) => (e: ChangeEvent<HTMLInputElement>) => {
72
            changeLength(occurrence, Number(e.currentTarget.value));
73
        };
74

    
75
    const onChangeSentiment = (occurrence: TagInstanceInfo) => (val: ETagSentiment) => {
76
        changeSentiment(occurrence, val);
77
    };
78

    
79
    const onChangeNote =
80
        (occurrence: TagInstanceInfo) => (e: ChangeEvent<HTMLTextAreaElement>) => {
81
            changeNote(occurrence, e.currentTarget.value);
82
        };
83

    
84
    /**
85
     * Changes visibility of properties of this annotation.
86
     */
87
    const changePropertiesVisibility = () => {
88
        setVisibleProperties(!visibleProperties);
89
    };
90

    
91
    return (
92
        <Container>
93
            <Row className="border rounded">
94
                <Col sm="auto" className="d-flex align-items-center">
95
                    <TagOutlined />
96
                </Col>
97
                <Col className="d-flex align-items-center">
98
                    {props.tag.tagName}
99
                    {props.tag.subtagName ? ' (' + props.tag.subtagName + ')' : ''}
100
                </Col>
101
                <Col sm="auto">
102
                    <Button
103
                        type="text"
104
                        shape="circle"
105
                        icon={<PlusOutlined />}
106
                        onClick={onAddOccurrence}
107
                    />
108
                    <Button
109
                        type="text"
110
                        shape="circle"
111
                        icon={<DownOutlined />}
112
                        onClick={changePropertiesVisibility}
113
                    />
114
                </Col>
115
            </Row>
116
            {visibleProperties && (
117
                <Stack gap={1} className="mb-2">
118
                    <div>Kategorie: {props.tag.category}</div>
119
                    <div>Výskyty:</div>
120
                    {props.tag.occurrences.map((occurrence, index) => {
121
                        return (
122
                            <Container key={index} className="shadow-sm pb-1 pt-1">
123
                                <Row>
124
                                    <Col>
125
                                        <Row>
126
                                            <Col>Pozice: {occurrence.position}</Col>
127
                                        </Row>
128
                                        <Row>
129
                                            <Col>Délka: {occurrence.length}</Col>
130
                                        </Row>
131
                                        <Row>
132
                                            <Col
133
                                                className="d-flex align-items-center"
134
                                                sm="4"
135
                                            >
136
                                                Poznámka:
137
                                            </Col>
138
                                            <Col>
139
                                                <Input.TextArea
140
                                                    defaultValue={occurrence.note ?? ''}
141
                                                    onBlur={onChangeNote(occurrence)}
142
                                                />
143
                                            </Col>
144
                                        </Row>
145
                                        {occurrence.sentiment && (
146
                                            <Row>
147
                                                <Col
148
                                                    className="d-flex align-items-center"
149
                                                    sm="4"
150
                                                >
151
                                                    Sentiment:
152
                                                </Col>
153
                                                <Col>
154
                                                    <Select
155
                                                        defaultValue={
156
                                                            occurrence.sentiment
157
                                                        }
158
                                                        style={{ width: '100%' }}
159
                                                        onChange={onChangeSentiment(
160
                                                            occurrence
161
                                                        )}
162
                                                    >
163
                                                        <Option
164
                                                            value={ETagSentiment.Positive}
165
                                                        >
166
                                                            Pozitivní
167
                                                        </Option>
168
                                                        <Option
169
                                                            value={ETagSentiment.Neutral}
170
                                                        >
171
                                                            Neutrální
172
                                                        </Option>
173
                                                        <Option
174
                                                            value={ETagSentiment.Negative}
175
                                                        >
176
                                                            Negativní
177
                                                        </Option>
178
                                                    </Select>
179
                                                </Col>
180
                                            </Row>
181
                                        )}
182
                                    </Col>
183
                                    <Col sm="auto" className="d-flex align-items-center">
184
                                        <Button
185
                                            icon={<DeleteOutlined />}
186
                                            onClick={onDeleteOccurrence(occurrence)}
187
                                            danger
188
                                        ></Button>
189
                                    </Col>
190
                                </Row>
191
                            </Container>
192
                        );
193
                    })}
194
                </Stack>
195
            )}
196
        </Container>
197
    );
198
}
(1-1/7)