@squiz/resource-browser 1.32.1-alpha.14 → 1.32.1-alpha.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.
Files changed (90) hide show
  1. package/jest.config.ts +12 -1
  2. package/lib/Hooks/useCategorisedSources.d.ts +14 -0
  3. package/lib/Hooks/useCategorisedSources.js +38 -0
  4. package/lib/Hooks/useChildResources.d.ts +19 -0
  5. package/lib/Hooks/useChildResources.js +35 -0
  6. package/lib/Hooks/useResourcePath.d.ts +16 -0
  7. package/lib/Hooks/useResourcePath.js +64 -0
  8. package/lib/Hooks/useSources.d.ts +16 -0
  9. package/lib/Hooks/useSources.js +29 -0
  10. package/lib/Icons/Icon.d.ts +7 -7
  11. package/lib/Icons/Icon.js +7 -9
  12. package/lib/Icons/MatrixResources/Audio.js +1 -1
  13. package/lib/Icons/MatrixResources/Excel.js +1 -1
  14. package/lib/Icons/MatrixResources/MatrixResourceMap.d.ts +6 -6
  15. package/lib/Icons/MatrixResources/MatrixResourceMap.js +6 -6
  16. package/lib/Icons/MatrixResources/Pdf.js +1 -1
  17. package/lib/Icons/MatrixResources/Powerpoint.js +1 -1
  18. package/lib/Icons/MatrixResources/Video.js +1 -1
  19. package/lib/Icons/MatrixResources/Word.js +1 -1
  20. package/lib/Modal/Modal.js +1 -1
  21. package/lib/PreviewPanel/PreviewModal.js +1 -1
  22. package/lib/PreviewPanel/PreviewPanel.d.ts +4 -6
  23. package/lib/PreviewPanel/PreviewPanel.js +11 -39
  24. package/lib/PreviewPanel/details/MatrixResource.d.ts +4 -9
  25. package/lib/PreviewPanel/details/MatrixResource.js +20 -16
  26. package/lib/ResourceBreadcrumb/ResourceBreadcrumb.d.ts +5 -5
  27. package/lib/ResourceBreadcrumb/ResourceBreadcrumb.js +3 -3
  28. package/lib/ResourceItem/ResourceItem.d.ts +6 -8
  29. package/lib/ResourceItem/ResourceItem.js +3 -3
  30. package/lib/ResourceList/ResourceList.d.ts +5 -4
  31. package/lib/ResourceList/ResourceList.js +3 -3
  32. package/lib/ResourcePickerContainer/ResourcePickerContainer.d.ts +4 -5
  33. package/lib/ResourcePickerContainer/ResourcePickerContainer.js +34 -89
  34. package/lib/SourceDropdown/SourceDropdown.d.ts +5 -5
  35. package/lib/SourceDropdown/SourceDropdown.js +19 -27
  36. package/lib/SourceList/SourceList.d.ts +4 -4
  37. package/lib/SourceList/SourceList.js +7 -5
  38. package/lib/index.css +6 -0
  39. package/lib/index.d.ts +6 -29
  40. package/lib/index.js +2 -3
  41. package/lib/uuid.js +1 -3
  42. package/package.json +3 -2
  43. package/src/Hooks/useCategorisedSources.spec.ts +39 -0
  44. package/src/Hooks/useCategorisedSources.ts +46 -0
  45. package/src/Hooks/useChildResources.spec.ts +49 -0
  46. package/src/Hooks/useChildResources.ts +43 -0
  47. package/src/Hooks/useResourcePath.spec.ts +124 -0
  48. package/src/Hooks/useResourcePath.ts +76 -0
  49. package/src/Hooks/useSources.spec.ts +33 -0
  50. package/src/Hooks/useSources.ts +33 -0
  51. package/src/Icons/Icon.stories.tsx +7 -7
  52. package/src/Icons/Icon.tsx +9 -14
  53. package/src/Icons/MatrixResources/Audio.tsx +1 -1
  54. package/src/Icons/MatrixResources/Excel.tsx +1 -1
  55. package/src/Icons/MatrixResources/MatrixResourceMap.ts +7 -7
  56. package/src/Icons/MatrixResources/Pdf.tsx +1 -1
  57. package/src/Icons/MatrixResources/Powerpoint.tsx +1 -1
  58. package/src/Icons/MatrixResources/Video.tsx +1 -1
  59. package/src/Icons/MatrixResources/Word.tsx +1 -1
  60. package/src/Modal/Modal.tsx +1 -1
  61. package/src/PreviewPanel/PreviewModal.tsx +1 -1
  62. package/src/PreviewPanel/PreviewPanel.spec.tsx +20 -62
  63. package/src/PreviewPanel/PreviewPanel.stories.tsx +16 -24
  64. package/src/PreviewPanel/PreviewPanel.tsx +15 -51
  65. package/src/PreviewPanel/details/MatrixResource.tsx +23 -19
  66. package/src/ResourceBreadcrumb/ResourceBreadcrumb.spec.tsx +13 -23
  67. package/src/ResourceBreadcrumb/ResourceBreadcrumb.stories.tsx +1 -1
  68. package/src/ResourceBreadcrumb/ResourceBreadcrumb.tsx +8 -9
  69. package/src/ResourceBreadcrumb/sample-hierarchy.json +15 -25
  70. package/src/ResourceItem/ResourceItem.tsx +10 -12
  71. package/src/ResourceList/ResourceList.spec.tsx +8 -53
  72. package/src/ResourceList/ResourceList.stories.tsx +2 -2
  73. package/src/ResourceList/ResourceList.tsx +12 -10
  74. package/src/ResourceList/sample-resources.json +551 -49
  75. package/src/ResourcePickerContainer/ResourcePickerContainer.spec.tsx +196 -315
  76. package/src/ResourcePickerContainer/ResourcePickerContainer.stories.tsx +7 -29
  77. package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +63 -127
  78. package/src/SourceDropdown/SourceDropdown.spec.tsx +63 -60
  79. package/src/SourceDropdown/SourceDropdown.stories.tsx +4 -7
  80. package/src/SourceDropdown/SourceDropdown.tsx +34 -41
  81. package/src/SourceList/SourceList.spec.tsx +38 -32
  82. package/src/SourceList/SourceList.tsx +17 -19
  83. package/src/SourceList/sample-sources.json +186 -77
  84. package/src/__mocks__/MockModels.ts +30 -0
  85. package/src/__mocks__/StorybookHelpers.ts +46 -0
  86. package/src/index.stories.tsx +13 -38
  87. package/src/index.tsx +5 -29
  88. package/src/types.d.ts +71 -0
  89. package/src/uuid.ts +2 -4
  90. package/src/SourceDropdown/sample-sources.json +0 -110
package/jest.config.ts CHANGED
@@ -3,10 +3,21 @@ import type { Config } from 'jest';
3
3
  // Sync object
4
4
  const config: Config = {
5
5
  preset: 'ts-jest',
6
+ clearMocks: true,
7
+ collectCoverage: true,
8
+ collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.stories.{ts,tsx}'],
9
+ coverageThreshold: {
10
+ global: {
11
+ branches: 90,
12
+ functions: 90,
13
+ lines: 90,
14
+ statements: 90,
15
+ },
16
+ },
17
+ errorOnDeprecated: true,
6
18
  moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
7
19
  testTimeout: 60_000,
8
20
  testEnvironment: 'jsdom',
9
- passWithNoTests: true,
10
21
  testPathIgnorePatterns: ['/lib/', `/node_modules/`],
11
22
  maxWorkers: 1,
12
23
  moduleNameMapper: {
@@ -0,0 +1,14 @@
1
+ import { ScopedSource, Source } from '../types';
2
+ export type CategorisedSource = {
3
+ key: string;
4
+ label: string;
5
+ sources: ScopedSource[];
6
+ };
7
+ /**
8
+ * Groups a list of source into scoped/un-scoped for rendering in the source list.
9
+ *
10
+ * @param {Source[]} sources
11
+ *
12
+ * @return {SourceList}
13
+ */
14
+ export declare const useCategorisedSources: (sources: Source[]) => CategorisedSource[];
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCategorisedSources = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Groups a list of source into scoped/un-scoped for rendering in the source list.
7
+ *
8
+ * @param {Source[]} sources
9
+ *
10
+ * @return {SourceList}
11
+ */
12
+ const useCategorisedSources = (sources) => {
13
+ return (0, react_1.useMemo)(() => {
14
+ const categorised = [];
15
+ const uncategorised = [];
16
+ sources.forEach((source) => {
17
+ if (source.nodes.length > 0) {
18
+ const category = { key: source.id, label: source.name, sources: [] };
19
+ source.nodes.forEach((resource) => {
20
+ category.sources.push({ source, resource });
21
+ });
22
+ categorised.push(category);
23
+ }
24
+ else {
25
+ uncategorised.push({ source, resource: null });
26
+ }
27
+ });
28
+ if (uncategorised.length > 0) {
29
+ categorised.push({
30
+ key: 'other',
31
+ label: 'Other systems',
32
+ sources: uncategorised,
33
+ });
34
+ }
35
+ return categorised;
36
+ }, [sources]);
37
+ };
38
+ exports.useCategorisedSources = useCategorisedSources;
@@ -0,0 +1,19 @@
1
+ import { Resource, ScopedSource, Source } from '../types';
2
+ type UseChildResourcesProps = {
3
+ source: ScopedSource | null;
4
+ currentResource: Resource | null;
5
+ onRequestChildren: (source: Source, resource: Resource | null) => Promise<Resource[]>;
6
+ };
7
+ /**
8
+ * Triggers a reload of the child resources when the source or current resource change.
9
+ *
10
+ * @param {ScopedSource|null} source
11
+ * @param {Resource|null} currentResource
12
+ * @param {Function} onRequestChildren
13
+ */
14
+ export declare const useChildResources: ({ source, currentResource, onRequestChildren }: UseChildResourcesProps) => {
15
+ isLoading: boolean;
16
+ error: Error | null;
17
+ resources: Resource[];
18
+ };
19
+ export {};
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useChildResources = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Triggers a reload of the child resources when the source or current resource change.
7
+ *
8
+ * @param {ScopedSource|null} source
9
+ * @param {Resource|null} currentResource
10
+ * @param {Function} onRequestChildren
11
+ */
12
+ const useChildResources = ({ source, currentResource, onRequestChildren }) => {
13
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
14
+ const [error, setError] = (0, react_1.useState)(null);
15
+ const [resources, setResources] = (0, react_1.useState)([]);
16
+ // trigger a reload of the resources when the source or the current resource changes.
17
+ (0, react_1.useEffect)(() => {
18
+ setError(null);
19
+ setResources([]);
20
+ if (source) {
21
+ setIsLoading(true);
22
+ onRequestChildren(source.source, currentResource)
23
+ .then((resources) => {
24
+ setResources(resources);
25
+ setIsLoading(false);
26
+ })
27
+ .catch((e) => {
28
+ setError(e);
29
+ setIsLoading(false);
30
+ });
31
+ }
32
+ }, [source, currentResource]);
33
+ return { isLoading, error, resources };
34
+ };
35
+ exports.useChildResources = useChildResources;
@@ -0,0 +1,16 @@
1
+ import { Hierarchy, ScopedSource, Resource } from '../types';
2
+ /**
3
+ * Retains the state relating to where in the resource tree we are.
4
+ *
5
+ * Including:
6
+ * * The source.
7
+ * * A full path from the source to the leaf resource being browser.
8
+ */
9
+ export declare const useResourcePath: () => {
10
+ source: ScopedSource | null;
11
+ currentResource: Resource | null;
12
+ hierarchy: Hierarchy<ScopedSource | Resource>;
13
+ setSource: (source: ScopedSource | null) => void;
14
+ push: (resource: Resource) => void;
15
+ popUntil: (node: ScopedSource | Resource) => void;
16
+ };
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useResourcePath = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Retains the state relating to where in the resource tree we are.
7
+ *
8
+ * Including:
9
+ * * The source.
10
+ * * A full path from the source to the leaf resource being browser.
11
+ */
12
+ const useResourcePath = () => {
13
+ const [source, setSourceInternal] = (0, react_1.useState)(null);
14
+ const [resourceStack, setResourceStack] = (0, react_1.useState)([]);
15
+ const setSource = (0, react_1.useCallback)((source) => {
16
+ setSourceInternal(source);
17
+ setResourceStack([]);
18
+ }, []);
19
+ const push = (0, react_1.useCallback)((resource) => {
20
+ setResourceStack([...resourceStack, resource]);
21
+ }, [resourceStack]);
22
+ const popUntil = (0, react_1.useCallback)((node) => {
23
+ if ('source' in node) {
24
+ // source node selected, just switch to the source
25
+ setSource(node);
26
+ return;
27
+ }
28
+ // resource node selected
29
+ const newResourceStack = [...resourceStack];
30
+ // pop until we reach the node that was selected in the breadcrumb
31
+ while (newResourceStack.length > 0 && newResourceStack[newResourceStack.length - 1].id !== node?.id) {
32
+ newResourceStack.pop();
33
+ }
34
+ if (newResourceStack.length === 0) {
35
+ // if we didn't find the node clear the source to push the user back to the root
36
+ setSource(null);
37
+ }
38
+ else {
39
+ setResourceStack(newResourceStack);
40
+ }
41
+ }, [source, resourceStack]);
42
+ const hierarchy = (0, react_1.useMemo)(() => {
43
+ if (!source) {
44
+ return [];
45
+ }
46
+ return [
47
+ {
48
+ key: `source:${source.source.id}-resource:${source.resource?.id || 'unscoped'}`,
49
+ label: source.resource?.name || source.source.name,
50
+ node: source,
51
+ },
52
+ ...resourceStack.map((resource) => ({ key: resource.id, node: resource, label: resource.name })),
53
+ ];
54
+ }, [source, resourceStack]);
55
+ return {
56
+ source,
57
+ currentResource: (resourceStack[resourceStack.length - 1] || null),
58
+ hierarchy,
59
+ setSource,
60
+ push,
61
+ popUntil,
62
+ };
63
+ };
64
+ exports.useResourcePath = useResourcePath;
@@ -0,0 +1,16 @@
1
+ import { Source } from '../types';
2
+ type UseSourcesProps = {
3
+ onRequestSources: () => Promise<Source[]>;
4
+ };
5
+ /**
6
+ * Loads and caches the source list when a component using the hook is mounted.
7
+ *
8
+ * @param {Function} onRequestSources
9
+ */
10
+ export declare const useSources: ({ onRequestSources }: UseSourcesProps) => {
11
+ isLoading: boolean;
12
+ error: Error | null;
13
+ sources: Source[];
14
+ reload: () => void;
15
+ };
16
+ export {};
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSources = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Loads and caches the source list when a component using the hook is mounted.
7
+ *
8
+ * @param {Function} onRequestSources
9
+ */
10
+ const useSources = ({ onRequestSources }) => {
11
+ const [isLoading, setIsLoading] = (0, react_1.useState)(true);
12
+ const [error, setError] = (0, react_1.useState)(null);
13
+ const [sources, setSources] = (0, react_1.useState)([]);
14
+ const loadSources = (0, react_1.useCallback)(() => {
15
+ onRequestSources()
16
+ .then((sources) => {
17
+ setIsLoading(false);
18
+ setSources(sources);
19
+ })
20
+ .catch((error) => {
21
+ setIsLoading(false);
22
+ setError(error);
23
+ });
24
+ }, []);
25
+ // trigger a load of the sources when the component using the hook is initially rendered.
26
+ (0, react_1.useEffect)(loadSources, []);
27
+ return { isLoading, error, sources, reload: loadSources };
28
+ };
29
+ exports.useSources = useSources;
@@ -9,21 +9,21 @@ export declare const iconSources: {
9
9
  close: typeof import("./Generics").Close;
10
10
  };
11
11
  matrix: {
12
- audio: typeof import("./MatrixResources").Audio;
13
- excel: typeof import("./MatrixResources").Excel;
12
+ audio_file: typeof import("./MatrixResources").Audio;
13
+ excel_doc: typeof import("./MatrixResources").Excel;
14
14
  folder: typeof import("./MatrixResources").Folder;
15
15
  generic_file: typeof import("./MatrixResources").GenericFile;
16
16
  image: typeof import("./MatrixResources").Image;
17
17
  page_standard: typeof import("./MatrixResources").Page;
18
- pdf: typeof import("./MatrixResources").Pdf;
19
- powerpoint: typeof import("./MatrixResources").Powerpoint;
18
+ pdf_file: typeof import("./MatrixResources").Pdf;
19
+ powerpoint_doc: typeof import("./MatrixResources").Powerpoint;
20
20
  site: typeof import("./MatrixResources").Site;
21
- video: typeof import("./MatrixResources").Video;
22
- word: typeof import("./MatrixResources").Word;
21
+ video_file: typeof import("./MatrixResources").Video;
22
+ word_doc: typeof import("./MatrixResources").Word;
23
23
  };
24
24
  };
25
25
  export type ResourceSources = keyof typeof iconSources;
26
- export type IconOptions = keyof (typeof iconSources)[ResourceSources];
26
+ export type IconOptions = string;
27
27
  /**
28
28
  * Renders an icon based on the resource source and the icon name
29
29
  * @param {{resourceSource?: ResourceSources; icon?: IconOptions; props: React.HTMLAttributes<HTMLOrSVGElement>}} props - The props for the Icon component
package/lib/Icons/Icon.js CHANGED
@@ -27,15 +27,13 @@ exports.iconSources = {
27
27
  * <Icon resourceSource="matrix" icon="page" className="custom-class" />
28
28
  */
29
29
  function Icon({ resourceSource = 'generic', icon, isDecorative = true, ...props }) {
30
- // Loop through the resource sources
31
- for (const source in exports.iconSources) {
32
- // If the resource source is the current source and the icon is in the current source map, render the icon
33
- if (resourceSource === source && icon && icon in exports.iconSources[source]) {
34
- // Get the icon from the current source map
35
- const Icon = exports.iconSources[source][icon];
36
- // Render the icon
37
- return react_1.default.createElement(Icon, { isDecorative: isDecorative, ...props });
38
- }
30
+ const icons = exports.iconSources[resourceSource] || null;
31
+ // If the resource source is the current source and the icon is in the current source map, render the icon
32
+ if (icons && icon && icon in icons) {
33
+ // Get the icon from the current source map
34
+ const Icon = icons[icon];
35
+ // Render the icon
36
+ return react_1.default.createElement(Icon, { isDecorative: isDecorative, ...props });
39
37
  }
40
38
  // If the icon is not defined, render the default icon
41
39
  const DefaultIcon = MatrixResourceMap_1.default['generic_file'];
@@ -23,6 +23,6 @@ function Audio({ isDecorative, ...props }) {
23
23
  react_1.default.createElement("circle", { cx: "7.5", cy: "16.5", fill: "#73c0cb", r: "2", stroke: "#057e91" }),
24
24
  react_1.default.createElement("path", { d: "m16 7 1 .32v7.18c0 .2761-.2239.5-.5.5s-.5-.2239-.5-.5z", fill: "#057e91" }),
25
25
  react_1.default.createElement("circle", { cx: "14.5", cy: "14.5", fill: "#73c0cb", r: "2", stroke: "#057e91" }),
26
- !isDecorative && react_1.default.createElement("title", null, "audio icon")));
26
+ !isDecorative && react_1.default.createElement("title", null, "audio file icon")));
27
27
  }
28
28
  exports.default = Audio;
@@ -22,6 +22,6 @@ function Excel({ isDecorative, ...props }) {
22
22
  react_1.default.createElement("rect", { y: "8", width: "12", height: "12", rx: "2", fill: "#4FAD6F" }),
23
23
  react_1.default.createElement("path", { d: "M3.5 11.5L8.5 16.5", stroke: "white", strokeLinecap: "round" }),
24
24
  react_1.default.createElement("path", { d: "M8.5 11.5L3.5 16.5", stroke: "white", strokeLinecap: "round" }),
25
- !isDecorative && react_1.default.createElement("title", null, "excel icon")));
25
+ !isDecorative && react_1.default.createElement("title", null, "excel doc icon")));
26
26
  }
27
27
  exports.default = Excel;
@@ -1,15 +1,15 @@
1
1
  import { Audio, Excel, Folder, GenericFile, Image, Page, Pdf, Powerpoint, Site, Video, Word } from '.';
2
2
  declare const MatrixResourceMap: {
3
- audio: typeof Audio;
4
- excel: typeof Excel;
3
+ audio_file: typeof Audio;
4
+ excel_doc: typeof Excel;
5
5
  folder: typeof Folder;
6
6
  generic_file: typeof GenericFile;
7
7
  image: typeof Image;
8
8
  page_standard: typeof Page;
9
- pdf: typeof Pdf;
10
- powerpoint: typeof Powerpoint;
9
+ pdf_file: typeof Pdf;
10
+ powerpoint_doc: typeof Powerpoint;
11
11
  site: typeof Site;
12
- video: typeof Video;
13
- word: typeof Word;
12
+ video_file: typeof Video;
13
+ word_doc: typeof Word;
14
14
  };
15
15
  export default MatrixResourceMap;
@@ -3,17 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const _1 = require(".");
4
4
  // Define our map of matrix types to icons
5
5
  const MatrixResourceMap = {
6
- audio: _1.Audio,
7
- excel: _1.Excel,
6
+ audio_file: _1.Audio,
7
+ excel_doc: _1.Excel,
8
8
  folder: _1.Folder,
9
9
  generic_file: _1.GenericFile,
10
10
  image: _1.Image,
11
11
  page_standard: _1.Page,
12
- pdf: _1.Pdf,
13
- powerpoint: _1.Powerpoint,
12
+ pdf_file: _1.Pdf,
13
+ powerpoint_doc: _1.Powerpoint,
14
14
  site: _1.Site,
15
- video: _1.Video,
16
- word: _1.Word,
15
+ video_file: _1.Video,
16
+ word_doc: _1.Word,
17
17
  };
18
18
  // Export our map
19
19
  exports.default = MatrixResourceMap;
@@ -26,6 +26,6 @@ function Pdf({ isDecorative, ...props }) {
26
26
  react_1.default.createElement("path", { d: "m7.5 17.3v-3.6c0-.1105.08954-.2.2-.2h.3c.82843 0 1.5.6716 1.5 1.5v1c0 .8284-.67157 1.5-1.5 1.5h-.3c-.11046 0-.2-.0895-.2-.2z" }),
27
27
  react_1.default.createElement("path", { d: "m11.5 17.5v-3.8c0-.1105.0895-.2.2-.2h1.8" }),
28
28
  react_1.default.createElement("path", { d: "m11.5 15.5h1" })),
29
- !isDecorative && react_1.default.createElement("title", null, "pdf icon")));
29
+ !isDecorative && react_1.default.createElement("title", null, "pdf file icon")));
30
30
  }
31
31
  exports.default = Pdf;
@@ -23,6 +23,6 @@ function Powerpoint({ isDecorative, ...props }) {
23
23
  react_1.default.createElement("g", { stroke: "#fff", strokeLinecap: "round" },
24
24
  react_1.default.createElement("path", { d: "m3.5 11.5v5" }),
25
25
  react_1.default.createElement("path", { d: "m3.5 11.5h3.5c.33333 0 1.5 0 1.5 1.5s-1.16667 1.5-1.5 1.5h-3" })),
26
- !isDecorative && react_1.default.createElement("title", null, "powerpoint icon")));
26
+ !isDecorative && react_1.default.createElement("title", null, "powerpoint doc icon")));
27
27
  }
28
28
  exports.default = Powerpoint;
@@ -19,6 +19,6 @@ function Video({ isDecorative, ...props }) {
19
19
  return (react_1.default.createElement("svg", { fill: "none", height: "24", viewBox: "0 0 24 24", width: "24", xmlns: "http://www.w3.org/2000/svg", ...props },
20
20
  react_1.default.createElement("rect", { fill: "#e0d9ef", height: "15", rx: "1.5", stroke: "#ac98d5", width: "21", x: "1.5", y: "4.5" }),
21
21
  react_1.default.createElement("path", { d: "m9.5 15.2516v-6.50318c0-.38671.42019-.62704.7535-.43097l5.5277 3.25155c.3287.1934.3287.6686 0 .862l-5.5277 3.2516c-.33331.196-.7535-.0443-.7535-.431z", fill: "#ac98d5", stroke: "#6b47b4", strokeLinecap: "round" }),
22
- !isDecorative && react_1.default.createElement("title", null, "video icon")));
22
+ !isDecorative && react_1.default.createElement("title", null, "video file icon")));
23
23
  }
24
24
  exports.default = Video;
@@ -23,6 +23,6 @@ function Word({ isDecorative, ...props }) {
23
23
  react_1.default.createElement("path", { d: "m14.5 3v3.5c0 .55228.4477 1 1 1h3.5", stroke: "#bcbcbc" }),
24
24
  react_1.default.createElement("rect", { fill: "#0774d2", height: "12", rx: "2", width: "12", y: "8" }),
25
25
  react_1.default.createElement("path", { d: "m2.5 11.5 1.5 5 2-5 2 5 1.5-5", stroke: "#fff", strokeLinecap: "round", strokeLinejoin: "round" }),
26
- !isDecorative && react_1.default.createElement("title", null, "word icon")));
26
+ !isDecorative && react_1.default.createElement("title", null, "word doc icon")));
27
27
  }
28
28
  exports.default = Word;
@@ -39,7 +39,7 @@ function Modal({ isDismissable, state, overlayProps, children, ...props }) {
39
39
  const { modalProps, underlayProps } = (0, react_aria_1.useModalOverlay)({ isDismissable, ...props }, state, ref);
40
40
  return (react_1.default.createElement(react_aria_1.Overlay, null,
41
41
  react_1.default.createElement("div", { className: "squiz-rb-scope" },
42
- react_1.default.createElement("div", { ...underlayProps, className: "h-full z-[9999] fixed inset-0 before:z-40 before:fixed before:inset-0 before:bg-black before:bg-opacity-25" },
42
+ react_1.default.createElement("div", { ...underlayProps, className: "h-full z-[9998] fixed inset-0 before:z-40 before:fixed before:inset-0 before:bg-black before:bg-opacity-25" },
43
43
  react_1.default.createElement("div", { ...modalProps, ref: ref, className: "h-full flex items-center justify-center" },
44
44
  react_1.default.createElement(ModalContent, { ...overlayProps }, (titleProps) => children(titleProps)))))));
45
45
  }
@@ -74,7 +74,7 @@ function PreviewModal({ state, overlayProps, children, onClose, ...props }) {
74
74
  };
75
75
  }, [modalRef]);
76
76
  return (react_1.default.createElement(react_aria_1.Overlay, null,
77
- react_1.default.createElement("div", { ref: modalRef, ...underlayProps, ...keyboardProps, className: "fixed z-50 overflow-y-scroll bottom-0 w-full h-[50vh] bg-white border-t border-gray-300" },
77
+ react_1.default.createElement("div", { ref: modalRef, ...underlayProps, ...keyboardProps, className: "fixed z-[9999] overflow-y-scroll bottom-0 w-full h-[50vh] bg-white border-t border-gray-300" },
78
78
  react_1.default.createElement("div", { ref: overlayRef, ...modalProps, className: "h-full" },
79
79
  react_1.default.createElement(PreviewModalContent, { ...overlayProps, onClose: onClose }, children)))));
80
80
  }
@@ -1,16 +1,14 @@
1
1
  /// <reference types="react" />
2
2
  import { OverlayTriggerState } from 'react-stately';
3
3
  import { DOMAttributes, FocusableElement } from '@react-types/shared';
4
- import { NodeIdentifier, ResourceDetail } from '../index';
4
+ import { Resource } from '../types';
5
5
  export interface PreviewPanelProps {
6
- node: NodeIdentifier | null;
7
- resourceDetail: ResourceDetail | null;
8
- isLoading: boolean;
6
+ resource: Resource | null;
9
7
  modalState: OverlayTriggerState;
10
8
  previewModalOverlayProps: DOMAttributes<FocusableElement>;
11
9
  allowedTypes: string[] | undefined;
12
- onSelect: (node: NodeIdentifier) => void;
10
+ onSelect: (resource: Resource) => void;
13
11
  onClose: () => void;
14
12
  }
15
- declare const PreviewPanel: ({ node, resourceDetail, isLoading, previewModalOverlayProps, modalState, onSelect, onClose, }: PreviewPanelProps) => JSX.Element;
13
+ declare const PreviewPanel: ({ resource, previewModalOverlayProps, modalState, onSelect, onClose, }: PreviewPanelProps) => JSX.Element;
16
14
  export default PreviewPanel;
@@ -31,57 +31,29 @@ const react_responsive_1 = require("react-responsive");
31
31
  const Icon_1 = __importDefault(require("../Icons/Icon"));
32
32
  const MatrixResource_1 = __importDefault(require("./details/MatrixResource"));
33
33
  const PreviewModal_1 = __importDefault(require("./PreviewModal"));
34
- const Spinner_1 = __importDefault(require("../Spinner/Spinner"));
35
- const PreviewPanel = function ({ node, resourceDetail, isLoading, previewModalOverlayProps, modalState, onSelect, onClose, }) {
34
+ const PreviewPanel = function ({ resource, previewModalOverlayProps, modalState, onSelect, onClose, }) {
36
35
  // Watch the media size to see if we are on mobile size
37
36
  const isMobile = (0, react_responsive_1.useMediaQuery)({ query: '(max-width: 640px)' });
38
- const previousIsMobile = (0, react_1.useRef)(null);
37
+ // If we are on mobile and the selected resource changes show the preview panel modal.
39
38
  (0, react_1.useEffect)(() => {
40
- if (node && isMobile) {
41
- modalState.setOpen(true);
42
- previousIsMobile.current = true;
39
+ if (!modalState.isOpen) {
40
+ modalState.setOpen(Boolean(resource && isMobile));
43
41
  }
44
- else {
45
- previousIsMobile.current = false;
46
- }
47
- }, []);
48
- // If the media changes from mobile to non mobile or reverse toggle modal showing to undo the aria-hidden etc
49
- (0, react_1.useEffect)(() => {
50
- // Only trigger if we have a node selected, otherwise the modal will re-open itself as soon as its closed
51
- if (node) {
52
- if (previousIsMobile.current !== isMobile) {
53
- previousIsMobile.current = isMobile;
54
- if (isMobile) {
55
- // If no mobile open the modal automatically
56
- modalState.setOpen(true);
57
- }
58
- else {
59
- // If not in mobile close the modal automatically
60
- modalState.setOpen(false);
61
- }
62
- }
63
- }
64
- }, [node, isMobile, modalState]);
65
- let previewPanel = node && resourceDetail && (react_1.default.createElement(react_1.default.Fragment, null,
42
+ }, [resource, isMobile]);
43
+ const previewPanel = resource && (react_1.default.createElement(react_1.default.Fragment, null,
66
44
  react_1.default.createElement("div", { className: "flex flex-col grow" },
67
- react_1.default.createElement(MatrixResource_1.default, { ...resourceDetail })),
45
+ react_1.default.createElement(MatrixResource_1.default, { resource: resource })),
68
46
  react_1.default.createElement("div", { className: "flex justify-end border-t border-gray-300" },
69
- react_1.default.createElement("button", { type: "button", onClick: () => onSelect(node), className: "rounded text-sm text-white bg-blue-300 py-2 px-2.5 m-5" }, "Select"))));
70
- if (isLoading) {
71
- previewPanel = (react_1.default.createElement("div", { className: "flex flex-col grow" },
72
- react_1.default.createElement("div", { className: "flex flex-col grow items-center mt-20 mx-20" },
73
- react_1.default.createElement(Spinner_1.default, null),
74
- react_1.default.createElement("div", { className: "text-sm text-gray-600 text-center mt-4" }, "Loading info"))));
75
- }
47
+ react_1.default.createElement("button", { type: "button", onClick: () => onSelect(resource), className: "rounded text-sm text-white bg-blue-300 py-2 px-2.5 m-5" }, "Select"))));
76
48
  return (react_1.default.createElement("div", { className: "sm:overflow-y-scroll sm:flex-1 sm:grow-[2] bg-white" },
77
49
  !isMobile && react_1.default.createElement("h3", { className: "sr-only" }, "Resource Details"),
78
- node === null && (react_1.default.createElement("div", { className: "max-sm:hidden flex flex-col h-full" },
50
+ resource === null && (react_1.default.createElement("div", { className: "max-sm:hidden flex flex-col h-full" },
79
51
  react_1.default.createElement("div", { className: "flex flex-col grow items-center mt-20 mx-20" },
80
52
  react_1.default.createElement(Icon_1.default, { icon: 'resource-select', "aria-hidden": true }),
81
53
  react_1.default.createElement("div", { className: "text-sm text-gray-600 text-center mt-4" }, "Make a selection to see more info here.")),
82
54
  react_1.default.createElement("div", { className: "flex justify-end border-t border-gray-300" },
83
55
  react_1.default.createElement("button", { disabled: true, type: "button", className: "rounded text-sm text-white bg-blue-300/[.6] py-2 px-2.5 m-5" }, "Select")))),
84
- node && isMobile && modalState.isOpen && (react_1.default.createElement(PreviewModal_1.default, { state: modalState, overlayProps: previewModalOverlayProps, onClose: onClose }, previewPanel)),
85
- node && !isMobile && react_1.default.createElement("div", { className: "flex flex-col h-full" }, previewPanel)));
56
+ resource && isMobile && modalState.isOpen && (react_1.default.createElement(PreviewModal_1.default, { state: modalState, overlayProps: previewModalOverlayProps, onClose: onClose }, previewPanel)),
57
+ resource && !isMobile && react_1.default.createElement("div", { className: "flex flex-col h-full" }, previewPanel)));
86
58
  };
87
59
  exports.default = PreviewPanel;
@@ -1,12 +1,7 @@
1
1
  /// <reference types="react" />
2
- import { ResourceDetail } from '../../index';
3
- export declare enum MatrixStatus {
4
- UnderConstruction = "Under Construction",
5
- Live = "Live"
6
- }
7
- export type MatrixAsset = ResourceDetail & {
8
- assetId?: string;
9
- status?: MatrixStatus;
2
+ import { Resource } from '../../types';
3
+ type MatrixResourceProps = {
4
+ resource: Resource;
10
5
  };
11
- declare const MatrixResource: ({ type, name, properties }: ResourceDetail) => JSX.Element;
6
+ declare const MatrixResource: ({ resource: { id, type, name, status } }: MatrixResourceProps) => JSX.Element;
12
7
  export default MatrixResource;
@@ -3,39 +3,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MatrixStatus = void 0;
7
6
  const react_1 = __importDefault(require("react"));
8
7
  const Icon_1 = __importDefault(require("../../Icons/Icon"));
9
8
  const statusColour = {
10
- UnderConstruction: '#94D1F9',
11
- Live: '#BEE509',
9
+ // Duplicated from the Matrix repository.
10
+ // src/Api/AssetManagementApi/Constants/AssetStatuses.php - contains a list of possible statuses.
11
+ // frontend/src/styles/common/status-colors.scss - contains the colours used for those statuses in Matrix.
12
+ unknown: '#ff0000',
13
+ archived: '#c98a67',
14
+ under_construction: '#94d1f9',
15
+ pending_approval: '#d0bbf0',
16
+ approved_to_go_live: '#f7eaa2',
17
+ live: '#bfe60a',
18
+ up_for_review: '#72cd32',
19
+ safe_editing: '#ff97b0',
20
+ safe_editing_pending_approval: '#d688db',
21
+ safe_edit_approved_to_go_live: '#ffb34a',
12
22
  };
13
- var MatrixStatus;
14
- (function (MatrixStatus) {
15
- MatrixStatus["UnderConstruction"] = "Under Construction";
16
- MatrixStatus["Live"] = "Live";
17
- })(MatrixStatus = exports.MatrixStatus || (exports.MatrixStatus = {}));
18
- const MatrixResource = ({ type, name, properties }) => {
19
- const assetId = properties.get('assetId');
20
- const status = properties.get('status');
23
+ const MatrixResource = ({ resource: { id, type, name, status } }) => {
24
+ const color = statusColour[status.code] || statusColour.unknown;
21
25
  return (react_1.default.createElement("div", null,
22
26
  react_1.default.createElement("div", { className: "flex flex-col items-center text-gray-800 mt-7 mx-5 pb-4 border-b border-gray-300" },
23
- react_1.default.createElement(Icon_1.default, { icon: type, resourceSource: "matrix", className: "w-14 h-14" }),
27
+ react_1.default.createElement(Icon_1.default, { icon: type.code, resourceSource: "matrix", className: "w-14 h-14" }),
24
28
  react_1.default.createElement("div", { className: "mt-4 font-semibold text-base" }, name)),
25
29
  react_1.default.createElement("div", { className: "text-gray-800 mx-6 mt-4" },
26
30
  react_1.default.createElement("dl", { className: "flex flex-col text-sm" },
27
31
  react_1.default.createElement("div", { className: "flex mb-2" },
28
32
  react_1.default.createElement("dt", { className: "w-[60px] mr-4 text-gray-600" }, "Type"),
29
- react_1.default.createElement("dd", { className: "font-semibold" }, type)),
33
+ react_1.default.createElement("dd", { className: "font-semibold" }, type.name)),
30
34
  react_1.default.createElement("div", { className: "flex mb-2" },
31
35
  react_1.default.createElement("dt", { className: "w-[60px] mr-4 text-gray-600" }, "Asset ID"),
32
36
  react_1.default.createElement("dd", { className: "font-semibold" },
33
37
  "#",
34
- assetId)),
38
+ id)),
35
39
  react_1.default.createElement("div", { className: "flex mb-2" },
36
40
  react_1.default.createElement("dt", { className: "w-[60px] mr-4 text-gray-600" }, "Status"),
37
41
  react_1.default.createElement("dd", { className: "flex items-center font-semibold" },
38
- react_1.default.createElement("span", { style: { backgroundColor: statusColour[status] }, className: "block rounded-full w-3 h-3 mr-1 border border-solid border-black border-opacity-20" }),
39
- MatrixStatus[status]))))));
42
+ react_1.default.createElement("span", { style: { backgroundColor: color }, className: "block rounded-full w-3 h-3 mr-1 border border-solid border-black border-opacity-20" }),
43
+ status.name))))));
40
44
  };
41
45
  exports.default = MatrixResource;
@@ -1,9 +1,9 @@
1
1
  /// <reference types="react" />
2
- import { NodeIdentifier, Hierarchy } from '../index';
3
- export interface ResourceBreadcrumbProps {
4
- hierarchy: Array<Hierarchy>;
5
- onBreadcrumbSelect: (node: NodeIdentifier) => void;
2
+ import { Hierarchy } from '../types';
3
+ export interface ResourceBreadcrumbProps<T> {
4
+ hierarchy: Hierarchy<T>;
5
+ onBreadcrumbSelect: (node: T) => void;
6
6
  onReturnToRoot: () => void;
7
7
  }
8
- declare const ResourceBreadcrumb: ({ hierarchy, onBreadcrumbSelect, onReturnToRoot }: ResourceBreadcrumbProps) => JSX.Element;
8
+ declare const ResourceBreadcrumb: <T>({ hierarchy, onBreadcrumbSelect, onReturnToRoot }: ResourceBreadcrumbProps<T>) => JSX.Element;
9
9
  export default ResourceBreadcrumb;