Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 6973d036

Přidáno uživatelem Lukáš Vlček před asi 2 roky(ů)

Selected tags highlighting

On click in the middle panel or on click on highlight buttons in the right panel

Zobrazit rozdíly:

webapp/components/annotation/AnnotationItem.tsx
8 8
    DownOutlined,
9 9
    DeleteOutlined,
10 10
    TagOutlined,
11
    EyeOutlined,
11 12
} from '@ant-design/icons';
12 13
import { AnnotationContext } from '../../contexts/AnnotationContext';
13 14
import { ETagSentiment, TagInstanceInfo } from '../../api';
......
20 21
 * @returns The item that represents an annotation.
21 22
 */
22 23
export function AnnotationItem(props: { tag: Tag }) {
23
    const { markSelectedText } = useContext(AnnotationContext);
24

  
25 24
    /**
26 25
     * Should properties of this annotation be visible?
27 26
     */
......
37 36
        changeNote,
38 37
        changeSentiment,
39 38
        changeLength,
39
        selectedOccurrenceId,
40
        selectedInstanceId,
41
        setSelectedOccurrenceId,
42
        setSelectedInstanceId,
40 43
    } = useContext(AnnotationContext);
41 44

  
42 45
    /**
......
90 93

  
91 94
    return (
92 95
        <Container>
93
            <Row className="border rounded">
96
            <Row
97
                className="border rounded"
98
                style={{
99
                    backgroundColor:
100
                        selectedInstanceId === props.tag.instanceId ? '#FCF3CF' : 'white',
101
                }}
102
            >
94 103
                <Col sm="auto" className="d-flex align-items-center">
95
                    <TagOutlined />
104
                    <Button
105
                        icon={<TagOutlined style={{ marginLeft: 0 }} />}
106
                        onClick={() => {
107
                            setSelectedInstanceId(props.tag.instanceId);
108
                            setSelectedOccurrenceId(null);
109
                        }}
110
                        style={{
111
                            border: 'none',
112
                            paddingLeft: 0,
113
                            backgroundColor:
114
                                selectedInstanceId === props.tag.instanceId
115
                                    ? '#FCF3CF'
116
                                    : 'white',
117
                        }}
118
                        title={'Zvýraznit značky'}
119
                    />
96 120
                </Col>
97 121
                <Col className="d-flex align-items-center">
98 122
                    {props.tag.tagName}
......
119 143
                    <div>Výskyty:</div>
120 144
                    {props.tag.occurrences.map((occurrence, index) => {
121 145
                        return (
122
                            <Container key={index} className="shadow-sm pb-1 pt-1">
123
                                <Row>
146
                            <Container
147
                                key={index}
148
                                className="shadow-sm"
149
                                style={{
150
                                    backgroundColor:
151
                                        selectedOccurrenceId === occurrence.occurenceId
152
                                            ? '#D8E1E9'
153
                                            : 'white',
154
                                }}
155
                            >
156
                                <Row className="mb-1 mt-1">
124 157
                                    <Col>
125 158
                                        <Row>
126 159
                                            <Col>Pozice: {occurrence.position}</Col>
......
180 213
                                            </Row>
181 214
                                        )}
182 215
                                    </Col>
183
                                    <Col sm="auto" className="d-flex align-items-center">
216
                                    <Col
217
                                        sm="auto"
218
                                        className="d-flex align-items-center flex-column justify-content-sm-evenly"
219
                                    >
220
                                        <Button
221
                                            icon={<EyeOutlined />}
222
                                            onClick={() => {
223
                                                setSelectedOccurrenceId(
224
                                                    occurrence.occurenceId ?? null
225
                                                );
226
                                                setSelectedInstanceId(
227
                                                    props.tag.instanceId
228
                                                );
229
                                            }}
230
                                            title={'Zvýraznit výskyt'}
231
                                        />
184 232
                                        <Button
185 233
                                            icon={<DeleteOutlined />}
186 234
                                            onClick={onDeleteOccurrence(occurrence)}
187 235
                                            danger
188
                                        ></Button>
236
                                        />
189 237
                                    </Col>
190 238
                                </Row>
191 239
                            </Container>
webapp/components/annotation/DocumentAnnotationView.tsx
4 4
 */
5 5
import { useContext } from 'react';
6 6
import { AnnotationContext } from '../../contexts/AnnotationContext';
7
import { Button } from 'antd';
8
import { DOCUMENT_INSTANCE_ID_ATTRIBUTE_NAME } from '../../constants';
7
import parse from 'html-react-parser';
8
import {
9
    DOCUMENT_INSTANCE_ID_ATTRIBUTE_NAME,
10
    DOCUMENT_OCCURRENCE_ID_ATTRIBUTE_NAME,
11
    DOCUMENT_TAG_ID_ATTRIBUTE_NAME,
12
} from '../../constants';
9 13

  
10 14
export function DocumentAnnotationView() {
11
    const { annotation } = useContext(AnnotationContext);
15
    const {
16
        annotation,
17
        setSelectedInstanceId,
18
        setSelectedOccurrenceId,
19
        selectedInstanceId,
20
        selectedOccurrenceId,
21
    } = useContext(AnnotationContext);
12 22

  
13 23
    if (!annotation) {
14 24
        return <p>Probíhá načítání anotace ...</p>;
15 25
    }
16 26

  
17
    function getCss() {
27
    function detectSelectedElement(e: any) {
28
        if (!(e.target instanceof HTMLElement)) {
29
            return;
30
        }
31

  
32
        const target = e.target as HTMLElement;
33

  
34
        const id = target.getAttribute(DOCUMENT_TAG_ID_ATTRIBUTE_NAME);
35
        const idInstance = target.getAttribute(DOCUMENT_INSTANCE_ID_ATTRIBUTE_NAME);
36
        const idOccurrence = target.getAttribute(DOCUMENT_OCCURRENCE_ID_ATTRIBUTE_NAME);
37

  
38
        if (!id || !idInstance || !idOccurrence) {
39
            setSelectedInstanceId(null);
40
            setSelectedOccurrenceId(null);
41
            return;
42
        }
18 43

  
44
        setSelectedInstanceId(idInstance);
45
        setSelectedOccurrenceId(idOccurrence);
46
    }
47

  
48
    function getCss() {
19 49
        let css = 'span.annotation {border-bottom: 2px solid;}\n';
20 50
        css += 'span {line-height: 30px}\n';
21 51
        css +=
......
27 57
            css += `span[${DOCUMENT_INSTANCE_ID_ATTRIBUTE_NAME}="${info.instanceId}"] { border-color:${info.color}; padding-bottom: ${info.padding}px }\n`;
28 58
        }
29 59

  
60
        if (selectedInstanceId) {
61
            css += `span[${DOCUMENT_INSTANCE_ID_ATTRIBUTE_NAME}="${selectedInstanceId}"] { background-color: #FCF3CF;  }\n`;
62
        }
63
        if (selectedOccurrenceId) {
64
            css += `span[${DOCUMENT_OCCURRENCE_ID_ATTRIBUTE_NAME}="${selectedOccurrenceId}"] { border-bottom: 4px dotted;  }\n`;
65
        }
66

  
30 67
        return <style dangerouslySetInnerHTML={{ __html: css }}></style>;
31 68
    }
32 69

  
33 70
    return (
34 71
        <div>
35 72
            {getCss()}
36
            <div
37
                dangerouslySetInnerHTML={{ __html: annotation.documentToRender ?? '' }}
38
            />
73
            <div onClick={detectSelectedElement}>
74
                {parse(annotation.documentToRender ?? '')}
75
            </div>
39 76
        </div>
40 77
    );
41 78
}
webapp/contexts/AnnotationContext.tsx
86 86
        subtagId: string | null,
87 87
        instanceID: string | null
88 88
    ) => void;
89

  
90
    selectedInstanceId: string | null;
91
    setSelectedInstanceId: (newId: string | null) => void;
92

  
93
    selectedOccurrenceId: string | null;
94
    setSelectedOccurrenceId: (newId: string | null) => void;
89 95
}
90 96

  
91 97
/**
......
178 184
    markSelectedText: () => {
179 185
        return;
180 186
    },
187

  
188
    selectedInstanceId: null,
189
    setSelectedInstanceId: (newId: string | null) => {
190
        return;
191
    },
192

  
193
    selectedOccurrenceId: null,
194
    setSelectedOccurrenceId: (newId: string | null) => {
195
        return;
196
    },
181 197
});
182 198

  
183 199
/**
......
197 213
    const [tags, setTags] = useState<TagInstanceInfo[] | null>(null);
198 214

  
199 215
    const [mappedTags, setMappedTags] = useState<Tag[] | null>(null);
216
    const [selectedInstanceId, setSelectedInstanceId] = useState<string | null>(null);
217
    const [selectedOccurrenceId, setSelectedOccurrenceId] = useState<string | null>(null);
200 218

  
201 219
    const [submitting, setSubmitting] = useState(false);
202 220

  
......
405 423
                annotation,
406 424
                mappedTags,
407 425
                markSelectedText,
426
                selectedInstanceId,
427
                setSelectedInstanceId,
428
                selectedOccurrenceId,
429
                setSelectedOccurrenceId,
408 430
            }}
409 431
        >
410 432
            {props.children}
webapp/package.json
18 18
    "antd": "^4.19.5",
19 19
    "axios": "^0.26.1",
20 20
    "bootstrap": "^5.1.3",
21
    "html-react-parser": "^1.4.12",
21 22
    "http-status-codes": "^2.2.0",
22 23
    "next": "12.1.0",
23 24
    "react": "17.0.2",
webapp/utils/selectionUtils.ts
1 1
import { AnnotationInfo } from '../api';
2
import { DOCUMENT_TAG_ID_ATTRIBUTE_NAME } from '../constants';
2 3

  
3 4
export interface SelectionInfo {
4 5
    startElementId: number;
......
9 10

  
10 11
    selectedText: string;
11 12
}
12
const idAttributeName = 'aswi-tag-id';
13 13

  
14 14
export function GetSelectionInfo(annotation: AnnotationInfo): SelectionInfo | null {
15 15
    const selection = window.getSelection();
......
60 60
    let startElement = startTag as Element;
61 61
    let endElement = endTag as Element;
62 62

  
63
    let startId: number = Number(startElement.getAttribute(idAttributeName)) ?? -1;
64
    let endId: number = Number(endElement.getAttribute(idAttributeName)) ?? -1;
63
    let startId: number =
64
        Number(startElement.getAttribute(DOCUMENT_TAG_ID_ATTRIBUTE_NAME)) ?? -1;
65
    let endId: number =
66
        Number(endElement.getAttribute(DOCUMENT_TAG_ID_ATTRIBUTE_NAME)) ?? -1;
65 67

  
66 68
    let startPosition =
67 69
        annotation.tagStartPositions[startId] +
webapp/yarn.lock
908 908
    "@babel/runtime" "^7.8.7"
909 909
    csstype "^3.0.2"
910 910

  
911
dom-serializer@^1.0.1:
912
  version "1.4.1"
913
  resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
914
  integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
915
  dependencies:
916
    domelementtype "^2.0.1"
917
    domhandler "^4.2.0"
918
    entities "^2.0.0"
919

  
920
domelementtype@^2.0.1, domelementtype@^2.2.0:
921
  version "2.3.0"
922
  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
923
  integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
924

  
925
domhandler@4.3.1, domhandler@^4.2.0, domhandler@^4.2.2:
926
  version "4.3.1"
927
  resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
928
  integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
929
  dependencies:
930
    domelementtype "^2.2.0"
931

  
932
domutils@^2.8.0:
933
  version "2.8.0"
934
  resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
935
  integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
936
  dependencies:
937
    dom-serializer "^1.0.1"
938
    domelementtype "^2.2.0"
939
    domhandler "^4.2.0"
940

  
911 941
dotenv-expand@^5.1.0:
912 942
  version "5.1.0"
913 943
  resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
......
935 965
  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
936 966
  integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
937 967

  
968
entities@^2.0.0:
969
  version "2.2.0"
970
  resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
971
  integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
972

  
973
entities@^3.0.1:
974
  version "3.0.1"
975
  resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
976
  integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
977

  
938 978
es-abstract@^1.19.1, es-abstract@^1.19.2:
939 979
  version "1.19.5"
940 980
  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.5.tgz#a2cb01eb87f724e815b278b0dd0d00f36ca9a7f1"
......
1454 1494
  dependencies:
1455 1495
    function-bind "^1.1.1"
1456 1496

  
1497
html-dom-parser@1.2.0:
1498
  version "1.2.0"
1499
  resolved "https://registry.yarnpkg.com/html-dom-parser/-/html-dom-parser-1.2.0.tgz#8f689b835982ffbf245eda99730e92b8462c111e"
1500
  integrity sha512-2HIpFMvvffsXHFUFjso0M9LqM+1Lm22BF+Df2ba+7QHJXjk63pWChEnI6YG27eaWqUdfnh5/Vy+OXrNTtepRsg==
1501
  dependencies:
1502
    domhandler "4.3.1"
1503
    htmlparser2 "7.2.0"
1504

  
1505
html-react-parser@^1.4.12:
1506
  version "1.4.12"
1507
  resolved "https://registry.yarnpkg.com/html-react-parser/-/html-react-parser-1.4.12.tgz#5d4336e3853a75e4ac678c9815c15c58581bb30e"
1508
  integrity sha512-nqYQzr4uXh67G9ejAG7djupTHmQvSTgjY83zbXLRfKHJ0F06751jXx6WKSFARDdXxCngo2/7H4Rwtfeowql4gQ==
1509
  dependencies:
1510
    domhandler "4.3.1"
1511
    html-dom-parser "1.2.0"
1512
    react-property "2.0.0"
1513
    style-to-js "1.1.0"
1514

  
1515
htmlparser2@7.2.0:
1516
  version "7.2.0"
1517
  resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5"
1518
  integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==
1519
  dependencies:
1520
    domelementtype "^2.0.1"
1521
    domhandler "^4.2.2"
1522
    domutils "^2.8.0"
1523
    entities "^3.0.1"
1524

  
1457 1525
http-status-codes@^2.2.0:
1458 1526
  version "2.2.0"
1459 1527
  resolved "https://registry.yarnpkg.com/http-status-codes/-/http-status-codes-2.2.0.tgz#bb2efe63d941dfc2be18e15f703da525169622be"
......
1507 1575
  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
1508 1576
  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
1509 1577

  
1578
inline-style-parser@0.1.1:
1579
  version "0.1.1"
1580
  resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1"
1581
  integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==
1582

  
1510 1583
inquirer@8.2.0:
1511 1584
  version "8.2.0"
1512 1585
  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a"
......
2533 2606
  resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
2534 2607
  integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
2535 2608

  
2609
react-property@2.0.0:
2610
  version "2.0.0"
2611
  resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.0.tgz#2156ba9d85fa4741faf1918b38efc1eae3c6a136"
2612
  integrity sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==
2613

  
2536 2614
react-transition-group@^4.4.2:
2537 2615
  version "4.4.2"
2538 2616
  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
......
2853 2931
  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
2854 2932
  integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
2855 2933

  
2934
style-to-js@1.1.0:
2935
  version "1.1.0"
2936
  resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.0.tgz#631cbb20fce204019b3aa1fcb5b69d951ceac4ac"
2937
  integrity sha512-1OqefPDxGrlMwcbfpsTVRyzwdhr4W0uxYQzeA2F1CBc8WG04udg2+ybRnvh3XYL4TdHQrCahLtax2jc8xaE6rA==
2938
  dependencies:
2939
    style-to-object "0.3.0"
2940

  
2941
style-to-object@0.3.0:
2942
  version "0.3.0"
2943
  resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46"
2944
  integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==
2945
  dependencies:
2946
    inline-style-parser "0.1.1"
2947

  
2856 2948
styled-jsx@5.0.0:
2857 2949
  version "5.0.0"
2858 2950
  resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0.tgz#816b4b92e07b1786c6b7111821750e0ba4d26e77"

Také k dispozici: Unified diff