@truedat/dd 4.48.11 → 4.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +5 -5
- package/src/api/fragments.js +2 -2
- package/src/api/mutations.js +33 -11
- package/src/api/queries.js +37 -10
- package/src/api.js +0 -4
- package/src/components/DictionaryRoutes.js +4 -4
- package/src/components/StructureSummary.js +12 -22
- package/src/components/StructureTag.js +83 -54
- package/src/components/StructureTagForm.js +149 -89
- package/src/components/StructureTags.js +57 -27
- package/src/components/Tag.js +62 -0
- package/src/components/TagCards.js +85 -0
- package/src/components/TagCrumbs.js +25 -0
- package/src/components/TagForm.js +101 -0
- package/src/components/TagStructureButton.js +58 -0
- package/src/components/Tags.js +33 -0
- package/src/components/TagsRoutes.js +39 -0
- package/src/components/__tests__/StructureSummary.spec.js +0 -7
- package/src/components/__tests__/StructureTag.spec.js +79 -5
- package/src/components/__tests__/StructureTagForm.spec.js +99 -50
- package/src/components/__tests__/Tag.spec.js +11 -0
- package/src/components/__tests__/{StructureTagsCards.spec.js → TagCards.spec.js} +10 -10
- package/src/components/__tests__/TagCrumbs.spec.js +10 -0
- package/src/components/__tests__/TagForm.spec.js +72 -0
- package/src/components/__tests__/Tags.spec.js +10 -0
- package/src/components/__tests__/__snapshots__/StructureSummary.spec.js.snap +18 -42
- package/src/components/__tests__/__snapshots__/StructureTag.spec.js.snap +10 -30
- package/src/components/__tests__/__snapshots__/StructureTagForm.spec.js.snap +255 -51
- package/src/components/__tests__/__snapshots__/Tag.spec.js.snap +36 -0
- package/src/components/__tests__/__snapshots__/{StructureTagsCards.spec.js.snap → TagCards.spec.js.snap} +1 -1
- package/src/components/__tests__/__snapshots__/TagCrumbs.spec.js.snap +102 -0
- package/src/components/__tests__/__snapshots__/TagForm.spec.js.snap +70 -0
- package/src/components/__tests__/__snapshots__/{StructureTags.spec.js.snap → Tags.spec.js.snap} +1 -1
- package/src/messages/en.js +25 -30
- package/src/messages/es.js +25 -30
- package/src/reducers/__tests__/{editableStructureTags.spec.js → availableTags.spec.js} +7 -11
- package/src/reducers/__tests__/structureTagSaving.spec.js +36 -0
- package/src/reducers/__tests__/tagSaving.spec.js +32 -0
- package/src/reducers/{editableStructureTags.js → availableTags.js} +2 -2
- package/src/reducers/index.js +6 -12
- package/src/reducers/structureRedirect.js +7 -7
- package/src/reducers/structureTagSaving.js +12 -10
- package/src/reducers/tagSaving.js +18 -0
- package/src/routines.js +5 -6
- package/src/sagas/__tests__/createTag.spec.js +81 -0
- package/src/sagas/__tests__/deleteStructureTag.spec.js +11 -12
- package/src/sagas/__tests__/deleteTag.spec.js +76 -0
- package/src/sagas/__tests__/tagStructure.spec.js +86 -0
- package/src/sagas/__tests__/updateTag.spec.js +81 -0
- package/src/sagas/createTag.js +29 -0
- package/src/sagas/deleteStructureTag.js +12 -9
- package/src/sagas/deleteTag.js +34 -0
- package/src/sagas/index.js +15 -18
- package/src/sagas/tagStructure.js +37 -0
- package/src/sagas/updateTag.js +23 -0
- package/src/components/LinkStructureTagForm.js +0 -163
- package/src/components/LinkedStructureTag.js +0 -124
- package/src/components/StructureLinkTagButton.js +0 -47
- package/src/components/StructureTagsCards.js +0 -92
- package/src/components/StructureTagsCrumbs.js +0 -44
- package/src/components/StructureTagsRoutes.js +0 -45
- package/src/components/TagsHeader.js +0 -32
- package/src/components/__tests__/LinkStructureTagForm.spec.js +0 -184
- package/src/components/__tests__/LinkedStructureTag.spec.js +0 -133
- package/src/components/__tests__/StructureTags.spec.js +0 -14
- package/src/components/__tests__/StructureTagsCrumbs.spec.js +0 -13
- package/src/components/__tests__/__snapshots__/LinkStructureTagForm.spec.js.snap +0 -456
- package/src/components/__tests__/__snapshots__/LinkedStructureTag.spec.js.snap +0 -16
- package/src/components/__tests__/__snapshots__/StructureTagsCrumbs.spec.js.snap +0 -36
- package/src/reducers/__tests__/deletingStructureTags.spec.js +0 -30
- package/src/reducers/__tests__/linkedStructureTags.spec.js +0 -69
- package/src/reducers/__tests__/linkedStructureTagsLoading.spec.js +0 -32
- package/src/reducers/__tests__/linkingStructureTags.spec.js +0 -30
- package/src/reducers/__tests__/structureTagsSaving.spec.js +0 -40
- package/src/reducers/deletingStructureTags.js +0 -16
- package/src/reducers/linkedStructureTags.js +0 -28
- package/src/reducers/linkedStructureTagsLoading.js +0 -16
- package/src/reducers/linkingStructureTags.js +0 -16
- package/src/sagas/__tests__/createStructureTag.spec.js +0 -85
- package/src/sagas/__tests__/deleteLinkStructureTag.spec.js +0 -96
- package/src/sagas/__tests__/fetchLinksStructureTags.spec.js +0 -105
- package/src/sagas/__tests__/linkStructureTag.spec.js +0 -102
- package/src/sagas/__tests__/updateStructureTag.spec.js +0 -84
- package/src/sagas/createStructureTag.js +0 -29
- package/src/sagas/deleteLinkStructureTag.js +0 -29
- package/src/sagas/fetchLinksStructureTags.js +0 -31
- package/src/sagas/linkStructureTag.js +0 -30
- package/src/sagas/updateStructureTag.js +0 -23
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
|
-
import React, { useEffect, useState } from "react";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
5
|
-
import { Icon, Label, Popup, Header } from "semantic-ui-react";
|
|
6
|
-
import { connect } from "react-redux";
|
|
7
|
-
import LinkStructureTagForm from "./LinkStructureTagForm";
|
|
8
|
-
|
|
9
|
-
export const LinkedStructureTag = ({
|
|
10
|
-
id,
|
|
11
|
-
_embedded,
|
|
12
|
-
editable,
|
|
13
|
-
comment,
|
|
14
|
-
loading,
|
|
15
|
-
structureTags,
|
|
16
|
-
}) => {
|
|
17
|
-
const { formatMessage } = useIntl();
|
|
18
|
-
const name = _embedded.data_structure_tag.name;
|
|
19
|
-
const description = _embedded.data_structure_tag.description;
|
|
20
|
-
const tagId = _embedded.data_structure_tag.id;
|
|
21
|
-
const [openDescription, setOpenDescription] = useState(false);
|
|
22
|
-
const [openForm, setOpenForm] = useState(false);
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
if (loading) setOpenForm(false);
|
|
26
|
-
}, [loading, setOpenForm]);
|
|
27
|
-
|
|
28
|
-
const trigger = editable ? <Icon link name="edit" /> : null;
|
|
29
|
-
|
|
30
|
-
const renderTooltip = () => {
|
|
31
|
-
const descriptionTooltip = _.isEmpty(description) ? null : (
|
|
32
|
-
<Header as="h2" subheader={description} />
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
const commentTooltip = _.isEmpty(comment) ? null : (
|
|
36
|
-
<>
|
|
37
|
-
<Header
|
|
38
|
-
as="h5"
|
|
39
|
-
content={formatMessage({ id: "structure.tag.tooltip.commentTitle" })}
|
|
40
|
-
/>
|
|
41
|
-
<p>{comment}</p>
|
|
42
|
-
</>
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<>
|
|
47
|
-
{descriptionTooltip}
|
|
48
|
-
{commentTooltip}
|
|
49
|
-
</>
|
|
50
|
-
);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<Popup
|
|
55
|
-
basic
|
|
56
|
-
open={openDescription}
|
|
57
|
-
onOpen={() => {
|
|
58
|
-
const commentCondition = !_.isEmpty(comment);
|
|
59
|
-
const descriptionCondition = !_.isEmpty(description);
|
|
60
|
-
const openFormCondition = !openForm;
|
|
61
|
-
|
|
62
|
-
const openTooltipCondition =
|
|
63
|
-
(commentCondition || descriptionCondition) && openFormCondition;
|
|
64
|
-
|
|
65
|
-
if (openTooltipCondition) setOpenDescription(true);
|
|
66
|
-
}}
|
|
67
|
-
onClose={() => setOpenDescription(false)}
|
|
68
|
-
positionFixed
|
|
69
|
-
className="popup-tag"
|
|
70
|
-
trigger={
|
|
71
|
-
<Label tag style={{ marginLeft: "1.5em" }}>
|
|
72
|
-
{_.isEmpty(structureTags) ? null : (
|
|
73
|
-
<Popup
|
|
74
|
-
on="click"
|
|
75
|
-
basic
|
|
76
|
-
onOpen={() => {
|
|
77
|
-
setOpenForm(true);
|
|
78
|
-
setOpenDescription(false);
|
|
79
|
-
}}
|
|
80
|
-
onClose={() => setOpenForm(false)}
|
|
81
|
-
open={openForm}
|
|
82
|
-
flowing
|
|
83
|
-
content={
|
|
84
|
-
<LinkStructureTagForm
|
|
85
|
-
comment={comment}
|
|
86
|
-
linkId={id}
|
|
87
|
-
tagId={tagId}
|
|
88
|
-
/>
|
|
89
|
-
}
|
|
90
|
-
position="bottom center"
|
|
91
|
-
size="large"
|
|
92
|
-
positionFixed
|
|
93
|
-
trigger={trigger}
|
|
94
|
-
/>
|
|
95
|
-
)}
|
|
96
|
-
|
|
97
|
-
{name}
|
|
98
|
-
</Label>
|
|
99
|
-
}
|
|
100
|
-
>
|
|
101
|
-
{renderTooltip()}
|
|
102
|
-
</Popup>
|
|
103
|
-
);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
LinkedStructureTag.propTypes = {
|
|
107
|
-
_embedded: PropTypes.object,
|
|
108
|
-
comment: PropTypes.string,
|
|
109
|
-
editable: PropTypes.bool,
|
|
110
|
-
id: PropTypes.number,
|
|
111
|
-
loading: PropTypes.bool,
|
|
112
|
-
structureTags: PropTypes.array,
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const mapStateToProps = ({
|
|
116
|
-
editableStructureTags,
|
|
117
|
-
linkingStructureTags,
|
|
118
|
-
deletingStructureTags,
|
|
119
|
-
}) => ({
|
|
120
|
-
loading: linkingStructureTags || deletingStructureTags,
|
|
121
|
-
structureTags: editableStructureTags,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
export default connect(mapStateToProps)(LinkedStructureTag);
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
|
-
import React, { useState } from "react";
|
|
3
|
-
import { Button, Popup } from "semantic-ui-react";
|
|
4
|
-
import { useIntl } from "react-intl";
|
|
5
|
-
import { connect } from "react-redux";
|
|
6
|
-
import PropTypes from "prop-types";
|
|
7
|
-
import LinkStructureTagForm from "./LinkStructureTagForm";
|
|
8
|
-
|
|
9
|
-
export const StructureLinkTagButton = ({ structureTags }) => {
|
|
10
|
-
const { formatMessage } = useIntl();
|
|
11
|
-
const [open, setOpen] = useState(false);
|
|
12
|
-
|
|
13
|
-
return _.isEmpty(structureTags) ? null : (
|
|
14
|
-
<Popup
|
|
15
|
-
on="click"
|
|
16
|
-
basic
|
|
17
|
-
flowing
|
|
18
|
-
onOpen={() => setOpen(true)}
|
|
19
|
-
onClose={() => setOpen(false)}
|
|
20
|
-
open={open}
|
|
21
|
-
content={<LinkStructureTagForm structureTags={structureTags} />}
|
|
22
|
-
position="bottom center"
|
|
23
|
-
size="large"
|
|
24
|
-
positionFixed
|
|
25
|
-
trigger={
|
|
26
|
-
<Button
|
|
27
|
-
style={{ marginLeft: "0.5em" }}
|
|
28
|
-
icon="plus"
|
|
29
|
-
size="tiny"
|
|
30
|
-
circular
|
|
31
|
-
basic
|
|
32
|
-
content={formatMessage({ id: "structure.add.tag" })}
|
|
33
|
-
/>
|
|
34
|
-
}
|
|
35
|
-
/>
|
|
36
|
-
);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
StructureLinkTagButton.propTypes = {
|
|
40
|
-
structureTags: PropTypes.array,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const mapStateToProps = ({ editableStructureTags }) => ({
|
|
44
|
-
structureTags: editableStructureTags,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
export default connect(mapStateToProps)(StructureLinkTagButton);
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import { connect } from "react-redux";
|
|
5
|
-
import { Link } from "react-router-dom";
|
|
6
|
-
import { Button, Card, Message, Icon } from "semantic-ui-react";
|
|
7
|
-
import { FormattedMessage } from "react-intl";
|
|
8
|
-
import { useQuery } from "@apollo/client";
|
|
9
|
-
import { ConfirmModal, Loading } from "@truedat/core/components";
|
|
10
|
-
import { linkTo } from "@truedat/core/routes";
|
|
11
|
-
import { accentInsensitivePathOrder } from "@truedat/core/services/sort";
|
|
12
|
-
import { STRUCTURE_TAGS_QUERY } from "../api/queries";
|
|
13
|
-
import { deleteStructureTag } from "../routines";
|
|
14
|
-
|
|
15
|
-
const EmptyMessage = () => (
|
|
16
|
-
<Message icon info>
|
|
17
|
-
<Icon name="folder open outline" />
|
|
18
|
-
<Message.Content>
|
|
19
|
-
<Message.Header>
|
|
20
|
-
<FormattedMessage id="structureTags.empty" />
|
|
21
|
-
</Message.Header>
|
|
22
|
-
</Message.Content>
|
|
23
|
-
</Message>
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
export const StructureTagsCards = ({ deleteStructureTag, structureTags }) => {
|
|
27
|
-
if (_.isEmpty(structureTags)) return <EmptyMessage />;
|
|
28
|
-
return (
|
|
29
|
-
<Card.Group>
|
|
30
|
-
{structureTags.map((structureTag) => (
|
|
31
|
-
<Card key={structureTag?.id}>
|
|
32
|
-
<Card.Content>
|
|
33
|
-
<Card.Header
|
|
34
|
-
as={Link}
|
|
35
|
-
to={linkTo.STRUCTURE_TAGS_EDIT({ id: structureTag.id })}
|
|
36
|
-
>
|
|
37
|
-
{_.prop("name")(structureTag)}
|
|
38
|
-
</Card.Header>
|
|
39
|
-
<Card.Description>
|
|
40
|
-
{_.prop("description")(structureTag)}
|
|
41
|
-
</Card.Description>
|
|
42
|
-
</Card.Content>
|
|
43
|
-
<Card.Content extra>
|
|
44
|
-
<div className="ui actions">
|
|
45
|
-
<ConfirmModal
|
|
46
|
-
icon="trash"
|
|
47
|
-
trigger={<Button icon="trash" basic color="red" />}
|
|
48
|
-
header={
|
|
49
|
-
<FormattedMessage id="structureTags.actions.delete.confirmation.header" />
|
|
50
|
-
}
|
|
51
|
-
content={
|
|
52
|
-
structureTag.structureCount > 0 ? (
|
|
53
|
-
<FormattedMessage
|
|
54
|
-
id="structureTags.actions.delete.confirmation.content"
|
|
55
|
-
values={{
|
|
56
|
-
name: <i>{`'${structureTag.name}'`}</i>,
|
|
57
|
-
count: structureTag.structureCount,
|
|
58
|
-
}}
|
|
59
|
-
/>
|
|
60
|
-
) : (
|
|
61
|
-
<FormattedMessage
|
|
62
|
-
id="structureTags.actions.delete.noStructures.confirmation.content"
|
|
63
|
-
values={{ name: <i>{`'${structureTag.name}'`}</i> }}
|
|
64
|
-
/>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
onConfirm={() => deleteStructureTag({ id: structureTag.id })}
|
|
68
|
-
/>
|
|
69
|
-
</div>
|
|
70
|
-
</Card.Content>
|
|
71
|
-
</Card>
|
|
72
|
-
))}
|
|
73
|
-
</Card.Group>
|
|
74
|
-
);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
StructureTagsCards.propTypes = {
|
|
78
|
-
structureTags: PropTypes.array,
|
|
79
|
-
deleteStructureTag: PropTypes.func,
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export const StructureTagsCardsLoader = (props) => {
|
|
83
|
-
const { loading, error, data } = useQuery(STRUCTURE_TAGS_QUERY);
|
|
84
|
-
if (error) return null;
|
|
85
|
-
if (loading) return <Loading />;
|
|
86
|
-
const structureTags = _.sortBy(accentInsensitivePathOrder("name"))(
|
|
87
|
-
data?.structureTags || []
|
|
88
|
-
);
|
|
89
|
-
return <StructureTagsCards structureTags={structureTags} {...props} />;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export default connect(null, { deleteStructureTag })(StructureTagsCardsLoader);
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import { Breadcrumb } from "semantic-ui-react";
|
|
5
|
-
import { Link } from "react-router-dom";
|
|
6
|
-
import { FormattedMessage } from "react-intl";
|
|
7
|
-
import { STRUCTURE_TAGS, linkTo } from "@truedat/core/routes";
|
|
8
|
-
|
|
9
|
-
export const StructureTagsCrumbs = ({ structureTag, action }) => {
|
|
10
|
-
const rootBreadcrumb =
|
|
11
|
-
!_.isEmpty(structureTag) && action
|
|
12
|
-
? { as: Link, to: linkTo.STRUCTURE_TAG(structureTag), active: false }
|
|
13
|
-
: { active: true };
|
|
14
|
-
return (
|
|
15
|
-
<Breadcrumb>
|
|
16
|
-
<Breadcrumb.Section as={Link} to={STRUCTURE_TAGS} active={false}>
|
|
17
|
-
<FormattedMessage id="structureTags.crumbs.root" />
|
|
18
|
-
</Breadcrumb.Section>
|
|
19
|
-
{_.isEmpty(structureTag) ? null : (
|
|
20
|
-
<>
|
|
21
|
-
<Breadcrumb.Divider icon="right angle" />
|
|
22
|
-
<Breadcrumb.Section {...rootBreadcrumb}>
|
|
23
|
-
{structureTag.name}
|
|
24
|
-
</Breadcrumb.Section>
|
|
25
|
-
</>
|
|
26
|
-
)}
|
|
27
|
-
{action ? (
|
|
28
|
-
<>
|
|
29
|
-
<Breadcrumb.Divider icon="right angle" />
|
|
30
|
-
<Breadcrumb.Section active>
|
|
31
|
-
<FormattedMessage id={action} />
|
|
32
|
-
</Breadcrumb.Section>
|
|
33
|
-
</>
|
|
34
|
-
) : null}
|
|
35
|
-
</Breadcrumb>
|
|
36
|
-
);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
StructureTagsCrumbs.propTypes = {
|
|
40
|
-
structureTag: PropTypes.object,
|
|
41
|
-
action: PropTypes.string,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export default StructureTagsCrumbs;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Route, Switch, useParams } from "react-router-dom";
|
|
3
|
-
import { useQuery } from "@apollo/client";
|
|
4
|
-
import { Unauthorized } from "@truedat/core/components";
|
|
5
|
-
import { useAuthorized } from "@truedat/core/hooks";
|
|
6
|
-
import {
|
|
7
|
-
STRUCTURE_TAGS,
|
|
8
|
-
STRUCTURE_TAGS_EDIT,
|
|
9
|
-
STRUCTURE_TAGS_NEW,
|
|
10
|
-
} from "@truedat/core/routes";
|
|
11
|
-
import { STRUCTURE_TAG_QUERY } from "../api/queries";
|
|
12
|
-
import StructureTag from "./StructureTag";
|
|
13
|
-
import StructureTags from "./StructureTags";
|
|
14
|
-
|
|
15
|
-
export const StructureTagLoader = () => {
|
|
16
|
-
const { id } = useParams();
|
|
17
|
-
const { loading, error, data } = useQuery(STRUCTURE_TAG_QUERY, {
|
|
18
|
-
variables: { id },
|
|
19
|
-
});
|
|
20
|
-
if (error) return null;
|
|
21
|
-
const structureTag = data?.structureTag;
|
|
22
|
-
return <StructureTag id={id} structureTag={structureTag} loading={loading} />;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const AuthorizedStructureTagsRoutes = () => (
|
|
26
|
-
<Switch>
|
|
27
|
-
<Route exact path={STRUCTURE_TAGS_NEW} render={() => <StructureTag />} />
|
|
28
|
-
<Route exact path={STRUCTURE_TAGS} render={() => <StructureTags />} />
|
|
29
|
-
<Route path={STRUCTURE_TAGS_EDIT} render={() => <StructureTagLoader />} />
|
|
30
|
-
</Switch>
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
export const StructureTagsRoutes = () => {
|
|
34
|
-
const authorized = useAuthorized();
|
|
35
|
-
return (
|
|
36
|
-
<Route
|
|
37
|
-
path={STRUCTURE_TAGS}
|
|
38
|
-
render={() =>
|
|
39
|
-
authorized ? <AuthorizedStructureTagsRoutes /> : <Unauthorized />
|
|
40
|
-
}
|
|
41
|
-
/>
|
|
42
|
-
);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export default StructureTagsRoutes;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { connect } from "react-redux";
|
|
4
|
-
import PropTypes from "prop-types";
|
|
5
|
-
import LinkedStructureTag from "./LinkedStructureTag";
|
|
6
|
-
import StructureLinkTagButton from "./StructureLinkTagButton";
|
|
7
|
-
|
|
8
|
-
export const TagsHeader = ({ linkedStructureTags, editable }) => (
|
|
9
|
-
<>
|
|
10
|
-
{_.isEmpty(linkedStructureTags)
|
|
11
|
-
? null
|
|
12
|
-
: _.flow(
|
|
13
|
-
_.sortBy("inserted_at"),
|
|
14
|
-
_.map.convert({ cap: false })((link, i) => (
|
|
15
|
-
<LinkedStructureTag key={i} editable={editable} {...link} />
|
|
16
|
-
))
|
|
17
|
-
)(linkedStructureTags)}
|
|
18
|
-
<StructureLinkTagButton />
|
|
19
|
-
</>
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
TagsHeader.propTypes = {
|
|
23
|
-
editable: PropTypes.bool,
|
|
24
|
-
linkedStructureTags: PropTypes.array,
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const mapStateToProps = ({ linkedStructureTags, editableStructureTags }) => ({
|
|
28
|
-
linkedStructureTags,
|
|
29
|
-
editable: !!editableStructureTags,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
export default connect(mapStateToProps)(TagsHeader);
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { intl } from "@truedat/test/intl-stub";
|
|
3
|
-
import { render, waitFor } from "@testing-library/react";
|
|
4
|
-
import userEvent from "@testing-library/user-event";
|
|
5
|
-
import { LinkStructureTagForm } from "../LinkStructureTagForm";
|
|
6
|
-
|
|
7
|
-
// workaround for enzyme issue with React.useContext
|
|
8
|
-
// see https://github.com/airbnb/enzyme/issues/2176#issuecomment-532361526
|
|
9
|
-
jest.spyOn(React, "useContext").mockImplementation(() => intl);
|
|
10
|
-
|
|
11
|
-
describe("<LinkStructureTagForm />", () => {
|
|
12
|
-
const deleteLinkStructureTag = jest.fn();
|
|
13
|
-
const linkStructureTag = jest.fn();
|
|
14
|
-
const structureTags = [
|
|
15
|
-
{ id: 1, name: "Tag1", description: "description test" },
|
|
16
|
-
{ id: 2, name: "Tag2", description: "large desc".repeat(5) },
|
|
17
|
-
{ id: 3, name: "Tag without description" },
|
|
18
|
-
];
|
|
19
|
-
const linkedStructureTags = [
|
|
20
|
-
{
|
|
21
|
-
id: 1,
|
|
22
|
-
comment: "foo",
|
|
23
|
-
inserted_at: "foo",
|
|
24
|
-
updated_at: "foo",
|
|
25
|
-
_embedded: {
|
|
26
|
-
data_structure: { id: 1, external_id: "baz" },
|
|
27
|
-
data_structure_tag: { ...structureTags[2] },
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
const comment = "foo";
|
|
33
|
-
const structureId = 1;
|
|
34
|
-
const tagId = 3;
|
|
35
|
-
const linkId = 1;
|
|
36
|
-
|
|
37
|
-
const propsCreate = {
|
|
38
|
-
deleteLinkStructureTag,
|
|
39
|
-
linkedStructureTags,
|
|
40
|
-
linkStructureTag,
|
|
41
|
-
structureId,
|
|
42
|
-
structureTags,
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const propsUpdate = {
|
|
46
|
-
deleteLinkStructureTag,
|
|
47
|
-
comment,
|
|
48
|
-
linkedStructureTags,
|
|
49
|
-
linkId,
|
|
50
|
-
linkStructureTag,
|
|
51
|
-
structureId,
|
|
52
|
-
structureTags,
|
|
53
|
-
tagId,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
it("matches the latest snapshot create", async () => {
|
|
57
|
-
const { container, findByRole } = render(
|
|
58
|
-
<LinkStructureTagForm {...propsCreate} />
|
|
59
|
-
);
|
|
60
|
-
await findByRole("button", { name: /add/ });
|
|
61
|
-
expect(container).toMatchSnapshot();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("matches the latest snapshot edit", async () => {
|
|
65
|
-
const { container, findByRole } = render(
|
|
66
|
-
<LinkStructureTagForm {...propsUpdate} />
|
|
67
|
-
);
|
|
68
|
-
await findByRole("button", { name: /edit/ });
|
|
69
|
-
await findByRole("button", { name: /delete/ });
|
|
70
|
-
expect(container).toMatchSnapshot();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("matches the latest snapshot create without comment", async () => {
|
|
74
|
-
const linkedStructureTagWithoutComment = {
|
|
75
|
-
...linkedStructureTags[0],
|
|
76
|
-
};
|
|
77
|
-
delete linkedStructureTagWithoutComment.comment;
|
|
78
|
-
|
|
79
|
-
const propsCreateWithoutComment = {
|
|
80
|
-
...propsCreate,
|
|
81
|
-
linkedStructureTags: [linkedStructureTagWithoutComment],
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const { container, getByRole, findByText } = render(
|
|
85
|
-
<LinkStructureTagForm {...propsCreateWithoutComment} />
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
// Select tag
|
|
89
|
-
userEvent.click(await findByText("Tag2"));
|
|
90
|
-
|
|
91
|
-
await waitFor(() =>
|
|
92
|
-
expect(getByRole("button", { name: /add/ })).not.toBeDisabled()
|
|
93
|
-
);
|
|
94
|
-
expect(container).toMatchSnapshot();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("create button enabled if there is only one tag available", async () => {
|
|
98
|
-
const propsCreateWithOneStrutureTagAvailable = {
|
|
99
|
-
...propsCreate,
|
|
100
|
-
structureTags: [structureTags[1], structureTags[2]],
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const { container, getByRole } = render(
|
|
104
|
-
<LinkStructureTagForm {...propsCreateWithOneStrutureTagAvailable} />
|
|
105
|
-
);
|
|
106
|
-
await waitFor(() =>
|
|
107
|
-
expect(getByRole("button", { name: /add/ })).not.toBeDisabled()
|
|
108
|
-
);
|
|
109
|
-
expect(container).toMatchSnapshot();
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it("Tag dropdown show tag description", async () => {
|
|
113
|
-
const { getByText } = render(<LinkStructureTagForm {...propsCreate} />);
|
|
114
|
-
await waitFor(() =>
|
|
115
|
-
expect(getByText("description test")).toBeInTheDocument()
|
|
116
|
-
);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("Tag dropdown with tag with large description show ellipsis", async () => {
|
|
120
|
-
const { getByText } = render(<LinkStructureTagForm {...propsCreate} />);
|
|
121
|
-
|
|
122
|
-
const tagElement = getByText("Tag2");
|
|
123
|
-
|
|
124
|
-
await waitFor(() => expect(tagElement).toBeInTheDocument());
|
|
125
|
-
|
|
126
|
-
const descriptionElement = tagElement.parentElement.firstElementChild;
|
|
127
|
-
|
|
128
|
-
expect(descriptionElement).toHaveClass("description");
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("calls ", async () => {
|
|
132
|
-
const { queryByTestId, findByRole, findByText, getByRole } = render(
|
|
133
|
-
<LinkStructureTagForm {...{ ...propsCreate, linkedStructureTags: [] }} />
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
// Submit button should initially be disabled
|
|
137
|
-
await waitFor(() =>
|
|
138
|
-
expect(getByRole("button", { name: /add/ })).toBeDisabled()
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
// Select tag
|
|
142
|
-
userEvent.click(await findByText("Tag1"));
|
|
143
|
-
|
|
144
|
-
// Submit button should now be enabled
|
|
145
|
-
await waitFor(() =>
|
|
146
|
-
expect(getByRole("button", { name: /add/ })).not.toBeDisabled()
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
// Description
|
|
150
|
-
// Issue: https://github.com/testing-library/user-event/issues/346
|
|
151
|
-
userEvent.type(queryByTestId("comment-id"), "x");
|
|
152
|
-
userEvent.type(queryByTestId("comment-id"), "yz");
|
|
153
|
-
|
|
154
|
-
userEvent.click(await findByRole("button", { name: /add/ }));
|
|
155
|
-
|
|
156
|
-
await waitFor(() =>
|
|
157
|
-
expect(linkStructureTag).toHaveBeenCalledWith({
|
|
158
|
-
structureId,
|
|
159
|
-
tagId: 1,
|
|
160
|
-
tag: { comment: "xyz" },
|
|
161
|
-
})
|
|
162
|
-
);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it("calls deleteLinkStructureTag on delete", async () => {
|
|
166
|
-
const { findByRole, getByRole } = render(
|
|
167
|
-
<LinkStructureTagForm {...propsUpdate} />
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
// Delete button should be enabled
|
|
171
|
-
await waitFor(() =>
|
|
172
|
-
expect(getByRole("button", { name: /delete/ })).not.toBeDisabled()
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
userEvent.click(await findByRole("button", { name: /delete/ }));
|
|
176
|
-
|
|
177
|
-
await waitFor(() =>
|
|
178
|
-
expect(deleteLinkStructureTag).toHaveBeenCalledWith({
|
|
179
|
-
structureId,
|
|
180
|
-
tagId,
|
|
181
|
-
})
|
|
182
|
-
);
|
|
183
|
-
});
|
|
184
|
-
});
|