@squiz/resource-browser 1.69.0 → 1.69.1

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.
@@ -2,35 +2,39 @@
2
2
  import React from 'react';
3
3
  import { screen, render, waitFor, within } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
- import { mockSource } from '../__mocks__/MockModels';
5
+ import { mockResource, mockSource } from '../__mocks__/MockModels';
6
6
  import { useOverlayTriggerState, OverlayTriggerState } from 'react-stately';
7
7
  import SourceList from './SourceList';
8
8
  import { Source } from '../types';
9
+ import { RecentResourcesPaths } from '../Hooks/useRecentResourcesPaths';
9
10
 
10
- const mockLocalStorageData = [
11
+ const mockRecentSources: RecentResourcesPaths[] = [
11
12
  {
12
- path: [],
13
- source: {
13
+ source: mockSource({
14
14
  id: '1',
15
- name: 'Test source',
16
- nodes: [],
17
- },
18
- rootNode: {
19
- childCount: 0,
20
- id: '1',
21
- lineages: [],
22
- name: 'Test resource',
23
- status: {
24
- code: 'live',
25
- name: 'Live',
26
- },
27
- type: {
28
- code: 'folder',
29
- name: 'Folder',
30
- },
31
- url: 'https://no-where.com',
32
- urls: [],
33
- },
15
+ name: 'Source 1',
16
+ nodes: [
17
+ {
18
+ id: '1',
19
+ type: {
20
+ code: 'site',
21
+ name: 'Site',
22
+ },
23
+ name: 'Node 1',
24
+ childCount: 21,
25
+ },
26
+ {
27
+ id: '2',
28
+ type: {
29
+ code: 'site',
30
+ name: 'Site',
31
+ },
32
+ name: 'Node 2',
33
+ childCount: 13,
34
+ },
35
+ ],
36
+ }),
37
+ path: [mockResource()],
34
38
  },
35
39
  ];
36
40
 
@@ -111,6 +115,7 @@ describe('SourceList', () => {
111
115
  error={null}
112
116
  handleReload={reload}
113
117
  setSource={() => {}}
118
+ recentSources={mockRecentSources}
114
119
  />
115
120
  );
116
121
  }}
@@ -138,6 +143,7 @@ describe('SourceList', () => {
138
143
  error={null}
139
144
  handleReload={reload}
140
145
  setSource={() => {}}
146
+ recentSources={mockRecentSources}
141
147
  />
142
148
  );
143
149
  }}
@@ -166,6 +172,7 @@ describe('SourceList', () => {
166
172
  error={null}
167
173
  handleReload={reload}
168
174
  setSource={() => {}}
175
+ recentSources={mockRecentSources}
169
176
  />
170
177
  );
171
178
  }}
@@ -193,6 +200,7 @@ describe('SourceList', () => {
193
200
  error={null}
194
201
  handleReload={reload}
195
202
  setSource={() => {}}
203
+ recentSources={mockRecentSources}
196
204
  />
197
205
  );
198
206
  }}
@@ -227,6 +235,7 @@ describe('SourceList', () => {
227
235
  error={null}
228
236
  handleReload={reload}
229
237
  setSource={() => {}}
238
+ recentSources={mockRecentSources}
230
239
  />
231
240
  );
232
241
  }}
@@ -266,6 +275,7 @@ describe('SourceList', () => {
266
275
  error={null}
267
276
  handleReload={reload}
268
277
  setSource={() => {}}
278
+ recentSources={mockRecentSources}
269
279
  />
270
280
  );
271
281
  }}
@@ -301,6 +311,7 @@ describe('SourceList', () => {
301
311
  error={new Error('Source list error!')}
302
312
  handleReload={reload}
303
313
  setSource={() => {}}
314
+ recentSources={mockRecentSources}
304
315
  />
305
316
  );
306
317
  }}
@@ -317,8 +328,6 @@ describe('SourceList', () => {
317
328
  const reload = jest.fn();
318
329
  const setSource = jest.fn();
319
330
 
320
- localStorage.setItem('rb_recent_locations', JSON.stringify(mockLocalStorageData));
321
-
322
331
  render(
323
332
  <SourceListTestWrapper
324
333
  constructFunction={(previewModalState) => {
@@ -332,6 +341,7 @@ describe('SourceList', () => {
332
341
  error={null}
333
342
  handleReload={reload}
334
343
  setSource={setSource}
344
+ recentSources={mockRecentSources}
335
345
  />
336
346
  );
337
347
  }}
@@ -348,8 +358,6 @@ describe('SourceList', () => {
348
358
  const reload = jest.fn();
349
359
  const setSource = jest.fn();
350
360
 
351
- localStorage.setItem('rb_recent_locations', JSON.stringify(mockLocalStorageData));
352
-
353
361
  render(
354
362
  <SourceListTestWrapper
355
363
  constructFunction={(previewModalState) => {
@@ -363,6 +371,7 @@ describe('SourceList', () => {
363
371
  error={null}
364
372
  handleReload={reload}
365
373
  setSource={setSource}
374
+ recentSources={mockRecentSources}
366
375
  />
367
376
  );
368
377
  }}
@@ -377,55 +386,63 @@ describe('SourceList', () => {
377
386
  // Provides the item that was clicked and an id reference to the button that was clicked
378
387
  expect(setSource).toHaveBeenCalledWith(
379
388
  {
380
- source: mockLocalStorageData[0].source,
381
- resource: mockLocalStorageData[0].rootNode,
382
- },
383
- mockLocalStorageData[0].path,
384
- );
385
- });
386
- });
387
-
388
- it('Uses source name if resource name is not available', async () => {
389
- const reload = jest.fn();
390
- const setSource = jest.fn();
391
-
392
- localStorage.setItem(
393
- 'rb_recent_locations',
394
- JSON.stringify([
395
- {
396
- path: [],
389
+ resource: {
390
+ childCount: 0,
391
+ id: '1',
392
+ lineages: [],
393
+ name: 'Test resource',
394
+ status: {
395
+ code: 'live',
396
+ name: 'Live',
397
+ },
398
+ type: {
399
+ code: 'folder',
400
+ name: 'Folder',
401
+ },
402
+ url: 'https://no-where.com',
403
+ urls: [],
404
+ },
397
405
  source: {
398
406
  id: '1',
399
- name: 'Test source',
400
- nodes: [],
407
+ name: 'Source 1',
408
+ nodes: [
409
+ {
410
+ childCount: 21,
411
+ id: '1',
412
+ lineages: [],
413
+ name: 'Node 1',
414
+ status: {
415
+ code: 'live',
416
+ name: 'Live',
417
+ },
418
+ type: {
419
+ code: 'site',
420
+ name: 'Site',
421
+ },
422
+ url: 'https://no-where.com',
423
+ urls: [],
424
+ },
425
+ {
426
+ childCount: 13,
427
+ id: '2',
428
+ lineages: [],
429
+ name: 'Node 2',
430
+ status: {
431
+ code: 'live',
432
+ name: 'Live',
433
+ },
434
+ type: {
435
+ code: 'site',
436
+ name: 'Site',
437
+ },
438
+ url: 'https://no-where.com',
439
+ urls: [],
440
+ },
441
+ ],
401
442
  },
402
- rootNode: null,
403
443
  },
404
- ]),
405
- );
406
-
407
- render(
408
- <SourceListTestWrapper
409
- constructFunction={(previewModalState) => {
410
- return (
411
- <SourceList
412
- sources={sources}
413
- previewModalState={previewModalState}
414
- isLoading={false}
415
- onSourceSelect={() => {}}
416
- onSourceDrilldown={() => {}}
417
- error={null}
418
- handleReload={reload}
419
- setSource={setSource}
420
- />
421
- );
422
- }}
423
- />,
424
- );
425
-
426
- await waitFor(() => {
427
- expect(screen.getByText('Recent locations')).toBeInTheDocument();
428
- expect(screen.getByText('Test source')).toBeInTheDocument();
444
+ [],
445
+ );
429
446
  });
430
447
  });
431
448
  });
@@ -6,8 +6,8 @@ import clsx from 'clsx';
6
6
 
7
7
  import { Source, ScopedSource, Resource } from '../types';
8
8
  import { useCategorisedSources } from '../Hooks/useCategorisedSources';
9
- import { useRecentLocations } from '../Hooks/useRecentLocations';
10
9
  import { HistoryIcon } from '../Icons/HistoryIcon';
10
+ import { RecentResourcesPaths } from '../Hooks/useRecentResourcesPaths';
11
11
 
12
12
  export interface SourceListProps {
13
13
  sources: Source[];
@@ -18,6 +18,7 @@ export interface SourceListProps {
18
18
  onSourceDrilldown: (source: ScopedSource) => void;
19
19
  handleReload: () => void;
20
20
  setSource: (source: ScopedSource | null, path?: Resource[]) => void;
21
+ recentSources: RecentResourcesPaths[];
21
22
  error: Error | null;
22
23
  }
23
24
 
@@ -30,11 +31,12 @@ const SourceList = function ({
30
31
  onSourceDrilldown,
31
32
  handleReload,
32
33
  setSource,
34
+ recentSources,
33
35
  error,
34
36
  }: SourceListProps) {
35
37
  const categorisedSources = useCategorisedSources(sources);
36
38
  const listRef = useRef<HTMLUListElement>(null);
37
- const { recentLocations } = useRecentLocations();
39
+ const filteredRecentSources = recentSources.filter((item) => item.path?.length);
38
40
 
39
41
  useEffect(() => {
40
42
  if (listRef.current) {
@@ -62,7 +64,7 @@ const SourceList = function ({
62
64
  >
63
65
  {error && <ResourceState state="error" message={error.message} handleReload={handleReload} />}
64
66
 
65
- {!error && recentLocations.length > 0 && (
67
+ {!error && filteredRecentSources.length > 0 && (
66
68
  <li className={`flex flex-col text-sm font-semibold text-grey-800`}>
67
69
  <div className="relative flex justify-center before:w-full before:h-px before:bg-gray-300 before:absolute before:top-2/4 before:z-0">
68
70
  <span className="z-10 bg-gray-100 px-2.5 flex gap-1 items-center">
@@ -71,31 +73,34 @@ const SourceList = function ({
71
73
  </span>
72
74
  </div>
73
75
  <ul aria-label={`recent location nodes`} className="flex flex-col">
74
- {recentLocations.map((item, index) => {
75
- const lastResource = item.path[item.path.length - 1];
76
- return (
77
- <ResourceItem
78
- key={`${index}-${item.source?.id}-${item.rootNode?.id}`}
79
- item={{ source: item.source, resource: item.rootNode }}
80
- label={lastResource?.name || item.rootNode?.name || item?.source.name}
81
- type={lastResource?.type?.code || item.rootNode?.type?.code || 'folder'}
82
- previewModalState={previewModalState}
83
- onSelect={() => {
84
- setSource(
85
- {
86
- source: item.source as Source,
87
- resource: item.rootNode,
88
- },
89
- item.path,
90
- );
91
- }}
92
- className={clsx(
93
- index === 0 && 'rounded-t-lg mt-3',
94
- index === recentLocations.length - 1 && 'rounded-b-lg',
95
- )}
96
- showChevron
97
- />
98
- );
76
+ {filteredRecentSources.map((item, index) => {
77
+ if (item.path) {
78
+ const lastResource = item.path[item.path.length - 1];
79
+ const [rootNode, ...path] = item.path;
80
+ return (
81
+ <ResourceItem
82
+ key={`${index}-${item.source?.id}-${lastResource?.id}`}
83
+ item={{ source: item.source, resource: lastResource }}
84
+ label={lastResource?.name || item.source?.name || ''}
85
+ type={lastResource?.type?.code || 'folder'}
86
+ previewModalState={previewModalState}
87
+ onSelect={() => {
88
+ setSource(
89
+ {
90
+ source: item.source as Source,
91
+ resource: rootNode,
92
+ },
93
+ path,
94
+ );
95
+ }}
96
+ className={clsx(
97
+ index === 0 && 'rounded-t-lg mt-3',
98
+ index === filteredRecentSources.length - 1 && 'rounded-b-lg',
99
+ )}
100
+ showChevron
101
+ />
102
+ );
103
+ }
99
104
  })}
100
105
  </ul>
101
106
  </li>
@@ -107,7 +112,7 @@ const SourceList = function ({
107
112
  <li
108
113
  key={key}
109
114
  className={`flex flex-col text-sm font-semibold text-grey-800 ${
110
- index > 0 || recentLocations.length > 0 ? 'mt-3' : ''
115
+ index > 0 || filteredRecentSources.length > 0 ? 'mt-3' : ''
111
116
  }`}
112
117
  >
113
118
  <div className="relative flex justify-center before:w-full before:h-px before:bg-gray-300 before:absolute before:top-2/4 before:z-0">