@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.
- package/jest.config.ts +12 -1
- package/lib/Hooks/useCategorisedSources.d.ts +14 -0
- package/lib/Hooks/useCategorisedSources.js +38 -0
- package/lib/Hooks/useChildResources.d.ts +19 -0
- package/lib/Hooks/useChildResources.js +35 -0
- package/lib/Hooks/useResourcePath.d.ts +16 -0
- package/lib/Hooks/useResourcePath.js +64 -0
- package/lib/Hooks/useSources.d.ts +16 -0
- package/lib/Hooks/useSources.js +29 -0
- package/lib/Icons/Icon.d.ts +7 -7
- package/lib/Icons/Icon.js +7 -9
- package/lib/Icons/MatrixResources/Audio.js +1 -1
- package/lib/Icons/MatrixResources/Excel.js +1 -1
- package/lib/Icons/MatrixResources/MatrixResourceMap.d.ts +6 -6
- package/lib/Icons/MatrixResources/MatrixResourceMap.js +6 -6
- package/lib/Icons/MatrixResources/Pdf.js +1 -1
- package/lib/Icons/MatrixResources/Powerpoint.js +1 -1
- package/lib/Icons/MatrixResources/Video.js +1 -1
- package/lib/Icons/MatrixResources/Word.js +1 -1
- package/lib/Modal/Modal.js +1 -1
- package/lib/PreviewPanel/PreviewModal.js +1 -1
- package/lib/PreviewPanel/PreviewPanel.d.ts +4 -6
- package/lib/PreviewPanel/PreviewPanel.js +11 -39
- package/lib/PreviewPanel/details/MatrixResource.d.ts +4 -9
- package/lib/PreviewPanel/details/MatrixResource.js +20 -16
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.d.ts +5 -5
- package/lib/ResourceBreadcrumb/ResourceBreadcrumb.js +3 -3
- package/lib/ResourceItem/ResourceItem.d.ts +6 -8
- package/lib/ResourceItem/ResourceItem.js +3 -3
- package/lib/ResourceList/ResourceList.d.ts +5 -4
- package/lib/ResourceList/ResourceList.js +3 -3
- package/lib/ResourcePickerContainer/ResourcePickerContainer.d.ts +4 -5
- package/lib/ResourcePickerContainer/ResourcePickerContainer.js +34 -89
- package/lib/SourceDropdown/SourceDropdown.d.ts +5 -5
- package/lib/SourceDropdown/SourceDropdown.js +19 -27
- package/lib/SourceList/SourceList.d.ts +4 -4
- package/lib/SourceList/SourceList.js +7 -5
- package/lib/index.css +6 -0
- package/lib/index.d.ts +6 -29
- package/lib/index.js +2 -3
- package/lib/uuid.js +1 -3
- package/package.json +3 -2
- package/src/Hooks/useCategorisedSources.spec.ts +39 -0
- package/src/Hooks/useCategorisedSources.ts +46 -0
- package/src/Hooks/useChildResources.spec.ts +49 -0
- package/src/Hooks/useChildResources.ts +43 -0
- package/src/Hooks/useResourcePath.spec.ts +124 -0
- package/src/Hooks/useResourcePath.ts +76 -0
- package/src/Hooks/useSources.spec.ts +33 -0
- package/src/Hooks/useSources.ts +33 -0
- package/src/Icons/Icon.stories.tsx +7 -7
- package/src/Icons/Icon.tsx +9 -14
- package/src/Icons/MatrixResources/Audio.tsx +1 -1
- package/src/Icons/MatrixResources/Excel.tsx +1 -1
- package/src/Icons/MatrixResources/MatrixResourceMap.ts +7 -7
- package/src/Icons/MatrixResources/Pdf.tsx +1 -1
- package/src/Icons/MatrixResources/Powerpoint.tsx +1 -1
- package/src/Icons/MatrixResources/Video.tsx +1 -1
- package/src/Icons/MatrixResources/Word.tsx +1 -1
- package/src/Modal/Modal.tsx +1 -1
- package/src/PreviewPanel/PreviewModal.tsx +1 -1
- package/src/PreviewPanel/PreviewPanel.spec.tsx +20 -62
- package/src/PreviewPanel/PreviewPanel.stories.tsx +16 -24
- package/src/PreviewPanel/PreviewPanel.tsx +15 -51
- package/src/PreviewPanel/details/MatrixResource.tsx +23 -19
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.spec.tsx +13 -23
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.stories.tsx +1 -1
- package/src/ResourceBreadcrumb/ResourceBreadcrumb.tsx +8 -9
- package/src/ResourceBreadcrumb/sample-hierarchy.json +15 -25
- package/src/ResourceItem/ResourceItem.tsx +10 -12
- package/src/ResourceList/ResourceList.spec.tsx +8 -53
- package/src/ResourceList/ResourceList.stories.tsx +2 -2
- package/src/ResourceList/ResourceList.tsx +12 -10
- package/src/ResourceList/sample-resources.json +551 -49
- package/src/ResourcePickerContainer/ResourcePickerContainer.spec.tsx +196 -315
- package/src/ResourcePickerContainer/ResourcePickerContainer.stories.tsx +7 -29
- package/src/ResourcePickerContainer/ResourcePickerContainer.tsx +63 -127
- package/src/SourceDropdown/SourceDropdown.spec.tsx +63 -60
- package/src/SourceDropdown/SourceDropdown.stories.tsx +4 -7
- package/src/SourceDropdown/SourceDropdown.tsx +34 -41
- package/src/SourceList/SourceList.spec.tsx +38 -32
- package/src/SourceList/SourceList.tsx +17 -19
- package/src/SourceList/sample-sources.json +186 -77
- package/src/__mocks__/MockModels.ts +30 -0
- package/src/__mocks__/StorybookHelpers.ts +46 -0
- package/src/index.stories.tsx +13 -38
- package/src/index.tsx +5 -29
- package/src/types.d.ts +71 -0
- package/src/uuid.ts +2 -4
- 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;
|
package/lib/Icons/Icon.d.ts
CHANGED
@@ -9,21 +9,21 @@ export declare const iconSources: {
|
|
9
9
|
close: typeof import("./Generics").Close;
|
10
10
|
};
|
11
11
|
matrix: {
|
12
|
-
|
13
|
-
|
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
|
-
|
19
|
-
|
18
|
+
pdf_file: typeof import("./MatrixResources").Pdf;
|
19
|
+
powerpoint_doc: typeof import("./MatrixResources").Powerpoint;
|
20
20
|
site: typeof import("./MatrixResources").Site;
|
21
|
-
|
22
|
-
|
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 =
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
4
|
-
|
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
|
-
|
10
|
-
|
9
|
+
pdf_file: typeof Pdf;
|
10
|
+
powerpoint_doc: typeof Powerpoint;
|
11
11
|
site: typeof Site;
|
12
|
-
|
13
|
-
|
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
|
-
|
7
|
-
|
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
|
-
|
13
|
-
|
12
|
+
pdf_file: _1.Pdf,
|
13
|
+
powerpoint_doc: _1.Powerpoint,
|
14
14
|
site: _1.Site,
|
15
|
-
|
16
|
-
|
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;
|
package/lib/Modal/Modal.js
CHANGED
@@ -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-[
|
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-
|
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 {
|
4
|
+
import { Resource } from '../types';
|
5
5
|
export interface PreviewPanelProps {
|
6
|
-
|
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: (
|
10
|
+
onSelect: (resource: Resource) => void;
|
13
11
|
onClose: () => void;
|
14
12
|
}
|
15
|
-
declare const PreviewPanel: ({
|
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
|
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
|
-
|
37
|
+
// If we are on mobile and the selected resource changes show the preview panel modal.
|
39
38
|
(0, react_1.useEffect)(() => {
|
40
|
-
if (
|
41
|
-
modalState.setOpen(
|
42
|
-
previousIsMobile.current = true;
|
39
|
+
if (!modalState.isOpen) {
|
40
|
+
modalState.setOpen(Boolean(resource && isMobile));
|
43
41
|
}
|
44
|
-
|
45
|
-
|
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, {
|
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(
|
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
|
-
|
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
|
-
|
85
|
-
|
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 {
|
3
|
-
|
4
|
-
|
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,
|
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
|
-
|
11
|
-
|
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
|
-
|
14
|
-
|
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
|
-
|
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:
|
39
|
-
|
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 {
|
3
|
-
export interface ResourceBreadcrumbProps {
|
4
|
-
hierarchy:
|
5
|
-
onBreadcrumbSelect: (node:
|
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;
|