Projekt

Obecné

Profil

Stáhnout (7.98 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 { faTag } from '@fortawesome/free-solid-svg-icons';
16
import styles from '/styles/Icon.module.scss';
17

    
18
const { Option } = Select;
19

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

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

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

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

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

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

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

    
112
                    <Button
113
                        type="text"
114
                        shape="circle"
115
                        icon={<PlusOutlined />}
116
                        onClick={onAddOccurrence}
117
                    />
118
                    <Button
119
                        type="text"
120
                        shape="circle"
121
                        icon={<DownOutlined />}
122
                        onClick={changePropertiesVisibility}
123
                    />
124
                </Col>
125
            </Row>
126
            {isFinal && !isAllAccepted() && (
127
                <>
128
                    <Row
129
                        style={{
130
                            backgroundColor: getBackgroundColor(),
131
                        }}
132
                    >
133
                        <Col sm="12" className="d-flex align-items-center">
134
                            {props.tag.occurrences.length === 1 && (
135
                                <div
136
                                    style={{
137
                                        display: 'flex',
138
                                        flexDirection: 'row',
139
                                        width: '100%',
140
                                        justifyContent: 'space-between',
141
                                    }}
142
                                >
143
                                    <div style={{ width: '60%' }}>
144
                                        Anotovali:{' '}
145
                                        {props.tag.occurrences[0].users?.map((u) => (
146
                                            <span
147
                                                title={
148
                                                    u.name +
149
                                                    ' ' +
150
                                                    u.surname +
151
                                                    ' (' +
152
                                                    u.username +
153
                                                    ')'
154
                                                }
155
                                                key={
156
                                                    props.tag.occurrences[0].occurenceId +
157
                                                    '.' +
158
                                                    u.id
159
                                                }
160
                                                style={{ marginRight: 10 }}
161
                                            >
162
                                                {getNameTruncated(u)}
163
                                            </span>
164
                                        ))}
165
                                    </div>
166
                                    <div>
167
                                        <Button
168
                                            onClick={() => {
169
                                                ShowConfirm(() => {
170
                                                    makeOccurrenceFinal(
171
                                                        props.tag.occurrences[0],
172
                                                        true
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)