@griddo/ax 11.4.24 → 11.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/Fields/ImageField/ImageField.test.tsx +52 -34
  3. package/src/api/folders.tsx +62 -0
  4. package/src/api/images.tsx +159 -1
  5. package/src/api/index.tsx +2 -0
  6. package/src/api/sites.tsx +1 -1
  7. package/src/components/Fields/ImageField/index.tsx +7 -6
  8. package/src/components/Fields/Wysiwyg/index.tsx +5 -3
  9. package/src/components/FileGallery/index.tsx +22 -16
  10. package/src/components/FileGallery/style.tsx +18 -4
  11. package/src/components/Gallery/FolderItem/index.tsx +39 -0
  12. package/src/components/Gallery/FolderItem/style.tsx +31 -0
  13. package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +112 -237
  14. package/src/components/Gallery/GalleryPanel/DetailPanel/style.tsx +77 -61
  15. package/src/components/Gallery/GalleryPanel/index.tsx +37 -32
  16. package/src/components/Gallery/GalleryPanel/style.tsx +1 -0
  17. package/src/components/Gallery/index.tsx +267 -163
  18. package/src/components/Gallery/style.tsx +200 -135
  19. package/src/components/Loading/index.tsx +7 -2
  20. package/src/components/Loading/style.tsx +2 -2
  21. package/src/components/TableFilters/StateFilter/index.tsx +1 -1
  22. package/src/containers/FileDrive/actions.tsx +1 -2
  23. package/src/containers/FileDrive/interfaces.tsx +3 -3
  24. package/src/containers/Gallery/actions.tsx +359 -13
  25. package/src/containers/Gallery/constants.tsx +12 -0
  26. package/src/containers/Gallery/interfaces.tsx +44 -1
  27. package/src/containers/Gallery/reducer.tsx +27 -3
  28. package/src/containers/Sites/actions.tsx +2 -2
  29. package/src/containers/Users/actions.tsx +9 -6
  30. package/src/helpers/files.tsx +37 -1
  31. package/src/helpers/index.tsx +3 -1
  32. package/src/modules/App/Routing/NavMenu/NavItem/NavSubItem/style.tsx +7 -2
  33. package/src/modules/App/Routing/NavMenu/index.tsx +2 -1
  34. package/src/modules/FileDrive/FileFilters/SortBy/style.tsx +3 -0
  35. package/src/modules/FileDrive/FileModal/DetailPanel/UsageContent/index.tsx +1 -1
  36. package/src/modules/FileDrive/FolderTree/MenuItem/index.tsx +14 -10
  37. package/src/modules/FileDrive/FolderTree/MenuItem/style.tsx +8 -1
  38. package/src/modules/FileDrive/FolderTree/MenuList/index.tsx +9 -2
  39. package/src/modules/FileDrive/index.tsx +45 -28
  40. package/src/modules/FileDrive/style.tsx +7 -6
  41. package/src/modules/GlobalEditor/index.tsx +1 -1
  42. package/src/modules/MediaGallery/Breadcrumb/index.tsx +42 -0
  43. package/src/modules/MediaGallery/Breadcrumb/style.tsx +18 -0
  44. package/src/modules/MediaGallery/BulkGridHeader/GridHeader/index.tsx +37 -0
  45. package/src/modules/MediaGallery/BulkGridHeader/GridHeader/style.tsx +19 -0
  46. package/src/modules/MediaGallery/BulkGridHeader/index.tsx +35 -0
  47. package/src/modules/MediaGallery/BulkGridHeader/style.tsx +17 -0
  48. package/src/modules/MediaGallery/BulkListHeader/TableHeader/index.tsx +46 -0
  49. package/src/modules/MediaGallery/BulkListHeader/TableHeader/style.tsx +53 -0
  50. package/src/modules/MediaGallery/BulkListHeader/index.tsx +42 -0
  51. package/src/modules/MediaGallery/BulkListHeader/style.tsx +17 -0
  52. package/src/modules/MediaGallery/FolderItem/index.tsx +191 -0
  53. package/src/modules/MediaGallery/FolderItem/style.tsx +39 -0
  54. package/src/modules/MediaGallery/FolderTree/MenuItem/index.tsx +87 -0
  55. package/src/modules/MediaGallery/FolderTree/MenuItem/style.tsx +76 -0
  56. package/src/modules/MediaGallery/FolderTree/MenuList/index.tsx +34 -0
  57. package/src/modules/MediaGallery/FolderTree/index.tsx +62 -0
  58. package/src/modules/MediaGallery/FolderTree/style.tsx +49 -0
  59. package/src/modules/MediaGallery/GridItem/index.tsx +149 -0
  60. package/src/modules/MediaGallery/GridItem/style.tsx +74 -0
  61. package/src/modules/MediaGallery/ImageDragAndDrop/index.tsx +299 -0
  62. package/src/{components/Gallery/GalleryPanel/GalleryDragAndDrop → modules/MediaGallery/ImageDragAndDrop}/style.tsx +114 -33
  63. package/src/{components/Gallery/GalleryFilters → modules/MediaGallery/ImageFilters}/Orientation/style.tsx +2 -1
  64. package/src/{components/Gallery/GalleryFilters → modules/MediaGallery/ImageFilters}/SortBy/style.tsx +3 -0
  65. package/src/{components/Gallery/GalleryFilters → modules/MediaGallery/ImageFilters}/Type/style.tsx +1 -0
  66. package/src/modules/MediaGallery/ImageFilters/Usage/index.tsx +75 -0
  67. package/src/modules/MediaGallery/ImageFilters/Usage/style.tsx +30 -0
  68. package/src/modules/MediaGallery/ImageModal/DetailPanel/UsageContent/Item/index.tsx +35 -0
  69. package/src/modules/MediaGallery/ImageModal/DetailPanel/UsageContent/Item/style.tsx +43 -0
  70. package/src/modules/MediaGallery/ImageModal/DetailPanel/UsageContent/ItemGroup/index.tsx +44 -0
  71. package/src/modules/MediaGallery/ImageModal/DetailPanel/UsageContent/ItemGroup/style.tsx +34 -0
  72. package/src/modules/MediaGallery/ImageModal/DetailPanel/UsageContent/index.tsx +233 -0
  73. package/src/modules/MediaGallery/ImageModal/DetailPanel/UsageContent/style.tsx +21 -0
  74. package/src/modules/MediaGallery/ImageModal/DetailPanel/index.tsx +209 -0
  75. package/src/modules/MediaGallery/ImageModal/DetailPanel/style.tsx +81 -0
  76. package/src/modules/MediaGallery/ImageModal/index.tsx +168 -0
  77. package/src/modules/MediaGallery/ImageModal/style.tsx +106 -0
  78. package/src/modules/MediaGallery/ListItem/index.tsx +181 -0
  79. package/src/modules/MediaGallery/ListItem/style.tsx +100 -0
  80. package/src/modules/MediaGallery/UploadItem/index.tsx +32 -0
  81. package/src/modules/MediaGallery/UploadItem/style.tsx +42 -0
  82. package/src/modules/MediaGallery/atoms.tsx +196 -0
  83. package/src/{components/Gallery → modules/MediaGallery}/hooks.tsx +10 -4
  84. package/src/modules/MediaGallery/index.tsx +892 -0
  85. package/src/modules/MediaGallery/style.tsx +216 -0
  86. package/src/{components/Gallery → modules/MediaGallery}/utils.tsx +1 -1
  87. package/src/modules/StructuredData/Form/index.tsx +2 -2
  88. package/src/routes/multisite.tsx +24 -4
  89. package/src/routes/site.tsx +24 -4
  90. package/src/types/files.tsx +98 -0
  91. package/src/types/index.tsx +33 -91
  92. package/src/__tests__/components/Gallery/Gallery.test.tsx +0 -559
  93. package/src/__tests__/components/Gallery/GalleryFilters/Orientation/Orientation.test.tsx +0 -54
  94. package/src/__tests__/components/Gallery/GalleryFilters/SortBy/SortBy.test.tsx +0 -118
  95. package/src/__tests__/components/Gallery/GalleryFilters/Type/Type.test.tsx +0 -54
  96. package/src/__tests__/components/Gallery/GalleryPanel/DetailPanel/DetailPanel.test.tsx +0 -869
  97. package/src/__tests__/components/Gallery/GalleryPanel/GalleryDragAndDrop/GalleryDragAndDrop.test.tsx +0 -249
  98. package/src/__tests__/components/Gallery/GalleryPanel/GalleryPanel.test.tsx +0 -55
  99. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +0 -239
  100. package/src/containers/FileDrive/utils.tsx +0 -37
  101. /package/src/{components/Gallery/GalleryFilters → modules/MediaGallery/ImageFilters}/Orientation/index.tsx +0 -0
  102. /package/src/{components/Gallery/GalleryFilters → modules/MediaGallery/ImageFilters}/SortBy/index.tsx +0 -0
  103. /package/src/{components/Gallery/GalleryFilters → modules/MediaGallery/ImageFilters}/Type/index.tsx +0 -0
@@ -1,3 +1,5 @@
1
+ import { IFolderTree } from "@ax/types";
2
+
1
3
  const getFileIcon = (type: string) => {
2
4
  switch (type) {
3
5
  case "pdf":
@@ -30,4 +32,38 @@ const getFileIcon = (type: string) => {
30
32
  }
31
33
  };
32
34
 
33
- export { getFileIcon };
35
+ const getPath = (tree: IFolderTree[], targetID: number): IFolderTree[] | undefined => {
36
+ for (const element of tree) {
37
+ if (element.id === targetID) {
38
+ return [element];
39
+ }
40
+ if (element.children.length) {
41
+ const result = getPath(element.children, targetID);
42
+ if (result) {
43
+ result.unshift(element);
44
+ return result;
45
+ }
46
+ }
47
+ }
48
+ };
49
+
50
+ const getNewBreadcrumb = (tree: IFolderTree[], target: number | null) => {
51
+ if (!target) return [];
52
+
53
+ return getPath(tree, target) || [];
54
+ };
55
+
56
+ const updatePropertyById = (id: number, data: IFolderTree[], property: string, value: any) => {
57
+ for (let i = 0; i < data.length; i++) {
58
+ if (data[i].id === id) {
59
+ data[i] = { ...data[i], [property]: value };
60
+ }
61
+ if (data[i].children !== undefined && data[i].children.length > 0) {
62
+ data[i].children = updatePropertyById(id, data[i].children, property, value);
63
+ }
64
+ }
65
+
66
+ return data;
67
+ };
68
+
69
+ export { getFileIcon, getNewBreadcrumb, updatePropertyById };
@@ -120,7 +120,7 @@ import {
120
120
 
121
121
  import { parseTheme } from "./parseTheme";
122
122
 
123
- import { getFileIcon } from "./files";
123
+ import { getFileIcon, getNewBreadcrumb, updatePropertyById } from "./files";
124
124
 
125
125
  import { getMaxColumns, updateColumns } from "./customColumns";
126
126
 
@@ -225,6 +225,8 @@ export {
225
225
  stripHtml,
226
226
  encodeData,
227
227
  getFileIcon,
228
+ getNewBreadcrumb,
229
+ updatePropertyById,
228
230
  arrayInsert,
229
231
  getMaxColumns,
230
232
  updateColumns,
@@ -1,8 +1,13 @@
1
1
  import styled from "styled-components";
2
2
 
3
3
  export const SubItem = styled.li<{ active: boolean; type: string }>`
4
- ${(p) => p.active ? p.theme.textStyle.uiMSemibold : p.theme.textStyle.uiM};
5
- background-color: ${(p) => (p.active ? p.theme.color.overlayHoverDark : `transparent`)};
4
+ ${(p) => (p.active ? p.theme.textStyle.uiMSemibold : p.theme.textStyle.uiM)};
5
+ background-color: ${(p) =>
6
+ p.active && p.type === "multisite"
7
+ ? "#23255C"
8
+ : p.active && p.type !== "multisite"
9
+ ? p.theme.color.overlayHoverDark
10
+ : `transparent`};
6
11
  display: block;
7
12
  color: ${(p) => (p.active ? p.theme.color.textHighEmphasisInverse : p.theme.color.textMediumEmphasisInverse)};
8
13
  clear: both;
@@ -43,7 +43,8 @@ const NavMenu = (props: IProps) => {
43
43
  currentSiteInfo && currentSiteInfo.smallAvatar ? currentSiteInfo.smallAvatar : logoMiniPlaceholder;
44
44
 
45
45
  const sitesPath = "/sites/";
46
- const isSite = location.pathname.includes(sitesPath) && location.pathname.length > sitesPath.length;
46
+ const isSite =
47
+ location.pathname.includes(sitesPath) && location.pathname.length > sitesPath.length && !!currentSiteInfo;
47
48
  const siteSelector = location.pathname === "/sites";
48
49
 
49
50
  const goToPublishedSite = () => {
@@ -5,6 +5,9 @@ import { Header } from "@ax/components/TableList/style";
5
5
  const SortBy = styled((props) => <Header {...props} />)<{ isActive: boolean }>`
6
6
  width: 100%;
7
7
  cursor: pointer;
8
+ flex-shrink: 0;
9
+ white-space: nowrap;
10
+ flex-wrap: nowrap;
8
11
  &:hover {
9
12
  color: ${(p) => p.theme.color.interactive01};
10
13
  }
@@ -46,7 +46,7 @@ const UsageContent = (props: IProps) => {
46
46
  setCurrentPageID(page.id);
47
47
  setHistoryPush("/sites/pages/editor", true);
48
48
  };
49
- return <ItemGroup title={item.siteName} items={item.pages} onClick={handleClick} />;
49
+ return <ItemGroup key={item.siteId} title={item.siteName} items={item.pages} onClick={handleClick} />;
50
50
  });
51
51
  }
52
52
  };
@@ -12,7 +12,9 @@ const MenuItem = (props: IMenuItem) => {
12
12
 
13
13
  const [isExpanded, setIsExpanded] = useState(true);
14
14
 
15
- const hasChildren = item.children && item.children.length > 0;
15
+ const hasChildren =
16
+ item.children &&
17
+ item.children.filter((listItem) => !hidden || (hidden && !hidden.includes(listItem.id))).length > 0;
16
18
 
17
19
  const handleToggle = (e: React.MouseEvent<HTMLDivElement>) => {
18
20
  e.stopPropagation();
@@ -49,7 +51,7 @@ const MenuItem = (props: IMenuItem) => {
49
51
  <li>
50
52
  <S.ItemWrapper>
51
53
  <S.Item onClick={handleClick} selected={folderID === item.id}>
52
- <S.ArrowWrapper onClick={handleToggle}>{getIcon(item)}</S.ArrowWrapper>
54
+ {hasChildren && <S.ArrowWrapper onClick={handleToggle}>{getIcon(item)}</S.ArrowWrapper>}
53
55
  <S.IconWrapper>
54
56
  <Icon name="project" size="16" />
55
57
  </S.IconWrapper>
@@ -58,14 +60,16 @@ const MenuItem = (props: IMenuItem) => {
58
60
  </S.Item>
59
61
  </S.ItemWrapper>
60
62
  {hasChildren && isExpanded && (
61
- <MenuList
62
- list={item.children}
63
- hidden={hidden}
64
- trimNames={trimNames}
65
- createAction={createAction}
66
- folderID={folderID}
67
- onClick={onClick}
68
- />
63
+ <S.ListWrapper>
64
+ <MenuList
65
+ list={item.children}
66
+ hidden={hidden}
67
+ trimNames={trimNames}
68
+ createAction={createAction}
69
+ folderID={folderID}
70
+ onClick={onClick}
71
+ />
72
+ </S.ListWrapper>
69
73
  )}
70
74
  </li>
71
75
  );
@@ -32,7 +32,10 @@ const Name = styled.div`
32
32
  ${(p) => p.theme.textStyle.uiS};
33
33
  color: ${(p) => p.theme.color.textMediumEmphasis};
34
34
  margin-left: ${(p) => p.theme.spacing.xs};
35
+ flex: 1;
35
36
  white-space: nowrap;
37
+ overflow: hidden;
38
+ text-overflow: ellipsis;
36
39
  `;
37
40
 
38
41
  const RootName = styled.div`
@@ -66,4 +69,8 @@ const Title = styled.div`
66
69
  margin-bottom: ${(p) => p.theme.spacing.xs};
67
70
  `;
68
71
 
69
- export { ItemWrapper, Item, Name, RootName, IconWrapper, ArrowWrapper, Title, NewIconWrapper };
72
+ const ListWrapper = styled.div`
73
+ padding-left: ${(p) => `calc(${p.theme.spacing.s} * 2)`};
74
+ `;
75
+
76
+ export { ItemWrapper, Item, Name, RootName, IconWrapper, ArrowWrapper, Title, NewIconWrapper, ListWrapper };
@@ -3,12 +3,19 @@ import { IFolderTree } from "@ax/types";
3
3
  import MenuItem from "../MenuItem";
4
4
 
5
5
  const MenuList = (props: IMenuListProps) => {
6
- const { list, folderID, createAction, onClick } = props;
6
+ const { list, folderID, hidden, createAction, onClick } = props;
7
7
 
8
8
  return (
9
9
  <ul>
10
10
  {list.map((listItem, index) => (
11
- <MenuItem key={index} item={listItem} onClick={onClick} folderID={folderID} createAction={createAction} />
11
+ <MenuItem
12
+ key={index}
13
+ item={listItem}
14
+ onClick={onClick}
15
+ folderID={folderID}
16
+ createAction={createAction}
17
+ hidden={hidden}
18
+ />
12
19
  ))}
13
20
  </ul>
14
21
  );
@@ -81,12 +81,14 @@ const FileDrive = (props: IProps) => {
81
81
  const [isPanelOpen, setPanelOpen] = useState(false);
82
82
  const [fileSelected, setFileSelected] = useState<IFile | null>(null);
83
83
  const [selectedFolder, setSelectedFolder] = useState<number>(currentFolderID || 0);
84
- const filesIds: number[] = items.map((file: any) => file.id) || [];
84
+ const filesIds: number[] = items.map((file) => file.id) || [];
85
85
  const [galleryItems, setGalleryItems] = useState<number[]>(filesIds);
86
86
  const [galleryDelete, setGalleryDelete] = useState(true);
87
87
  const [numDocs, setNumDocs] = useState(1);
88
88
  const [progressItems, setProgressItems] = useState<number[]>([]);
89
+ const [wrapperWidth, setWrapperWidth] = useState<number>();
89
90
  const tableRef = useRef<HTMLDivElement>(null);
91
+ const wrapperRef = useRef<HTMLDivElement>(null);
90
92
  const { isOpen: isNewOpen, toggleModal: toggleNewModal } = useModal();
91
93
  const { isOpen: isUploadOpen, toggleModal: toggleUploadModal } = useModal();
92
94
  const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
@@ -144,29 +146,29 @@ const FileDrive = (props: IProps) => {
144
146
  const allowedToAddSiteFile = usePermission("mediaGallery.addFiles");
145
147
  const allowedToAddGlobalFile = usePermission("global.mediaGallery.addGlobalFiles");
146
148
  const allowedToAddGlobalFileFromSite = usePermission("mediaGallery.addGlobalFilesFromSite");
147
- const allowedToAddFile = isTabGlobal
148
- ? allowedToAddGlobalFileFromSite
149
- : isSiteView
150
- ? allowedToAddSiteFile
151
- : allowedToAddGlobalFile;
149
+ const allowedToAddFile = !isSiteView
150
+ ? allowedToAddGlobalFile
151
+ : isTabGlobal
152
+ ? allowedToAddGlobalFileFromSite
153
+ : allowedToAddSiteFile;
152
154
 
153
155
  const allowedToEditSiteFile = usePermission("mediaGallery.editFiles");
154
156
  const allowedToEditGlobalFile = usePermission("global.mediaGallery.editGlobalFiles");
155
157
  const allowedToEditGlobalFileFromSite = usePermission("mediaGallery.editGlobalFilesInSite");
156
- const allowedToEditFile = isTabGlobal
157
- ? allowedToEditGlobalFileFromSite
158
- : isSiteView
159
- ? allowedToEditSiteFile
160
- : allowedToEditGlobalFile;
158
+ const allowedToEditFile = !isSiteView
159
+ ? allowedToEditGlobalFile
160
+ : isTabGlobal
161
+ ? allowedToEditGlobalFileFromSite
162
+ : allowedToEditSiteFile;
161
163
 
162
164
  const allowedToDeleteSiteFile = usePermission("mediaGallery.deleteFiles");
163
165
  const allowedToDeleteGlobalFile = usePermission("global.mediaGallery.deleteGlobalFiles");
164
166
  const allowedToDeleteGlobalFileFromSite = usePermission("mediaGallery.deleteGlobalFilesInSite");
165
- const allowedToDeleteFile = isTabGlobal
166
- ? allowedToDeleteGlobalFileFromSite
167
- : isSiteView
168
- ? allowedToDeleteSiteFile
169
- : allowedToDeleteGlobalFile;
167
+ const allowedToDeleteFile = !isSiteView
168
+ ? allowedToDeleteGlobalFile
169
+ : isTabGlobal
170
+ ? allowedToDeleteGlobalFileFromSite
171
+ : allowedToDeleteSiteFile;
170
172
 
171
173
  const getParams = useCallback(() => {
172
174
  const params = {
@@ -178,13 +180,14 @@ const FileDrive = (props: IProps) => {
178
180
  };
179
181
 
180
182
  return params;
181
- }, [currentFolderID, selectedTab, searchQuery, filterQuery]);
183
+ }, [currentFolderID, searchQuery, filterQuery, siteID]);
182
184
 
183
185
  useLayoutEffect(() => {
184
186
  return () => {
185
187
  updateCurrentFolder(null);
186
188
  updateTab("site");
187
189
  };
190
+ // eslint-disable-next-line react-hooks/exhaustive-deps
188
191
  }, []);
189
192
 
190
193
  useEffect(() => {
@@ -192,22 +195,31 @@ const FileDrive = (props: IProps) => {
192
195
  const params = getParams();
193
196
  await getFolderContent(params);
194
197
  };
195
- handleGetContent();
196
- // eslint-disable-next-line react-hooks/exhaustive-deps
197
- }, [getParams]);
198
-
199
- useEffect(() => {
200
198
  const handleGetTree = async () => await getFoldersTree(siteID);
201
199
  handleGetTree();
200
+ handleGetContent();
202
201
  // eslint-disable-next-line react-hooks/exhaustive-deps
203
- }, [selectedTab]);
202
+ }, [getParams, selectedTab]);
204
203
 
205
204
  useEffect(() => {
206
- const filesIds: number[] = items.map((file: any) => file.id) || [];
205
+ const filesIds = items.map((file) => file.id) || [];
207
206
  setGalleryItems(filesIds);
208
207
  // eslint-disable-next-line react-hooks/exhaustive-deps
209
208
  }, [items]);
210
209
 
210
+ useEffect(() => {
211
+ const handleResize = () => {
212
+ if (wrapperRef.current) {
213
+ setWrapperWidth(wrapperRef.current.offsetWidth);
214
+ }
215
+ };
216
+ handleResize();
217
+
218
+ window.addEventListener("resize", handleResize);
219
+ return () => window.removeEventListener("resize", handleResize);
220
+ // eslint-disable-next-line react-hooks/exhaustive-deps
221
+ }, [wrapperRef.current]);
222
+
211
223
  const {
212
224
  resetBulkSelection,
213
225
  selectedItems,
@@ -275,7 +287,7 @@ const FileDrive = (props: IProps) => {
275
287
  await getFolderContent(params);
276
288
  };
277
289
 
278
- const uploadMultipleFiles = async (files: File[], progressArray: number[]) => {
290
+ const uploadMultipleFiles = async (files: File[]) => {
279
291
  try {
280
292
  let index = 0;
281
293
  while (files.length) {
@@ -298,7 +310,7 @@ const FileDrive = (props: IProps) => {
298
310
  const initialProgress = files.map(() => 0);
299
311
  setProgressItems(initialProgress);
300
312
 
301
- await uploadMultipleFiles(files, initialProgress);
313
+ await uploadMultipleFiles(files);
302
314
 
303
315
  setProgressItems([]);
304
316
  const params = getParams();
@@ -610,8 +622,13 @@ const FileDrive = (props: IProps) => {
610
622
 
611
623
  return (
612
624
  <MainWrapper backLink={false} title="File Drive Manager" rightButton={rightButtonProps}>
613
- <S.Wrapper>
614
- <S.FolderPanel isOpen={isPanelOpen} ref={ref} style={{ width: isPanelOpen ? "240px" : "0" }}>
625
+ <S.Wrapper ref={wrapperRef}>
626
+ <S.FolderPanel
627
+ isOpen={isPanelOpen}
628
+ ref={ref}
629
+ style={{ width: isPanelOpen ? "240px" : "0" }}
630
+ maxWidth={wrapperWidth}
631
+ >
615
632
  <S.FolderPanelContent>
616
633
  <FolderTree
617
634
  folderID={currentFolderID || 0}
@@ -7,13 +7,13 @@ const Wrapper = styled.div`
7
7
  height: 100%;
8
8
  `;
9
9
 
10
- const FolderPanel = styled.div<{ isOpen: boolean }>`
10
+ const FolderPanel = styled.div<{ isOpen: boolean; maxWidth?: number }>`
11
11
  position: relative;
12
12
  background-color: ${(p) => p.theme.color.uiBackground02};
13
13
  border-right: ${(p) => `1px solid ${p.theme.color.uiLine}`};
14
14
  width: ${(p) => (p.isOpen ? "240px" : "0")};
15
15
  min-width: ${(p) => (p.isOpen ? "240px" : "0")};
16
- max-width: ${(p) => (p.isOpen ? "50%" : "0")};
16
+ max-width: ${(p) => (p.isOpen && p.maxWidth ? `${p.maxWidth - 860}px` : "0")};
17
17
  overflow: hidden;
18
18
  flex-shrink: 0;
19
19
  `;
@@ -32,6 +32,7 @@ const ContentWrapper = styled.div`
32
32
  overflow: auto;
33
33
  display: flex;
34
34
  flex-direction: column;
35
+ min-width: 860px;
35
36
  `;
36
37
 
37
38
  const FolderContent = styled.div`
@@ -174,11 +175,11 @@ const ResizeHandle = styled.div`
174
175
  `;
175
176
 
176
177
  const SearchTags = styled.div`
177
- & > div:nth-child(1){
178
- margin-top: ${p => p.theme.spacing.m};
178
+ & > div:nth-child(1) {
179
+ margin-top: ${(p) => p.theme.spacing.m};
179
180
  }
180
- & > div:nth-child(2){
181
- margin-top: ${p => p.theme.spacing.xs};
181
+ & > div:nth-child(2) {
182
+ margin-top: ${(p) => p.theme.spacing.xs};
182
183
  }
183
184
  `;
184
185
 
@@ -731,7 +731,7 @@ interface IPageEditorDispatchProps {
731
731
  sendPagePing(pageID: number): Promise<boolean>;
732
732
  setStructuredDataFilter(filter: string | null): void;
733
733
  discardDraft(): Promise<void>;
734
- getUserCurrentPermissions(): void;
734
+ getUserCurrentPermissions(): Promise<void>;
735
735
  schedulePublication(date: string | null, isDraft: boolean): Promise<boolean>;
736
736
  }
737
737
 
@@ -0,0 +1,42 @@
1
+ import React from "react";
2
+ import { IFolderTree } from "@ax/types";
3
+
4
+ import * as S from "./style";
5
+
6
+ const Breadcrumb = (props: IBreadcrumbProps): JSX.Element => {
7
+ const { breadcrumb, onClick } = props;
8
+
9
+ const handleRootClick = () => onClick(null);
10
+
11
+ return (
12
+ <S.BreadcrumbGroup data-testid="file-breadcrumb">
13
+ <React.Fragment key="root">
14
+ <S.BreadcrumbItem onClick={handleRootClick} isLastItem={false}>
15
+ All Documents
16
+ </S.BreadcrumbItem>
17
+ {"/"}
18
+ </React.Fragment>
19
+ {breadcrumb.slice(0).map((item: IFolderTree, index: number, arr: any) => {
20
+ const { id, name } = item;
21
+ const isLastItem = breadcrumb.length === index + 1;
22
+ const handleClick = () => onClick(id);
23
+
24
+ return (
25
+ <React.Fragment key={`${id}${index}`}>
26
+ <S.BreadcrumbItem onClick={handleClick} isLastItem={isLastItem}>
27
+ {name}
28
+ </S.BreadcrumbItem>
29
+ {index <= arr.length - 2 && "/"}
30
+ </React.Fragment>
31
+ );
32
+ })}
33
+ </S.BreadcrumbGroup>
34
+ );
35
+ };
36
+
37
+ export interface IBreadcrumbProps {
38
+ breadcrumb: IFolderTree[];
39
+ onClick(folderID: number | null): void;
40
+ }
41
+
42
+ export default Breadcrumb;
@@ -0,0 +1,18 @@
1
+ import styled from "styled-components";
2
+
3
+ const BreadcrumbGroup = styled.div`
4
+ display: flex;
5
+ align-items: center;
6
+ flex-wrap: wrap;
7
+ padding-top: ${p => p.theme.spacing.s};
8
+ `;
9
+
10
+ const BreadcrumbItem = styled.div<{isLastItem: boolean}>`
11
+ ${p => p.theme.textStyle.uiM};
12
+ color: ${p => p.isLastItem ? p.theme.color.textMediumEmphasis : p.theme.color.interactive01};
13
+ padding: 0 ${p => p.theme.spacing.xxs};
14
+ cursor: ${p => p.isLastItem ? "default" : "pointer"};
15
+ font-weight: 600;
16
+ `;
17
+
18
+ export { BreadcrumbGroup, BreadcrumbItem }
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+
3
+ import { CheckField, TableCounter } from "@ax/components";
4
+
5
+ import * as S from "./style";
6
+
7
+ const GridHeader = (props: IProps): JSX.Element => {
8
+ const { selectAllItems, checkState, totalItems } = props;
9
+
10
+ return (
11
+ <S.Header>
12
+ <S.CheckWrapper>
13
+ <CheckField
14
+ key="selectAll"
15
+ name="selectAll"
16
+ value="selectAll"
17
+ onChange={selectAllItems}
18
+ checked={checkState.isAllSelected}
19
+ disabled={false}
20
+ error={false}
21
+ title="Select all images"
22
+ />
23
+ </S.CheckWrapper>
24
+ <S.CounterWrapper>
25
+ <TableCounter totalItems={totalItems} />
26
+ </S.CounterWrapper>
27
+ </S.Header>
28
+ );
29
+ };
30
+
31
+ interface IProps {
32
+ totalItems: number;
33
+ selectAllItems: () => void;
34
+ checkState: Record<string, boolean>;
35
+ }
36
+
37
+ export default GridHeader;
@@ -0,0 +1,19 @@
1
+ import styled from "styled-components";
2
+
3
+ const Header = styled.div`
4
+ width: 100%;
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: space-between;
8
+ margin-left: ${(p) => p.theme.spacing.m};
9
+ `;
10
+
11
+ const CheckWrapper = styled.div`
12
+ label {
13
+ margin-bottom: 0;
14
+ }
15
+ `;
16
+
17
+ const CounterWrapper = styled.div``;
18
+
19
+ export { Header, CheckWrapper, CounterWrapper };
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+ import { IBulkAction } from "@ax/types";
3
+
4
+ import GridHeader from "./GridHeader";
5
+
6
+ import * as S from "./style";
7
+
8
+ const BulkGridHeader = (props: IBulkHeaderProps): JSX.Element => {
9
+ const { showBulk, checkState, selectItems, selectAllItems, totalItems, bulkActions } = props;
10
+
11
+ return showBulk ? (
12
+ <S.BulkWrapper>
13
+ <S.StyledBulkSelectionOptions
14
+ isScrolling={false}
15
+ checkState={checkState}
16
+ actions={bulkActions}
17
+ selectItems={selectItems}
18
+ totalItems={totalItems}
19
+ />
20
+ </S.BulkWrapper>
21
+ ) : (
22
+ <GridHeader selectAllItems={selectAllItems} checkState={checkState} totalItems={totalItems} />
23
+ );
24
+ };
25
+
26
+ export interface IBulkHeaderProps {
27
+ showBulk: boolean;
28
+ checkState: any;
29
+ selectItems: () => void;
30
+ selectAllItems: () => void;
31
+ totalItems: number;
32
+ bulkActions: IBulkAction[];
33
+ }
34
+
35
+ export default BulkGridHeader;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import styled from "styled-components";
3
+ import { BulkSelectionOptions } from "@ax/components";
4
+
5
+ const BulkWrapper = styled.div`
6
+ width: 100%;
7
+ span {
8
+ margin-left: ${(p) => p.theme.spacing.xs};
9
+ }
10
+ `;
11
+
12
+ const StyledBulkSelectionOptions = styled(BulkSelectionOptions)`
13
+ padding: ${(p) => `0 0 0 ${p.theme.spacing.xs}`};
14
+ height: ${(p) => p.theme.spacing.s};
15
+ `;
16
+
17
+ export { BulkWrapper, StyledBulkSelectionOptions }
@@ -0,0 +1,46 @@
1
+ import React from "react";
2
+
3
+ import { CheckField, TableCounter, Tooltip } from "@ax/components";
4
+
5
+ import * as S from "./style";
6
+
7
+ const TableHeader = (props: IProps): JSX.Element => {
8
+ const { isScrolling, selectAllItems, checkState, totalItems, setHoverCheck } = props;
9
+
10
+ return (
11
+ <S.TableHeader isScrolling={isScrolling}>
12
+ <S.CheckHeader>
13
+ <Tooltip content="Select All Files">
14
+ <CheckField
15
+ key="selectAll"
16
+ name="selectAll"
17
+ value="selectAll"
18
+ onChange={selectAllItems}
19
+ checked={checkState.isAllSelected || checkState.hoverCheck}
20
+ disabled={false}
21
+ error={false}
22
+ setHoverCheck={setHoverCheck}
23
+ />
24
+ </Tooltip>
25
+ </S.CheckHeader>
26
+ <S.NameHeader>Name</S.NameHeader>
27
+ <S.TypeHeader>Type</S.TypeHeader>
28
+ <S.SizeHeader>Size</S.SizeHeader>
29
+ <S.UpdatedHeader>Resolution</S.UpdatedHeader>
30
+ <S.TagsHeader>Tags</S.TagsHeader>
31
+ <S.CounterHeader>
32
+ <TableCounter totalItems={totalItems} />
33
+ </S.CounterHeader>
34
+ </S.TableHeader>
35
+ );
36
+ };
37
+
38
+ interface IProps {
39
+ isScrolling: boolean;
40
+ totalItems: number;
41
+ selectAllItems: () => void;
42
+ checkState: Record<string, boolean>;
43
+ setHoverCheck: (state: boolean) => void;
44
+ }
45
+
46
+ export default TableHeader;
@@ -0,0 +1,53 @@
1
+ import styled from "styled-components";
2
+
3
+ import { Header } from "@ax/components/TableList/style";
4
+
5
+ const TableHeader = styled.div<{ isScrolling?: boolean }>`
6
+ width: 100%;
7
+ display: flex;
8
+ flex-direction: row;
9
+ padding-bottom: ${(p) => p.theme.spacing.m};
10
+ border-bottom: ${(p) => (p.isScrolling ? `1px solid ${p.theme.color.uiLine};` : "")};
11
+ `;
12
+
13
+ const CheckHeader = styled(Header)`
14
+ padding-right: 0;
15
+ width: 40px;
16
+ label {
17
+ margin-bottom: ${(p) => p.theme.spacing.s};
18
+ }
19
+ > div {
20
+ width: ${(p) => p.theme.spacing.s};
21
+ }
22
+ `;
23
+
24
+ const NameHeader = styled(Header)`
25
+ flex-grow: 1;
26
+ `;
27
+
28
+ const TypeHeader = styled(Header)`
29
+ flex: 0 0 80px;
30
+ justify-content: center;
31
+ `;
32
+
33
+ const SizeHeader = styled(Header)`
34
+ flex: 0 0 85px;
35
+ justify-content: center;
36
+ `;
37
+
38
+ const UpdatedHeader = styled(Header)`
39
+ flex: 0 0 120px;
40
+ justify-content: center;
41
+ `;
42
+
43
+ const TagsHeader = styled(Header)`
44
+ flex: 0 0 300px;
45
+ `;
46
+
47
+ const CounterHeader = styled(Header)`
48
+ flex: 0 0 70px;
49
+ justify-content: flex-end;
50
+ padding 0;
51
+ `;
52
+
53
+ export { TableHeader, CheckHeader, NameHeader, TypeHeader, SizeHeader, UpdatedHeader, TagsHeader, CounterHeader };