@squiz/resource-browser 1.69.1 → 2.1.8-rc.0
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/CHANGELOG.md +88 -35
- package/LICENSE.md +15 -0
- package/README.md +9 -0
- package/jest.config.ts +22 -21
- package/lib/Hooks/useSelectedState.d.ts +15 -0
- package/lib/Hooks/useSelectedState.js +16 -0
- package/lib/Hooks/useSources.d.ts +5 -4
- package/lib/Hooks/useSources.js +25 -1
- package/lib/MainContainer/MainContainer.d.ts +17 -0
- package/lib/MainContainer/MainContainer.js +61 -0
- package/lib/Plugin/Plugin.d.ts +13 -0
- package/lib/Plugin/Plugin.js +17 -0
- package/lib/ResourceBrowserContext/ResourceBrowserContext.d.ts +2 -3
- package/lib/ResourceBrowserContext/ResourceBrowserContext.js +4 -17
- package/lib/ResourceBrowserInput/ResourceBrowserInput.d.ts +24 -0
- package/lib/ResourceBrowserInput/ResourceBrowserInput.js +16 -0
- package/lib/ResourcePicker/ResourcePicker.d.ts +6 -4
- package/lib/ResourcePicker/ResourcePicker.js +14 -8
- package/lib/ResourcePicker/States/Selected.d.ts +10 -4
- package/lib/ResourcePicker/States/Selected.js +11 -32
- package/lib/SourceDropdown/SourceDropdown.d.ts +5 -11
- package/lib/SourceDropdown/SourceDropdown.js +20 -99
- package/lib/SourceList/SourceList.d.ts +5 -16
- package/lib/SourceList/SourceList.js +14 -75
- package/lib/index.css +42 -202
- package/lib/index.d.ts +7 -7
- package/lib/index.js +69 -13
- package/lib/types.d.ts +41 -59
- package/package.json +82 -80
- package/src/Hooks/useSelectedState.spec.ts +46 -0
- package/src/Hooks/useSelectedState.ts +22 -0
- package/src/Hooks/useSources.spec.ts +30 -12
- package/src/Hooks/useSources.ts +33 -4
- package/src/Icons/CircledLoopIcon.tsx +8 -8
- package/src/MainContainer/MainContainer.spec.tsx +203 -0
- package/src/MainContainer/MainContainer.stories.tsx +62 -0
- package/src/MainContainer/MainContainer.tsx +101 -0
- package/src/Plugin/Plugin.spec.tsx +46 -0
- package/src/Plugin/Plugin.tsx +20 -0
- package/src/ResourceBrowserContext/ResourceBrowserContext.spec.tsx +65 -106
- package/src/ResourceBrowserContext/ResourceBrowserContext.tsx +24 -39
- package/src/ResourceBrowserInput/ResourceBrowserInput.spec.tsx +192 -0
- package/src/ResourceBrowserInput/ResourceBrowserInput.tsx +81 -0
- package/src/ResourcePicker/ResourcePicker.spec.tsx +159 -116
- package/src/ResourcePicker/ResourcePicker.stories.tsx +28 -24
- package/src/ResourcePicker/ResourcePicker.tsx +79 -59
- package/src/ResourcePicker/States/Error.tsx +8 -8
- package/src/ResourcePicker/States/Loading.tsx +3 -3
- package/src/ResourcePicker/States/Selected.tsx +66 -73
- package/src/ResourcePicker/mock-image-resource.json +25 -47
- package/src/ResourcePicker/mock-resource.json +11 -13
- package/src/ResourcePicker/resource-picker.scss +13 -13
- package/src/SourceDropdown/SourceDropdown.spec.tsx +65 -391
- package/src/SourceDropdown/SourceDropdown.stories.tsx +21 -24
- package/src/SourceDropdown/SourceDropdown.tsx +80 -258
- package/src/SourceList/SourceList.spec.tsx +37 -430
- package/src/SourceList/SourceList.stories.tsx +17 -37
- package/src/SourceList/SourceList.tsx +28 -155
- package/src/__mocks__/MockModels.ts +56 -25
- package/src/__mocks__/PluginExample.tsx +98 -0
- package/src/__mocks__/StorybookHelpers.tsx +141 -0
- package/src/__mocks__/renderWithContext.tsx +14 -18
- package/src/__mocks__/sample-sources.json +32 -0
- package/src/index.scss +18 -8
- package/src/index.spec.tsx +277 -99
- package/src/index.stories.tsx +65 -39
- package/src/index.tsx +119 -57
- package/src/types.ts +54 -63
- package/tailwind.config.cjs +92 -92
- package/vite.config.js +12 -12
- package/lib/Hooks/useCategorisedSources.d.ts +0 -14
- package/lib/Hooks/useCategorisedSources.js +0 -38
- package/lib/Hooks/useChildResources.d.ts +0 -16
- package/lib/Hooks/useChildResources.js +0 -13
- package/lib/Hooks/usePreselectedResourcePath.d.ts +0 -20
- package/lib/Hooks/usePreselectedResourcePath.js +0 -31
- package/lib/Hooks/useRecentLocations.d.ts +0 -5
- package/lib/Hooks/useRecentLocations.js +0 -38
- package/lib/Hooks/useRecentResourcesPaths.d.ts +0 -20
- package/lib/Hooks/useRecentResourcesPaths.js +0 -30
- package/lib/Hooks/useResource.d.ts +0 -28
- package/lib/Hooks/useResource.js +0 -23
- package/lib/Hooks/useResourcePath.d.ts +0 -16
- package/lib/Hooks/useResourcePath.js +0 -64
- package/lib/Icons/HistoryIcon.d.ts +0 -4
- package/lib/Icons/HistoryIcon.js +0 -13
- package/lib/PreviewPanel/PreviewPanel.d.ts +0 -5
- package/lib/PreviewPanel/PreviewPanel.js +0 -8
- package/lib/PreviewPanel/details/MatrixResource.d.ts +0 -7
- package/lib/PreviewPanel/details/MatrixResource.js +0 -35
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.d.ts +0 -9
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.js +0 -54
- package/lib/ResourceList/ResourceList.d.ts +0 -18
- package/lib/ResourceList/ResourceList.js +0 -49
- package/lib/ResourcePickerContainer/ResourcePickerContainer.d.ts +0 -17
- package/lib/ResourcePickerContainer/ResourcePickerContainer.js +0 -166
- package/lib/StatusIndicator/StatusIndicator.d.ts +0 -8
- package/lib/StatusIndicator/StatusIndicator.js +0 -27
- package/lib/utils/findBestMatchLineage.d.ts +0 -2
- package/lib/utils/findBestMatchLineage.js +0 -28
- package/lib/utils/uuid.d.ts +0 -1
- package/lib/utils/uuid.js +0 -6
- package/src/Hooks/useCategorisedSources.spec.ts +0 -39
- package/src/Hooks/useCategorisedSources.ts +0 -46
- package/src/Hooks/useChildResources.spec.ts +0 -29
- package/src/Hooks/useChildResources.ts +0 -21
- package/src/Hooks/usePreselectedResourcePath.ts +0 -54
- package/src/Hooks/useRecentLocations.spec.ts +0 -81
- package/src/Hooks/useRecentLocations.ts +0 -44
- package/src/Hooks/useRecentResourcesPaths.ts +0 -54
- package/src/Hooks/useResource.spec.ts +0 -61
- package/src/Hooks/useResource.ts +0 -38
- package/src/Hooks/useResourcePath.spec.ts +0 -120
- package/src/Hooks/useResourcePath.ts +0 -76
- package/src/Icons/HistoryIcon.tsx +0 -17
- package/src/PreviewPanel/PreviewPanel.spec.tsx +0 -198
- package/src/PreviewPanel/PreviewPanel.stories.tsx +0 -76
- package/src/PreviewPanel/PreviewPanel.tsx +0 -6
- package/src/PreviewPanel/details/MatrixResource.tsx +0 -54
- package/src/PreviewPanel/details/matrix-resource.scss +0 -16
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.spec.tsx +0 -133
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.stories.tsx +0 -24
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.tsx +0 -79
- package/src/ResourceBreadcrumb/resource-breadcrumb.scss +0 -28
- package/src/ResourceBreadcrumb/sample-hierarchy.json +0 -27
- package/src/ResourceList/ResourceList.spec.tsx +0 -202
- package/src/ResourceList/ResourceList.stories.tsx +0 -40
- package/src/ResourceList/ResourceList.tsx +0 -83
- package/src/ResourceList/sample-resources.json +0 -851
- package/src/ResourcePickerContainer/ResourcePickerContainer.spec.tsx +0 -780
- package/src/ResourcePickerContainer/ResourcePickerContainer.stories.tsx +0 -45
- package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +0 -290
- package/src/SourceList/sample-sources.json +0 -251
- package/src/StatusIndicator/StatusIndicator.stories.tsx +0 -83
- package/src/StatusIndicator/StatusIndicator.tsx +0 -38
- package/src/__mocks__/JestHelpers.ts +0 -65
- package/src/__mocks__/StorybookHelpers.ts +0 -128
- package/src/__mocks__/jestHelpers.spec.ts +0 -38
- package/src/utils/findBestMatchLineage.spec.ts +0 -81
- package/src/utils/findBestMatchLineage.ts +0 -30
- package/src/utils/uuid.ts +0 -5
package/lib/types.d.ts
CHANGED
@@ -1,74 +1,56 @@
|
|
1
|
+
import React, { ReactElement } from 'react';
|
1
2
|
import { SquizImageType } from '@squiz/dx-json-schema-lib';
|
2
|
-
export type
|
3
|
-
|
4
|
-
|
3
|
+
export type OnRequestSources = () => Promise<ResourceBrowserSource[]>;
|
4
|
+
export type ResourceBrowserPluginType = 'dam' | 'matrix';
|
5
|
+
export type ResourceBrowserSource = {
|
6
|
+
name?: string;
|
7
|
+
id: string;
|
8
|
+
type: ResourceBrowserPluginType;
|
5
9
|
};
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
export type ResourceBrowserUnresolvedResource = {
|
11
|
+
sourceId: string;
|
12
|
+
resourceId: string;
|
13
|
+
};
|
14
|
+
export type ResourceBrowserResource = {
|
10
15
|
id: string;
|
11
16
|
name: string;
|
17
|
+
url: string;
|
18
|
+
source: ResourceBrowserSource;
|
12
19
|
type: {
|
13
20
|
code: string;
|
14
21
|
name: string;
|
15
22
|
};
|
16
|
-
status: Status;
|
17
|
-
url: string;
|
18
|
-
urls: string[];
|
19
|
-
childCount: number;
|
20
23
|
squizImage?: SquizImageType['__shape__'];
|
21
|
-
lineages?: ResourceLineage[];
|
22
|
-
};
|
23
|
-
export type ResourceLineage = {
|
24
|
-
resourceIds: string[];
|
25
|
-
};
|
26
|
-
/**
|
27
|
-
* Represents a system that resources can be picked from.
|
28
|
-
* Optionally, may indicate a list of "nodes" that can be used to scope the source to a subset of its resources.
|
29
|
-
*/
|
30
|
-
export type Source = {
|
31
|
-
id: string;
|
32
|
-
name: string;
|
33
|
-
nodes: Resource[];
|
34
24
|
};
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
resource: Resource | null;
|
25
|
+
export type ResourceBrowserSelectedState = {
|
26
|
+
showThumbnail?: boolean;
|
27
|
+
icon?: ReactElement;
|
28
|
+
label: string;
|
29
|
+
description: Array<ReactElement>;
|
41
30
|
};
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
resource:
|
31
|
+
export type ResourceBrowserUIProps = {
|
32
|
+
source: ResourceBrowserSource;
|
33
|
+
allowedTypes?: string[];
|
34
|
+
headerPortal?: Element;
|
35
|
+
preselectedResource?: ResourceBrowserResource;
|
36
|
+
onSelected: (resource: ResourceBrowserResource) => void;
|
48
37
|
};
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
source: Source;
|
54
|
-
resource: Resource;
|
38
|
+
export type useResolveResourceResponse = {
|
39
|
+
data: ResourceBrowserResource | null;
|
40
|
+
error: Error | null;
|
41
|
+
isLoading: boolean;
|
55
42
|
};
|
56
43
|
/**
|
57
|
-
*
|
58
|
-
* Within the picker T will be ScopedSource|Resource.
|
59
|
-
* ScopedSource will be the first item in the array, Resource will be every other item.
|
60
|
-
*/
|
61
|
-
export type Hierarchy<T> = Array<{
|
62
|
-
key: string;
|
63
|
-
label: string;
|
64
|
-
node: T;
|
65
|
-
}>;
|
66
|
-
/**
|
67
|
-
* Augments a type so that all properties are optional.
|
44
|
+
* If you change this interface please update the example here: src/__mocks__/PluginExample.tsx
|
68
45
|
*/
|
69
|
-
export
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
46
|
+
export interface ResourceBrowserPlugin {
|
47
|
+
/** Datasource type this plugin should be used for */
|
48
|
+
type: ResourceBrowserPluginType;
|
49
|
+
createHeaderPortal?: boolean;
|
50
|
+
/** React Functional Component to provde the UI to render to allow a user to select a resource to use */
|
51
|
+
sourceBrowserComponent: () => React.FunctionComponent<ResourceBrowserUIProps>;
|
52
|
+
/** Function to provde the the summary information to show what resource is currently selected */
|
53
|
+
renderSelectedResource: (resource: ResourceBrowserResource) => Promise<ResourceBrowserSelectedState>;
|
54
|
+
/** Function to resolve a resource and source id into a fully resolved output reference */
|
55
|
+
useResolveResource: (resourceId: string | null, source: ResourceBrowserSource | null) => useResolveResourceResponse;
|
56
|
+
}
|
package/package.json
CHANGED
@@ -1,83 +1,85 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
},
|
10
|
-
"scripts": {
|
11
|
-
"compile": "npm run clean && npm run compile:styles && npm run compile:code",
|
12
|
-
"compile:code": "tsc",
|
13
|
-
"compile:styles": "node build.js",
|
14
|
-
"dev": "vite compile",
|
15
|
-
"storybook": "storybook dev -p 6006",
|
16
|
-
"test": "jest",
|
17
|
-
"test:watch": "jest --watch",
|
18
|
-
"clean": "rimraf ./lib"
|
19
|
-
},
|
20
|
-
"dependencies": {
|
21
|
-
"@mui/icons-material": "5.11.16",
|
22
|
-
"@squiz/dx-json-schema-lib": "^1.67.0",
|
23
|
-
"@squiz/generic-browser-lib": "^1.67.0",
|
24
|
-
"expiry-map": "^2.0.0",
|
25
|
-
"p-memoize": "^4.0.4",
|
26
|
-
"pretty-bytes": "5.6.0",
|
27
|
-
"react-aria": "3.23.1",
|
28
|
-
"react-responsive": "9.0.2",
|
29
|
-
"react-stately": "3.21.0"
|
30
|
-
},
|
31
|
-
"devDependencies": {
|
32
|
-
"@storybook/addon-essentials": "^7.5.3",
|
33
|
-
"@storybook/addon-interactions": "^7.5.3",
|
34
|
-
"@storybook/addon-links": "^7.5.3",
|
35
|
-
"@storybook/addon-styling": "1.0.1",
|
36
|
-
"@storybook/blocks": "^7.5.3",
|
37
|
-
"@storybook/react": "^7.5.3",
|
38
|
-
"@storybook/react-vite": "^7.5.3",
|
39
|
-
"@storybook/testing-library": "0.0.14-next.1",
|
40
|
-
"@testing-library/jest-dom": "5.16.5",
|
41
|
-
"@testing-library/react": "14.0.0",
|
42
|
-
"@testing-library/user-event": "14.4.3",
|
43
|
-
"@types/postcss-js": "4.0.0",
|
44
|
-
"@types/react": "^18.2.45",
|
45
|
-
"@types/react-dom": "^18.2.18",
|
46
|
-
"@vitejs/plugin-react-swc": "3.0.0",
|
47
|
-
"autoprefixer": "10.4.14",
|
48
|
-
"esbuild": "^0.20.2",
|
49
|
-
"esbuild-sass-plugin": "2.8.0",
|
50
|
-
"jest": "29.4.1",
|
51
|
-
"jest-environment-jsdom": "29.4.1",
|
52
|
-
"postcss": "8.4.31",
|
53
|
-
"postcss-loader": "7.2.4",
|
54
|
-
"postcss-nested": "6.0.1",
|
55
|
-
"postcss-prefix-selector": "1.16.0",
|
56
|
-
"prop-types": "15.8.1",
|
57
|
-
"react": "18.2.0",
|
58
|
-
"react-dom": "18.2.0",
|
59
|
-
"rimraf": "4.1.2",
|
60
|
-
"storybook": "^7.5.3",
|
61
|
-
"tailwindcss": "3.3.1",
|
62
|
-
"ts-jest": "29.0.5",
|
63
|
-
"typescript": "4.9.3",
|
64
|
-
"vite": "^4.5.0"
|
65
|
-
},
|
66
|
-
"peerDependencies": {
|
67
|
-
"@types/react": "^16.14.0 || ^17 || ^18",
|
68
|
-
"@types/react-dom": "^16.9.0 || ^17 || ^18",
|
69
|
-
"react": "^16.14.0 || ^17 || ^18",
|
70
|
-
"react-dom": "^16.14.0 || ^17 || ^18"
|
71
|
-
},
|
72
|
-
"peerDependenciesMeta": {
|
73
|
-
"@types/react": {
|
74
|
-
"optional": true
|
2
|
+
"name": "@squiz/resource-browser",
|
3
|
+
"version": "2.1.8-rc.0",
|
4
|
+
"main": "lib/index.js",
|
5
|
+
"types": "lib/index.d.ts",
|
6
|
+
"private": false,
|
7
|
+
"publishConfig": {
|
8
|
+
"access": "public"
|
75
9
|
},
|
76
|
-
"
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
10
|
+
"scripts": {
|
11
|
+
"compile": "npm run compile:styles && npm run compile:code",
|
12
|
+
"compile:code": "tsc",
|
13
|
+
"compile:styles": "node build.js",
|
14
|
+
"storybook": "storybook dev -p 6006",
|
15
|
+
"test": "jest",
|
16
|
+
"test:unit": "jest",
|
17
|
+
"test:watch": "jest --watch"
|
18
|
+
},
|
19
|
+
"dependencies": {
|
20
|
+
"@emotion/styled": "^11.11.5",
|
21
|
+
"@mui/icons-material": "5.11.16",
|
22
|
+
"@react-aria/interactions": "^3.21.1",
|
23
|
+
"@react-types/shared": "^3.22.1",
|
24
|
+
"@squiz/dx-json-schema-lib": "^1.67.0",
|
25
|
+
"@squiz/generic-browser-lib": "^1.66.0",
|
26
|
+
"@squiz/resource-browser-ui-lib": "^0.8.1-rc.0",
|
27
|
+
"clsx": "^2.1.0",
|
28
|
+
"expiry-map": "^2.0.0",
|
29
|
+
"p-memoize": "^4.0.4",
|
30
|
+
"react-aria": "3.23.1",
|
31
|
+
"react-responsive": "9.0.2",
|
32
|
+
"react-stately": "3.21.0"
|
33
|
+
},
|
34
|
+
"devDependencies": {
|
35
|
+
"@storybook/addon-essentials": "^7.5.3",
|
36
|
+
"@storybook/addon-interactions": "^7.5.3",
|
37
|
+
"@storybook/addon-links": "^7.5.3",
|
38
|
+
"@storybook/addon-styling": "1.0.1",
|
39
|
+
"@storybook/blocks": "^7.5.3",
|
40
|
+
"@storybook/react": "^7.5.3",
|
41
|
+
"@storybook/react-vite": "^7.5.3",
|
42
|
+
"@storybook/testing-library": "0.0.14-next.1",
|
43
|
+
"@testing-library/jest-dom": "5.16.5",
|
44
|
+
"@testing-library/react": "14.0.0",
|
45
|
+
"@testing-library/user-event": "14.4.3",
|
46
|
+
"@types/postcss-js": "4.0.0",
|
47
|
+
"@types/react": "^18.2.45",
|
48
|
+
"@types/react-dom": "^18.2.18",
|
49
|
+
"autoprefixer": "10.4.14",
|
50
|
+
"esbuild": "^0.19.3",
|
51
|
+
"esbuild-sass-plugin": "^2.8.0",
|
52
|
+
"jest": "29.4.1",
|
53
|
+
"jest-environment-jsdom": "29.4.1",
|
54
|
+
"postcss": "8.4.31",
|
55
|
+
"postcss-loader": "7.2.4",
|
56
|
+
"postcss-nested": "6.0.1",
|
57
|
+
"postcss-prefix-selector": "1.16.0",
|
58
|
+
"prop-types": "15.8.1",
|
59
|
+
"react": "^18.0.0",
|
60
|
+
"react-dom": "^18.0.0",
|
61
|
+
"storybook": "^7.5.3",
|
62
|
+
"tailwindcss": "3.3.1",
|
63
|
+
"ts-jest": "29.0.5",
|
64
|
+
"typescript": "4.9.3",
|
65
|
+
"vite": "^4.5.0"
|
66
|
+
},
|
67
|
+
"peerDependencies": {
|
68
|
+
"@types/react": "^16.14.0 || ^17 || ^18",
|
69
|
+
"@types/react-dom": "^16.9.0 || ^17 || ^18",
|
70
|
+
"react": "^16.14.0 || ^17 || ^18",
|
71
|
+
"react-dom": "^16.14.0 || ^17 || ^18"
|
72
|
+
},
|
73
|
+
"peerDependenciesMeta": {
|
74
|
+
"@types/react": {
|
75
|
+
"optional": true
|
76
|
+
},
|
77
|
+
"@types/react-dom": {
|
78
|
+
"optional": true
|
79
|
+
}
|
80
|
+
},
|
81
|
+
"volta": {
|
82
|
+
"node": "18.18.0"
|
83
|
+
},
|
84
|
+
"gitHead": "95c233207d4a87157029512d0bd9edacaf15826d"
|
83
85
|
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { renderHook, waitFor } from '@testing-library/react';
|
2
|
+
import { ResourceBrowserPlugin } from '../types';
|
3
|
+
import { mockResource } from '../__mocks__/MockModels';
|
4
|
+
import { useSelectedState } from './useSelectedState';
|
5
|
+
|
6
|
+
describe('useSelectedState', () => {
|
7
|
+
it('Should load the selectedState from the plugin', async () => {
|
8
|
+
const selectedStateResponse = {};
|
9
|
+
const resource = mockResource({ id: '1' });
|
10
|
+
const mockRenderSelectedResource = jest.fn().mockResolvedValue(selectedStateResponse);
|
11
|
+
const secondMockRenderSelectedResource = jest.fn();
|
12
|
+
const plugin: Partial<ResourceBrowserPlugin> = {
|
13
|
+
type: 'dam',
|
14
|
+
renderSelectedResource: mockRenderSelectedResource,
|
15
|
+
};
|
16
|
+
|
17
|
+
const { result } = renderHook(() => useSelectedState({ plugin: plugin as ResourceBrowserPlugin, resource }));
|
18
|
+
|
19
|
+
expect(result.current.isLoading).toBe(true);
|
20
|
+
expect(result.current.error).toBe(null);
|
21
|
+
expect(result.current.data).toEqual(null);
|
22
|
+
|
23
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
24
|
+
|
25
|
+
expect(mockRenderSelectedResource).toHaveBeenCalledTimes(1);
|
26
|
+
expect(secondMockRenderSelectedResource).not.toHaveBeenCalled();
|
27
|
+
|
28
|
+
expect(result.current.isLoading).toBe(false);
|
29
|
+
expect(result.current.data).toBe(selectedStateResponse);
|
30
|
+
});
|
31
|
+
|
32
|
+
it('Should not load the resource if no reference provided', async () => {
|
33
|
+
const mockRenderSelectedResource = jest.fn();
|
34
|
+
const plugin: Partial<ResourceBrowserPlugin> = {
|
35
|
+
type: 'dam',
|
36
|
+
renderSelectedResource: mockRenderSelectedResource,
|
37
|
+
};
|
38
|
+
|
39
|
+
const { result } = renderHook(() => useSelectedState({ plugin: plugin as ResourceBrowserPlugin, resource: null }));
|
40
|
+
|
41
|
+
expect(result.current.isLoading).toBe(false);
|
42
|
+
expect(result.current.error).toBe(null);
|
43
|
+
expect(result.current.data).toEqual(null);
|
44
|
+
expect(mockRenderSelectedResource).not.toHaveBeenCalled();
|
45
|
+
});
|
46
|
+
});
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { useAsync } from '@squiz/generic-browser-lib';
|
2
|
+
import { ResourceBrowserPlugin, ResourceBrowserResource } from '../types';
|
3
|
+
|
4
|
+
type UseResourceProps = {
|
5
|
+
plugin: ResourceBrowserPlugin | null;
|
6
|
+
resource: ResourceBrowserResource | null;
|
7
|
+
};
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Loads the selected state for the provided resource
|
11
|
+
*/
|
12
|
+
export const useSelectedState = ({ plugin, resource }: UseResourceProps) => {
|
13
|
+
// Find the resolver for this resource
|
14
|
+
const renderSelectedResource = resource && plugin?.renderSelectedResource;
|
15
|
+
return useAsync(
|
16
|
+
{
|
17
|
+
callback: () => (resource && renderSelectedResource ? renderSelectedResource(resource) : null),
|
18
|
+
defaultValue: null,
|
19
|
+
},
|
20
|
+
[resource],
|
21
|
+
);
|
22
|
+
};
|
@@ -1,20 +1,38 @@
|
|
1
1
|
import { renderHook, waitFor } from '@testing-library/react';
|
2
|
-
import { mockSource } from '../__mocks__/MockModels';
|
2
|
+
import { mockSource, mockPlugin } from '../__mocks__/MockModels';
|
3
3
|
import { useSources } from './useSources';
|
4
4
|
|
5
5
|
describe('useSources', () => {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
it('Should trigger and load the sources', async () => {
|
7
|
+
const sources = [mockSource()];
|
8
|
+
const plugins = [mockPlugin()];
|
9
|
+
const onRequestSources = jest.fn().mockResolvedValue(sources);
|
10
|
+
const { result } = renderHook(() => useSources({ onRequestSources, plugins }));
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
expect(result.current.isLoading).toBe(true);
|
13
|
+
expect(result.current.error).toBe(null);
|
14
|
+
expect(result.current.data).toEqual([]);
|
14
15
|
|
15
|
-
|
16
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
expect(result.current.isLoading).toBe(false);
|
19
|
+
expect(result.current.data).toEqual(sources);
|
20
|
+
});
|
21
|
+
|
22
|
+
it('Should filters sources that plugins dont exist for', async () => {
|
23
|
+
const sources = [mockSource({ type: 'dam' }), mockSource({ id: '2', type: 'matrix' })];
|
24
|
+
const plugins = [mockPlugin({ type: 'dam' })];
|
25
|
+
const onRequestSources = jest.fn().mockResolvedValue(sources);
|
26
|
+
const { result } = renderHook(() => useSources({ onRequestSources, plugins }));
|
27
|
+
|
28
|
+
expect(result.current.isLoading).toBe(true);
|
29
|
+
expect(result.current.error).toBe(null);
|
30
|
+
expect(result.current.data).toEqual([]);
|
31
|
+
|
32
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
33
|
+
|
34
|
+
expect(result.current.isLoading).toBe(false);
|
35
|
+
expect(result.current.data).toEqual([sources[0]]);
|
36
|
+
expect(result.current.data.length).toEqual(1);
|
37
|
+
});
|
20
38
|
});
|
package/src/Hooks/useSources.ts
CHANGED
@@ -1,12 +1,41 @@
|
|
1
|
-
import {
|
1
|
+
import { ResourceBrowserSource, ResourceBrowserPlugin } from '../types';
|
2
2
|
import { useAsync } from '@squiz/generic-browser-lib';
|
3
3
|
|
4
4
|
type UseSourcesProps = {
|
5
|
-
|
5
|
+
onRequestSources: () => Promise<ResourceBrowserSource[]>;
|
6
|
+
plugins: Array<ResourceBrowserPlugin>;
|
6
7
|
};
|
7
8
|
|
8
9
|
/**
|
9
10
|
* Loads and caches the source list when a component using the hook is mounted.
|
10
11
|
*/
|
11
|
-
export const useSources = ({ onRequestSources }: UseSourcesProps) =>
|
12
|
-
|
12
|
+
export const useSources = ({ onRequestSources, plugins }: UseSourcesProps) => {
|
13
|
+
return useAsync(
|
14
|
+
{
|
15
|
+
callback: () => {
|
16
|
+
return new Promise<ResourceBrowserSource[]>((resolve, reject) => {
|
17
|
+
// Get all the sources from the outer context
|
18
|
+
onRequestSources()
|
19
|
+
.then((sources: ResourceBrowserSource[]) => {
|
20
|
+
// Remove any sources which we don't have a plugin to handle
|
21
|
+
resolve(
|
22
|
+
sources.filter((source) => {
|
23
|
+
return !!plugins.find((plugin) => {
|
24
|
+
if (plugin.type === source.type) {
|
25
|
+
return true;
|
26
|
+
}
|
27
|
+
return false;
|
28
|
+
});
|
29
|
+
}),
|
30
|
+
);
|
31
|
+
})
|
32
|
+
.catch((e: unknown) => {
|
33
|
+
reject(e);
|
34
|
+
});
|
35
|
+
});
|
36
|
+
},
|
37
|
+
defaultValue: [] as ResourceBrowserSource[],
|
38
|
+
},
|
39
|
+
[plugins],
|
40
|
+
);
|
41
|
+
};
|
@@ -3,12 +3,12 @@ import React, { SVGAttributes } from 'react';
|
|
3
3
|
type CircledLoopIconProps = SVGAttributes<SVGElement>;
|
4
4
|
|
5
5
|
export const CircledLoopIcon = (props: CircledLoopIconProps) => {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
return (
|
7
|
+
<svg fill="none" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" {...props}>
|
8
|
+
<path
|
9
|
+
d="M8 0.5C3.86 0.5 0.5 3.86 0.5 8C0.5 12.14 3.86 15.5 8 15.5C12.14 15.5 15.5 12.14 15.5 8C15.5 3.86 12.14 0.5 8 0.5ZM8 14C4.6925 14 2 11.3075 2 8C2 4.6925 4.6925 2 8 2C11.3075 2 14 4.6925 14 8C14 11.3075 11.3075 14 8 14ZM11.1275 10.07L10.3025 9.245C10.835 8.2475 10.7 6.9875 9.86 6.1475C9.3425 5.63 8.675 5.375 8 5.375C7.9775 5.375 7.955 5.3825 7.9325 5.3825L8.75 6.2L7.955 6.995L5.8325 4.8725L7.955 2.75L8.75 3.545L8.03 4.265C8.9825 4.2725 9.9275 4.625 10.655 5.345C11.93 6.6275 12.0875 8.615 11.1275 10.07ZM10.1675 11.1275L8.045 13.25L7.25 12.455L7.9625 11.7425C7.0175 11.735 6.0725 11.3675 5.3525 10.6475C4.07 9.365 3.9125 7.385 4.8725 5.93L5.6975 6.755C5.165 7.7525 5.3 9.0125 6.14 9.8525C6.665 10.3775 7.3625 10.6325 8.06 10.61L7.25 9.8L8.045 9.005L10.1675 11.1275Z"
|
10
|
+
fill="#949494"
|
11
|
+
/>
|
12
|
+
</svg>
|
13
|
+
);
|
14
14
|
};
|