@griddo/ax 10.3.9 → 10.3.11

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 (29) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/Gallery/GalleryPanel/GalleryDragAndDrop/GalleryDragAndDrop.test.tsx +2 -1
  3. package/src/api/files.tsx +10 -5
  4. package/src/api/images.tsx +3 -3
  5. package/src/api/utils.tsx +30 -1
  6. package/src/components/DragAndDrop/index.tsx +5 -0
  7. package/src/components/Fields/UrlField/index.tsx +10 -2
  8. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +15 -10
  9. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/style.tsx +11 -10
  10. package/src/containers/FileDrive/actions.tsx +20 -7
  11. package/src/containers/Gallery/actions.tsx +6 -2
  12. package/src/containers/Sites/actions.tsx +30 -4
  13. package/src/containers/Sites/reducer.tsx +1 -1
  14. package/src/modules/App/Routing/NavMenu/index.tsx +1 -1
  15. package/src/modules/Content/index.tsx +30 -3
  16. package/src/modules/FileDrive/FileDragAndDrop/index.tsx +56 -21
  17. package/src/modules/FileDrive/FileDragAndDrop/style.tsx +69 -27
  18. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/Item/index.tsx +31 -0
  19. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/Item/style.tsx +43 -0
  20. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/ItemGroup/index.tsx +42 -0
  21. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/ItemGroup/style.tsx +34 -0
  22. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/index.tsx +138 -0
  23. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/style.tsx +21 -0
  24. package/src/modules/FileDrive/FileModal/DetailPanel/index.tsx +86 -68
  25. package/src/modules/FileDrive/FileModal/DetailPanel/style.tsx +1 -1
  26. package/src/modules/FileDrive/UploadItem/index.tsx +32 -0
  27. package/src/modules/FileDrive/UploadItem/style.tsx +40 -0
  28. package/src/modules/FileDrive/index.tsx +71 -30
  29. package/src/types/index.tsx +18 -0
@@ -18,11 +18,13 @@ const FileDragAndDrop = (props: IProps) => {
18
18
  inverse = false,
19
19
  uploadError,
20
20
  uploadFile,
21
+ handleMultipleUpload,
21
22
  handleUpload,
22
23
  replaceData,
23
24
  replaceFile,
24
25
  siteID,
25
26
  isAllowedToUpload = true,
27
+ resetError,
26
28
  } = props;
27
29
 
28
30
  const validExtensions = validFormats.map((format) => `.${format}`).join(",");
@@ -32,10 +34,10 @@ const FileDragAndDrop = (props: IProps) => {
32
34
  const [inDropZone, setInDropZone] = useState(false);
33
35
  const [dropDepth, setDropDepth] = useState(0);
34
36
  const [uploadingState, setUploadingState] = useState({ total: 0, ready: 0 });
37
+ const [progress, setProgress] = useState(0);
35
38
 
36
39
  const uploading = isUploading || uploadingState.total > uploadingState.ready;
37
40
  const success = isSuccess && uploadingState.total === uploadingState.ready;
38
- const uploadPercentage = (uploadingState.ready * 100) / uploadingState.total;
39
41
 
40
42
  const handleDragEnter = () => {
41
43
  setDropDepth((depth) => depth + 1);
@@ -61,14 +63,29 @@ const FileDragAndDrop = (props: IProps) => {
61
63
 
62
64
  const handleDrop = async (e: React.DragEvent<HTMLDivElement>) => {
63
65
  const files = Array.from(e.dataTransfer.files);
64
- e.dataTransfer.clearData();
65
- await uploadFiles(files);
66
+ if (handleMultipleUpload && files.length > 1) {
67
+ if (!files.every((file) => checkType(file.type))) {
68
+ uploadError(true, "Invalid format");
69
+ } else {
70
+ handleMultipleUpload(files);
71
+ }
72
+ } else {
73
+ await uploadFiles(files);
74
+ }
66
75
  setDropDepth(0);
67
76
  };
68
77
 
69
- const handleFilesUpload = (e: any) => {
78
+ const handleFilesUpload = async (e: any) => {
70
79
  const files: File[] = Array.from(e.currentTarget.files);
71
- uploadFiles(files);
80
+ if (handleMultipleUpload && files.length > 1) {
81
+ if (!files.every((file) => checkType(file.type))) {
82
+ uploadError(true, "Invalid format");
83
+ } else {
84
+ handleMultipleUpload(files);
85
+ }
86
+ } else {
87
+ await uploadFiles(files);
88
+ }
72
89
  };
73
90
 
74
91
  const uploadFiles = async (files: File[]) => {
@@ -82,27 +99,29 @@ const FileDragAndDrop = (props: IProps) => {
82
99
 
83
100
  let result: IFile[] = [];
84
101
  if (replaceData) {
85
- const fileUploaded = files[0] && (await replaceFile(files[0], replaceData.fileID, replaceData.keepURL, siteID));
102
+ const fileUploaded =
103
+ files[0] && (await replaceFile(files[0], replaceData.fileID, replaceData.keepURL, siteID, setProgress));
86
104
  if (fileUploaded) {
87
105
  result.push(fileUploaded);
106
+ setUploadingState((state) => ({ total: state.total, ready: state.ready + 1 }));
88
107
  }
89
108
  } else {
90
109
  while (files.length) {
91
110
  const file = files.shift();
92
- const fileUploaded = file && (await uploadFile(file, folderID, siteID || "global"));
111
+ const fileUploaded = file && (await uploadFile(file, folderID, siteID || "global", setProgress));
93
112
  if (fileUploaded) {
94
113
  result.push(fileUploaded);
114
+ setUploadingState((state) => ({ total: state.total, ready: state.ready + 1 }));
95
115
  }
96
- setUploadingState((state) => ({ total: state.total, ready: state.ready + 1 }));
97
116
  }
98
117
  }
99
118
 
100
- if (result) {
119
+ if (result.length) {
101
120
  setInDropZone(false);
102
121
  setUploadingState({ total: 0, ready: 0 });
103
122
  setTimeout(() => {
104
123
  handleUpload(result);
105
- }, 3000)
124
+ }, 3000);
106
125
  }
107
126
  } catch (error) {
108
127
  console.log(error);
@@ -111,6 +130,8 @@ const FileDragAndDrop = (props: IProps) => {
111
130
 
112
131
  const handleTryAgain = () => {
113
132
  setInDropZone(false);
133
+ setUploadingState({ total: 0, ready: 0 });
134
+ resetError();
114
135
  };
115
136
 
116
137
  const handleFileClick = () => {
@@ -149,9 +170,9 @@ const FileDragAndDrop = (props: IProps) => {
149
170
  <S.DragSubtitle>Valid formats: {validFormats.join(", ")}. Max. size: 50MB</S.DragSubtitle>
150
171
  </S.DragStatus>
151
172
  <S.DragOverStatus onDragEnter={handleDragEnter} onDragLeave={handleDragLeave}>
152
- <S.DragIcon>
153
- <Icon name="success" size="48" />
154
- </S.DragIcon>
173
+ <S.DropIcon>
174
+ <Icon name="page" size="48" />
175
+ </S.DropIcon>
155
176
  <S.DragTitle>Drop your file</S.DragTitle>
156
177
  <S.DragSubtitle>Valid formats: {validFormats.join(", ")}. Max. size: 50MB</S.DragSubtitle>
157
178
  </S.DragOverStatus>
@@ -189,17 +210,17 @@ const FileDragAndDrop = (props: IProps) => {
189
210
  <S.StatusWrapper>
190
211
  <S.UploadingStatus>
191
212
  <S.DragIcon>
192
- <Icon name="uploadFile" size="48" />
213
+ <Icon name="page" size="48" />
193
214
  </S.DragIcon>
194
215
  <S.ProgressBar>
195
- <ProgressBar percentage={uploadPercentage} inverse={inverse} />
216
+ <ProgressBar percentage={progress} inverse={inverse} />
196
217
  </S.ProgressBar>
197
218
  <S.DragTitle>Uploading...</S.DragTitle>
198
219
  </S.UploadingStatus>
199
220
  <S.SuccessStatus>
200
- <S.DragIcon>
221
+ <S.SuccessIcon>
201
222
  <Icon name="success" size="48" />
202
- </S.DragIcon>
223
+ </S.SuccessIcon>
203
224
  <S.DragTitle>File loaded!</S.DragTitle>
204
225
  </S.SuccessStatus>
205
226
  <S.ErrorStatus>
@@ -228,11 +249,24 @@ interface IProps {
228
249
  inverse?: boolean;
229
250
  siteID: number | "global";
230
251
  isAllowedToUpload?: boolean;
231
- uploadError: (error: boolean, msg?: string) => Promise<void>;
232
- uploadFile: (docFiles: File | File[], folderID: number | null, siteID: number | "global") => Promise<IFile | null>;
233
- handleUpload: (result: IFile[]) => void;
234
252
  replaceData?: { fileID: number; keepURL: boolean };
235
- replaceFile: (docFile: File, fileID: number, keepUrl: boolean, siteID: number | "global") => Promise<IFile | null>;
253
+ handleUpload: (result: IFile[]) => void;
254
+ handleMultipleUpload?: (files: File[]) => void;
255
+ uploadError: (error: boolean, msg?: string) => Promise<void>;
256
+ uploadFile: (
257
+ docFiles: File | File[],
258
+ folderID: number | null,
259
+ siteID: number | "global",
260
+ setProgress?: (progress: number) => void
261
+ ) => Promise<IFile | null>;
262
+ replaceFile: (
263
+ docFile: File,
264
+ fileID: number,
265
+ keepUrl: boolean,
266
+ siteID: number | "global",
267
+ setProgress?: (progress: number) => void
268
+ ) => Promise<IFile | null>;
269
+ resetError: () => void;
236
270
  }
237
271
 
238
272
  const mapStateToProps = (state: IRootState) => ({
@@ -246,6 +280,7 @@ const mapDispatchToProps = {
246
280
  uploadError: fileDriveActions.uploadError,
247
281
  uploadFile: fileDriveActions.uploadFile,
248
282
  replaceFile: fileDriveActions.replaceFile,
283
+ resetError: fileDriveActions.resetError,
249
284
  };
250
285
 
251
286
  export default connect(mapStateToProps, mapDispatchToProps)(memo(FileDragAndDrop));
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import styled from "styled-components";
3
3
  import Button from "@ax/components/Button";
4
4
 
5
- export const Wrapper = styled.div<{ inverse: boolean }>`
5
+ const Wrapper = styled.div<{ inverse: boolean }>`
6
6
  background-color: ${(p) => (p.inverse ? p.theme.color.overlay : p.theme.color.uiBarBackground)};
7
7
  position: relative;
8
8
  transition: opacity 0.1s;
@@ -11,7 +11,7 @@ export const Wrapper = styled.div<{ inverse: boolean }>`
11
11
  padding: ${(p) => p.theme.spacing.m};
12
12
  `;
13
13
 
14
- export const StatusWrapper = styled.div`
14
+ const StatusWrapper = styled.div`
15
15
  position: absolute;
16
16
  top: 50%;
17
17
  left: 50%;
@@ -19,69 +19,89 @@ export const StatusWrapper = styled.div`
19
19
  text-align: center;
20
20
  `;
21
21
 
22
- export const DragStatus = styled.div`
22
+ const DragStatus = styled.div`
23
23
  transition: opacity 0.1s;
24
24
  `;
25
25
 
26
- export const DragTitle = styled.div`
26
+ const DragTitle = styled.div`
27
27
  ${(p) => p.theme.textStyle.fieldLabel};
28
28
  margin-bottom: ${(p) => p.theme.spacing.xxs};
29
29
  `;
30
30
 
31
- export const DragSubtitle = styled.div`
31
+ const DragSubtitle = styled.div`
32
32
  ${(p) => p.theme.textStyle.uiXS};
33
33
  margin-bottom: ${(p) => p.theme.spacing.xxs};
34
34
  `;
35
35
 
36
- export const DragIcon = styled.div`
36
+ const DragIcon = styled.div`
37
37
  height: ${(p) => p.theme.spacing.l};
38
38
  margin-bottom: ${(p) => p.theme.spacing.s};
39
39
  `;
40
40
 
41
- export const DragOverStatus = styled.div`
42
- transition: opacity 0.1s;
43
- ${DragIcon} {
44
- svg {
45
- path {
46
- fill: #ffffff;
47
- }
41
+ const DropIcon = styled.div`
42
+ height: ${(p) => p.theme.spacing.l};
43
+ margin-bottom: ${(p) => p.theme.spacing.s};
44
+ svg {
45
+ path {
46
+ fill: ${(p) => p.theme.color.interactiveInverse};
48
47
  }
49
48
  }
50
49
  `;
51
50
 
52
- export const UploadingStatus = styled.div`
51
+ const SuccessIcon = styled.div`
52
+ height: ${(p) => p.theme.spacing.l};
53
+ margin-bottom: ${(p) => p.theme.spacing.s};
54
+ svg {
55
+ path {
56
+ fill: ${(p) => p.theme.color.online};
57
+ }
58
+ }
59
+ `;
60
+
61
+ const UploadingStatus = styled.div`
53
62
  transition: opacity 0.1s;
54
63
  `;
55
64
 
56
- export const SuccessStatus = styled.div`
65
+ const SuccessStatus = styled.div`
57
66
  transition: opacity 0.1s;
58
- ${DragIcon as any} {
67
+ ${DragIcon} {
59
68
  svg {
60
69
  path {
61
70
  fill: ${(p) => p.theme.color.online};
62
71
  }
63
72
  }
64
73
  }
65
- ${DragTitle as any} {
74
+ ${DragTitle} {
66
75
  color: ${(p) => p.theme.color.textHighEmphasis};
67
76
  }
68
77
  `;
69
78
 
70
- export const ErrorStatus = styled.div`
79
+ const ErrorStatus = styled.div`
71
80
  transition: opacity 0.1s;
72
- ${DragIcon as any} {
81
+ ${DragIcon} {
73
82
  svg {
74
83
  path {
75
84
  fill: ${(p) => p.theme.color.error};
76
85
  }
77
86
  }
78
87
  }
79
- ${DragTitle as any} {
88
+ ${DragTitle} {
80
89
  color: ${(p) => p.theme.color.textHighEmphasis};
81
90
  }
82
91
  `;
83
92
 
84
- export const DragAndDropWrapper = styled.div<{
93
+ const DragOverStatus = styled.div`
94
+ transition: opacity 0.1s;
95
+ ${DragIcon} {
96
+ svg {
97
+ path {
98
+ fill: #ffffff;
99
+ }
100
+ }
101
+ }
102
+ `;
103
+
104
+ const DragAndDropWrapper = styled.div<{
85
105
  inDropZone: boolean;
86
106
  uploading: boolean;
87
107
  success: boolean;
@@ -127,7 +147,7 @@ export const DragAndDropWrapper = styled.div<{
127
147
  }
128
148
  `;
129
149
 
130
- export const UploadingWrapper = styled.div<{
150
+ const UploadingWrapper = styled.div<{
131
151
  inDropZone: boolean;
132
152
  uploading: boolean;
133
153
  success: boolean;
@@ -172,22 +192,22 @@ export const UploadingWrapper = styled.div<{
172
192
  }
173
193
  `;
174
194
 
175
- export const ErrorMsg = styled.div`
195
+ const ErrorMsg = styled.div`
176
196
  ${(p) => p.theme.textStyle.uiXS};
177
197
  color: ${(p) => p.theme.color.textMediumEmphasis};
178
198
  margin-top: ${(p) => p.theme.spacing.xxs};
179
199
  `;
180
200
 
181
- export const StyledButton = styled((props) => <Button {...props} />)`
201
+ const StyledButton = styled((props) => <Button {...props} />)`
182
202
  margin-top: ${(p) => p.theme.spacing.s};
183
203
  `;
184
204
 
185
- export const FilesInput = styled.input<{ ref: any }>`
205
+ const FilesInput = styled.input<{ ref: any }>`
186
206
  display: none;
187
207
  `;
188
208
 
189
209
  const _Button: any = React.forwardRef((props: any, ref?: React.Ref<HTMLDivElement>) => <Button {...props} />);
190
- export const FilesButton = styled(_Button)`
210
+ const FilesButton = styled(_Button)`
191
211
  margin-top: ${(p) => p.theme.spacing.xs};
192
212
  margin-bottom: ${(p) => p.theme.spacing.xs};
193
213
 
@@ -206,6 +226,28 @@ export const FilesButton = styled(_Button)`
206
226
  }
207
227
  `;
208
228
 
209
- export const ProgressBar = styled.div`
229
+ const ProgressBar = styled.div`
210
230
  margin-bottom: ${(p) => p.theme.spacing.xs};
211
231
  `;
232
+
233
+ export {
234
+ Wrapper,
235
+ StatusWrapper,
236
+ DragStatus,
237
+ DragTitle,
238
+ DragSubtitle,
239
+ DragIcon,
240
+ DropIcon,
241
+ SuccessIcon,
242
+ UploadingStatus,
243
+ SuccessStatus,
244
+ ErrorStatus,
245
+ DragOverStatus,
246
+ DragAndDropWrapper,
247
+ UploadingWrapper,
248
+ ErrorMsg,
249
+ StyledButton,
250
+ FilesInput,
251
+ FilesButton,
252
+ ProgressBar,
253
+ };
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import { getFormattedDateWithTimezone } from "@ax/helpers";
3
+
4
+ import * as S from "./style";
5
+
6
+ const Item = (props: IItemProps): JSX.Element => {
7
+ const { title, type, date, onClick } = props;
8
+
9
+ const pageType = type || "Page";
10
+
11
+ return (
12
+ <S.ListItem onClick={onClick}>
13
+ <S.Content>
14
+ <S.Header>
15
+ <S.Type>{pageType}</S.Type>
16
+ <S.Date>{getFormattedDateWithTimezone(date, "d MMM Y")}</S.Date>
17
+ </S.Header>
18
+ <S.Title>{title}</S.Title>
19
+ </S.Content>
20
+ </S.ListItem>
21
+ );
22
+ };
23
+
24
+ interface IItemProps {
25
+ title: string;
26
+ type?: string;
27
+ date: Date;
28
+ onClick: () => void;
29
+ }
30
+
31
+ export default Item;
@@ -0,0 +1,43 @@
1
+ import styled from "styled-components";
2
+
3
+ const ListItem = styled.li`
4
+ display: flex;
5
+ width: 100%;
6
+ padding: ${(p) => p.theme.spacing.s};
7
+ background-color: ${(p) => p.theme.color.uiBarBackground};
8
+ border: 1px solid ${(p) => p.theme.color.uiLine};
9
+ border-radius: ${(p) => p.theme.radii.s};
10
+ margin-bottom: ${(p) => p.theme.spacing.xs};
11
+ :hover {
12
+ background-color: ${(p) => p.theme.color.overlayHoverPrimary};
13
+ cursor: pointer;
14
+ }
15
+ `;
16
+
17
+ const Title = styled.div`
18
+ ${(p) => p.theme.textStyle.fieldContent}
19
+ color: ${(p) => p.theme.colors.textHighEmphasis};
20
+ `;
21
+
22
+ const Header = styled.div`
23
+ display: flex;
24
+ margin-bottom: ${(p) => p.theme.spacing.xxs};
25
+ `;
26
+
27
+ const Type = styled.div`
28
+ ${(p) => p.theme.textStyle.headingXXS};
29
+ color: ${(p) => p.theme.colors.textLowEmphasis};
30
+ `;
31
+
32
+ const Date = styled.div`
33
+ ${(p) => p.theme.textStyle.uiXS};
34
+ color: ${(p) => p.theme.colors.textLowEmphasis};
35
+ margin-left: auto;
36
+ `;
37
+
38
+
39
+ const Content = styled.div`
40
+ width: 100%;
41
+ `;
42
+
43
+ export { ListItem, Title, Header, Type, Date, Content };
@@ -0,0 +1,42 @@
1
+ import React, { useState } from "react";
2
+ import { IFileUseItem } from "@ax/types";
3
+ import Item from "../Item";
4
+
5
+ import * as S from "./style";
6
+
7
+ const ItemGroup = (props: IItemGroupProps): React.ReactElement => {
8
+ const { title, items, onClick } = props;
9
+ const [isOpen, setIsOpen] = useState(false);
10
+
11
+ const handleClick = () => setIsOpen(!isOpen);
12
+
13
+ return (
14
+ <S.Wrapper>
15
+ <S.Label onClick={handleClick} isOpen={isOpen}>
16
+ {title}
17
+ </S.Label>
18
+ <S.Content isOpen={isOpen}>
19
+ {items.map((item: any) => {
20
+ const handleClick = () => onClick(item);
21
+ return (
22
+ <Item
23
+ title={item.title}
24
+ date={item.published}
25
+ type={item.structuredDataId || "Page"}
26
+ key={item.id}
27
+ onClick={handleClick}
28
+ />
29
+ );
30
+ })}
31
+ </S.Content>
32
+ </S.Wrapper>
33
+ );
34
+ };
35
+
36
+ interface IItemGroupProps {
37
+ title: string;
38
+ items: IFileUseItem[];
39
+ onClick(item: IFileUseItem): void;
40
+ }
41
+
42
+ export default ItemGroup;
@@ -0,0 +1,34 @@
1
+ import styled from "styled-components";
2
+
3
+ const Wrapper = styled.div`
4
+ margin: ${(p) => `${p.theme.spacing.m} 0 ${p.theme.spacing.m} 0`};
5
+ `;
6
+
7
+ const Label = styled.div<{ isOpen: boolean }>`
8
+ position: relative;
9
+ ${(p) => p.theme.textStyle.headingXXS};
10
+ color: ${(p) => p.theme.colors.textMediumEmphasis};
11
+ padding-bottom: ${(p) => p.theme.spacing.xs};
12
+ margin-bottom: ${(p) => p.theme.spacing.xs};
13
+ cursor: pointer;
14
+ :after {
15
+ position: absolute;
16
+ right: 10px;
17
+ top: ${(p) => (p.isOpen ? `10px` : `6px`)};
18
+ content: "";
19
+ border: solid ${(p) => p.theme.color.interactive01};
20
+ border-width: 0 2px 2px 0;
21
+ display: inline-block;
22
+ padding: 3px;
23
+ transform: ${(p) => (p.isOpen ? `rotate(-135deg)` : `rotate(45deg)`)};
24
+ }
25
+ `;
26
+
27
+ const Content = styled.div<{ isOpen: boolean }>`
28
+ overflow-y: ${(p) => (p.isOpen ? "visible" : "hidden")};
29
+ max-height: ${(p) => (p.isOpen ? `auto` : 0)};
30
+ transition: all 0.5s ease-in-out;
31
+ border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
32
+ `;
33
+
34
+ export { Wrapper, Label, Content };
@@ -0,0 +1,138 @@
1
+ import React from "react";
2
+ import { connect } from "react-redux";
3
+ import { appActions } from "@ax/containers/App";
4
+ import { pageEditorActions } from "@ax/containers/PageEditor";
5
+ import { sitesActions } from "@ax/containers/Sites";
6
+ import { structuredDataActions } from "@ax/containers/StructuredData";
7
+ import { ISetCurrentPageIDAction } from "@ax/containers/PageEditor/interfaces";
8
+ import { IFile, IFileUseItem, IFileUsePages, IRootState } from "@ax/types";
9
+ import Item from "./Item";
10
+ import ItemGroup from "./ItemGroup";
11
+
12
+ import * as S from "./style";
13
+
14
+ const UsageContent = (props: IProps) => {
15
+ const {
16
+ file,
17
+ currentSiteID,
18
+ selectedTab,
19
+ setHistoryPush,
20
+ setCurrentPageID,
21
+ getSite,
22
+ setCurrentDataID,
23
+ setSelectedStructuredData,
24
+ } = props;
25
+ const {
26
+ contentInUse: { pages, simpleStructuredData, globalPages },
27
+ } = file;
28
+
29
+ const isSiteView = !!currentSiteID;
30
+
31
+ const getPageList = () => {
32
+ if (isSiteView && selectedTab !== "global") {
33
+ const pageItems = pages[0] ? pages[0].pages : [];
34
+ return pageItems.map((item: IFileUseItem) => {
35
+ const handleClick = () => {
36
+ setCurrentPageID(item.id);
37
+ setHistoryPush("pages/editor", true);
38
+ };
39
+
40
+ return <Item title={item.title} date={item.published} key={item.id} onClick={handleClick} />;
41
+ });
42
+ } else {
43
+ return pages.map((item: IFileUsePages) => {
44
+ const handleClick = async (page: IFileUseItem) => {
45
+ await getSite(item.siteId);
46
+ setCurrentPageID(page.id);
47
+ setHistoryPush("/sites/pages/editor", true);
48
+ };
49
+ return <ItemGroup title={item.siteName} items={item.pages} onClick={handleClick} />;
50
+ });
51
+ }
52
+ };
53
+
54
+ const getGlobalPageList = () => {
55
+ if (globalPages.length === 0) {
56
+ return <></>;
57
+ } else {
58
+ const handleClick = (item: IFileUseItem) => {
59
+ setCurrentPageID(item.id);
60
+ const path = isSiteView ? "/data/pages/editor" : "data/pages/editor";
61
+ setHistoryPush(path, true);
62
+ };
63
+ return <ItemGroup title="Global Pages" items={globalPages} onClick={handleClick} />;
64
+ }
65
+ };
66
+
67
+ const getStructuredDataList = () => {
68
+ if (simpleStructuredData.length === 0) {
69
+ return <></>;
70
+ }
71
+ if (isSiteView && selectedTab !== "global") {
72
+ return simpleStructuredData.map((item: IFileUseItem) => {
73
+ const handleClick = () => {
74
+ item.structuredDataId && setSelectedStructuredData(item.structuredDataId, "site");
75
+ setCurrentDataID(item.id);
76
+ setHistoryPush(`data/${item.structuredDataId}/editor`, true);
77
+ };
78
+
79
+ return (
80
+ <Item
81
+ title={item.title}
82
+ date={item.published}
83
+ key={item.id}
84
+ type={item.structuredDataId}
85
+ onClick={handleClick}
86
+ />
87
+ );
88
+ });
89
+ } else {
90
+ const handleClick = (item: IFileUseItem) => {
91
+ item.structuredDataId && setSelectedStructuredData(item.structuredDataId, "global");
92
+ setCurrentDataID(item.id);
93
+ setHistoryPush(`/data/${item.structuredDataId}/editor`, true);
94
+ };
95
+ return <ItemGroup title="Global Simple Content" items={simpleStructuredData} onClick={handleClick} />;
96
+ }
97
+ };
98
+
99
+ return (
100
+ <S.Content>
101
+ <S.Note>
102
+ Only documents <strong>selected from the File field</strong> are counted. Documents added via a URL are not
103
+ displayed in this list.
104
+ </S.Note>
105
+ <S.ListWrapper>
106
+ {getPageList()}
107
+ {getGlobalPageList()}
108
+ {getStructuredDataList()}
109
+ </S.ListWrapper>
110
+ </S.Content>
111
+ );
112
+ };
113
+
114
+ interface IProps {
115
+ file: IFile;
116
+ currentSiteID: number | null;
117
+ selectedTab: "local" | "global";
118
+ setHistoryPush(page: string, isEditor: boolean): Promise<void>;
119
+ setCurrentPageID(currentPageID: number | null): ISetCurrentPageIDAction;
120
+ getSite(siteID: number): Promise<void>;
121
+ setCurrentDataID(id: number | null): void;
122
+ setSelectedStructuredData(id: string, scope: string): void;
123
+ }
124
+
125
+ const mapDispatchToProps = {
126
+ setHistoryPush: appActions.setHistoryPush,
127
+ setCurrentPageID: pageEditorActions.setCurrentPageID,
128
+ getSite: sitesActions.getSite,
129
+ setCurrentDataID: structuredDataActions.setCurrentDataID,
130
+ setSelectedStructuredData: structuredDataActions.setSelectedStructuredData,
131
+ };
132
+
133
+ const mapStateToProps = (state: IRootState) => ({
134
+ currentSiteID: state.sites.currentSiteInfo && state.sites.currentSiteInfo.id,
135
+ selectedTab: state.fileDrive.selectedTab,
136
+ });
137
+
138
+ export default connect(mapStateToProps, mapDispatchToProps)(UsageContent);
@@ -0,0 +1,21 @@
1
+ import styled from "styled-components";
2
+
3
+ const Content = styled.div`
4
+ padding: ${(p) => p.theme.spacing.s};
5
+ overflow: auto;
6
+ height: 100%;
7
+ `;
8
+
9
+ const Note = styled.div`
10
+ ${(p) => p.theme.textStyle.uiXS};
11
+ color: ${(p) => p.theme.color.textMediumEmphasis};
12
+ background-color: ${(p) => p.theme.color.uiBackground03};
13
+ padding: ${(p) => p.theme.spacing.s};
14
+ border-radius: ${(p) => p.theme.radii.s};
15
+ `;
16
+
17
+ const ListWrapper = styled.div`
18
+ margin-top: ${(p) => p.theme.spacing.xs};
19
+ `;
20
+
21
+ export { Content, Note, ListWrapper };