@truedat/core 7.0.4 → 7.0.6
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 +3 -3
- package/src/components/DomainSelector.js +15 -0
- package/src/components/DropdownMenuItem.js +7 -1
- package/src/components/Hierarchy.js +316 -0
- package/src/components/HierarchyNodeFinder.js +65 -0
- package/src/components/HierarchySelector.js +18 -2
- package/src/components/NodeOpenActions.js +30 -0
- package/src/components/ResourceMembers.js +2 -3
- package/src/components/TreeSelector.js +102 -52
- package/src/components/__tests__/AddResourceMember.spec.js +1 -1
- package/src/components/__tests__/DomainSelector.spec.js +18 -1
- package/src/components/__tests__/Hierarchy.spec.js +42 -0
- package/src/components/__tests__/HierarchyNodeFinder.spec.js +203 -0
- package/src/components/__tests__/ResourceMembers.spec.js +1 -2
- package/src/components/__tests__/TreeSelector.spec.js +19 -1
- package/src/components/__tests__/__snapshots__/DomainSelector.spec.js.snap +83 -2
- package/src/components/__tests__/__snapshots__/Hierarchy.spec.js.snap +189 -0
- package/src/components/__tests__/__snapshots__/HierarchyNodeFinder.spec.js.snap +146 -0
- package/src/components/__tests__/__snapshots__/HierarchySelector.spec.js.snap +2 -2
- package/src/components/__tests__/__snapshots__/TreeSelector.spec.js.snap +45 -2
- package/src/components/index.js +2 -0
- package/src/messages/en.js +3 -0
- package/src/messages/es.js +3 -1
- package/src/routes.js +0 -2
- package/src/search/SearchContext.js +1 -1
- package/src/services/__tests__/tree.spec.js +14 -0
- package/src/services/tree.js +16 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<Hierarchy /> matches snapshot with edition mode 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="column"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="row"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
style="display: flex; flex-direction: row; align-items: self-start;"
|
|
13
|
+
>
|
|
14
|
+
<div
|
|
15
|
+
class="ui input"
|
|
16
|
+
>
|
|
17
|
+
<input
|
|
18
|
+
placeholder="Hierarchy name"
|
|
19
|
+
type="text"
|
|
20
|
+
value="Baggins"
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
23
|
+
<div
|
|
24
|
+
class="description_wrapper"
|
|
25
|
+
>
|
|
26
|
+
<div
|
|
27
|
+
class="description"
|
|
28
|
+
>
|
|
29
|
+
bar
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<ul
|
|
35
|
+
class="wtree expanded"
|
|
36
|
+
>
|
|
37
|
+
<li>
|
|
38
|
+
<i
|
|
39
|
+
aria-hidden="true"
|
|
40
|
+
class="cut large icon li_trash"
|
|
41
|
+
style="cursor: pointer; visibility: hidden;"
|
|
42
|
+
title="Delete node"
|
|
43
|
+
/>
|
|
44
|
+
<div
|
|
45
|
+
style="display: flex; flex-direction: row; align-items: self-start;"
|
|
46
|
+
>
|
|
47
|
+
<div>
|
|
48
|
+
<div
|
|
49
|
+
class="ui left labeled input"
|
|
50
|
+
>
|
|
51
|
+
<div
|
|
52
|
+
class="ui basic label"
|
|
53
|
+
title="Expand"
|
|
54
|
+
>
|
|
55
|
+
<i
|
|
56
|
+
aria-hidden="true"
|
|
57
|
+
class="circle fitted icon"
|
|
58
|
+
style="cursor: pointer;"
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
<input
|
|
62
|
+
placeholder="Node"
|
|
63
|
+
type="text"
|
|
64
|
+
value="Fosco"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
<div
|
|
69
|
+
class="description_wrapper"
|
|
70
|
+
>
|
|
71
|
+
<div
|
|
72
|
+
class="description"
|
|
73
|
+
>
|
|
74
|
+
Add description
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</li>
|
|
79
|
+
<li
|
|
80
|
+
class="add_node"
|
|
81
|
+
>
|
|
82
|
+
<div>
|
|
83
|
+
<form
|
|
84
|
+
class="ui form"
|
|
85
|
+
>
|
|
86
|
+
<div
|
|
87
|
+
class="ui input"
|
|
88
|
+
>
|
|
89
|
+
<input
|
|
90
|
+
placeholder="New node"
|
|
91
|
+
type="text"
|
|
92
|
+
value=""
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
</form>
|
|
96
|
+
</div>
|
|
97
|
+
</li>
|
|
98
|
+
</ul>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
exports[`<Hierarchy /> matches the last snapshot with edition mode false 1`] = `
|
|
104
|
+
<div>
|
|
105
|
+
<div
|
|
106
|
+
class="column"
|
|
107
|
+
>
|
|
108
|
+
<div
|
|
109
|
+
class="row"
|
|
110
|
+
>
|
|
111
|
+
<div
|
|
112
|
+
style="display: flex; flex-direction: row; align-items: self-start;"
|
|
113
|
+
>
|
|
114
|
+
<div
|
|
115
|
+
class="ui disabled input"
|
|
116
|
+
data-position="top left"
|
|
117
|
+
data-tooltip="Baggins"
|
|
118
|
+
style="opacity: 1;"
|
|
119
|
+
>
|
|
120
|
+
<input
|
|
121
|
+
disabled=""
|
|
122
|
+
placeholder="Hierarchy name"
|
|
123
|
+
tabindex="-1"
|
|
124
|
+
type="text"
|
|
125
|
+
value="Baggins"
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
<div
|
|
129
|
+
class="description_wrapper"
|
|
130
|
+
>
|
|
131
|
+
<div
|
|
132
|
+
class="description disabled"
|
|
133
|
+
>
|
|
134
|
+
bar
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
<ul
|
|
140
|
+
class="wtree expanded"
|
|
141
|
+
>
|
|
142
|
+
<li>
|
|
143
|
+
<i
|
|
144
|
+
aria-hidden="true"
|
|
145
|
+
class="cut large icon li_trash"
|
|
146
|
+
style="cursor: pointer; visibility: hidden;"
|
|
147
|
+
title="Delete node"
|
|
148
|
+
/>
|
|
149
|
+
<div
|
|
150
|
+
style="display: flex; flex-direction: row; align-items: self-start;"
|
|
151
|
+
>
|
|
152
|
+
<div>
|
|
153
|
+
<div
|
|
154
|
+
class="ui disabled left labeled input hierarchyNode"
|
|
155
|
+
data-position="top left"
|
|
156
|
+
data-tooltip="Fosco"
|
|
157
|
+
>
|
|
158
|
+
<div
|
|
159
|
+
class="ui basic label"
|
|
160
|
+
title="Expand"
|
|
161
|
+
>
|
|
162
|
+
<i
|
|
163
|
+
aria-hidden="true"
|
|
164
|
+
class="circle fitted icon"
|
|
165
|
+
style="cursor: pointer;"
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
<input
|
|
169
|
+
disabled=""
|
|
170
|
+
placeholder="Node"
|
|
171
|
+
tabindex="-1"
|
|
172
|
+
type="text"
|
|
173
|
+
value="Fosco"
|
|
174
|
+
/>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
<div
|
|
178
|
+
class="description_wrapper"
|
|
179
|
+
>
|
|
180
|
+
<div
|
|
181
|
+
class="description disabled"
|
|
182
|
+
/>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</li>
|
|
186
|
+
</ul>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
`;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`HierarchyNodeFinder matches the latest snapshot 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="ui segment"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="ui grid"
|
|
10
|
+
>
|
|
11
|
+
<div
|
|
12
|
+
class="row"
|
|
13
|
+
>
|
|
14
|
+
<div
|
|
15
|
+
class="sixteen wide column"
|
|
16
|
+
>
|
|
17
|
+
<button
|
|
18
|
+
class="ui icon secondary right floated button nodeOpenActions"
|
|
19
|
+
data-position="bottom right"
|
|
20
|
+
data-tooltip="Open all"
|
|
21
|
+
>
|
|
22
|
+
<i
|
|
23
|
+
aria-hidden="true"
|
|
24
|
+
class="plus icon"
|
|
25
|
+
/>
|
|
26
|
+
</button>
|
|
27
|
+
<div
|
|
28
|
+
class="menu transition hierarchyNodeFinderTreeSelector"
|
|
29
|
+
>
|
|
30
|
+
<div
|
|
31
|
+
class="ui fluid left icon input search notDropdownInput"
|
|
32
|
+
>
|
|
33
|
+
<input
|
|
34
|
+
type="text"
|
|
35
|
+
/>
|
|
36
|
+
<i
|
|
37
|
+
aria-hidden="true"
|
|
38
|
+
class="search icon"
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
41
|
+
<div
|
|
42
|
+
class="scrolling menu transition notDropdownSelector"
|
|
43
|
+
>
|
|
44
|
+
<div
|
|
45
|
+
aria-selected="false"
|
|
46
|
+
class="item"
|
|
47
|
+
role="option"
|
|
48
|
+
>
|
|
49
|
+
<div
|
|
50
|
+
style="margin-left: 0px;"
|
|
51
|
+
>
|
|
52
|
+
<i
|
|
53
|
+
aria-hidden="true"
|
|
54
|
+
class="icon"
|
|
55
|
+
/>
|
|
56
|
+
<span
|
|
57
|
+
style="opacity: 1;"
|
|
58
|
+
>
|
|
59
|
+
element_1
|
|
60
|
+
</span>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
<div
|
|
64
|
+
aria-selected="false"
|
|
65
|
+
class="item"
|
|
66
|
+
role="option"
|
|
67
|
+
>
|
|
68
|
+
<div
|
|
69
|
+
style="margin-left: 0px;"
|
|
70
|
+
>
|
|
71
|
+
<i
|
|
72
|
+
aria-hidden="true"
|
|
73
|
+
class="plus icon"
|
|
74
|
+
/>
|
|
75
|
+
<span
|
|
76
|
+
style="opacity: 1;"
|
|
77
|
+
>
|
|
78
|
+
element_2
|
|
79
|
+
</span>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
<div
|
|
83
|
+
aria-selected="false"
|
|
84
|
+
class="item ascendant"
|
|
85
|
+
role="option"
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
style="margin-left: 0px;"
|
|
89
|
+
>
|
|
90
|
+
<i
|
|
91
|
+
aria-hidden="true"
|
|
92
|
+
class="minus icon"
|
|
93
|
+
/>
|
|
94
|
+
<span
|
|
95
|
+
style="opacity: 1;"
|
|
96
|
+
>
|
|
97
|
+
element_5
|
|
98
|
+
</span>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
<div
|
|
102
|
+
aria-selected="false"
|
|
103
|
+
class="item ascendant"
|
|
104
|
+
role="option"
|
|
105
|
+
>
|
|
106
|
+
<div
|
|
107
|
+
style="margin-left: 8px;"
|
|
108
|
+
>
|
|
109
|
+
<i
|
|
110
|
+
aria-hidden="true"
|
|
111
|
+
class="minus icon"
|
|
112
|
+
/>
|
|
113
|
+
<span
|
|
114
|
+
style="opacity: 1;"
|
|
115
|
+
>
|
|
116
|
+
element_6
|
|
117
|
+
</span>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<div
|
|
121
|
+
aria-selected="true"
|
|
122
|
+
class="selected item ascendant"
|
|
123
|
+
role="option"
|
|
124
|
+
>
|
|
125
|
+
<div
|
|
126
|
+
style="margin-left: 16px;"
|
|
127
|
+
>
|
|
128
|
+
<i
|
|
129
|
+
aria-hidden="true"
|
|
130
|
+
class="icon"
|
|
131
|
+
/>
|
|
132
|
+
<span
|
|
133
|
+
style="opacity: 1;"
|
|
134
|
+
>
|
|
135
|
+
element_7
|
|
136
|
+
</span>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
`;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<HierarchySelector /> matches latest snapshot 1`] = `
|
|
4
4
|
<div>
|
|
5
5
|
<div
|
|
6
|
-
class="field fix-dropdown-selector"
|
|
6
|
+
class="field fix-dropdown-selector "
|
|
7
7
|
>
|
|
8
8
|
<div
|
|
9
9
|
aria-disabled="false"
|
|
@@ -24,7 +24,7 @@ exports[`<HierarchySelector /> matches latest snapshot 1`] = `
|
|
|
24
24
|
class="menu transition"
|
|
25
25
|
>
|
|
26
26
|
<div
|
|
27
|
-
class="ui left icon input search"
|
|
27
|
+
class="ui fluid left icon input search "
|
|
28
28
|
>
|
|
29
29
|
<input
|
|
30
30
|
type="text"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<TreeSelector /> matches latest snapshot 1`] = `
|
|
4
4
|
<div>
|
|
5
5
|
<div
|
|
6
|
-
class="field fix-dropdown-selector"
|
|
6
|
+
class="field fix-dropdown-selector testClassName"
|
|
7
7
|
>
|
|
8
8
|
<div
|
|
9
9
|
aria-disabled="false"
|
|
@@ -24,7 +24,7 @@ exports[`<TreeSelector /> matches latest snapshot 1`] = `
|
|
|
24
24
|
class="menu transition"
|
|
25
25
|
>
|
|
26
26
|
<div
|
|
27
|
-
class="ui left icon input search"
|
|
27
|
+
class="ui fluid left icon input search "
|
|
28
28
|
>
|
|
29
29
|
<input
|
|
30
30
|
type="text"
|
|
@@ -62,3 +62,46 @@ exports[`<TreeSelector /> matches latest snapshot 1`] = `
|
|
|
62
62
|
</div>
|
|
63
63
|
</div>
|
|
64
64
|
`;
|
|
65
|
+
|
|
66
|
+
exports[`<TreeSelector /> matches latest snapshot with notDropdown parameter 1`] = `
|
|
67
|
+
<div>
|
|
68
|
+
<div
|
|
69
|
+
class="menu transition testClassName"
|
|
70
|
+
>
|
|
71
|
+
<div
|
|
72
|
+
class="ui fluid left icon input search notDropdownInput"
|
|
73
|
+
>
|
|
74
|
+
<input
|
|
75
|
+
type="text"
|
|
76
|
+
/>
|
|
77
|
+
<i
|
|
78
|
+
aria-hidden="true"
|
|
79
|
+
class="search icon"
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
<div
|
|
83
|
+
class="scrolling menu transition notDropdownSelector"
|
|
84
|
+
>
|
|
85
|
+
<div
|
|
86
|
+
aria-selected="false"
|
|
87
|
+
class="item"
|
|
88
|
+
role="option"
|
|
89
|
+
>
|
|
90
|
+
<div
|
|
91
|
+
style="margin-left: 0px;"
|
|
92
|
+
>
|
|
93
|
+
<i
|
|
94
|
+
aria-hidden="true"
|
|
95
|
+
class="plus icon"
|
|
96
|
+
/>
|
|
97
|
+
<span
|
|
98
|
+
style="opacity: 1;"
|
|
99
|
+
>
|
|
100
|
+
foo
|
|
101
|
+
</span>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
`;
|
package/src/components/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import AdminMenu from "./AdminMenu";
|
|
|
3
3
|
import Alert from "./Alert";
|
|
4
4
|
import Authorized from "./Authorized";
|
|
5
5
|
import AvailableFilters from "./AvailableFilters";
|
|
6
|
+
import HierarchyNodeFinder from "./HierarchyNodeFinder";
|
|
6
7
|
import CardGroupsAccordion from "./CardGroupsAccordion";
|
|
7
8
|
import CatalogMenu from "./CatalogMenu";
|
|
8
9
|
import Comments from "./Comments";
|
|
@@ -59,6 +60,7 @@ export {
|
|
|
59
60
|
Alert,
|
|
60
61
|
Authorized,
|
|
61
62
|
AvailableFilters,
|
|
63
|
+
HierarchyNodeFinder,
|
|
62
64
|
CardGroupsAccordion,
|
|
63
65
|
CatalogMenu,
|
|
64
66
|
Comments,
|
package/src/messages/en.js
CHANGED
|
@@ -15,6 +15,8 @@ export default {
|
|
|
15
15
|
"actions.share": "Share",
|
|
16
16
|
"actions.submit": "Send for approval",
|
|
17
17
|
"actions.update": "Update",
|
|
18
|
+
"actions.close.all": "Close all",
|
|
19
|
+
"actions.open.all": "Open all",
|
|
18
20
|
"alert.createComment.failed.header": "Error creating comment",
|
|
19
21
|
"alert.fetchComments.failed.header": "Error fetching comments list",
|
|
20
22
|
"alert.status.401.content":
|
|
@@ -47,6 +49,7 @@ export default {
|
|
|
47
49
|
"dateFilter.weeks": "weeks ago",
|
|
48
50
|
"dateFilter.months": "months ago",
|
|
49
51
|
"dateFilter.years": "years ago",
|
|
52
|
+
"domains.notExist": "There are no domains",
|
|
50
53
|
emptyBucket: "(Empty)",
|
|
51
54
|
"error.content": "Please report this error to the Truedat team.",
|
|
52
55
|
"error.duplicated": "duplicated",
|
package/src/messages/es.js
CHANGED
|
@@ -15,6 +15,8 @@ export default {
|
|
|
15
15
|
"actions.share": "Compartir",
|
|
16
16
|
"actions.submit": "Solicitar aprobación",
|
|
17
17
|
"actions.update": "Actualizar",
|
|
18
|
+
"actions.close.all": "Cerrar todos",
|
|
19
|
+
"actions.open.all": "Abrir todos",
|
|
18
20
|
"alert.createComment.failed.header": "Error creando comentario",
|
|
19
21
|
"alert.fetchComments.failed.header": "Error cargando la lista de comentarios",
|
|
20
22
|
"alert.status.401.content":
|
|
@@ -48,6 +50,7 @@ export default {
|
|
|
48
50
|
"dateFilter.weeks": "semanas",
|
|
49
51
|
"dateFilter.months": "meses",
|
|
50
52
|
"dateFilter.years": "años",
|
|
53
|
+
"domains.notExist": "No existen dominios",
|
|
51
54
|
emptyBucket: "(Vacío)",
|
|
52
55
|
"error.content": "Por favor, coméntaselo al equipo de Truedat.",
|
|
53
56
|
"error.duplicated": "duplicado",
|
|
@@ -63,7 +66,6 @@ export default {
|
|
|
63
66
|
"hierarchy.multiple.placeholder": "Seleccionar Jerarquías",
|
|
64
67
|
"hierarchy.selector.placeholder": "Seleccionar Jerarquía",
|
|
65
68
|
"i18n.actions.createMessage": "Crear mensaje",
|
|
66
|
-
|
|
67
69
|
"i18n.message.form.messageId.placeholder": "Id del mensaje",
|
|
68
70
|
"i18n.message.form.definition.placeholder": "Definición",
|
|
69
71
|
"i18n.message.form.description.placeholder": "Descripción",
|
package/src/routes.js
CHANGED
|
@@ -50,7 +50,6 @@ export const DOMAIN = "/domains/:id";
|
|
|
50
50
|
export const DOMAINS = "/domains";
|
|
51
51
|
export const DOMAINS_ACTIONS = "/domains/:action";
|
|
52
52
|
export const DOMAINS_NEW = "/domains/new";
|
|
53
|
-
export const DOMAINS_SEARCH = "/domains/search";
|
|
54
53
|
export const DOMAIN_CONCEPTS = "/domains/:id/concepts";
|
|
55
54
|
export const DOMAIN_IMPLEMENTATIONS = "/domains/:id/implementations";
|
|
56
55
|
export const DOMAIN_EDIT = "/domains/:id/edit";
|
|
@@ -300,7 +299,6 @@ const routes = {
|
|
|
300
299
|
DOMAINS,
|
|
301
300
|
DOMAINS_ACTIONS,
|
|
302
301
|
DOMAINS_NEW,
|
|
303
|
-
DOMAINS_SEARCH,
|
|
304
302
|
DOMAIN_CONCEPTS,
|
|
305
303
|
DOMAIN_EDIT,
|
|
306
304
|
DOMAIN_IMPLEMENTATIONS,
|
|
@@ -17,7 +17,7 @@ import { makeOption } from "@truedat/core/services/i18n";
|
|
|
17
17
|
|
|
18
18
|
const SearchContext = createContext();
|
|
19
19
|
|
|
20
|
-
const debounceQueryTime = 300;
|
|
20
|
+
const debounceQueryTime = process.env.SEARCH_DEBOUNCE_TIME || 300;
|
|
21
21
|
|
|
22
22
|
export const SearchContextProvider = (props) => {
|
|
23
23
|
const initialDefaultFilters = _.prop("defaultFilters")(props);
|
|
@@ -2,6 +2,7 @@ import _ from "lodash/fp";
|
|
|
2
2
|
import {
|
|
3
3
|
flatten,
|
|
4
4
|
childIds,
|
|
5
|
+
ascendants,
|
|
5
6
|
descendents,
|
|
6
7
|
recursiveMatch,
|
|
7
8
|
stratify,
|
|
@@ -56,6 +57,19 @@ describe("descendents", () => {
|
|
|
56
57
|
});
|
|
57
58
|
});
|
|
58
59
|
|
|
60
|
+
describe("ascendants", () => {
|
|
61
|
+
it("returns ascendant ids", () => {
|
|
62
|
+
const foo = { id: 1, name: "foo", parent_id: null };
|
|
63
|
+
const bar = { id: 2, name: "bar", parent_id: 1 };
|
|
64
|
+
const baz = { id: 3, name: "baz", parent_id: 2 };
|
|
65
|
+
const qux = { id: 4, name: "qux", parent_id: null };
|
|
66
|
+
const nodes = [foo, bar, baz, qux];
|
|
67
|
+
const selectedNode = 3;
|
|
68
|
+
const res = ascendants(selectedNode, nodes);
|
|
69
|
+
expect(res).toEqual(["1", "2", "3"]);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
59
73
|
describe("recursiveMatch", () => {
|
|
60
74
|
it("matches recursively", () => {
|
|
61
75
|
const match =
|
package/src/services/tree.js
CHANGED
|
@@ -36,6 +36,22 @@ export const recursiveMatch = (match) => (query) => (d) =>
|
|
|
36
36
|
export const descendents = ({ id, children }) =>
|
|
37
37
|
_.isArray(children) ? [id, ...children.flatMap(descendents)] : [id];
|
|
38
38
|
|
|
39
|
+
export const ascendants = (selectedNode, nodes) => {
|
|
40
|
+
const ascendants = [];
|
|
41
|
+
const findAscendantsRecursive = (nodeId) => {
|
|
42
|
+
const node = selectedNode ? nodes.find((n) => n.id === nodeId) : [];
|
|
43
|
+
if (node && nodeId) {
|
|
44
|
+
ascendants.push(`${nodeId}`);
|
|
45
|
+
if (node.parent_id) {
|
|
46
|
+
findAscendantsRecursive(node.parent_id);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
findAscendantsRecursive(selectedNode);
|
|
51
|
+
const reversedAscendants = [...ascendants].reverse();
|
|
52
|
+
return reversedAscendants;
|
|
53
|
+
};
|
|
54
|
+
|
|
39
55
|
export const childIds = (ids) =>
|
|
40
56
|
_.flow(
|
|
41
57
|
_.filter(({ id }) => _.contains(id)(ids)),
|