Projekt

Obecné

Profil

Stáhnout (7.94 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { Col, Container, Row } from 'react-bootstrap';
2
import { Tag } from '../types/tag';
3
import { ChangeEvent, useContext } from 'react';
4
import 'antd/dist/antd.css';
5
import { Button, Input, Select } from 'antd';
6
import {
7
    DeleteOutlined,
8
    DislikeOutlined,
9
    EyeOutlined,
10
    LikeOutlined,
11
} from '@ant-design/icons';
12
import { AnnotationContext } from '../../contexts/AnnotationContext';
13
import { ETagSentiment, TagInstanceInfo } from '../../api';
14
import { getNameTruncated, getTextMaxLength } from '../../utils/strings';
15
import {
16
    COLOR_ALL_OCCURRENCES_ACCEPTED,
17
    COLOR_HIGHLIGHTED_OCCURRENCE,
18
    COLOR_HIGHLIGHTED_TAG,
19
    COLOR_OCCURRENCE_ACCEPTED,
20
} from '../../constants';
21
import { ShowConfirm } from '../../utils/alerts';
22

    
23
const { Option } = Select;
24

    
25
/**
26
 * Creates a single item in an annotation panel.
27
 * @param props Properties should contain a tag that will be shown in this annotation.
28
 * @returns The item that represents an annotation.
29
 */
30
export function AnnotationOccurrenceItem(props: {
31
    tag: Tag;
32
    occurrence: TagInstanceInfo;
33
}) {
34
    /**
35
     * Context that manages annotations.
36
     */
37
    const {
38
        deleteOccurrence,
39
        changeNote,
40
        changeSentiment,
41
        selectedOccurrenceId,
42
        setSelectedOccurrenceId,
43
        setSelectedInstanceId,
44
        isFinal,
45
        makeOccurrenceFinal,
46
    } = useContext(AnnotationContext);
47

    
48
    const onChangeSentiment = (occurrence: TagInstanceInfo) => (val: ETagSentiment) => {
49
        changeSentiment(occurrence, val);
50
    };
51

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

    
60
    const onChangeNote =
61
        (occurrence: TagInstanceInfo) => (e: ChangeEvent<HTMLTextAreaElement>) => {
62
            changeNote(occurrence, e.currentTarget.value);
63
        };
64

    
65
    function getBackgroundColor(): string {
66
        if (selectedOccurrenceId === props.occurrence.occurenceId) {
67
            // highlighted occurrence
68
            return COLOR_HIGHLIGHTED_OCCURRENCE;
69
        }
70

    
71
        if (isFinal) {
72
            if (props.occurrence.isFinal) {
73
                return COLOR_OCCURRENCE_ACCEPTED;
74
            }
75
        }
76

    
77
        return 'white';
78
    }
79

    
80
    return (
81
        <Container
82
            className="shadow-sm"
83
            style={{
84
                backgroundColor: getBackgroundColor(),
85
            }}
86
        >
87
            <Row className="mb-1 mt-1">
88
                <Col>
89
                    <Row>
90
                        <Col>Pozice: {props.occurrence.position}</Col>
91
                        <Col>Délka: {props.occurrence.length}</Col>
92
                    </Row>
93
                    <Row>
94
                        <i title={props.occurrence.selectedText ?? ''}>
95
                            {getTextMaxLength(props.occurrence.selectedText ?? '', 35)}
96
                        </i>
97
                    </Row>
98
                    <Row>
99
                        <Col className="d-flex align-items-center" sm="4">
100
                            Poznámka:
101
                        </Col>
102
                        <Col>
103
                            <Input.TextArea
104
                                defaultValue={props.occurrence.note ?? ''}
105
                                onBlur={onChangeNote(props.occurrence)}
106
                                rows={1}
107
                            />
108
                        </Col>
109
                    </Row>
110
                    {props.occurrence.sentiment && (
111
                        <Row>
112
                            <Col className="d-flex align-items-center" sm="4">
113
                                Sentiment:
114
                            </Col>
115
                            <Col>
116
                                <Select
117
                                    defaultValue={props.occurrence.sentiment}
118
                                    style={{ width: '100%' }}
119
                                    onChange={onChangeSentiment(props.occurrence)}
120
                                >
121
                                    <Option value={ETagSentiment.Positive}>
122
                                        <span style={{ color: 'green' }}>Pozitivní</span>
123
                                    </Option>
124
                                    <Option value={ETagSentiment.Neutral}>
125
                                        Neutrální
126
                                    </Option>
127
                                    <Option value={ETagSentiment.Negative}>
128
                                        <span
129
                                            style={{
130
                                                color: '#ff4d4f',
131
                                            }}
132
                                        >
133
                                            Negativní
134
                                        </span>
135
                                    </Option>
136
                                </Select>
137
                            </Col>
138
                        </Row>
139
                    )}
140
                </Col>
141
                <Col
142
                    sm="auto"
143
                    className="d-flex align-items-center flex-column justify-content-sm-evenly"
144
                >
145
                    <Button
146
                        icon={<EyeOutlined />}
147
                        onClick={() => {
148
                            setSelectedOccurrenceId(props.occurrence.occurenceId ?? null);
149
                            setSelectedInstanceId(props.tag.instanceId);
150
                        }}
151
                        title={'Zvýraznit výskyt'}
152
                    />
153
                    <Button
154
                        icon={<DeleteOutlined />}
155
                        onClick={onDeleteOccurrence(props.occurrence)}
156
                        danger
157
                        className={'mt-1'}
158
                    />
159
                    {isFinal && (
160
                        <Button
161
                            icon={
162
                                props.occurrence.isFinal ? (
163
                                    <DislikeOutlined />
164
                                ) : (
165
                                    <LikeOutlined />
166
                                )
167
                            }
168
                            title={
169
                                props.occurrence.isFinal
170
                                    ? 'ZRUŠIT označení správného řešení'
171
                                    : 'Označit jako správné řešení'
172
                            }
173
                            onClick={() => {
174
                                ShowConfirm(
175
                                    () => {
176
                                        makeOccurrenceFinal(
177
                                            props.occurrence,
178
                                            !props.occurrence.isFinal
179
                                        );
180
                                    },
181
                                    props.occurrence.isFinal
182
                                        ? 'ZRUŠIT označené správného řešení'
183
                                        : 'označit toto řešení jako správné'
184
                                );
185
                            }}
186
                            className={'mt-1'}
187
                        />
188
                    )}
189
                </Col>
190
            </Row>
191
            {isFinal && (
192
                <Row className="mb-1 mt-1">
193
                    <Col>
194
                        Označili:{' '}
195
                        {props.occurrence.users?.map((u) => (
196
                            <span
197
                                title={u.name + ' ' + u.surname + ' (' + u.username + ')'}
198
                                key={props.occurrence.occurenceId + '.' + u.id}
199
                                style={{ marginRight: 10 }}
200
                            >
201
                                {getNameTruncated(u)}
202
                            </span>
203
                        ))}
204
                    </Col>
205
                </Row>
206
            )}
207
        </Container>
208
    );
209
}
(2-2/8)