@truedat/dd 6.0.2 → 6.0.3
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/package.json +6 -6
- package/src/components/StructureCrumbs.js +4 -2
- package/src/components/StructureItemRoot.js +6 -5
- package/src/components/StructureNotesEdit.js +13 -5
- package/src/components/SystemStructures.js +3 -1
- package/src/components/__tests__/FilteredNav.spec.js +7 -0
- package/src/components/__tests__/StructureItems.spec.js +2 -2
- package/src/components/__tests__/StructureNav.spec.js +1 -1
- package/src/components/__tests__/SystemFilteredNav.spec.js +4 -1
- package/src/hooks/useBucketStructures.js +6 -1
- package/src/components/StructureNoteSuggestions.js +0 -179
- package/src/components/__tests__/StructureNoteSuggestions.spec.js +0 -151
- package/src/components/__tests__/__snapshots__/StructureNoteSuggestions.spec.js.snap +0 -316
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.3",
|
|
4
4
|
"description": "Truedat Web Data Dictionary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.16.5",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "6.0.
|
|
37
|
+
"@truedat/test": "6.0.3",
|
|
38
38
|
"babel-jest": "^28.1.0",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -88,9 +88,9 @@
|
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@apollo/client": "^3.7.1",
|
|
91
|
-
"@truedat/auth": "6.0.
|
|
92
|
-
"@truedat/core": "6.0.
|
|
93
|
-
"@truedat/df": "6.0.
|
|
91
|
+
"@truedat/auth": "6.0.3",
|
|
92
|
+
"@truedat/core": "6.0.3",
|
|
93
|
+
"@truedat/df": "6.0.3",
|
|
94
94
|
"lodash": "^4.17.21",
|
|
95
95
|
"moment": "^2.29.4",
|
|
96
96
|
"path-to-regexp": "^1.7.0",
|
|
@@ -115,5 +115,5 @@
|
|
|
115
115
|
"react-dom": ">= 16.8.6 < 17",
|
|
116
116
|
"semantic-ui-react": ">= 2.0.3 < 2.2"
|
|
117
117
|
},
|
|
118
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "c88ddc501214b8c4e2732654ca0052ebbcc802c9"
|
|
119
119
|
}
|
|
@@ -23,7 +23,7 @@ const filterQueryParams = _.flow(
|
|
|
23
23
|
propertyPath,
|
|
24
24
|
propertyValue,
|
|
25
25
|
}),
|
|
26
|
-
(queryParams) => new URLSearchParams(queryParams)
|
|
26
|
+
(queryParams) => new URLSearchParams(queryParams)
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
export const SystemCrumb = ({ id, name, navFilter }) => {
|
|
@@ -52,7 +52,9 @@ export const SystemCrumb = ({ id, name, navFilter }) => {
|
|
|
52
52
|
<Breadcrumb.Divider icon="right angle" />
|
|
53
53
|
<Breadcrumb.Section
|
|
54
54
|
as={Link}
|
|
55
|
-
to={`${linkTo.BUCKET_VIEW()}?${filterQueryParams(
|
|
55
|
+
to={`${linkTo.BUCKET_VIEW()}?${filterQueryParams(
|
|
56
|
+
navFilter.filter
|
|
57
|
+
)}`}
|
|
56
58
|
active={false}
|
|
57
59
|
>
|
|
58
60
|
{propertyValue}
|
|
@@ -18,11 +18,12 @@ const filterParams = _.flow(
|
|
|
18
18
|
|
|
19
19
|
export const StructureItemRoot = ({ navFilter }) => {
|
|
20
20
|
const history = useHistory();
|
|
21
|
-
const url =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const url =
|
|
22
|
+
navFilter?.view === "BUCKET_VIEW"
|
|
23
|
+
? linkTo.BUCKETS_VIEW({
|
|
24
|
+
propertyPath: filterParams(navFilter.filter)?.propertyPath,
|
|
25
|
+
})
|
|
26
|
+
: STRUCTURES;
|
|
26
27
|
return (
|
|
27
28
|
<List.Item onClick={() => history.push(url)}>
|
|
28
29
|
<List.Icon name="angle double left" verticalAlign="middle" />
|
|
@@ -7,9 +7,10 @@ import { useIntl } from "react-intl";
|
|
|
7
7
|
import { HistoryBackButton } from "@truedat/core/components";
|
|
8
8
|
import { selectTemplate, selectDomains } from "@truedat/df/routines";
|
|
9
9
|
import { applyTemplate, validateContent } from "@truedat/df/utils";
|
|
10
|
+
import { apiJson } from "@truedat/core/services/api";
|
|
11
|
+
import SuggestionsWidget from "@truedat/ai/components/suggestions/SuggestionsWidget";
|
|
10
12
|
import { doStructureNoteAction } from "../routines";
|
|
11
13
|
import { getLatestDfContent } from "../selectors/getSortedStructureNotes";
|
|
12
|
-
import StructureNoteSuggestions from "./StructureNoteSuggestions";
|
|
13
14
|
|
|
14
15
|
const DynamicForm = React.lazy(() =>
|
|
15
16
|
import("@truedat/df/components/DynamicForm")
|
|
@@ -30,7 +31,9 @@ export const StructureNotesEdit = ({
|
|
|
30
31
|
latestDfContent,
|
|
31
32
|
}) => {
|
|
32
33
|
const [content, setContent] = useState(latestDfContent);
|
|
33
|
-
const
|
|
34
|
+
const aiSuggestionsUrl = _.prop("_actions.ai_suggestions.href")(
|
|
35
|
+
structureNotes
|
|
36
|
+
);
|
|
34
37
|
|
|
35
38
|
const isModification = !_.isEmpty(latestDfContent);
|
|
36
39
|
|
|
@@ -75,13 +78,18 @@ export const StructureNotesEdit = ({
|
|
|
75
78
|
setContent({ ...content, ...suggestions });
|
|
76
79
|
};
|
|
77
80
|
|
|
81
|
+
const requestAiSuggestion = (callback) => {
|
|
82
|
+
const url = `${aiSuggestionsUrl}?language=${locale}`;
|
|
83
|
+
apiJson(url).then(callback);
|
|
84
|
+
};
|
|
85
|
+
|
|
78
86
|
return (
|
|
79
87
|
<Segment attached="bottom">
|
|
80
88
|
<TemplateLoader />
|
|
81
89
|
|
|
82
|
-
{
|
|
83
|
-
<
|
|
84
|
-
|
|
90
|
+
{aiSuggestionsUrl ? (
|
|
91
|
+
<SuggestionsWidget
|
|
92
|
+
requestAiSuggestion={requestAiSuggestion}
|
|
85
93
|
template={template}
|
|
86
94
|
applySuggestions={applySuggestions}
|
|
87
95
|
isModification={isModification}
|
|
@@ -38,7 +38,9 @@ export const SystemStructures = ({
|
|
|
38
38
|
<Grid.Row stretched>
|
|
39
39
|
<Grid.Column width={4}>
|
|
40
40
|
<Segment>
|
|
41
|
-
{navFilter?.filter?.system_id ?
|
|
41
|
+
{navFilter?.filter?.system_id ? (
|
|
42
|
+
<FilteredNav navFilter={navFilter} />
|
|
43
|
+
) : null}
|
|
42
44
|
</Segment>
|
|
43
45
|
</Grid.Column>
|
|
44
46
|
<Grid.Column width={12}>
|
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
import userEvent from "@testing-library/user-event";
|
|
3
3
|
import { render } from "@truedat/test/render";
|
|
4
4
|
import { act } from "react-dom/test-utils";
|
|
5
|
+
import en from "../../messages/en";
|
|
5
6
|
|
|
6
7
|
import FilteredNavLoader, { FilteredNav } from "../FilteredNav";
|
|
7
8
|
|
|
@@ -64,6 +65,12 @@ const renderOpts = {
|
|
|
64
65
|
state: {
|
|
65
66
|
navFilter,
|
|
66
67
|
},
|
|
68
|
+
messages: {
|
|
69
|
+
en: {
|
|
70
|
+
...en,
|
|
71
|
+
"structures.props.functional_name": "structures.props.functional_name",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
67
74
|
};
|
|
68
75
|
|
|
69
76
|
describe("<FilteredNav />", () => {
|
|
@@ -5,7 +5,7 @@ import { StructureItems } from "../StructureItems";
|
|
|
5
5
|
describe("<StructureItems />", () => {
|
|
6
6
|
it("matches the latest snapshot", () => {
|
|
7
7
|
const structures = [{ id: 1, name: "some structure" }];
|
|
8
|
-
const props = { structures, fnHasCatalogViewProp: jest.fn()
|
|
8
|
+
const props = { structures, fnHasCatalogViewProp: jest.fn() };
|
|
9
9
|
|
|
10
10
|
const { container } = render(<StructureItems {...props} />);
|
|
11
11
|
expect(container).toMatchSnapshot();
|
|
@@ -13,7 +13,7 @@ describe("<StructureItems />", () => {
|
|
|
13
13
|
|
|
14
14
|
it("matches the latest snapshot with alias", () => {
|
|
15
15
|
const structures = [{ id: 1, name: "some structure", alias: "alias" }];
|
|
16
|
-
const props = { structures, fnHasCatalogViewProp: jest.fn()
|
|
16
|
+
const props = { structures, fnHasCatalogViewProp: jest.fn() };
|
|
17
17
|
|
|
18
18
|
const { container } = render(<StructureItems {...props} />);
|
|
19
19
|
expect(container).toMatchSnapshot();
|
|
@@ -17,7 +17,7 @@ const renderOpts = {
|
|
|
17
17
|
describe("<StructureNav />", () => {
|
|
18
18
|
it("matches the latest snapshot", () => {
|
|
19
19
|
const childStructures = [{ id: 1 }];
|
|
20
|
-
const props = { childStructures, fnHasCatalogViewProp: jest.fn()
|
|
20
|
+
const props = { childStructures, fnHasCatalogViewProp: jest.fn() };
|
|
21
21
|
|
|
22
22
|
const { container } = render(<StructureNav {...props} />, renderOpts);
|
|
23
23
|
expect(container).toMatchSnapshot();
|
|
@@ -26,7 +26,10 @@ const renderOpts = {
|
|
|
26
26
|
|
|
27
27
|
describe("<SystemFilteredNav />", () => {
|
|
28
28
|
it("matches the latest snapshot", () => {
|
|
29
|
-
const { container } = render(
|
|
29
|
+
const { container } = render(
|
|
30
|
+
<SystemFilteredNav fnHasCatalogViewProp={jest.fn()} />,
|
|
31
|
+
renderOpts
|
|
32
|
+
);
|
|
30
33
|
expect(container).toMatchSnapshot();
|
|
31
34
|
});
|
|
32
35
|
});
|
|
@@ -2,7 +2,12 @@ import useSWR from "swr";
|
|
|
2
2
|
import { apiJsonPost } from "@truedat/core/services/api";
|
|
3
3
|
import { API_BUCKET_STRUCTURES } from "../api";
|
|
4
4
|
|
|
5
|
-
export const useBucketStructures = ({
|
|
5
|
+
export const useBucketStructures = ({
|
|
6
|
+
navFilter,
|
|
7
|
+
parentFilter,
|
|
8
|
+
ids,
|
|
9
|
+
query,
|
|
10
|
+
}) => {
|
|
6
11
|
const params =
|
|
7
12
|
navFilter?.view === "SYSTEM_STRUCTURES"
|
|
8
13
|
? { filters: { ...navFilter.filter, ...parentFilter }, query }
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import _ from "lodash/fp";
|
|
2
|
-
import React, { useState } from "react";
|
|
3
|
-
import PropTypes from "prop-types";
|
|
4
|
-
import {
|
|
5
|
-
Button,
|
|
6
|
-
Checkbox,
|
|
7
|
-
Container,
|
|
8
|
-
Divider,
|
|
9
|
-
Icon,
|
|
10
|
-
List,
|
|
11
|
-
Message,
|
|
12
|
-
Segment,
|
|
13
|
-
} from "semantic-ui-react";
|
|
14
|
-
import { FormattedMessage, useIntl } from "react-intl";
|
|
15
|
-
import { apiJson } from "@truedat/core/services/api";
|
|
16
|
-
|
|
17
|
-
export default function StructureNoteSuggestions({
|
|
18
|
-
aiSuggestionsAction,
|
|
19
|
-
applySuggestions,
|
|
20
|
-
template,
|
|
21
|
-
isModification,
|
|
22
|
-
}) {
|
|
23
|
-
const [loadingSuggestion, setLoadingSuggestion] = useState();
|
|
24
|
-
const [suggestions, setSuggestions] = useState();
|
|
25
|
-
const [suggestionsError, setSuggestionsError] = useState();
|
|
26
|
-
const [selectedSuggestions, setSelectedSuggestions] = useState([]);
|
|
27
|
-
|
|
28
|
-
const { locale } = useIntl();
|
|
29
|
-
|
|
30
|
-
const suggestionKeys = _.keys(suggestions);
|
|
31
|
-
const fieldInSuggestions = ({ name }) => _.includes(name)(suggestionKeys);
|
|
32
|
-
const templateFields = _.flow(
|
|
33
|
-
_.prop("content"),
|
|
34
|
-
_.filter(({ fields }) => _.any(fieldInSuggestions)(fields)),
|
|
35
|
-
_.map(({ name, fields }) => ({
|
|
36
|
-
name,
|
|
37
|
-
fields: _.filter(fieldInSuggestions)(fields),
|
|
38
|
-
}))
|
|
39
|
-
)(template);
|
|
40
|
-
const validFields = _.flow(
|
|
41
|
-
_.prop("content"),
|
|
42
|
-
_.flatMap(({ fields }) =>
|
|
43
|
-
_.flow(
|
|
44
|
-
_.filter(({ editable }) => editable || !isModification),
|
|
45
|
-
_.map(({ name }) => name)
|
|
46
|
-
)(fields)
|
|
47
|
-
)
|
|
48
|
-
)(template);
|
|
49
|
-
|
|
50
|
-
const handleRequestSuggestions = () => {
|
|
51
|
-
setLoadingSuggestion(true);
|
|
52
|
-
setSuggestionsError(null);
|
|
53
|
-
setSelectedSuggestions([]);
|
|
54
|
-
setSuggestions(null);
|
|
55
|
-
const url = `${aiSuggestionsAction.href}?language=${locale}`;
|
|
56
|
-
apiJson(url).then(({ data: { data: suggestions } }) => {
|
|
57
|
-
if (_.prop("[0]")(suggestions) === "error") {
|
|
58
|
-
setSuggestionsError(
|
|
59
|
-
_.prop("[1].error.message")(suggestions) || _.prop("[1]")(suggestions)
|
|
60
|
-
);
|
|
61
|
-
} else {
|
|
62
|
-
setSuggestions(suggestions);
|
|
63
|
-
const selectedFields = _.flow(
|
|
64
|
-
_.keys,
|
|
65
|
-
_.filter(
|
|
66
|
-
(key) =>
|
|
67
|
-
_.includes(key)(validFields) && !_.isEmpty(suggestions[key])
|
|
68
|
-
)
|
|
69
|
-
)(suggestions);
|
|
70
|
-
setSelectedSuggestions(selectedFields);
|
|
71
|
-
}
|
|
72
|
-
setLoadingSuggestion(false);
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
const handleApplySuggestions = () => {
|
|
76
|
-
applySuggestions(_.pick(selectedSuggestions)(suggestions));
|
|
77
|
-
setSelectedSuggestions([]);
|
|
78
|
-
setSuggestions(null);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const toggleSelectedSuggestion = (name) => {
|
|
82
|
-
setSelectedSuggestions(
|
|
83
|
-
_.includes(name)(selectedSuggestions)
|
|
84
|
-
? _.reject((v) => v == name)(selectedSuggestions)
|
|
85
|
-
: [...selectedSuggestions, name]
|
|
86
|
-
);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<Segment loading={loadingSuggestion}>
|
|
91
|
-
<Container style={{ display: "flex", justifyContent: "space-between" }}>
|
|
92
|
-
<h4>
|
|
93
|
-
{suggestions ? (
|
|
94
|
-
<Icon name="lightbulb outline" />
|
|
95
|
-
) : (
|
|
96
|
-
<Icon name="lightbulb" />
|
|
97
|
-
)}
|
|
98
|
-
<FormattedMessage id="structure_note.ai_suggestion.header" />
|
|
99
|
-
</h4>
|
|
100
|
-
<Divider hidden />
|
|
101
|
-
{suggestions ? null : (
|
|
102
|
-
<Button onClick={handleRequestSuggestions}>
|
|
103
|
-
<FormattedMessage id="actions.ai_suggestion" />
|
|
104
|
-
</Button>
|
|
105
|
-
)}
|
|
106
|
-
</Container>
|
|
107
|
-
{suggestionsError ? (
|
|
108
|
-
<Message negative>
|
|
109
|
-
<Message.Header>
|
|
110
|
-
<FormattedMessage id="structure_note.ai_suggestion.error" />
|
|
111
|
-
</Message.Header>
|
|
112
|
-
<p>{suggestionsError}</p>
|
|
113
|
-
</Message>
|
|
114
|
-
) : null}
|
|
115
|
-
{suggestions ? (
|
|
116
|
-
<>
|
|
117
|
-
{_.map(({ name: groupName, fields }) => (
|
|
118
|
-
<Container key={`group-${groupName}`}>
|
|
119
|
-
<>
|
|
120
|
-
<h5>{groupName ? groupName : ""}</h5>
|
|
121
|
-
<List>
|
|
122
|
-
{_.map(({ name, label, editable }) => (
|
|
123
|
-
<List.Item
|
|
124
|
-
key={name}
|
|
125
|
-
style={{
|
|
126
|
-
display: "flex",
|
|
127
|
-
alignItems: "center",
|
|
128
|
-
gap: "12px",
|
|
129
|
-
}}
|
|
130
|
-
>
|
|
131
|
-
<Checkbox
|
|
132
|
-
id={name}
|
|
133
|
-
disabled={
|
|
134
|
-
(isModification && !editable) ||
|
|
135
|
-
_.isEmpty(suggestions[name])
|
|
136
|
-
}
|
|
137
|
-
checked={_.includes(name)(selectedSuggestions)}
|
|
138
|
-
onChange={() => toggleSelectedSuggestion(name)}
|
|
139
|
-
/>
|
|
140
|
-
<label
|
|
141
|
-
htmlFor={name}
|
|
142
|
-
style={{ cursor: "pointer" }}
|
|
143
|
-
disabled
|
|
144
|
-
>
|
|
145
|
-
<List.Header>{label}</List.Header>
|
|
146
|
-
<List.Description>
|
|
147
|
-
{_.isEmpty(suggestions[name])
|
|
148
|
-
? "-"
|
|
149
|
-
: suggestions[name]}
|
|
150
|
-
</List.Description>
|
|
151
|
-
</label>
|
|
152
|
-
</List.Item>
|
|
153
|
-
))(fields)}
|
|
154
|
-
</List>
|
|
155
|
-
<Divider hidden />
|
|
156
|
-
</>
|
|
157
|
-
</Container>
|
|
158
|
-
))(templateFields)}
|
|
159
|
-
<Container textAlign="right">
|
|
160
|
-
<Button
|
|
161
|
-
primary
|
|
162
|
-
onClick={handleApplySuggestions}
|
|
163
|
-
disabled={_.isEmpty(selectedSuggestions)}
|
|
164
|
-
>
|
|
165
|
-
<FormattedMessage id="actions.apply_ai_suggestion" />
|
|
166
|
-
</Button>
|
|
167
|
-
</Container>
|
|
168
|
-
</>
|
|
169
|
-
) : null}
|
|
170
|
-
</Segment>
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
StructureNoteSuggestions.propTypes = {
|
|
175
|
-
aiSuggestionsAction: PropTypes.object,
|
|
176
|
-
applySuggestions: PropTypes.func,
|
|
177
|
-
template: PropTypes.object,
|
|
178
|
-
isModification: PropTypes.bool,
|
|
179
|
-
};
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import React, { Suspense } from "react";
|
|
2
|
-
import { waitFor } from "@testing-library/react";
|
|
3
|
-
import userEvent from "@testing-library/user-event";
|
|
4
|
-
import { render } from "@truedat/test/render";
|
|
5
|
-
import StructureNoteSuggestions from "../StructureNoteSuggestions";
|
|
6
|
-
|
|
7
|
-
const mockSuggestions = {
|
|
8
|
-
editable_field: "editable_field_value",
|
|
9
|
-
non_editable_field: "non_editable_field_value",
|
|
10
|
-
unselect_field: "unselect_field_value",
|
|
11
|
-
};
|
|
12
|
-
jest.mock("@truedat/core/services/api", () => ({
|
|
13
|
-
apiJson: (url) => ({
|
|
14
|
-
then: (callback) =>
|
|
15
|
-
callback({
|
|
16
|
-
data: {
|
|
17
|
-
data: url.startsWith("suggestions")
|
|
18
|
-
? mockSuggestions
|
|
19
|
-
: url.startsWith("error_message")
|
|
20
|
-
? ["error", { error: { message: "ERROR MESSAGE" } }]
|
|
21
|
-
: ["error", "ERROR TEXT"],
|
|
22
|
-
},
|
|
23
|
-
}),
|
|
24
|
-
}),
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
const messages = {
|
|
28
|
-
en: {
|
|
29
|
-
"actions.cancel": "cancel",
|
|
30
|
-
"actions.save": "save",
|
|
31
|
-
"structure_note.ai_suggestion.header": "header",
|
|
32
|
-
"actions.apply_ai_suggestion": "actions.apply_ai_suggestion",
|
|
33
|
-
"actions.ai_suggestion": "actions.ai_suggestion",
|
|
34
|
-
"structure_note.ai_suggestion.error": "error",
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
describe("<StructureNoteSuggestions />", () => {
|
|
39
|
-
it("matches the latest snapshot", () => {
|
|
40
|
-
const props = {
|
|
41
|
-
template: {},
|
|
42
|
-
};
|
|
43
|
-
const { container } = render(
|
|
44
|
-
<Suspense fallback={null}>
|
|
45
|
-
<StructureNoteSuggestions {...props} />
|
|
46
|
-
</Suspense>,
|
|
47
|
-
{ messages }
|
|
48
|
-
);
|
|
49
|
-
expect(container).toMatchSnapshot();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("component lifecycle", async () => {
|
|
53
|
-
const applySuggestions = jest.fn();
|
|
54
|
-
const props = {
|
|
55
|
-
aiSuggestionsAction: { href: "suggestions" },
|
|
56
|
-
applySuggestions,
|
|
57
|
-
template: {
|
|
58
|
-
content: [
|
|
59
|
-
{
|
|
60
|
-
fields: [
|
|
61
|
-
{
|
|
62
|
-
name: "editable_field",
|
|
63
|
-
label: "EditableField",
|
|
64
|
-
editable: true,
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: "Group2",
|
|
70
|
-
fields: [
|
|
71
|
-
{
|
|
72
|
-
name: "non_editable_field",
|
|
73
|
-
label: "NonEditableField",
|
|
74
|
-
editable: false,
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
name: "unselect_field",
|
|
78
|
-
label: "UnselectedField",
|
|
79
|
-
editable: true,
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
isModification: true,
|
|
86
|
-
};
|
|
87
|
-
const { container, findByText, queryByText } = render(
|
|
88
|
-
<Suspense fallback={null}>
|
|
89
|
-
<StructureNoteSuggestions {...props} />
|
|
90
|
-
</Suspense>,
|
|
91
|
-
{ messages }
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
userEvent.click(await findByText(/actions.ai_suggestion/i));
|
|
95
|
-
await waitFor(() =>
|
|
96
|
-
expect(queryByText(/actions.ai_suggestion/i)).not.toBeInTheDocument()
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
expect(container).toMatchSnapshot();
|
|
100
|
-
|
|
101
|
-
userEvent.click(await findByText(/UnselectedField/i));
|
|
102
|
-
userEvent.click(await findByText(/UnselectedField/i));
|
|
103
|
-
userEvent.click(await findByText(/UnselectedField/i));
|
|
104
|
-
|
|
105
|
-
userEvent.click(await findByText(/actions.apply_ai_suggestion/i));
|
|
106
|
-
await waitFor(() =>
|
|
107
|
-
expect(
|
|
108
|
-
queryByText(/actions.apply_ai_suggestion/i)
|
|
109
|
-
).not.toBeInTheDocument()
|
|
110
|
-
);
|
|
111
|
-
expect(applySuggestions).toHaveBeenCalledWith(
|
|
112
|
-
expect.objectContaining({ editable_field: "editable_field_value" })
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
expect(container).toMatchSnapshot();
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("renders error with message", async () => {
|
|
119
|
-
const props = {
|
|
120
|
-
aiSuggestionsAction: { href: "error_message" },
|
|
121
|
-
};
|
|
122
|
-
const { container, findByText, queryByText } = render(
|
|
123
|
-
<Suspense fallback={null}>
|
|
124
|
-
<StructureNoteSuggestions {...props} />
|
|
125
|
-
</Suspense>,
|
|
126
|
-
{ messages }
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
userEvent.click(await findByText(/actions.ai_suggestion/i));
|
|
130
|
-
await waitFor(() =>
|
|
131
|
-
expect(queryByText(/error message/i)).toBeInTheDocument()
|
|
132
|
-
);
|
|
133
|
-
expect(container).toMatchSnapshot();
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it("renders error with message", async () => {
|
|
137
|
-
const props = {
|
|
138
|
-
aiSuggestionsAction: { href: "error_text" },
|
|
139
|
-
};
|
|
140
|
-
const { container, findByText, queryByText } = render(
|
|
141
|
-
<Suspense fallback={null}>
|
|
142
|
-
<StructureNoteSuggestions {...props} />
|
|
143
|
-
</Suspense>,
|
|
144
|
-
{ messages }
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
userEvent.click(await findByText(/actions.ai_suggestion/i));
|
|
148
|
-
await waitFor(() => expect(queryByText(/error text/i)).toBeInTheDocument());
|
|
149
|
-
expect(container).toMatchSnapshot();
|
|
150
|
-
});
|
|
151
|
-
});
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`<StructureNoteSuggestions /> component lifecycle 1`] = `
|
|
4
|
-
<div>
|
|
5
|
-
<div
|
|
6
|
-
class="ui segment"
|
|
7
|
-
>
|
|
8
|
-
<div
|
|
9
|
-
class="ui container"
|
|
10
|
-
style="display: flex; justify-content: space-between;"
|
|
11
|
-
>
|
|
12
|
-
<h4>
|
|
13
|
-
<i
|
|
14
|
-
aria-hidden="true"
|
|
15
|
-
class="lightbulb outline icon"
|
|
16
|
-
/>
|
|
17
|
-
header
|
|
18
|
-
</h4>
|
|
19
|
-
<div
|
|
20
|
-
class="ui hidden divider"
|
|
21
|
-
/>
|
|
22
|
-
</div>
|
|
23
|
-
<div
|
|
24
|
-
class="ui container"
|
|
25
|
-
>
|
|
26
|
-
<h5 />
|
|
27
|
-
<div
|
|
28
|
-
class="ui list"
|
|
29
|
-
role="list"
|
|
30
|
-
>
|
|
31
|
-
<div
|
|
32
|
-
class="item"
|
|
33
|
-
role="listitem"
|
|
34
|
-
style="display: flex; align-items: center; gap: 12px;"
|
|
35
|
-
>
|
|
36
|
-
<div
|
|
37
|
-
class="ui checked fitted checkbox"
|
|
38
|
-
>
|
|
39
|
-
<input
|
|
40
|
-
checked=""
|
|
41
|
-
class="hidden"
|
|
42
|
-
id="editable_field"
|
|
43
|
-
readonly=""
|
|
44
|
-
tabindex="0"
|
|
45
|
-
type="checkbox"
|
|
46
|
-
value=""
|
|
47
|
-
/>
|
|
48
|
-
<label
|
|
49
|
-
for="editable_field"
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
<label
|
|
53
|
-
disabled=""
|
|
54
|
-
for="editable_field"
|
|
55
|
-
style="cursor: pointer;"
|
|
56
|
-
>
|
|
57
|
-
<div
|
|
58
|
-
class="header"
|
|
59
|
-
>
|
|
60
|
-
EditableField
|
|
61
|
-
</div>
|
|
62
|
-
<div
|
|
63
|
-
class="description"
|
|
64
|
-
>
|
|
65
|
-
editable_field_value
|
|
66
|
-
</div>
|
|
67
|
-
</label>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
<div
|
|
71
|
-
class="ui hidden divider"
|
|
72
|
-
/>
|
|
73
|
-
</div>
|
|
74
|
-
<div
|
|
75
|
-
class="ui container"
|
|
76
|
-
>
|
|
77
|
-
<h5>
|
|
78
|
-
Group2
|
|
79
|
-
</h5>
|
|
80
|
-
<div
|
|
81
|
-
class="ui list"
|
|
82
|
-
role="list"
|
|
83
|
-
>
|
|
84
|
-
<div
|
|
85
|
-
class="item"
|
|
86
|
-
role="listitem"
|
|
87
|
-
style="display: flex; align-items: center; gap: 12px;"
|
|
88
|
-
>
|
|
89
|
-
<div
|
|
90
|
-
class="ui disabled fitted checkbox"
|
|
91
|
-
>
|
|
92
|
-
<input
|
|
93
|
-
class="hidden"
|
|
94
|
-
disabled=""
|
|
95
|
-
id="non_editable_field"
|
|
96
|
-
readonly=""
|
|
97
|
-
tabindex="-1"
|
|
98
|
-
type="checkbox"
|
|
99
|
-
value=""
|
|
100
|
-
/>
|
|
101
|
-
<label
|
|
102
|
-
for="non_editable_field"
|
|
103
|
-
/>
|
|
104
|
-
</div>
|
|
105
|
-
<label
|
|
106
|
-
disabled=""
|
|
107
|
-
for="non_editable_field"
|
|
108
|
-
style="cursor: pointer;"
|
|
109
|
-
>
|
|
110
|
-
<div
|
|
111
|
-
class="header"
|
|
112
|
-
>
|
|
113
|
-
NonEditableField
|
|
114
|
-
</div>
|
|
115
|
-
<div
|
|
116
|
-
class="description"
|
|
117
|
-
>
|
|
118
|
-
non_editable_field_value
|
|
119
|
-
</div>
|
|
120
|
-
</label>
|
|
121
|
-
</div>
|
|
122
|
-
<div
|
|
123
|
-
class="item"
|
|
124
|
-
role="listitem"
|
|
125
|
-
style="display: flex; align-items: center; gap: 12px;"
|
|
126
|
-
>
|
|
127
|
-
<div
|
|
128
|
-
class="ui checked fitted checkbox"
|
|
129
|
-
>
|
|
130
|
-
<input
|
|
131
|
-
checked=""
|
|
132
|
-
class="hidden"
|
|
133
|
-
id="unselect_field"
|
|
134
|
-
readonly=""
|
|
135
|
-
tabindex="0"
|
|
136
|
-
type="checkbox"
|
|
137
|
-
value=""
|
|
138
|
-
/>
|
|
139
|
-
<label
|
|
140
|
-
for="unselect_field"
|
|
141
|
-
/>
|
|
142
|
-
</div>
|
|
143
|
-
<label
|
|
144
|
-
disabled=""
|
|
145
|
-
for="unselect_field"
|
|
146
|
-
style="cursor: pointer;"
|
|
147
|
-
>
|
|
148
|
-
<div
|
|
149
|
-
class="header"
|
|
150
|
-
>
|
|
151
|
-
UnselectedField
|
|
152
|
-
</div>
|
|
153
|
-
<div
|
|
154
|
-
class="description"
|
|
155
|
-
>
|
|
156
|
-
unselect_field_value
|
|
157
|
-
</div>
|
|
158
|
-
</label>
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
<div
|
|
162
|
-
class="ui hidden divider"
|
|
163
|
-
/>
|
|
164
|
-
</div>
|
|
165
|
-
<div
|
|
166
|
-
class="ui right aligned container"
|
|
167
|
-
>
|
|
168
|
-
<button
|
|
169
|
-
class="ui primary button"
|
|
170
|
-
>
|
|
171
|
-
actions.apply_ai_suggestion
|
|
172
|
-
</button>
|
|
173
|
-
</div>
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
`;
|
|
177
|
-
|
|
178
|
-
exports[`<StructureNoteSuggestions /> component lifecycle 2`] = `
|
|
179
|
-
<div>
|
|
180
|
-
<div
|
|
181
|
-
class="ui segment"
|
|
182
|
-
>
|
|
183
|
-
<div
|
|
184
|
-
class="ui container"
|
|
185
|
-
style="display: flex; justify-content: space-between;"
|
|
186
|
-
>
|
|
187
|
-
<h4>
|
|
188
|
-
<i
|
|
189
|
-
aria-hidden="true"
|
|
190
|
-
class="lightbulb icon"
|
|
191
|
-
/>
|
|
192
|
-
header
|
|
193
|
-
</h4>
|
|
194
|
-
<div
|
|
195
|
-
class="ui hidden divider"
|
|
196
|
-
/>
|
|
197
|
-
<button
|
|
198
|
-
class="ui button"
|
|
199
|
-
>
|
|
200
|
-
actions.ai_suggestion
|
|
201
|
-
</button>
|
|
202
|
-
</div>
|
|
203
|
-
</div>
|
|
204
|
-
</div>
|
|
205
|
-
`;
|
|
206
|
-
|
|
207
|
-
exports[`<StructureNoteSuggestions /> matches the latest snapshot 1`] = `
|
|
208
|
-
<div>
|
|
209
|
-
<div
|
|
210
|
-
class="ui segment"
|
|
211
|
-
>
|
|
212
|
-
<div
|
|
213
|
-
class="ui container"
|
|
214
|
-
style="display: flex; justify-content: space-between;"
|
|
215
|
-
>
|
|
216
|
-
<h4>
|
|
217
|
-
<i
|
|
218
|
-
aria-hidden="true"
|
|
219
|
-
class="lightbulb icon"
|
|
220
|
-
/>
|
|
221
|
-
header
|
|
222
|
-
</h4>
|
|
223
|
-
<div
|
|
224
|
-
class="ui hidden divider"
|
|
225
|
-
/>
|
|
226
|
-
<button
|
|
227
|
-
class="ui button"
|
|
228
|
-
>
|
|
229
|
-
actions.ai_suggestion
|
|
230
|
-
</button>
|
|
231
|
-
</div>
|
|
232
|
-
</div>
|
|
233
|
-
</div>
|
|
234
|
-
`;
|
|
235
|
-
|
|
236
|
-
exports[`<StructureNoteSuggestions /> renders error with message 1`] = `
|
|
237
|
-
<div>
|
|
238
|
-
<div
|
|
239
|
-
class="ui segment"
|
|
240
|
-
>
|
|
241
|
-
<div
|
|
242
|
-
class="ui container"
|
|
243
|
-
style="display: flex; justify-content: space-between;"
|
|
244
|
-
>
|
|
245
|
-
<h4>
|
|
246
|
-
<i
|
|
247
|
-
aria-hidden="true"
|
|
248
|
-
class="lightbulb icon"
|
|
249
|
-
/>
|
|
250
|
-
header
|
|
251
|
-
</h4>
|
|
252
|
-
<div
|
|
253
|
-
class="ui hidden divider"
|
|
254
|
-
/>
|
|
255
|
-
<button
|
|
256
|
-
class="ui button"
|
|
257
|
-
>
|
|
258
|
-
actions.ai_suggestion
|
|
259
|
-
</button>
|
|
260
|
-
</div>
|
|
261
|
-
<div
|
|
262
|
-
class="ui negative message"
|
|
263
|
-
>
|
|
264
|
-
<div
|
|
265
|
-
class="header"
|
|
266
|
-
>
|
|
267
|
-
error
|
|
268
|
-
</div>
|
|
269
|
-
<p>
|
|
270
|
-
ERROR MESSAGE
|
|
271
|
-
</p>
|
|
272
|
-
</div>
|
|
273
|
-
</div>
|
|
274
|
-
</div>
|
|
275
|
-
`;
|
|
276
|
-
|
|
277
|
-
exports[`<StructureNoteSuggestions /> renders error with message 2`] = `
|
|
278
|
-
<div>
|
|
279
|
-
<div
|
|
280
|
-
class="ui segment"
|
|
281
|
-
>
|
|
282
|
-
<div
|
|
283
|
-
class="ui container"
|
|
284
|
-
style="display: flex; justify-content: space-between;"
|
|
285
|
-
>
|
|
286
|
-
<h4>
|
|
287
|
-
<i
|
|
288
|
-
aria-hidden="true"
|
|
289
|
-
class="lightbulb icon"
|
|
290
|
-
/>
|
|
291
|
-
header
|
|
292
|
-
</h4>
|
|
293
|
-
<div
|
|
294
|
-
class="ui hidden divider"
|
|
295
|
-
/>
|
|
296
|
-
<button
|
|
297
|
-
class="ui button"
|
|
298
|
-
>
|
|
299
|
-
actions.ai_suggestion
|
|
300
|
-
</button>
|
|
301
|
-
</div>
|
|
302
|
-
<div
|
|
303
|
-
class="ui negative message"
|
|
304
|
-
>
|
|
305
|
-
<div
|
|
306
|
-
class="header"
|
|
307
|
-
>
|
|
308
|
-
error
|
|
309
|
-
</div>
|
|
310
|
-
<p>
|
|
311
|
-
ERROR TEXT
|
|
312
|
-
</p>
|
|
313
|
-
</div>
|
|
314
|
-
</div>
|
|
315
|
-
</div>
|
|
316
|
-
`;
|