datajunction-ui 0.0.14 → 0.0.16
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 +1 -1
- package/src/app/components/__tests__/NodeMaterializationDelete.test.jsx +263 -0
- package/src/app/components/__tests__/QueryInfo.test.jsx +174 -46
- package/src/app/components/__tests__/Search.test.jsx +300 -56
- package/src/app/pages/AddEditNodePage/FormikSelect.jsx +15 -2
- package/src/app/pages/NamespacePage/Explorer.jsx +192 -21
- package/src/app/pages/NamespacePage/__tests__/AddNamespacePopover.test.jsx +283 -0
- package/src/app/pages/NamespacePage/__tests__/index.test.jsx +74 -41
- package/src/app/pages/NamespacePage/index.jsx +13 -7
- package/src/app/pages/NodePage/AddComplexDimensionLinkPopover.jsx +367 -0
- package/src/app/pages/NodePage/LinkDimensionPopover.jsx +1 -1
- package/src/app/pages/NodePage/ManageDimensionLinksDialog.jsx +526 -0
- package/src/app/pages/NodePage/NodeColumnTab.jsx +223 -58
- package/src/app/pages/NodePage/__tests__/AddComplexDimensionLinkPopover.test.jsx +459 -0
- package/src/app/pages/NodePage/__tests__/EditColumnPopover.test.jsx +2 -6
- package/src/app/pages/NodePage/__tests__/LinkDimensionPopover.test.jsx +19 -48
- package/src/app/pages/NodePage/__tests__/ManageDimensionLinksDialog.test.jsx +390 -0
- package/src/app/pages/NodePage/__tests__/NodePage.test.jsx +22 -12
- package/src/app/pages/RegisterTablePage/__tests__/RegisterTablePage.test.jsx +4 -2
- package/src/app/services/DJService.js +46 -6
- package/src/app/services/__tests__/DJService.test.jsx +551 -5
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, fireEvent, waitFor, act } from '@testing-library/react';
|
|
3
|
+
import AddNamespacePopover from '../AddNamespacePopover';
|
|
4
|
+
import DJClientContext from '../../../providers/djclient';
|
|
5
|
+
|
|
6
|
+
// Mock window.location.reload
|
|
7
|
+
delete window.location;
|
|
8
|
+
window.location = { reload: jest.fn() };
|
|
9
|
+
|
|
10
|
+
const mockDjClient = {
|
|
11
|
+
DataJunctionAPI: {
|
|
12
|
+
addNamespace: jest.fn(),
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe('<AddNamespacePopover />', () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.clearAllMocks();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const defaultProps = {
|
|
22
|
+
namespace: 'default',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
it('renders the toggle button', () => {
|
|
26
|
+
const { getByLabelText } = render(
|
|
27
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
28
|
+
<AddNamespacePopover {...defaultProps} />
|
|
29
|
+
</DJClientContext.Provider>,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
expect(getByLabelText('AddNamespaceTogglePopover')).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('opens popover when toggle button is clicked', async () => {
|
|
36
|
+
const { getByLabelText, getByRole } = render(
|
|
37
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
38
|
+
<AddNamespacePopover {...defaultProps} />
|
|
39
|
+
</DJClientContext.Provider>,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
43
|
+
|
|
44
|
+
await waitFor(() => {
|
|
45
|
+
expect(
|
|
46
|
+
getByRole('dialog', { name: 'AddNamespacePopover' }),
|
|
47
|
+
).toBeVisible();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('pre-fills namespace field with parent namespace', async () => {
|
|
52
|
+
const { getByLabelText, getByDisplayValue } = render(
|
|
53
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
54
|
+
<AddNamespacePopover namespace="parent" />
|
|
55
|
+
</DJClientContext.Provider>,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
59
|
+
|
|
60
|
+
await waitFor(() => {
|
|
61
|
+
expect(getByDisplayValue('parent.')).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('displays namespace input field and save button', async () => {
|
|
66
|
+
const { getByLabelText, getByText } = render(
|
|
67
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
68
|
+
<AddNamespacePopover {...defaultProps} />
|
|
69
|
+
</DJClientContext.Provider>,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
73
|
+
|
|
74
|
+
await waitFor(() => {
|
|
75
|
+
expect(getByLabelText('Namespace')).toBeInTheDocument();
|
|
76
|
+
expect(getByLabelText('SaveNamespace')).toBeInTheDocument();
|
|
77
|
+
expect(getByText('Save')).toBeInTheDocument();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('allows typing in namespace field', async () => {
|
|
82
|
+
const { getByLabelText, getByPlaceholderText } = render(
|
|
83
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
84
|
+
<AddNamespacePopover {...defaultProps} />
|
|
85
|
+
</DJClientContext.Provider>,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
89
|
+
|
|
90
|
+
const namespaceInput = getByPlaceholderText('New namespace');
|
|
91
|
+
|
|
92
|
+
await act(async () => {
|
|
93
|
+
fireEvent.change(namespaceInput, {
|
|
94
|
+
target: { value: 'default.new_namespace' },
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
expect(namespaceInput.value).toBe('default.new_namespace');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('calls addNamespace with correct value on form submission - success', async () => {
|
|
102
|
+
mockDjClient.DataJunctionAPI.addNamespace.mockResolvedValue({
|
|
103
|
+
status: 200,
|
|
104
|
+
json: { message: 'Namespace created' },
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const { getByLabelText, getByPlaceholderText, getByText } = render(
|
|
108
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
109
|
+
<AddNamespacePopover {...defaultProps} />
|
|
110
|
+
</DJClientContext.Provider>,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
114
|
+
|
|
115
|
+
const namespaceInput = getByPlaceholderText('New namespace');
|
|
116
|
+
|
|
117
|
+
await act(async () => {
|
|
118
|
+
fireEvent.change(namespaceInput, { target: { value: 'default.child' } });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const saveButton = getByLabelText('SaveNamespace');
|
|
122
|
+
|
|
123
|
+
await act(async () => {
|
|
124
|
+
fireEvent.click(saveButton);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
await waitFor(() => {
|
|
128
|
+
expect(mockDjClient.DataJunctionAPI.addNamespace).toHaveBeenCalledWith(
|
|
129
|
+
'default.child',
|
|
130
|
+
);
|
|
131
|
+
expect(getByText('Saved')).toBeInTheDocument();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Should reload page after success
|
|
135
|
+
expect(window.location.reload).toHaveBeenCalled();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('calls addNamespace with correct value on form submission - status 201', async () => {
|
|
139
|
+
mockDjClient.DataJunctionAPI.addNamespace.mockResolvedValue({
|
|
140
|
+
status: 201,
|
|
141
|
+
json: { message: 'Namespace created' },
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const { getByLabelText, getByPlaceholderText, getByText } = render(
|
|
145
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
146
|
+
<AddNamespacePopover {...defaultProps} />
|
|
147
|
+
</DJClientContext.Provider>,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
151
|
+
|
|
152
|
+
const namespaceInput = getByPlaceholderText('New namespace');
|
|
153
|
+
|
|
154
|
+
await act(async () => {
|
|
155
|
+
fireEvent.change(namespaceInput, {
|
|
156
|
+
target: { value: 'default.another' },
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const saveButton = getByLabelText('SaveNamespace');
|
|
161
|
+
|
|
162
|
+
await act(async () => {
|
|
163
|
+
fireEvent.click(saveButton);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await waitFor(() => {
|
|
167
|
+
expect(mockDjClient.DataJunctionAPI.addNamespace).toHaveBeenCalledWith(
|
|
168
|
+
'default.another',
|
|
169
|
+
);
|
|
170
|
+
expect(getByText('Saved')).toBeInTheDocument();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(window.location.reload).toHaveBeenCalled();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('displays error message when addNamespace fails', async () => {
|
|
177
|
+
mockDjClient.DataJunctionAPI.addNamespace.mockResolvedValue({
|
|
178
|
+
status: 400,
|
|
179
|
+
json: { message: 'Namespace already exists' },
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const { getByLabelText, getByPlaceholderText, getByText } = render(
|
|
183
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
184
|
+
<AddNamespacePopover {...defaultProps} />
|
|
185
|
+
</DJClientContext.Provider>,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
189
|
+
|
|
190
|
+
const namespaceInput = getByPlaceholderText('New namespace');
|
|
191
|
+
|
|
192
|
+
await act(async () => {
|
|
193
|
+
fireEvent.change(namespaceInput, {
|
|
194
|
+
target: { value: 'default.duplicate' },
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const saveButton = getByLabelText('SaveNamespace');
|
|
199
|
+
|
|
200
|
+
await act(async () => {
|
|
201
|
+
fireEvent.click(saveButton);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
await waitFor(() => {
|
|
205
|
+
expect(mockDjClient.DataJunctionAPI.addNamespace).toHaveBeenCalledWith(
|
|
206
|
+
'default.duplicate',
|
|
207
|
+
);
|
|
208
|
+
expect(getByText('Namespace already exists')).toBeInTheDocument();
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Should still reload page even on failure
|
|
212
|
+
expect(window.location.reload).toHaveBeenCalled();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('closes popover when toggle button is clicked again', async () => {
|
|
216
|
+
const { getByLabelText, getByRole, container } = render(
|
|
217
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
218
|
+
<AddNamespacePopover {...defaultProps} />
|
|
219
|
+
</DJClientContext.Provider>,
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
// Open popover
|
|
223
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
224
|
+
|
|
225
|
+
await waitFor(() => {
|
|
226
|
+
expect(getByRole('dialog')).toBeVisible();
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Close popover
|
|
230
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
231
|
+
|
|
232
|
+
// Popover should still exist but be hidden
|
|
233
|
+
const popover = container.querySelector('[role="dialog"]');
|
|
234
|
+
expect(popover).toHaveStyle({ display: 'none' });
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('handles nested namespace creation', async () => {
|
|
238
|
+
mockDjClient.DataJunctionAPI.addNamespace.mockResolvedValue({
|
|
239
|
+
status: 200,
|
|
240
|
+
json: { message: 'Namespace created' },
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const { getByLabelText, getByDisplayValue } = render(
|
|
244
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
245
|
+
<AddNamespacePopover namespace="parent.child" />
|
|
246
|
+
</DJClientContext.Provider>,
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
250
|
+
|
|
251
|
+
await waitFor(() => {
|
|
252
|
+
expect(getByDisplayValue('parent.child.')).toBeInTheDocument();
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('submits with initial value if not changed', async () => {
|
|
257
|
+
mockDjClient.DataJunctionAPI.addNamespace.mockResolvedValue({
|
|
258
|
+
status: 200,
|
|
259
|
+
json: { message: 'Namespace created' },
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const { getByLabelText, getByText } = render(
|
|
263
|
+
<DJClientContext.Provider value={mockDjClient}>
|
|
264
|
+
<AddNamespacePopover namespace="test" />
|
|
265
|
+
</DJClientContext.Provider>,
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
fireEvent.click(getByLabelText('AddNamespaceTogglePopover'));
|
|
269
|
+
|
|
270
|
+
const saveButton = getByLabelText('SaveNamespace');
|
|
271
|
+
|
|
272
|
+
await act(async () => {
|
|
273
|
+
fireEvent.click(saveButton);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
await waitFor(() => {
|
|
277
|
+
expect(mockDjClient.DataJunctionAPI.addNamespace).toHaveBeenCalledWith(
|
|
278
|
+
'test.',
|
|
279
|
+
);
|
|
280
|
+
expect(getByText('Saved')).toBeInTheDocument();
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|
|
@@ -201,7 +201,15 @@ describe('NamespacePage', () => {
|
|
|
201
201
|
fireEvent.click(screen.getByText('common'));
|
|
202
202
|
});
|
|
203
203
|
|
|
204
|
-
it('can add new namespace via
|
|
204
|
+
it('can add new namespace via inline creation', async () => {
|
|
205
|
+
// Mock window.location to track navigation
|
|
206
|
+
delete window.location;
|
|
207
|
+
window.location = { href: jest.fn() };
|
|
208
|
+
Object.defineProperty(window.location, 'href', {
|
|
209
|
+
set: jest.fn(),
|
|
210
|
+
get: jest.fn(),
|
|
211
|
+
});
|
|
212
|
+
|
|
205
213
|
mockDjClient.addNamespace.mockReturnValue({
|
|
206
214
|
status: 201,
|
|
207
215
|
json: {},
|
|
@@ -212,45 +220,53 @@ describe('NamespacePage', () => {
|
|
|
212
220
|
</DJClientContext.Provider>
|
|
213
221
|
);
|
|
214
222
|
render(
|
|
215
|
-
<MemoryRouter initialEntries={['/namespaces/
|
|
223
|
+
<MemoryRouter initialEntries={['/namespaces/default']}>
|
|
216
224
|
<Routes>
|
|
217
225
|
<Route path="namespaces/:namespace" element={element} />
|
|
218
226
|
</Routes>
|
|
219
227
|
</MemoryRouter>,
|
|
220
228
|
);
|
|
221
229
|
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
230
|
+
// Wait for namespaces to load
|
|
231
|
+
await waitFor(() => {
|
|
232
|
+
expect(screen.getByText('default')).toBeInTheDocument();
|
|
225
233
|
});
|
|
226
|
-
expect(addNamespaceToggle).toBeInTheDocument();
|
|
227
234
|
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
name
|
|
232
|
-
|
|
233
|
-
expect(addNamespacePopover).toBeInTheDocument();
|
|
235
|
+
// Find the namespace and hover to reveal add button
|
|
236
|
+
const defaultNamespace = screen
|
|
237
|
+
.getByText('default')
|
|
238
|
+
.closest('.select-name');
|
|
239
|
+
fireEvent.mouseEnter(defaultNamespace);
|
|
234
240
|
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
241
|
+
// Find the add namespace button (it exists but is hidden, so use getAllByTitle)
|
|
242
|
+
const addButtons = screen.getAllByTitle('Add child namespace');
|
|
243
|
+
const defaultAddButton = addButtons.find(btn =>
|
|
244
|
+
btn
|
|
245
|
+
.closest('.namespace-item')
|
|
246
|
+
?.querySelector('a[href="/namespaces/default"]'),
|
|
239
247
|
);
|
|
240
248
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
249
|
+
expect(defaultAddButton).toBeInTheDocument();
|
|
250
|
+
fireEvent.click(defaultAddButton);
|
|
251
|
+
|
|
252
|
+
// Type in the new namespace name
|
|
253
|
+
await waitFor(() => {
|
|
254
|
+
const input = screen.getByPlaceholderText('New namespace name');
|
|
255
|
+
expect(input).toBeInTheDocument();
|
|
244
256
|
});
|
|
257
|
+
|
|
258
|
+
const input = screen.getByPlaceholderText('New namespace name');
|
|
259
|
+
await userEvent.type(input, 'new_child');
|
|
260
|
+
|
|
261
|
+
// Submit the form
|
|
262
|
+
const submitButton = screen.getByRole('button', { name: '✓' });
|
|
263
|
+
fireEvent.click(submitButton);
|
|
264
|
+
|
|
245
265
|
await waitFor(() => {
|
|
246
|
-
|
|
266
|
+
expect(mockDjClient.addNamespace).toHaveBeenCalledWith(
|
|
267
|
+
'default.new_child',
|
|
268
|
+
);
|
|
247
269
|
});
|
|
248
|
-
expect(mockDjClient.addNamespace).toHaveBeenCalled();
|
|
249
|
-
expect(mockDjClient.addNamespace).toHaveBeenCalledWith(
|
|
250
|
-
'test.namespace.some.random.namespace',
|
|
251
|
-
);
|
|
252
|
-
expect(screen.getByText('Saved')).toBeInTheDocument();
|
|
253
|
-
expect(window.location.reload).toHaveBeenCalled();
|
|
254
270
|
});
|
|
255
271
|
|
|
256
272
|
it('can fail to add namespace', async () => {
|
|
@@ -264,34 +280,51 @@ describe('NamespacePage', () => {
|
|
|
264
280
|
</DJClientContext.Provider>
|
|
265
281
|
);
|
|
266
282
|
render(
|
|
267
|
-
<MemoryRouter initialEntries={['/namespaces/
|
|
283
|
+
<MemoryRouter initialEntries={['/namespaces/default']}>
|
|
268
284
|
<Routes>
|
|
269
285
|
<Route path="namespaces/:namespace" element={element} />
|
|
270
286
|
</Routes>
|
|
271
287
|
</MemoryRouter>,
|
|
272
288
|
);
|
|
273
289
|
|
|
274
|
-
//
|
|
275
|
-
|
|
276
|
-
|
|
290
|
+
// Wait for namespaces to load
|
|
291
|
+
await waitFor(() => {
|
|
292
|
+
expect(screen.getByText('default')).toBeInTheDocument();
|
|
277
293
|
});
|
|
278
|
-
fireEvent.click(addNamespaceToggle);
|
|
279
294
|
|
|
280
|
-
//
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
'
|
|
295
|
+
// Find the namespace and hover to reveal add button
|
|
296
|
+
const defaultNamespace = screen
|
|
297
|
+
.getByText('default')
|
|
298
|
+
.closest('.select-name');
|
|
299
|
+
fireEvent.mouseEnter(defaultNamespace);
|
|
300
|
+
|
|
301
|
+
// Find the add namespace button (it exists but is hidden, so use getAllByTitle)
|
|
302
|
+
const addButtons = screen.getAllByTitle('Add child namespace');
|
|
303
|
+
const defaultAddButton = addButtons.find(btn =>
|
|
304
|
+
btn
|
|
305
|
+
.closest('.namespace-item')
|
|
306
|
+
?.querySelector('a[href="/namespaces/default"]'),
|
|
284
307
|
);
|
|
285
308
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
309
|
+
expect(defaultAddButton).toBeInTheDocument();
|
|
310
|
+
fireEvent.click(defaultAddButton);
|
|
311
|
+
|
|
312
|
+
// Type in the new namespace name
|
|
290
313
|
await waitFor(() => {
|
|
291
|
-
|
|
314
|
+
const input = screen.getByPlaceholderText('New namespace name');
|
|
315
|
+
expect(input).toBeInTheDocument();
|
|
292
316
|
});
|
|
293
317
|
|
|
318
|
+
const input = screen.getByPlaceholderText('New namespace name');
|
|
319
|
+
await userEvent.type(input, 'bad_namespace');
|
|
320
|
+
|
|
321
|
+
// Submit the form
|
|
322
|
+
const submitButton = screen.getByRole('button', { name: '✓' });
|
|
323
|
+
fireEvent.click(submitButton);
|
|
324
|
+
|
|
294
325
|
// Should display failure alert
|
|
295
|
-
|
|
326
|
+
await waitFor(() => {
|
|
327
|
+
expect(screen.getByText('you failed')).toBeInTheDocument();
|
|
328
|
+
});
|
|
296
329
|
});
|
|
297
330
|
});
|
|
@@ -290,23 +290,29 @@ export function NamespacePage() {
|
|
|
290
290
|
</div>
|
|
291
291
|
<div className="table-responsive">
|
|
292
292
|
<div className={`sidebar`}>
|
|
293
|
-
<
|
|
293
|
+
<div
|
|
294
294
|
style={{
|
|
295
|
-
textTransform: 'uppercase',
|
|
296
|
-
fontSize: '0.8125rem',
|
|
297
|
-
fontWeight: '600',
|
|
298
|
-
color: '#95aac9',
|
|
299
295
|
padding: '1rem 1rem 1rem 0',
|
|
300
296
|
}}
|
|
301
297
|
>
|
|
302
|
-
|
|
303
|
-
|
|
298
|
+
<span
|
|
299
|
+
style={{
|
|
300
|
+
textTransform: 'uppercase',
|
|
301
|
+
fontSize: '0.8125rem',
|
|
302
|
+
fontWeight: '600',
|
|
303
|
+
color: '#95aac9',
|
|
304
|
+
}}
|
|
305
|
+
>
|
|
306
|
+
Namespaces
|
|
307
|
+
</span>
|
|
308
|
+
</div>
|
|
304
309
|
{namespaceHierarchy
|
|
305
310
|
? namespaceHierarchy.map(child => (
|
|
306
311
|
<Explorer
|
|
307
312
|
item={child}
|
|
308
313
|
current={state.namespace}
|
|
309
314
|
defaultExpand={true}
|
|
315
|
+
isTopLevel={true}
|
|
310
316
|
key={child.namespace}
|
|
311
317
|
/>
|
|
312
318
|
))
|