Projekt

Obecné

Profil

Stáhnout (8.01 KB) Statistiky
| Větev: | Tag: | Revize:
1
import { Col, Container, Row, Stack } from 'react-bootstrap';
2
import { Tag } from '../types/tag';
3
import { useContext, useState } from 'react';
4
import 'antd/dist/antd.css';
5
import { Button, Select } from 'antd';
6
import { DownOutlined, PlusOutlined, TagOutlined } from '@ant-design/icons';
7
import { AnnotationContext } from '../../contexts/AnnotationContext';
8
import { AnnotationOccurrenceItem } from './AnnotationOccurrenceItem';
9
import { COLOR_ALL_OCCURRENCES_ACCEPTED, COLOR_HIGHLIGHTED_TAG } from '../../constants';
10
import { ABadge, BadgeStyle } from '../common/ABadge';
11
import { getNameTruncated } from '../../utils/strings';
12
import { ShowConfirm } from '../../utils/alerts';
13

    
14
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
15
import { faAngleDown, faAngleUp, faTag } from '@fortawesome/free-solid-svg-icons';
16
import { faCircleQuestion } from '@fortawesome/free-regular-svg-icons';
17
import styles from '/styles/Icon.module.scss';
18

    
19
const { Option } = Select;
20

    
21
/**
22
 * Creates a single item in an annotation panel.
23
 * @param props Properties should contain a tag that will be shown in this annotation.
24
 * @returns The item that represents an annotation.
25
 */
26
export function AnnotationItem(props: { tag: Tag }) {
27
    /**
28
     * Should properties of this annotation be visible?
29
     */
30
    const [detailsVisible, setDetailsVisible] = useState(false);
31

    
32
    /**
33
     * Context that manages annotations.
34
     */
35
    const {
36
        addOccurrence,
37
        selectedInstanceId,
38
        setSelectedOccurrenceId,
39
        setSelectedInstanceId,
40
        isFinal,
41
        makeOccurrenceFinal,
42
    } = useContext(AnnotationContext);
43

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

    
51
    /**
52
     * Changes visibility of properties of this annotation.
53
     */
54
    const changePropertiesVisibility = () => {
55
        setDetailsVisible(!detailsVisible);
56
    };
57

    
58
    function isAllAccepted() {
59
        return props.tag.occurrences.filter((o) => !o.isFinal).length === 0;
60
    }
61
    function getBackgroundColor(): string {
62
        if (selectedInstanceId === props.tag.instanceId) {
63
            // highlighted tag
64
            return COLOR_HIGHLIGHTED_TAG;
65
        }
66

    
67
        if (isFinal) {
68
            if (isAllAccepted()) {
69
                return COLOR_ALL_OCCURRENCES_ACCEPTED;
70
            } else {
71
                return '#E4C8CC';
72
            }
73
        }
74

    
75
        return 'white';
76
    }
77
    return (
78
        <Container
79
            className="border rounded"
80
            style={{
81
                backgroundColor: getBackgroundColor(),
82
            }}
83
        >
84
            <Row className="">
85
                <Col sm="auto" className="d-flex align-items-center">
86
                    <Button
87
                        icon={
88
                            <FontAwesomeIcon icon={faTag} className={styles.iconLeft} />
89
                        }
90
                        onClick={() => {
91
                            setSelectedInstanceId(props.tag.instanceId);
92
                            setSelectedOccurrenceId(null);
93
                        }}
94
                        style={{
95
                            border: 'none',
96
                            paddingLeft: 0,
97
                            backgroundColor: getBackgroundColor(),
98
                        }}
99
                        title={'Zvýraznit značky'}
100
                    />
101
                </Col>
102
                <Col className="d-flex align-items-center">
103
                    {props.tag.tagName}
104
                    {props.tag.subtagName ? ' (' + props.tag.subtagName + ')' : ''}
105
                </Col>
106
                <Col sm="auto">
107
                    {props.tag.occurrences.length > 1 && (
108
                        <ABadge style={BadgeStyle.GENERAL}>
109
                            {props.tag.occurrences.length}
110
                        </ABadge>
111
                    )}
112

    
113
                    <Button
114
                        type="text"
115
                        shape="circle"
116
                        icon={<PlusOutlined />}
117
                        onClick={onAddOccurrence}
118
                    />
119
                    <Button
120
                        type="text"
121
                        shape="circle"
122
                        icon={<DownOutlined />}
123
                        onClick={changePropertiesVisibility}
124
                    />
125
                </Col>
126
            </Row>
127
            {isFinal && !isAllAccepted() && (
128
                <>
129
                    <Row
130
                        style={{
131
                            backgroundColor: getBackgroundColor(),
132
                        }}
133
                    >
134
                        <Col sm="12" className="d-flex align-items-center">
135
                            {props.tag.occurrences.length === 1 && (
136
                                <div
137
                                    style={{
138
                                        display: 'flex',
139
                                        flexDirection: 'row',
140
                                        width: '100%',
141
                                        justifyContent: 'space-between',
142
                                    }}
143
                                >
144
                                    <div style={{ width: '60%' }}>
145
                                        Anotovali:{' '}
146
                                        {props.tag.occurrences[0].users?.map((u) => (
147
                                            <span
148
                                                title={
149
                                                    u.name +
150
                                                    ' ' +
151
                                                    u.surname +
152
                                                    ' (' +
153
                                                    u.username +
154
                                                    ')'
155
                                                }
156
                                                key={
157
                                                    props.tag.occurrences[0].occurenceId +
158
                                                    '.' +
159
                                                    u.id
160
                                                }
161
                                                style={{ marginRight: 10 }}
162
                                            >
163
                                                {getNameTruncated(u)}
164
                                            </span>
165
                                        ))}
166
                                    </div>
167
                                    <div>
168
                                        <Button
169
                                            onClick={() => {
170
                                                ShowConfirm(() => {
171
                                                    makeOccurrenceFinal(
172
                                                        props.tag.occurrences[0]
173
                                                    );
174
                                                }, 'označit toto řešení jako správné');
175
                                            }}
176
                                        >
177
                                            Přijmout toto řešení
178
                                        </Button>
179
                                    </div>
180
                                </div>
181
                            )}
182
                        </Col>
183
                    </Row>
184
                </>
185
            )}
186

    
187
            {detailsVisible && (
188
                <Stack gap={1} className="mb-2">
189
                    <div>Kategorie: {props.tag.category}</div>
190
                    <div>Výskyty (části):</div>
191
                    {props.tag.occurrences.map((occurrence, index) => {
192
                        return (
193
                            <AnnotationOccurrenceItem
194
                                occurrence={occurrence}
195
                                tag={props.tag}
196
                                key={'occ-' + occurrence.occurenceId}
197
                            />
198
                        );
199
                    })}
200
                </Stack>
201
            )}
202
        </Container>
203
    );
204
}
(1-1/8)