@truedat/bg 4.51.2 → 4.51.4

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.
@@ -1,188 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React, { useState, useEffect } from "react";
3
- import { connect } from "react-redux";
4
- import { Dropdown, Form, Icon, Input, Label } from "semantic-ui-react";
5
- import PropTypes from "prop-types";
6
- import { lowerDeburr } from "@truedat/core/services/sort";
7
- import { useIntl } from "react-intl";
8
- import { DropdownMenuItem } from "@truedat/core/components";
9
- import { getDomainSelectorOptions } from "../selectors";
10
-
11
- export const DomainMenuSelector = ({
12
- domainOptions: options,
13
- error,
14
- label,
15
- name,
16
- onBlur,
17
- onChange,
18
- required = false,
19
- value: externalValue,
20
- }) => {
21
- const [value, setValue] = useState(externalValue || []);
22
- const [query, setQuery] = useState();
23
- const [open, setOpen] = useState([]);
24
- const [displayed, setDisplayed] = useState([]);
25
- const { formatMessage } = useIntl();
26
-
27
- useEffect(() => {
28
- const selectIds = (key, fromIds) =>
29
- _.flow(
30
- _.filter(({ id }) => _.contains(id)(fromIds)),
31
- _.map(key),
32
- _.flatten,
33
- _.map("id"),
34
- _.uniq
35
- );
36
-
37
- const ancestorIds = selectIds("ancestors", value)(options);
38
- setOpen(_.union(open)(ancestorIds));
39
-
40
- const childrenIds = selectIds("children", ancestorIds)(options);
41
- setDisplayed(_.union(displayed)(childrenIds));
42
- }, [options]);
43
- const handleOpen = (domainId) => {
44
- const domain = _.find({ id: domainId })(options);
45
- const isOpen = _.contains(domainId)(open);
46
- const children = _.map("id")(domain.children);
47
- const descendents = _.map("id")(domain.descendents);
48
-
49
- if (isOpen) {
50
- setOpen(_.without([domainId, ...descendents])(open));
51
- setDisplayed(_.without(descendents)(displayed));
52
- } else {
53
- setOpen(_.union([domainId])(open));
54
- setDisplayed(_.union(children)(displayed));
55
- }
56
- };
57
-
58
- const displayAll = () => {
59
- const ids = _.map("id")(options);
60
- setOpen(ids);
61
- setDisplayed(ids);
62
- };
63
-
64
- const handleSearch = (e, { value }) => {
65
- e.preventDefault();
66
- setQuery(lowerDeburr(value));
67
- if (!_.isEmpty(value)) {
68
- displayAll();
69
- }
70
- };
71
-
72
- const handleClick = (e, domainId) => {
73
- const ids = _.includes(domainId)(value)
74
- ? _.without([domainId])(value)
75
- : _.union([domainId])(value);
76
- setValue(ids);
77
- onChange && onChange(e, { value: ids });
78
- };
79
-
80
- const match = (name, query) => _.contains(query)(lowerDeburr(name));
81
- const filterSearch = (all) => {
82
- if (query) {
83
- return _.filter(
84
- (domain) =>
85
- match(domain.name, query) ||
86
- _.some((descendent) => match(descendent.name, query))(
87
- domain.descendents
88
- )
89
- )(all);
90
- }
91
- return all;
92
- };
93
-
94
- const filterDisplayed = (all) =>
95
- _.filter((domain) => domain.level == 0 || _.contains(domain.id)(displayed))(
96
- all
97
- );
98
-
99
- const trigger = _.isEmpty(value) ? (
100
- <label>{formatMessage({ id: "domain.multiple.placeholder" })}</label>
101
- ) : (
102
- <>
103
- {_.map((id) => (
104
- <Label key={id}>
105
- {_.flow(_.find({ id }), _.prop("name"))(options)}
106
- <Icon
107
- name="delete"
108
- onClick={(e) => {
109
- e.preventDefault();
110
- e.stopPropagation();
111
- handleClick(e, id);
112
- }}
113
- />
114
- </Label>
115
- ))(value)}
116
- </>
117
- );
118
-
119
- const filteredOptions = _.flow(filterSearch, filterDisplayed)(options);
120
-
121
- return (
122
- <Form.Dropdown
123
- error={error}
124
- floating
125
- label={label}
126
- name={name}
127
- onBlur={onBlur}
128
- upward={false}
129
- required={required}
130
- trigger={trigger}
131
- multiple
132
- value={value}
133
- >
134
- <Dropdown.Menu>
135
- <Input
136
- icon="search"
137
- iconPosition="left"
138
- className="search"
139
- onKeyDown={(e) => {
140
- if (e.key === " ") {
141
- e.stopPropagation();
142
- }
143
- }}
144
- onChange={handleSearch}
145
- onClick={(e) => {
146
- e.preventDefault();
147
- e.stopPropagation();
148
- }}
149
- />
150
- <Dropdown.Menu scrolling>
151
- {_.map.convert({ cap: false })((option, i) => (
152
- <DropdownMenuItem
153
- key={i}
154
- check={false}
155
- onOpen={handleOpen}
156
- onClick={handleClick}
157
- open={_.contains(option.id)(open)}
158
- canOpen={_.negate(_.isEmpty)(option.children)}
159
- selected={_.contains(option.id)(value)}
160
- {...option}
161
- />
162
- ))(filteredOptions)}
163
- </Dropdown.Menu>
164
- </Dropdown.Menu>
165
- </Form.Dropdown>
166
- );
167
- };
168
-
169
- DomainMenuSelector.propTypes = {
170
- disabledOptions: PropTypes.array,
171
- domainOptions: PropTypes.array,
172
- error: PropTypes.bool,
173
- label: PropTypes.string,
174
- name: PropTypes.string,
175
- onBlur: PropTypes.func,
176
- onChange: PropTypes.func,
177
- required: PropTypes.bool,
178
- value: PropTypes.array,
179
- };
180
-
181
- const mapStateToProps = (state, props) => ({
182
- domainOptions: _.flow(
183
- _.prop("domainOptions"),
184
- _.defaultTo(getDomainSelectorOptions(state))
185
- )(props),
186
- });
187
-
188
- export default connect(mapStateToProps)(DomainMenuSelector);
@@ -1,119 +0,0 @@
1
- import React from "react";
2
- import { waitFor } from "@testing-library/react";
3
- import userEvent, { specialChars } from "@testing-library/user-event";
4
- import { render } from "@truedat/test/render";
5
- import { DomainDropdownSelector } from "../DomainDropdownSelector";
6
-
7
- describe("<DomainDropdownSelector />", () => {
8
- const onChange = jest.fn();
9
-
10
- const domainOptions = [
11
- {
12
- id: 1,
13
- name: "Domain 1",
14
- level: 0,
15
- ancestors: [],
16
- children: [{ id: 2, name: "Domain 2", level: 1 }],
17
- descendents: [{ id: 2, name: "Domain 2", level: 1 }],
18
- },
19
- {
20
- id: 2,
21
- name: "Domain 2",
22
- level: 1,
23
- children: [],
24
- ancestors: [
25
- {
26
- id: 1,
27
- name: "Domain 1",
28
- },
29
- ],
30
- },
31
- { id: 3, name: "Domain 3", level: 0, children: [], ancestors: [] },
32
- ];
33
-
34
- const props = {
35
- domainOptions,
36
- onChange: onChange,
37
- };
38
-
39
- const messages = {
40
- en: {
41
- "template.form.validation.empty_required": "Required",
42
- "domain.selector.label": "Domain",
43
- "domain.selector.placeholder": "Select domain...",
44
- },
45
- };
46
-
47
- it("matches the latest snapshot", () => {
48
- const { container } = render(<DomainDropdownSelector {...props} />, {
49
- messages,
50
- });
51
- expect(container).toMatchSnapshot();
52
- });
53
-
54
- it("handles the selection of a colapsed element", async () => {
55
- const { getByRole, container, queryByText } = render(
56
- <DomainDropdownSelector {...props} />,
57
- {
58
- messages,
59
- }
60
- );
61
-
62
- userEvent.click(container.querySelector('[class="plus icon"]'));
63
- await waitFor(() => {
64
- expect(getByRole("option", { name: /Domain 2/i })).toBeTruthy();
65
- });
66
- userEvent.click(container.querySelector('[class="minus icon"]'));
67
- await waitFor(() => {
68
- expect(queryByText(/Domain 2/)).toBeFalsy();
69
- });
70
- userEvent.click(container.querySelector('[class="plus icon"]'));
71
- const option = getByRole("option", { name: /Domain 2/i });
72
- userEvent.click(option);
73
- await waitFor(() => {
74
- expect(onChange.mock.calls[0][1]).toEqual({ value: 2 });
75
- });
76
- });
77
-
78
- it("handles the selection of searched elements", async () => {
79
- const { container, getByRole } = render(
80
- <DomainDropdownSelector {...props} />,
81
- {
82
- messages,
83
- }
84
- );
85
- await waitFor(() => {
86
- expect(getByRole("option", { name: /Domain 1/i })).toBeTruthy();
87
- expect(getByRole("option", { name: /Domain 3/i })).toBeTruthy();
88
- });
89
-
90
- const plusIcon = container.querySelector('[class="plus icon"]');
91
- userEvent.click(plusIcon);
92
-
93
- await waitFor(() => {
94
- expect(getByRole("option", { name: /Domain 1/i })).toBeTruthy();
95
- expect(getByRole("option", { name: /Domain 2/i })).toBeTruthy();
96
- expect(getByRole("option", { name: /Domain 3/i })).toBeTruthy();
97
- });
98
-
99
- const input = container.querySelector('[class="search"]');
100
- userEvent.type(input, "2");
101
-
102
- await waitFor(() => {
103
- expect(getByRole("option", { name: /Domain 2/i })).toBeTruthy();
104
- });
105
-
106
- userEvent.type(input, `${specialChars.backspace}1`);
107
-
108
- await waitFor(() => {
109
- expect(getByRole("option", { name: /Domain 1/i })).toBeTruthy();
110
- });
111
-
112
- const option = getByRole("option", { name: /Domain 1/i });
113
- userEvent.click(option);
114
- await waitFor(() => {
115
- expect(onChange.mock.calls[1][1]).toEqual({ value: 1 });
116
- });
117
- document.activeElement.blur();
118
- });
119
- });
@@ -1,122 +0,0 @@
1
- import React from "react";
2
- import { waitFor } from "@testing-library/react";
3
- import userEvent, { specialChars } from "@testing-library/user-event";
4
- import { render } from "@truedat/test/render";
5
- import { DomainMenuSelector } from "../DomainMenuSelector";
6
-
7
- describe("<DomainMenuSelector />", () => {
8
- const onChange = jest.fn();
9
-
10
- const domainOptions = [
11
- {
12
- id: 1,
13
- name: "Domain 1",
14
- level: 0,
15
- ancestors: [],
16
- children: [{ id: 2, name: "Domain 2", level: 1 }],
17
- descendents: [{ id: 2, name: "Domain 2", level: 1 }],
18
- },
19
- {
20
- id: 2,
21
- name: "Domain 2",
22
- level: 1,
23
- children: [],
24
- ancestors: [
25
- {
26
- id: 1,
27
- name: "Domain 1",
28
- },
29
- ],
30
- },
31
- { id: 3, name: "Domain 3", level: 0, children: [], ancestors: [] },
32
- ];
33
-
34
- const props = {
35
- domainOptions,
36
- onChange,
37
- };
38
-
39
- const messages = {
40
- en: {
41
- "domain.multiple.placeholder": "Select domains...",
42
- },
43
- };
44
-
45
- it("matches the latest snapshot", () => {
46
- const { container } = render(<DomainMenuSelector {...props} />, {
47
- messages,
48
- });
49
- expect(container).toMatchSnapshot();
50
- });
51
-
52
- it("handles the selection of a colapsed element", async () => {
53
- const { getByRole, container, queryByText } = render(
54
- <DomainMenuSelector {...props} />,
55
- {
56
- messages,
57
- }
58
- );
59
-
60
- userEvent.click(container.querySelector('[class="plus icon"]'));
61
- await waitFor(() => {
62
- expect(getByRole("option", { name: /Domain 2/i })).toBeTruthy();
63
- });
64
- userEvent.click(container.querySelector('[class="minus icon"]'));
65
- await waitFor(() => {
66
- expect(queryByText(/Domain 2/)).toBeFalsy();
67
- });
68
- userEvent.click(container.querySelector('[class="plus icon"]'));
69
- const option = getByRole("option", { name: /Domain 2/i });
70
- userEvent.click(option);
71
- await waitFor(() => {
72
- expect(onChange.mock.calls[0][1]).toEqual({ value: [2] });
73
- });
74
- });
75
-
76
- it("handles the selection of searched elements", async () => {
77
- const { container, getByRole } = render(<DomainMenuSelector {...props} />, {
78
- messages,
79
- });
80
- await waitFor(() => {
81
- expect(getByRole("option", { name: /Domain 1/i })).toBeTruthy();
82
- expect(getByRole("option", { name: /Domain 3/i })).toBeTruthy();
83
- });
84
-
85
- const plusIcon = container.querySelector('[class="plus icon"]');
86
- userEvent.click(plusIcon);
87
-
88
- await waitFor(() => {
89
- expect(getByRole("option", { name: /Domain 1/i })).toBeTruthy();
90
- expect(getByRole("option", { name: /Domain 2/i })).toBeTruthy();
91
- expect(getByRole("option", { name: /Domain 3/i })).toBeTruthy();
92
- });
93
-
94
- const input = container.querySelector('[type="text"]');
95
- userEvent.type(input, "2");
96
-
97
- await waitFor(() => {
98
- expect(getByRole("option", { name: /Domain 2/i })).toBeTruthy();
99
- });
100
-
101
- userEvent.type(input, `${specialChars.backspace}1`);
102
-
103
- await waitFor(() => {
104
- expect(getByRole("option", { name: /Domain 1/i })).toBeTruthy();
105
- });
106
-
107
- const option = getByRole("option", { name: /Domain 1/i });
108
- userEvent.click(option);
109
- await waitFor(() => {
110
- expect(onChange.mock.calls[1][1]).toEqual({ value: [1] });
111
- expect(
112
- container.querySelector('[class="ui label"]').firstChild.nodeValue
113
- ).toEqual("Domain 1");
114
- });
115
-
116
- userEvent.click(container.querySelector('[class="delete icon"]'));
117
- await waitFor(() => {
118
- expect(onChange.mock.calls[2][1]).toEqual({ value: [] });
119
- expect(container.querySelector('[class="ui label"]')).toBeFalsy();
120
- });
121
- });
122
- });
@@ -1,86 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`<DomainDropdownSelector /> matches the latest snapshot 1`] = `
4
- <div>
5
- <div
6
- class="required field"
7
- >
8
- <label>
9
- Domain
10
- </label>
11
- <div
12
- class="field"
13
- >
14
- <div
15
- aria-expanded="false"
16
- class="ui fluid search selection dropdown"
17
- name="domain"
18
- role="combobox"
19
- >
20
- <input
21
- aria-autocomplete="list"
22
- autocomplete="off"
23
- class="search"
24
- tabindex="0"
25
- type="text"
26
- value=""
27
- />
28
- <div
29
- aria-atomic="true"
30
- aria-live="polite"
31
- class="divider default text"
32
- role="alert"
33
- >
34
- Select domain...
35
- </div>
36
- <i
37
- aria-hidden="true"
38
- class="dropdown icon"
39
- />
40
- <div
41
- aria-multiselectable="false"
42
- class="menu transition"
43
- role="listbox"
44
- >
45
- <div
46
- aria-checked="false"
47
- aria-selected="true"
48
- class="selected item"
49
- role="option"
50
- style="pointer-events: all;"
51
- >
52
- <div
53
- class="text"
54
- style="margin-left: 0px;"
55
- >
56
- <i
57
- aria-hidden="true"
58
- class="plus icon"
59
- />
60
- Domain 1
61
- </div>
62
- </div>
63
- <div
64
- aria-checked="false"
65
- aria-selected="false"
66
- class="item"
67
- role="option"
68
- style="pointer-events: all;"
69
- >
70
- <div
71
- class="text"
72
- style="margin-left: 0px;"
73
- >
74
- <i
75
- aria-hidden="true"
76
- class="icon"
77
- />
78
- Domain 3
79
- </div>
80
- </div>
81
- </div>
82
- </div>
83
- </div>
84
- </div>
85
- </div>
86
- `;
@@ -1,74 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`<DomainMenuSelector /> matches the latest snapshot 1`] = `
4
- <div>
5
- <div
6
- class="field"
7
- >
8
- <div
9
- aria-expanded="false"
10
- aria-multiselectable="true"
11
- class="ui floating multiple dropdown"
12
- role="listbox"
13
- tabindex="0"
14
- >
15
- <label>
16
- Select domains...
17
- </label>
18
- <i
19
- aria-hidden="true"
20
- class="dropdown icon"
21
- />
22
- <div
23
- class="menu transition"
24
- >
25
- <div
26
- class="ui left icon input search"
27
- >
28
- <input
29
- type="text"
30
- />
31
- <i
32
- aria-hidden="true"
33
- class="search icon"
34
- />
35
- </div>
36
- <div
37
- class="scrolling menu transition"
38
- >
39
- <div
40
- aria-selected="false"
41
- class="item"
42
- role="option"
43
- >
44
- <div
45
- style="margin-left: 0px;"
46
- >
47
- <i
48
- aria-hidden="true"
49
- class="plus icon"
50
- />
51
- Domain 1
52
- </div>
53
- </div>
54
- <div
55
- aria-selected="false"
56
- class="item"
57
- role="option"
58
- >
59
- <div
60
- style="margin-left: 0px;"
61
- >
62
- <i
63
- aria-hidden="true"
64
- class="icon"
65
- />
66
- Domain 3
67
- </div>
68
- </div>
69
- </div>
70
- </div>
71
- </div>
72
- </div>
73
- </div>
74
- `;