@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.
Files changed (141) hide show
  1. package/CHANGELOG.md +88 -35
  2. package/LICENSE.md +15 -0
  3. package/README.md +9 -0
  4. package/jest.config.ts +22 -21
  5. package/lib/Hooks/useSelectedState.d.ts +15 -0
  6. package/lib/Hooks/useSelectedState.js +16 -0
  7. package/lib/Hooks/useSources.d.ts +5 -4
  8. package/lib/Hooks/useSources.js +25 -1
  9. package/lib/MainContainer/MainContainer.d.ts +17 -0
  10. package/lib/MainContainer/MainContainer.js +61 -0
  11. package/lib/Plugin/Plugin.d.ts +13 -0
  12. package/lib/Plugin/Plugin.js +17 -0
  13. package/lib/ResourceBrowserContext/ResourceBrowserContext.d.ts +2 -3
  14. package/lib/ResourceBrowserContext/ResourceBrowserContext.js +4 -17
  15. package/lib/ResourceBrowserInput/ResourceBrowserInput.d.ts +24 -0
  16. package/lib/ResourceBrowserInput/ResourceBrowserInput.js +16 -0
  17. package/lib/ResourcePicker/ResourcePicker.d.ts +6 -4
  18. package/lib/ResourcePicker/ResourcePicker.js +14 -8
  19. package/lib/ResourcePicker/States/Selected.d.ts +10 -4
  20. package/lib/ResourcePicker/States/Selected.js +11 -32
  21. package/lib/SourceDropdown/SourceDropdown.d.ts +5 -11
  22. package/lib/SourceDropdown/SourceDropdown.js +20 -99
  23. package/lib/SourceList/SourceList.d.ts +5 -16
  24. package/lib/SourceList/SourceList.js +14 -75
  25. package/lib/index.css +42 -202
  26. package/lib/index.d.ts +7 -7
  27. package/lib/index.js +69 -13
  28. package/lib/types.d.ts +41 -59
  29. package/package.json +82 -80
  30. package/src/Hooks/useSelectedState.spec.ts +46 -0
  31. package/src/Hooks/useSelectedState.ts +22 -0
  32. package/src/Hooks/useSources.spec.ts +30 -12
  33. package/src/Hooks/useSources.ts +33 -4
  34. package/src/Icons/CircledLoopIcon.tsx +8 -8
  35. package/src/MainContainer/MainContainer.spec.tsx +203 -0
  36. package/src/MainContainer/MainContainer.stories.tsx +62 -0
  37. package/src/MainContainer/MainContainer.tsx +101 -0
  38. package/src/Plugin/Plugin.spec.tsx +46 -0
  39. package/src/Plugin/Plugin.tsx +20 -0
  40. package/src/ResourceBrowserContext/ResourceBrowserContext.spec.tsx +65 -106
  41. package/src/ResourceBrowserContext/ResourceBrowserContext.tsx +24 -39
  42. package/src/ResourceBrowserInput/ResourceBrowserInput.spec.tsx +192 -0
  43. package/src/ResourceBrowserInput/ResourceBrowserInput.tsx +81 -0
  44. package/src/ResourcePicker/ResourcePicker.spec.tsx +159 -116
  45. package/src/ResourcePicker/ResourcePicker.stories.tsx +28 -24
  46. package/src/ResourcePicker/ResourcePicker.tsx +79 -59
  47. package/src/ResourcePicker/States/Error.tsx +8 -8
  48. package/src/ResourcePicker/States/Loading.tsx +3 -3
  49. package/src/ResourcePicker/States/Selected.tsx +66 -73
  50. package/src/ResourcePicker/mock-image-resource.json +25 -47
  51. package/src/ResourcePicker/mock-resource.json +11 -13
  52. package/src/ResourcePicker/resource-picker.scss +13 -13
  53. package/src/SourceDropdown/SourceDropdown.spec.tsx +65 -391
  54. package/src/SourceDropdown/SourceDropdown.stories.tsx +21 -24
  55. package/src/SourceDropdown/SourceDropdown.tsx +80 -258
  56. package/src/SourceList/SourceList.spec.tsx +37 -430
  57. package/src/SourceList/SourceList.stories.tsx +17 -37
  58. package/src/SourceList/SourceList.tsx +28 -155
  59. package/src/__mocks__/MockModels.ts +56 -25
  60. package/src/__mocks__/PluginExample.tsx +98 -0
  61. package/src/__mocks__/StorybookHelpers.tsx +141 -0
  62. package/src/__mocks__/renderWithContext.tsx +14 -18
  63. package/src/__mocks__/sample-sources.json +32 -0
  64. package/src/index.scss +18 -8
  65. package/src/index.spec.tsx +277 -99
  66. package/src/index.stories.tsx +65 -39
  67. package/src/index.tsx +119 -57
  68. package/src/types.ts +54 -63
  69. package/tailwind.config.cjs +92 -92
  70. package/vite.config.js +12 -12
  71. package/lib/Hooks/useCategorisedSources.d.ts +0 -14
  72. package/lib/Hooks/useCategorisedSources.js +0 -38
  73. package/lib/Hooks/useChildResources.d.ts +0 -16
  74. package/lib/Hooks/useChildResources.js +0 -13
  75. package/lib/Hooks/usePreselectedResourcePath.d.ts +0 -20
  76. package/lib/Hooks/usePreselectedResourcePath.js +0 -31
  77. package/lib/Hooks/useRecentLocations.d.ts +0 -5
  78. package/lib/Hooks/useRecentLocations.js +0 -38
  79. package/lib/Hooks/useRecentResourcesPaths.d.ts +0 -20
  80. package/lib/Hooks/useRecentResourcesPaths.js +0 -30
  81. package/lib/Hooks/useResource.d.ts +0 -28
  82. package/lib/Hooks/useResource.js +0 -23
  83. package/lib/Hooks/useResourcePath.d.ts +0 -16
  84. package/lib/Hooks/useResourcePath.js +0 -64
  85. package/lib/Icons/HistoryIcon.d.ts +0 -4
  86. package/lib/Icons/HistoryIcon.js +0 -13
  87. package/lib/PreviewPanel/PreviewPanel.d.ts +0 -5
  88. package/lib/PreviewPanel/PreviewPanel.js +0 -8
  89. package/lib/PreviewPanel/details/MatrixResource.d.ts +0 -7
  90. package/lib/PreviewPanel/details/MatrixResource.js +0 -35
  91. package/lib/ResourceBreadcrumb/ResourceBreadcrumb.d.ts +0 -9
  92. package/lib/ResourceBreadcrumb/ResourceBreadcrumb.js +0 -54
  93. package/lib/ResourceList/ResourceList.d.ts +0 -18
  94. package/lib/ResourceList/ResourceList.js +0 -49
  95. package/lib/ResourcePickerContainer/ResourcePickerContainer.d.ts +0 -17
  96. package/lib/ResourcePickerContainer/ResourcePickerContainer.js +0 -166
  97. package/lib/StatusIndicator/StatusIndicator.d.ts +0 -8
  98. package/lib/StatusIndicator/StatusIndicator.js +0 -27
  99. package/lib/utils/findBestMatchLineage.d.ts +0 -2
  100. package/lib/utils/findBestMatchLineage.js +0 -28
  101. package/lib/utils/uuid.d.ts +0 -1
  102. package/lib/utils/uuid.js +0 -6
  103. package/src/Hooks/useCategorisedSources.spec.ts +0 -39
  104. package/src/Hooks/useCategorisedSources.ts +0 -46
  105. package/src/Hooks/useChildResources.spec.ts +0 -29
  106. package/src/Hooks/useChildResources.ts +0 -21
  107. package/src/Hooks/usePreselectedResourcePath.ts +0 -54
  108. package/src/Hooks/useRecentLocations.spec.ts +0 -81
  109. package/src/Hooks/useRecentLocations.ts +0 -44
  110. package/src/Hooks/useRecentResourcesPaths.ts +0 -54
  111. package/src/Hooks/useResource.spec.ts +0 -61
  112. package/src/Hooks/useResource.ts +0 -38
  113. package/src/Hooks/useResourcePath.spec.ts +0 -120
  114. package/src/Hooks/useResourcePath.ts +0 -76
  115. package/src/Icons/HistoryIcon.tsx +0 -17
  116. package/src/PreviewPanel/PreviewPanel.spec.tsx +0 -198
  117. package/src/PreviewPanel/PreviewPanel.stories.tsx +0 -76
  118. package/src/PreviewPanel/PreviewPanel.tsx +0 -6
  119. package/src/PreviewPanel/details/MatrixResource.tsx +0 -54
  120. package/src/PreviewPanel/details/matrix-resource.scss +0 -16
  121. package/src/ResourceBreadcrumb/ResourceBreadcrumb.spec.tsx +0 -133
  122. package/src/ResourceBreadcrumb/ResourceBreadcrumb.stories.tsx +0 -24
  123. package/src/ResourceBreadcrumb/ResourceBreadcrumb.tsx +0 -79
  124. package/src/ResourceBreadcrumb/resource-breadcrumb.scss +0 -28
  125. package/src/ResourceBreadcrumb/sample-hierarchy.json +0 -27
  126. package/src/ResourceList/ResourceList.spec.tsx +0 -202
  127. package/src/ResourceList/ResourceList.stories.tsx +0 -40
  128. package/src/ResourceList/ResourceList.tsx +0 -83
  129. package/src/ResourceList/sample-resources.json +0 -851
  130. package/src/ResourcePickerContainer/ResourcePickerContainer.spec.tsx +0 -780
  131. package/src/ResourcePickerContainer/ResourcePickerContainer.stories.tsx +0 -45
  132. package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +0 -290
  133. package/src/SourceList/sample-sources.json +0 -251
  134. package/src/StatusIndicator/StatusIndicator.stories.tsx +0 -83
  135. package/src/StatusIndicator/StatusIndicator.tsx +0 -38
  136. package/src/__mocks__/JestHelpers.ts +0 -65
  137. package/src/__mocks__/StorybookHelpers.ts +0 -128
  138. package/src/__mocks__/jestHelpers.spec.ts +0 -38
  139. package/src/utils/findBestMatchLineage.spec.ts +0 -81
  140. package/src/utils/findBestMatchLineage.ts +0 -30
  141. package/src/utils/uuid.ts +0 -5
@@ -1,45 +0,0 @@
1
- import React from 'react';
2
- import { StoryFn, Meta } from '@storybook/react';
3
- import ResourcePickerContainer from './ResourcePickerContainer';
4
- import { createResourceBrowserCallbacks } from '../__mocks__/StorybookHelpers';
5
- import sampleSources from '../SourceList/sample-sources.json';
6
-
7
- export default {
8
- title: 'Resource Picker container',
9
- component: ResourcePickerContainer,
10
- } as Meta<typeof ResourcePickerContainer>;
11
-
12
- const Template: StoryFn<typeof ResourcePickerContainer> = ({ title, preselectedSourceId, preselectedResource }) => {
13
- const { onRequestSources, onRequestChildren, onRequestResource, onChange } = createResourceBrowserCallbacks();
14
-
15
- return (
16
- <ResourcePickerContainer
17
- title={title}
18
- titleAriaProps={{}}
19
- allowedTypes={undefined}
20
- onRequestSources={onRequestSources}
21
- onRequestChildren={onRequestChildren}
22
- onRequestResource={onRequestResource}
23
- preselectedSourceId={preselectedSourceId}
24
- preselectedResource={preselectedResource}
25
- onChange={onChange}
26
- onClose={() => {
27
- alert('Resource Browser closed');
28
- }}
29
- />
30
- );
31
- };
32
-
33
- export const Primary = Template.bind({});
34
-
35
- Primary.args = {
36
- title: 'Asset Picker',
37
- };
38
-
39
- export const SourceListResourceSelected = Template.bind({});
40
- // SourceList root node is selected
41
- SourceListResourceSelected.args = {
42
- title: 'Asset Picker',
43
- preselectedSourceId: sampleSources[0].id,
44
- preselectedResource: sampleSources[0].nodes[1],
45
- };
@@ -1,290 +0,0 @@
1
- import React, { useState, useCallback, useMemo, useEffect } from 'react';
2
- import { DOMAttributes, FocusableElement } from '@react-types/shared';
3
- import { useOverlayTriggerState } from 'react-stately';
4
- import SourceList from '../SourceList/SourceList';
5
- import ResourceList from '../ResourceList/ResourceList';
6
- import ResourceBreadcrumb from '../ResourceBreadcrumb/ResourceBreadcrumb';
7
- import PreviewPanel from '../PreviewPanel/PreviewPanel';
8
- import SourceDropdown from '../SourceDropdown/SourceDropdown';
9
- import {
10
- Source,
11
- Resource,
12
- HydratedResourceReference,
13
- ScopedSource,
14
- OnRequestSources,
15
- OnRequestChildren,
16
- OnRequestResource,
17
- } from '../types';
18
- import { useResourcePath } from '../Hooks/useResourcePath';
19
- import { useChildResources } from '../Hooks/useChildResources';
20
- import { useSources } from '../Hooks/useSources';
21
- import { usePreselectedResourcePath } from '../Hooks/usePreselectedResourcePath';
22
- import { useRecentLocations } from '../Hooks/useRecentLocations';
23
- import { useResources } from '../Hooks/useResource';
24
- import { RecentResourcesPaths, useRecentResourcesPaths } from '../Hooks/useRecentResourcesPaths';
25
-
26
- interface ResourcePickerContainerProps {
27
- title: string;
28
- titleAriaProps: DOMAttributes<FocusableElement>;
29
- allowedTypes: string[] | undefined;
30
- onRequestSources: OnRequestSources;
31
- onRequestResource: OnRequestResource;
32
- onRequestChildren: OnRequestChildren;
33
- onChange(resource: HydratedResourceReference | null): void;
34
- onClose: () => void;
35
- preselectedSourceId?: string;
36
- preselectedResource?: Resource | null;
37
- }
38
-
39
- function ResourcePickerContainer({
40
- title,
41
- titleAriaProps,
42
- allowedTypes,
43
- onRequestSources,
44
- onRequestResource,
45
- onRequestChildren,
46
- onChange,
47
- onClose,
48
- preselectedSourceId,
49
- preselectedResource,
50
- }: ResourcePickerContainerProps) {
51
- const previewModalState = useOverlayTriggerState({});
52
- const [selectedSource, setSelectedSource] = useState<Source | null>(null);
53
- const [selectedResourceId, setSelectedResourceId] = useState<string | null>(null);
54
- const [previewModalOverlayProps, setPreviewModalOverlayProps] = useState<DOMAttributes>({});
55
- const { source, currentResource, hierarchy, setSource, push, popUntil } = useResourcePath();
56
-
57
- // Recent locations relevant data
58
- const { addRecentLocation, recentLocations } = useRecentLocations();
59
-
60
- const { data: recentLocationsResources, isLoading: recentLocationsResourcesLoading } = useResources({
61
- onRequestResource,
62
- references: recentLocations,
63
- });
64
-
65
- const { data: recentLocationsSources, isLoading: recentLocationsLoading } = useRecentResourcesPaths({
66
- sourceIds: recentLocations.map((item) => item.source),
67
- resources: recentLocationsResources,
68
- onRequestResource,
69
- onRequestSources,
70
- });
71
-
72
- // Type check the returned values from recent locations requests
73
- let recentSources: RecentResourcesPaths[] = [];
74
- if (Array.isArray(recentLocationsSources)) recentSources = recentLocationsSources;
75
-
76
- const {
77
- data: sources,
78
- isLoading: isSourceLoading,
79
- reload: handleSourceReload,
80
- error: sourceError,
81
- } = useSources({ onRequestSources });
82
-
83
- const {
84
- data: resources,
85
- isLoading: isResourcesLoading,
86
- reload: handleResourceReload,
87
- error: resourceError,
88
- } = useChildResources({ source, currentResource, onRequestChildren });
89
-
90
- const {
91
- data: { source: preselectedSource, path: preselectedPath },
92
- isLoading: isPreselectedResourcePathLoading,
93
- } = usePreselectedResourcePath({
94
- sourceId: preselectedSourceId,
95
- resource: preselectedResource,
96
- onRequestResource,
97
- onRequestSources,
98
- });
99
-
100
- const selectedResource = useMemo(() => {
101
- if (selectedSource) {
102
- return selectedSource?.nodes.find((resource: Resource) => resource.id === selectedResourceId) || null;
103
- }
104
- return resources.find((resource: Resource) => resource.id === selectedResourceId) || null;
105
- }, [selectedResourceId, resources, selectedSource]);
106
-
107
- const handleResourceDrillDown = useCallback(
108
- (resource: Resource) => {
109
- push(resource);
110
- },
111
- [push],
112
- );
113
-
114
- const handleResourceSelected = useCallback((resource: Resource, overlayProps: DOMAttributes) => {
115
- setPreviewModalOverlayProps(overlayProps);
116
- setSelectedSource(null);
117
- setSelectedResourceId(resource.id);
118
- }, []);
119
-
120
- const handleSourceDrilldown = useCallback(
121
- (source: ScopedSource) => {
122
- setSelectedSource(null);
123
- setSelectedResourceId(null);
124
- setSource(source);
125
- },
126
- [setSource],
127
- );
128
-
129
- const handleSourceSelected = useCallback((node: ScopedSource, overlayProps: DOMAttributes) => {
130
- const { source, resource } = node;
131
- setPreviewModalOverlayProps(overlayProps);
132
- setSelectedSource(source || null);
133
- setSelectedResourceId(resource?.id || null);
134
- }, []);
135
-
136
- const handleReturnToRoot = useCallback(() => {
137
- setSelectedSource(null);
138
- setSelectedResourceId(null);
139
- setSource(null);
140
- }, [setSource]);
141
-
142
- const handleDetailSelect = useCallback(
143
- (resource: Resource) => {
144
- const detailSelectedSource = selectedSource ?? (source?.source as Source);
145
- onChange({ resource, source: detailSelectedSource });
146
-
147
- // Find the path that got them to where they are
148
- const lastPathItem = hierarchy[hierarchy.length - 1]?.node as ScopedSource;
149
- const lastPathResource = lastPathItem && 'resource' in lastPathItem ? lastPathItem?.resource : lastPathItem;
150
-
151
- if (lastPathResource) {
152
- addRecentLocation({
153
- resource: lastPathResource.id,
154
- source: detailSelectedSource.id,
155
- });
156
- }
157
-
158
- onClose();
159
- },
160
- [selectedSource, source, currentResource],
161
- );
162
-
163
- const handleDetailClose = useCallback(() => {
164
- setSelectedSource(null);
165
- setSelectedResourceId(null);
166
- }, []);
167
-
168
- // Clear the selected resource if it no longer exists in the list of resources
169
- // (eg. due to navigating up/down the tree).
170
- useEffect(() => {
171
- if (resources.length > 0 && selectedResourceId && !selectedResource) {
172
- setSelectedSource(null);
173
- setSelectedResourceId(null);
174
- }
175
- }, [resources, selectedResourceId, selectedResource]);
176
-
177
- useEffect(() => {
178
- if (preselectedSource && preselectedPath?.length) {
179
- const [rootNode, ...path] = preselectedPath;
180
- const leaf = path.pop();
181
-
182
- if (leaf) {
183
- setSource(
184
- {
185
- source: preselectedSource,
186
- resource: rootNode,
187
- },
188
- path,
189
- );
190
-
191
- setSelectedResourceId(leaf.id);
192
- } else {
193
- setSelectedSource(preselectedSource);
194
- setSelectedResourceId(rootNode.id);
195
- }
196
- }
197
- }, [preselectedSource, preselectedSource]);
198
-
199
- return (
200
- <div className="relative flex flex-col h-full text-gray-800">
201
- <div className="flex items-center p-4.5">
202
- <h2 {...titleAriaProps} className="text-xl leading-6 text-gray-800 font-semibold mr-6">
203
- {title}
204
- </h2>
205
- <div className="px-3 border-l border-gray-300 w-300px">
206
- <SourceDropdown
207
- sources={sources}
208
- selectedSource={source}
209
- isLoading={isSourceLoading || recentLocationsLoading || recentLocationsResourcesLoading}
210
- onSourceSelect={handleSourceDrilldown}
211
- onRootSelect={handleReturnToRoot}
212
- setSource={setSource}
213
- currentResource={currentResource}
214
- recentSources={recentSources}
215
- />
216
- </div>
217
- <button
218
- type="button"
219
- aria-label={`Close ${title} dialog`}
220
- onClick={onClose}
221
- className="absolute top-2 right-2 p-2.5 rounded hover:bg-blue-100 focus:bg-blue-100"
222
- >
223
- <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
224
- <path
225
- d="M13.3 0.710017C13.1131 0.522765 12.8595 0.417532 12.595 0.417532C12.3305 0.417532 12.0768 0.522765 11.89 0.710017L6.99997 5.59002L2.10997 0.700017C1.92314 0.512765 1.66949 0.407532 1.40497 0.407532C1.14045 0.407532 0.886802 0.512765 0.699971 0.700017C0.309971 1.09002 0.309971 1.72002 0.699971 2.11002L5.58997 7.00002L0.699971 11.89C0.309971 12.28 0.309971 12.91 0.699971 13.3C1.08997 13.69 1.71997 13.69 2.10997 13.3L6.99997 8.41002L11.89 13.3C12.28 13.69 12.91 13.69 13.3 13.3C13.69 12.91 13.69 12.28 13.3 11.89L8.40997 7.00002L13.3 2.11002C13.68 1.73002 13.68 1.09002 13.3 0.710017Z"
226
- fill="currentColor"
227
- />
228
- </svg>
229
- </button>
230
- </div>
231
- <div className="flex border-t border-gray-300 h-[calc(100%-72px)]">
232
- <div className="overflow-y-scroll flex-1 grow-[3] border-r border-gray-300">
233
- <h3 className="sr-only">Resource List</h3>
234
- {hierarchy.length > 0 && (
235
- <ResourceBreadcrumb
236
- hierarchy={hierarchy}
237
- onBreadcrumbSelect={popUntil}
238
- onReturnToRoot={handleReturnToRoot}
239
- />
240
- )}
241
- {!source && (
242
- <SourceList
243
- sources={sources}
244
- selectedResource={selectedResource}
245
- previewModalState={previewModalState}
246
- isLoading={
247
- isSourceLoading ||
248
- isPreselectedResourcePathLoading ||
249
- recentLocationsLoading ||
250
- recentLocationsResourcesLoading
251
- }
252
- onSourceSelect={handleSourceSelected}
253
- onSourceDrilldown={handleSourceDrilldown}
254
- handleReload={handleSourceReload}
255
- setSource={setSource}
256
- recentSources={recentSources}
257
- error={sourceError}
258
- />
259
- )}
260
- {source && (
261
- <ResourceList
262
- previewModalState={previewModalState}
263
- resources={resources}
264
- selectedResource={selectedResource}
265
- isLoading={isResourcesLoading}
266
- onResourceSelect={handleResourceSelected}
267
- onResourceDrillDown={handleResourceDrillDown}
268
- allowedTypes={allowedTypes}
269
- handleReturnToRoot={handleReturnToRoot}
270
- handleReload={handleResourceReload}
271
- error={resourceError}
272
- />
273
- )}
274
- </div>
275
- <div className="sm:overflow-y-scroll sm:flex-1 sm:grow-[2] bg-white">
276
- <PreviewPanel
277
- resource={isResourcesLoading ? null : selectedResource}
278
- modalState={previewModalState}
279
- previewModalOverlayProps={previewModalOverlayProps}
280
- allowedTypes={allowedTypes}
281
- onSelect={handleDetailSelect}
282
- onClose={handleDetailClose}
283
- />
284
- </div>
285
- </div>
286
- </div>
287
- );
288
- }
289
-
290
- export default ResourcePickerContainer;
@@ -1,251 +0,0 @@
1
- [
2
- {
3
- "id": "1",
4
- "name": "Acme corporate system",
5
- "nodes": [
6
- {
7
- "id": "1",
8
- "type": {
9
- "code": "site",
10
- "name": "Site"
11
- },
12
- "status": {
13
- "code": "live",
14
- "name": "Live"
15
- },
16
- "name": "HandyHomes Website",
17
- "childCount": 21
18
- },
19
- {
20
- "id": "10",
21
- "type": {
22
- "code": "site",
23
- "name": "Site"
24
- },
25
- "status": {
26
- "code": "live",
27
- "name": "Live"
28
- },
29
- "name": "Another Website very long title to make it wrap to multiple lines",
30
- "childCount": 135877
31
- },
32
- {
33
- "id": "20",
34
- "type": {
35
- "code": "folder",
36
- "name": "Folder"
37
- },
38
- "status": {
39
- "code": "live",
40
- "name": "Live"
41
- },
42
- "name": "Images",
43
- "childCount": 100
44
- },
45
- {
46
- "id": "9999",
47
- "type": {
48
- "code": "site",
49
- "name": "Site"
50
- },
51
- "status": {
52
- "code": "live",
53
- "name": "Live"
54
- },
55
- "name": "Another very unique id site",
56
- "childCount": 100
57
- }
58
- ]
59
- },
60
- {
61
- "id": "2",
62
- "name": "Acme internal system",
63
- "nodes": [
64
- {
65
- "id": "32",
66
- "type": {
67
- "code": "site",
68
- "name": "Site"
69
- },
70
- "status": {
71
- "code": "live",
72
- "name": "Live"
73
- },
74
- "name": "Intranet Website",
75
- "childCount": 15
76
- },
77
- {
78
- "id": "33",
79
- "type": {
80
- "code": "site",
81
- "name": "Site"
82
- },
83
- "status": {
84
- "code": "live",
85
- "name": "Live"
86
- },
87
- "name": "Social Website",
88
- "childCount": 10
89
- }
90
- ]
91
- },
92
- {
93
- "id": "3",
94
- "name": "Digital asset manager",
95
- "nodes": []
96
- },
97
- {
98
- "id": "4",
99
- "name": "Unsplash image library",
100
- "nodes": []
101
- },
102
- {
103
- "id": "5",
104
- "name": "Unsplash image library 2",
105
- "nodes": []
106
- },
107
- {
108
- "id": "6",
109
- "name": "Unsplash image library 3",
110
- "nodes": []
111
- },
112
- {
113
- "id": "7",
114
- "name": "Unsplash image library 4",
115
- "nodes": []
116
- },
117
- {
118
- "id": "8",
119
- "name": "Unsplash image library 5",
120
- "nodes": []
121
- },
122
- {
123
- "id": "9",
124
- "name": "Unsplash image library 6",
125
- "nodes": []
126
- },
127
- {
128
- "id": "10",
129
- "name": "Unsplash image library 7",
130
- "nodes": []
131
- },
132
- {
133
- "id": "11",
134
- "name": "Unsplash image library 8",
135
- "nodes": []
136
- },
137
- {
138
- "id": "12",
139
- "name": "Unsplash image library 9",
140
- "nodes": []
141
- },
142
- {
143
- "id": "13",
144
- "name": "Unsplash image library 10",
145
- "nodes": []
146
- },
147
- {
148
- "id": "14",
149
- "name": "Unsplash image library 11",
150
- "nodes": []
151
- },
152
- {
153
- "id": "15",
154
- "name": "Unsplash image library 12",
155
- "nodes": []
156
- },
157
- {
158
- "id": "16",
159
- "name": "Unsplash image library 13",
160
- "nodes": []
161
- },
162
- {
163
- "id": "17",
164
- "name": "Unsplash image library 14",
165
- "nodes": []
166
- },
167
- {
168
- "id": "18",
169
- "name": "Unsplash image library 15",
170
- "nodes": []
171
- },
172
- {
173
- "id": "19",
174
- "name": "Unsplash image library 16",
175
- "nodes": []
176
- },
177
- {
178
- "id": "20",
179
- "name": "Unsplash image library 17",
180
- "nodes": []
181
- },
182
- {
183
- "id": "21",
184
- "name": "Unsplash image library 18",
185
- "nodes": []
186
- },
187
- {
188
- "id": "22",
189
- "name": "Unsplash image library 19",
190
- "nodes": []
191
- },
192
- {
193
- "id": "23",
194
- "name": "Unsplash image library 20",
195
- "nodes": []
196
- },
197
- {
198
- "id": "24",
199
- "name": "Unsplash image library 21",
200
- "nodes": []
201
- },
202
- {
203
- "id": "25",
204
- "name": "Unsplash image library 22",
205
- "nodes": []
206
- },
207
- {
208
- "id": "26",
209
- "name": "Unsplash image library 23",
210
- "nodes": []
211
- },
212
- {
213
- "id": "27",
214
- "name": "Unsplash image library 24",
215
- "nodes": []
216
- },
217
- {
218
- "id": "28",
219
- "name": "Unsplash image library 25",
220
- "nodes": []
221
- },
222
- {
223
- "id": "29",
224
- "name": "Unsplash image library 26",
225
- "nodes": []
226
- },
227
- {
228
- "id": "30",
229
- "name": "Unsplash image library 27",
230
- "nodes": []
231
- },
232
- {
233
- "id": "31",
234
- "name": "Acme no children",
235
- "nodes": [
236
- {
237
- "id": "3",
238
- "type": {
239
- "code": "site",
240
- "name": "Site"
241
- },
242
- "status": {
243
- "code": "live",
244
- "name": "Live"
245
- },
246
- "name": "What Children?",
247
- "childCount": 0
248
- }
249
- ]
250
- }
251
- ]
@@ -1,83 +0,0 @@
1
- import StatusIndicator, { StatusIndicatorProps } from './StatusIndicator';
2
- import { Meta, StoryFn } from '@storybook/react';
3
-
4
- export default {
5
- title: 'Status Indicator',
6
- component: StatusIndicator,
7
- } as Meta<typeof StatusIndicator>;
8
-
9
- const Template: StoryFn<StatusIndicatorProps> = (args: StatusIndicatorProps) => (
10
- <div className="m-3">
11
- <StatusIndicator {...args} />
12
- </div>
13
- );
14
-
15
- export const UnderConstruction = Template.bind({});
16
- UnderConstruction.args = {
17
- status: {
18
- code: 'under_construction',
19
- name: 'Under construction',
20
- },
21
- };
22
-
23
- export const PendingApproval = Template.bind({});
24
- PendingApproval.args = {
25
- status: {
26
- code: 'pending_approval',
27
- name: 'Pending approval',
28
- },
29
- };
30
-
31
- export const ApprovedToGoLive = Template.bind({});
32
- ApprovedToGoLive.args = {
33
- status: {
34
- code: 'approved_to_go_live',
35
- name: 'Approved to go live',
36
- },
37
- };
38
-
39
- export const Live = Template.bind({});
40
- Live.args = {
41
- status: {
42
- code: 'live',
43
- name: 'Live',
44
- },
45
- };
46
-
47
- export const UpForReview = Template.bind({});
48
- UpForReview.args = {
49
- status: {
50
- code: 'up_for_review',
51
- name: 'Up for review',
52
- },
53
- };
54
-
55
- export const SafeEditing = Template.bind({});
56
- SafeEditing.args = {
57
- status: {
58
- code: 'safe_editing',
59
- name: 'Safe editing',
60
- },
61
- };
62
-
63
- export const SafeEditingPendingApproval = Template.bind({});
64
- SafeEditingPendingApproval.args = {
65
- status: {
66
- code: 'safe_editing_pending_approval',
67
- name: 'Safe editing pending approval',
68
- },
69
- };
70
- export const SafeEditApprovedToGoLive = Template.bind({});
71
- SafeEditApprovedToGoLive.args = {
72
- status: {
73
- code: 'safe_edit_approved_to_go_live',
74
- name: 'Safe edit approved to go live',
75
- },
76
- };
77
- export const Archived = Template.bind({});
78
- Archived.args = {
79
- status: {
80
- code: 'archived',
81
- name: 'Archived',
82
- },
83
- };
@@ -1,38 +0,0 @@
1
- import React from 'react';
2
- import clsx from 'clsx';
3
- import { Status } from '../types';
4
-
5
- const statusColour = {
6
- // Duplicated from the Matrix repository.
7
- // src/Api/AssetManagementApi/Constants/AssetStatuses.php - contains a list of possible statuses.
8
- // frontend/src/styles/common/status-colors.scss - contains the colours used for those statuses in Matrix.
9
- unknown: '#ff0000',
10
- archived: '#c98a67',
11
- under_construction: '#94d1f9',
12
- pending_approval: '#d0bbf0',
13
- approved_to_go_live: '#f7eaa2',
14
- live: '#bfe60a',
15
- up_for_review: '#72cd32',
16
- safe_editing: '#ff97b0',
17
- safe_editing_pending_approval: '#d688db',
18
- safe_edit_approved_to_go_live: '#ffb34a',
19
- };
20
-
21
- export type StatusIndicatorProps = {
22
- className?: string;
23
- status: Status;
24
- };
25
-
26
- const StatusIndicator = ({ className, status }: StatusIndicatorProps) => {
27
- const color = statusColour[status.code as keyof typeof statusColour] || statusColour.unknown;
28
-
29
- return (
30
- <span
31
- style={{ backgroundColor: color }}
32
- className={clsx('block rounded-full w-3 h-3 border-1 border-solid border-black border-opacity-20', className)}
33
- title={status.name}
34
- ></span>
35
- );
36
- };
37
-
38
- export default StatusIndicator;