@truedat/bg 7.10.4 → 7.11.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.
Files changed (25) hide show
  1. package/package.json +3 -3
  2. package/src/concepts/components/ConceptLinksUploadButton.js +0 -4
  3. package/src/concepts/components/ConceptRoutes.js +28 -46
  4. package/src/concepts/components/__tests__/ConceptRoutes.spec.js +201 -0
  5. package/src/concepts/components/__tests__/__snapshots__/ConceptRoutes.spec.js.snap +165 -0
  6. package/src/concepts/relations/api.js +9 -1
  7. package/src/concepts/relations/components/ConceptLinksApprovalResults.js +91 -0
  8. package/src/concepts/relations/components/ConceptLinksApprovals.js +225 -0
  9. package/src/concepts/relations/components/ConceptLinksApprovalsLabelResults.js +42 -0
  10. package/src/concepts/relations/components/ConceptLinksApprovalsRow.js +43 -0
  11. package/src/concepts/relations/components/ConceptLinksApprovalsTable.js +104 -0
  12. package/src/concepts/relations/components/__tests__/ConceptLinksApprovalResults.spec.js +123 -0
  13. package/src/concepts/relations/components/__tests__/ConceptLinksApprovals.spec.js +77 -0
  14. package/src/concepts/relations/components/__tests__/ConceptLinksApprovalsLabelResults.spec.js +47 -0
  15. package/src/concepts/relations/components/__tests__/ConceptLinksApprovalsRow.spec.js +68 -0
  16. package/src/concepts/relations/components/__tests__/ConceptLinksApprovalsTable.spec.js +107 -0
  17. package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalResults.spec.js.snap +217 -0
  18. package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovals.spec.js.snap +559 -0
  19. package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalsLabelResults.spec.js.snap +34 -0
  20. package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalsRow.spec.js.snap +47 -0
  21. package/src/concepts/relations/components/__tests__/__snapshots__/ConceptLinksApprovalsTable.spec.js.snap +132 -0
  22. package/src/concepts/relations/hooks/useLinks.js +25 -0
  23. package/src/concepts/relations/selectors/getLinksSearchColumns.js +106 -0
  24. package/src/concepts/relations/selectors/index.js +2 -0
  25. package/src/concepts/relations/styles/ConceptLinksApprovals.less +15 -0
@@ -0,0 +1,225 @@
1
+ import _ from "lodash/fp";
2
+ import { useEffect, useState } from "react";
3
+ import { useNavigate } from "react-router";
4
+ import { CONCEPT_LINKS_APPROVALS_RESULTS } from "@truedat/core/routes";
5
+ import {
6
+ Header,
7
+ Button,
8
+ Checkbox,
9
+ Icon,
10
+ Segment,
11
+ Dimmer,
12
+ Loader,
13
+ Grid,
14
+ GridColumn,
15
+ GridRow,
16
+ } from "semantic-ui-react";
17
+ import { FormattedMessage, useIntl } from "react-intl";
18
+ import SearchWidget from "@truedat/core/search/SearchWidget";
19
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
20
+ import { useLinksBulkUpdateStatus } from "../hooks/useLinks";
21
+ import Pagination from "@truedat/core/search/Pagination";
22
+ import ConceptLinksApprovalsLabelResults from "./ConceptLinksApprovalsLabelResults";
23
+ import ConceptLinksApprovalsTable from "./ConceptLinksApprovalsTable";
24
+
25
+ export const ConceptLinksApprovals = () => {
26
+ const { searchData, loading, setOnSearchChange, searchMust, setSearchMust } =
27
+ useSearchContext();
28
+
29
+ const navigate = useNavigate();
30
+ const { formatMessage } = useIntl();
31
+ const { trigger: triggerUpdateStatus, isMutating: mutatingStatus } =
32
+ useLinksBulkUpdateStatus();
33
+
34
+ const links = _.propOr([], "data")(searchData);
35
+
36
+ const [selectedLinks, setSelectedLinks] = useState([]);
37
+
38
+ const cleanSelection = () => setSelectedLinks([]);
39
+ const approveView = _.isEqual(searchMust.status, ["pending"]);
40
+
41
+ useEffect(() => {
42
+ setOnSearchChange(() => cleanSelection);
43
+ }, []);
44
+
45
+ const allChecked = () => {
46
+ const ids = _.map(_.prop("id"))(links);
47
+ return (
48
+ _.negate(_.isEmpty)(selectedLinks) &&
49
+ _.every((id) => _.includes(id)(selectedLinks))(ids)
50
+ );
51
+ };
52
+
53
+ const addAll = (_e, target) => {
54
+ const checkedAll = _.prop("checked")(target);
55
+ const ids = _.map(_.prop("id"))(links);
56
+ checkedAll
57
+ ? setSelectedLinks(_.flow(_.concat(ids), _.uniq)(selectedLinks))
58
+ : setSelectedLinks(
59
+ _.flow(_.difference(selectedLinks), _.uniq)(selectedLinks)
60
+ );
61
+ };
62
+
63
+ const checkRow = (link) => {
64
+ const id = _.prop("id")(link);
65
+ const exists = _.some((selectedId) => _.eq(id, selectedId))(selectedLinks);
66
+ exists
67
+ ? setSelectedLinks(
68
+ _.flow(
69
+ _.remove((selectedId) => _.eq(id, selectedId)),
70
+ _.uniq()
71
+ )(selectedLinks)
72
+ )
73
+ : setSelectedLinks(_.flow(_.concat(id), _.uniq)(selectedLinks));
74
+ };
75
+
76
+ const isRowChecked = (link) => {
77
+ const id = _.prop("id")(link);
78
+ return _.some((selectedId) => _.eq(id, selectedId))(selectedLinks);
79
+ };
80
+
81
+ const disableUpdate = mutatingStatus || _.isEmpty(selectedLinks);
82
+
83
+ const handleStatusFilterChange = (_e, { value }) =>
84
+ _.includes(value, searchMust.status)
85
+ ? setSearchMust({
86
+ ...searchMust,
87
+ status: _.without([value], searchMust.status),
88
+ })
89
+ : setSearchMust({
90
+ ...searchMust,
91
+ status: _.concat(value, searchMust.status),
92
+ });
93
+
94
+ const handleUpdateStatus = (newState) => {
95
+ const params = { relation_ids: selectedLinks, status: newState };
96
+
97
+ triggerUpdateStatus(params).then((response) => {
98
+ navigate(CONCEPT_LINKS_APPROVALS_RESULTS, {
99
+ state: {
100
+ ..._.prop("data.data")(response),
101
+ status: newState,
102
+ },
103
+ });
104
+ });
105
+ };
106
+
107
+ return (
108
+ <Segment>
109
+ <Header as="h2">
110
+ <Icon
111
+ circular
112
+ name={formatMessage({
113
+ id: "conceptRelations.approvals.header.icon",
114
+ defaultMessage: "linkify",
115
+ })}
116
+ />
117
+ <Header.Content>
118
+ <FormattedMessage id={"conceptRelations.approvals.header"} />
119
+ <Header.Subheader>
120
+ <FormattedMessage id={"conceptRelations.approvals.subheader"} />
121
+ </Header.Subheader>
122
+ </Header.Content>
123
+ </Header>
124
+ <Segment attached="bottom">
125
+ <Grid className="grant-requests-bulk-actions">
126
+ <GridRow>
127
+ <GridColumn width={8}>
128
+ <SearchWidget />
129
+ </GridColumn>
130
+ <GridColumn width={8} textAlign="right">
131
+ {approveView ? (
132
+ <>
133
+ <Button
134
+ primary
135
+ disabled={disableUpdate}
136
+ onClick={() => handleUpdateStatus("approved")}
137
+ >
138
+ <FormattedMessage id="conceptRelations.approvals.actions.approve" />
139
+ </Button>
140
+ <Button
141
+ secondary
142
+ disabled={disableUpdate}
143
+ onClick={() => handleUpdateStatus("rejected")}
144
+ >
145
+ <FormattedMessage id="conceptRelations.approvals.actions.reject" />
146
+ </Button>
147
+ </>
148
+ ) : null}
149
+ </GridColumn>
150
+ </GridRow>
151
+ <GridRow>
152
+ <GridColumn
153
+ width={8}
154
+ className="concepts-links-approvals-status-selector"
155
+ >
156
+ <Checkbox
157
+ label={
158
+ <label>
159
+ <FormattedMessage
160
+ id={`conceptRelations.approvals.status.pending`}
161
+ />
162
+ </label>
163
+ }
164
+ value="pending"
165
+ checked={_.includes("pending", searchMust.status)}
166
+ onChange={handleStatusFilterChange}
167
+ />
168
+ <Checkbox
169
+ label={
170
+ <label>
171
+ <FormattedMessage
172
+ id={`conceptRelations.approvals.status.approved`}
173
+ />
174
+ </label>
175
+ }
176
+ value="approved"
177
+ checked={_.includes("approved", searchMust.status)}
178
+ onChange={handleStatusFilterChange}
179
+ />
180
+ <Checkbox
181
+ label={
182
+ <label>
183
+ <FormattedMessage
184
+ id={`conceptRelations.approvals.status.rejected`}
185
+ />
186
+ </label>
187
+ }
188
+ value="rejected"
189
+ checked={_.includes("rejected", searchMust.status)}
190
+ onChange={handleStatusFilterChange}
191
+ />
192
+ </GridColumn>
193
+ <GridColumn width={8} textAlign="right">
194
+ <ConceptLinksApprovalsLabelResults
195
+ approveView={approveView}
196
+ selectedCount={_.size(selectedLinks)}
197
+ />
198
+ </GridColumn>
199
+ </GridRow>
200
+ </Grid>
201
+ <Segment attached="bottom">
202
+ <Dimmer.Dimmable dimmed={loading}>
203
+ {loading ? (
204
+ <Dimmer active inverted>
205
+ <Loader />
206
+ </Dimmer>
207
+ ) : null}
208
+
209
+ <ConceptLinksApprovalsTable
210
+ approveView={approveView}
211
+ addAll={addAll}
212
+ checkedAll={allChecked()}
213
+ checkRow={checkRow}
214
+ isRowChecked={isRowChecked}
215
+ />
216
+
217
+ <Pagination />
218
+ </Dimmer.Dimmable>
219
+ </Segment>
220
+ </Segment>
221
+ </Segment>
222
+ );
223
+ };
224
+
225
+ export default ConceptLinksApprovals;
@@ -0,0 +1,42 @@
1
+ import PropTypes from "prop-types";
2
+ import { FormattedMessage } from "react-intl";
3
+ import { Label } from "semantic-ui-react";
4
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
5
+
6
+ export const ConceptLinksApprovalsLabelResults = ({
7
+ selectedCount,
8
+ approveView,
9
+ }) => {
10
+ const { count, loading } = useSearchContext();
11
+ return (
12
+ <div className="concepts-links-bulk-label-results">
13
+ <Label>
14
+ {loading ? (
15
+ <FormattedMessage id="conceptRelations.searching" />
16
+ ) : (
17
+ <FormattedMessage
18
+ id="conceptRelations.retrieved.results"
19
+ values={{ count }}
20
+ />
21
+ )}
22
+ </Label>
23
+ {!loading && approveView ? (
24
+ <Label>
25
+ <FormattedMessage
26
+ id="conceptRelations.bulk.selected"
27
+ values={{
28
+ count: selectedCount,
29
+ }}
30
+ />
31
+ </Label>
32
+ ) : null}
33
+ </div>
34
+ );
35
+ };
36
+
37
+ ConceptLinksApprovalsLabelResults.propTypes = {
38
+ selectedCount: PropTypes.number,
39
+ approveView: PropTypes.bool,
40
+ };
41
+
42
+ export default ConceptLinksApprovalsLabelResults;
@@ -0,0 +1,43 @@
1
+ import _ from "lodash/fp";
2
+ import PropTypes from "prop-types";
3
+ import { Checkbox, Table } from "semantic-ui-react";
4
+ import { columnDecoratorComponent } from "@truedat/core/services";
5
+
6
+ export const ConceptLinksApprovalsRow = ({
7
+ checked,
8
+ columns,
9
+ onCheckboxChange,
10
+ link,
11
+ approveView,
12
+ }) => {
13
+ return _.isEmpty(columns) || _.isEmpty(link) ? null : (
14
+ <Table.Row>
15
+ {approveView ? (
16
+ <Table.Cell collapsing width="1" textAlign="center">
17
+ <Checkbox
18
+ id={link.id}
19
+ checked={checked}
20
+ onChange={onCheckboxChange}
21
+ />
22
+ </Table.Cell>
23
+ ) : null}
24
+ {columns.map((column, key) => (
25
+ <Table.Cell
26
+ key={key}
27
+ textAlign={column.textAlign}
28
+ content={columnDecoratorComponent(column)(link)}
29
+ />
30
+ ))}
31
+ </Table.Row>
32
+ );
33
+ };
34
+
35
+ ConceptLinksApprovalsRow.propTypes = {
36
+ approveView: PropTypes.bool,
37
+ checked: PropTypes.bool,
38
+ link: PropTypes.object,
39
+ columns: PropTypes.array,
40
+ onCheckboxChange: PropTypes.func,
41
+ };
42
+
43
+ export default ConceptLinksApprovalsRow;
@@ -0,0 +1,104 @@
1
+ import _ from "lodash/fp";
2
+ import PropTypes from "prop-types";
3
+ import { connect } from "react-redux";
4
+ import { useIntl } from "react-intl";
5
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
6
+ import { Checkbox, Table, Header, Icon } from "semantic-ui-react";
7
+ import { getLinksSearchColumns } from "../selectors";
8
+ import { ConceptLinksApprovalsRow } from "./ConceptLinksApprovalsRow";
9
+
10
+ export const ConceptLinksApprovalsTable = ({
11
+ addAll,
12
+ checkedAll,
13
+ checkRow,
14
+ isRowChecked,
15
+ columns,
16
+ approveView,
17
+ }) => {
18
+ const { formatMessage } = useIntl();
19
+ const {
20
+ searchData,
21
+ loading,
22
+ sortColumn,
23
+ sortDirection,
24
+ handleSortSelection,
25
+ } = useSearchContext();
26
+
27
+ const links = _.propOr([], "data")(searchData);
28
+
29
+ return (
30
+ <>
31
+ {!_.isEmpty(links) ? (
32
+ <Table sortable selectable>
33
+ <Table.Header>
34
+ <Table.Row>
35
+ {approveView ? (
36
+ <Table.HeaderCell textAlign="center">
37
+ <Checkbox
38
+ id="selectLink"
39
+ onChange={addAll}
40
+ checked={checkedAll}
41
+ />
42
+ </Table.HeaderCell>
43
+ ) : null}
44
+ {columns.map((column, key) => (
45
+ <Table.HeaderCell
46
+ key={key}
47
+ width={column.width}
48
+ content={formatMessage({
49
+ id: `conceptRelations.approvals.header.${column.name}`,
50
+ defaultMessage: column.name,
51
+ })}
52
+ sorted={
53
+ _.path("sort.name")(column) === sortColumn
54
+ ? sortDirection
55
+ : null
56
+ }
57
+ className={_.path("sort.name")(column) ? "" : "disabled"}
58
+ onClick={() =>
59
+ handleSortSelection(_.path("sort.name")(column))
60
+ }
61
+ />
62
+ ))}
63
+ </Table.Row>
64
+ </Table.Header>
65
+ <Table.Body>
66
+ {links.map((link, key) => (
67
+ <ConceptLinksApprovalsRow
68
+ key={key}
69
+ checked={isRowChecked && isRowChecked(link)}
70
+ link={link}
71
+ columns={columns}
72
+ approveView={approveView}
73
+ onCheckboxChange={() => checkRow && checkRow(link)}
74
+ />
75
+ ))}
76
+ </Table.Body>
77
+ </Table>
78
+ ) : null}
79
+ {_.isEmpty(links) && !loading ? (
80
+ <Header as="h4">
81
+ <Icon name="search" />
82
+ <Header.Content>
83
+ {formatMessage({ id: "conceptRelations.approvals.links.empty" })}
84
+ </Header.Content>
85
+ </Header>
86
+ ) : null}
87
+ </>
88
+ );
89
+ };
90
+
91
+ ConceptLinksApprovalsTable.propTypes = {
92
+ columns: PropTypes.array,
93
+ approveView: PropTypes.bool,
94
+ checkedAll: PropTypes.bool,
95
+ addAll: PropTypes.func,
96
+ checkRow: PropTypes.func,
97
+ isRowChecked: PropTypes.func,
98
+ };
99
+
100
+ const mapStateToProps = (state) => ({
101
+ columns: getLinksSearchColumns(state),
102
+ });
103
+
104
+ export default connect(mapStateToProps)(ConceptLinksApprovalsTable);
@@ -0,0 +1,123 @@
1
+ import { render, waitForLoad } from "@truedat/test/render";
2
+ import LinksApprovalResults from "../ConceptLinksApprovalResults";
3
+ import { useLocation } from "react-router";
4
+
5
+ jest.mock("react-router", () => {
6
+ const actual = jest.requireActual("react-router");
7
+ return {
8
+ ...actual,
9
+ useLocation: jest.fn(),
10
+ };
11
+ });
12
+
13
+ const mockFormatMessage = jest.fn(({ id }) => id);
14
+ jest.mock("react-intl", () => ({
15
+ ...jest.requireActual("react-intl"),
16
+ useIntl: () => ({
17
+ formatMessage: mockFormatMessage,
18
+ }),
19
+ }));
20
+
21
+ describe("<LinksApprovalResults />", () => {
22
+ beforeEach(() => {
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it("renders approval results with relations and errors", async () => {
27
+ useLocation.mockReturnValue({
28
+ state: {
29
+ status: "approved",
30
+ relations: [
31
+ {
32
+ id: 1,
33
+ source_id: 10,
34
+ source_name: "Source 1",
35
+ target_id: 20,
36
+ target_name: "Target 1",
37
+ },
38
+ ],
39
+ errors: {
40
+ permissions: {
41
+ message: "forbidden",
42
+ reason: "permissions",
43
+ relations: [
44
+ {
45
+ id: 2,
46
+ source_id: 11,
47
+ source_name: "Source 2",
48
+ target_id: 21,
49
+ target_name: "Target 2",
50
+ },
51
+ ],
52
+ },
53
+ },
54
+ },
55
+ });
56
+
57
+ const rendered = render(<LinksApprovalResults />);
58
+ await waitForLoad(rendered);
59
+
60
+ expect(rendered.container).toMatchSnapshot();
61
+ });
62
+
63
+ it("renders rejection results", async () => {
64
+ useLocation.mockReturnValue({
65
+ state: {
66
+ status: "rejected",
67
+ relations: [
68
+ {
69
+ id: 3,
70
+ source_id: 12,
71
+ source_name: "Source 3",
72
+ target_id: 22,
73
+ target_name: "Target 3",
74
+ },
75
+ ],
76
+ errors: {},
77
+ },
78
+ });
79
+
80
+ const rendered = render(<LinksApprovalResults />);
81
+ await waitForLoad(rendered);
82
+
83
+ expect(rendered.container).toMatchSnapshot();
84
+ });
85
+
86
+ it("renders with no errors", async () => {
87
+ useLocation.mockReturnValue({
88
+ state: {
89
+ status: "approved",
90
+ relations: [
91
+ {
92
+ id: 4,
93
+ source_id: 13,
94
+ source_name: "Source 4",
95
+ target_id: 23,
96
+ target_name: "Target 4",
97
+ },
98
+ ],
99
+ errors: {},
100
+ },
101
+ });
102
+
103
+ const rendered = render(<LinksApprovalResults />);
104
+ await waitForLoad(rendered);
105
+
106
+ expect(rendered.container).toMatchSnapshot();
107
+ });
108
+
109
+ it("renders with empty relations and errors", async () => {
110
+ useLocation.mockReturnValue({
111
+ state: {
112
+ status: "approved",
113
+ relations: [],
114
+ errors: {},
115
+ },
116
+ });
117
+
118
+ const rendered = render(<LinksApprovalResults />);
119
+ await waitForLoad(rendered);
120
+
121
+ expect(rendered.container).toMatchSnapshot();
122
+ });
123
+ });
@@ -0,0 +1,77 @@
1
+ import { render, waitForLoad } from "@truedat/test/render";
2
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
3
+ import { ConceptLinksApprovals } from "../ConceptLinksApprovals";
4
+
5
+ jest.mock("@truedat/core/search/SearchContext", () => {
6
+ const originalModule = jest.requireActual(
7
+ "@truedat/core/search/SearchContext"
8
+ );
9
+
10
+ return {
11
+ __esModule: true,
12
+ ...originalModule,
13
+ useSearchContext: jest.fn(),
14
+ };
15
+ });
16
+
17
+ describe("<ConceptLinksApprovals />", () => {
18
+ it("matches the latest snapshot", async () => {
19
+ useSearchContext.mockReturnValue({
20
+ searchData: {
21
+ data: [
22
+ {
23
+ domain_ids: [2],
24
+ id: 1,
25
+ origin: null,
26
+ source_domain_ids: [2],
27
+ source_id: 11,
28
+ source_name: "Busines 11",
29
+ source_type: "business_concept",
30
+ status: "pending",
31
+ target_domain_ids: [2],
32
+ target_id: 21,
33
+ target_name: "Structure 21",
34
+ target_type: "data_structure",
35
+ updated_at: "2025-08-11T07:07:13.336631Z",
36
+ },
37
+ {
38
+ domain_ids: [2, 1],
39
+ id: 2,
40
+ origin: null,
41
+ source_domain_ids: [2],
42
+ source_id: 21,
43
+ source_name: "Busines 21",
44
+ source_type: "business_concept",
45
+ status: "pending",
46
+ target_domain_ids: [1],
47
+ target_id: 22,
48
+ target_name: "Structure 22",
49
+ target_type: "data_structure",
50
+ updated_at: "2025-08-11T07:07:13.336631Z",
51
+ },
52
+ ],
53
+ scroll_id: null,
54
+ },
55
+ searchMust: { status: ["pending"] },
56
+ setOnSearchChange: jest.fn(),
57
+ });
58
+ const rendered = render(<ConceptLinksApprovals />);
59
+
60
+ await waitForLoad(rendered);
61
+
62
+ expect(rendered.container).toMatchSnapshot();
63
+ });
64
+
65
+ it("matches the latest snapshot for empty results", async () => {
66
+ useSearchContext.mockReturnValue({
67
+ searchData: [],
68
+ searchMust: { status: ["pending"] },
69
+ setOnSearchChange: jest.fn(),
70
+ });
71
+ const rendered = render(<ConceptLinksApprovals />);
72
+
73
+ await waitForLoad(rendered);
74
+
75
+ expect(rendered.container).toMatchSnapshot();
76
+ });
77
+ });
@@ -0,0 +1,47 @@
1
+ import { render, waitForLoad } from "@truedat/test/render";
2
+ import { useSearchContext } from "@truedat/core/search/SearchContext";
3
+ import { ConceptLinksApprovalsLabelResults } from "../ConceptLinksApprovalsLabelResults";
4
+
5
+ jest.mock("@truedat/core/search/SearchContext", () => {
6
+ const originalModule = jest.requireActual(
7
+ "@truedat/core/search/SearchContext"
8
+ );
9
+
10
+ return {
11
+ __esModule: true,
12
+ ...originalModule,
13
+ useSearchContext: jest.fn(),
14
+ };
15
+ });
16
+
17
+ describe("ConceptLinksApprovalsLabelResults", () => {
18
+ it("matches the latest snapshot", async () => {
19
+ useSearchContext.mockReturnValue({
20
+ count: 1,
21
+ loading: false,
22
+ });
23
+
24
+ const props = {
25
+ selectedCount: 1,
26
+ approveView: true,
27
+ };
28
+ const rendered = render(<ConceptLinksApprovalsLabelResults {...props} />);
29
+ await waitForLoad(rendered);
30
+ rendered.debug();
31
+ expect(rendered.container).toMatchSnapshot();
32
+ });
33
+
34
+ it("should not render results count when is loading", async () => {
35
+ useSearchContext.mockReturnValue({
36
+ count: 1,
37
+ loading: true,
38
+ });
39
+ const props = {
40
+ selectedCount: 1,
41
+ approveView: true,
42
+ };
43
+ const rendered = render(<ConceptLinksApprovalsLabelResults {...props} />);
44
+ await waitForLoad(rendered);
45
+ expect(rendered.container).toMatchSnapshot();
46
+ });
47
+ });