@griddo/ax 10.2.25 → 10.3.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 (94) hide show
  1. package/package.json +2 -2
  2. package/public/img/icons/excel.png +0 -0
  3. package/public/img/icons/pdf.png +0 -0
  4. package/public/img/icons/word.png +0 -0
  5. package/public/img/icons/zip.png +0 -0
  6. package/src/GlobalStore.tsx +3 -0
  7. package/src/__mocks__/store/GenericStore.ts +3 -0
  8. package/src/__tests__/components/Fields/FileField/FileField.test.tsx +34 -8
  9. package/src/__tests__/components/Gallery/GalleryPanel/GalleryDragAndDrop/GalleryDragAndDrop.test.tsx +1 -1
  10. package/src/api/files.tsx +171 -1
  11. package/src/api/users.tsx +5 -2
  12. package/src/components/ActionMenu/index.tsx +5 -13
  13. package/src/components/BackFolder/index.tsx +28 -0
  14. package/src/components/BackFolder/style.tsx +33 -0
  15. package/src/components/BulkSelectionOptions/index.tsx +4 -8
  16. package/src/components/Button/index.tsx +8 -3
  17. package/src/components/Button/style.tsx +5 -3
  18. package/src/components/ElementsTooltip/index.tsx +22 -7
  19. package/src/components/ElementsTooltip/style.tsx +2 -2
  20. package/src/components/Fields/FileField/index.tsx +7 -7
  21. package/src/components/Fields/TextField/index.tsx +3 -0
  22. package/src/components/FileGallery/FolderItem/index.tsx +39 -0
  23. package/src/components/FileGallery/FolderItem/style.tsx +31 -0
  24. package/src/components/FileGallery/GalleryPanel/DetailPanel/index.tsx +164 -0
  25. package/src/components/FileGallery/GalleryPanel/DetailPanel/style.tsx +113 -0
  26. package/src/components/FileGallery/GalleryPanel/index.tsx +42 -0
  27. package/src/components/FileGallery/GalleryPanel/style.tsx +7 -0
  28. package/src/components/FileGallery/GridItem/index.tsx +47 -0
  29. package/src/components/FileGallery/GridItem/style.tsx +51 -0
  30. package/src/components/FileGallery/index.tsx +304 -0
  31. package/src/components/FileGallery/style.tsx +173 -0
  32. package/src/components/FileGallery/utils.tsx +19 -0
  33. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +4 -6
  34. package/src/components/Icon/components/Back.js +10 -0
  35. package/src/components/Icon/components/ClosePanel.js +12 -0
  36. package/src/components/Icon/components/NewFolder.js +10 -0
  37. package/src/components/Icon/components/OpenPanel.js +12 -0
  38. package/src/components/Icon/svgs/Back.svg +3 -0
  39. package/src/components/Icon/svgs/Close_panel.svg +3 -0
  40. package/src/components/Icon/svgs/New-folder.svg +3 -0
  41. package/src/components/Icon/svgs/Open_panel.svg +3 -0
  42. package/src/components/Modal/index.tsx +7 -5
  43. package/src/components/Modal/style.tsx +6 -6
  44. package/src/components/ProgressBar/index.tsx +3 -2
  45. package/src/components/ProgressBar/style.tsx +5 -3
  46. package/src/components/TableList/index.tsx +3 -2
  47. package/src/components/TableList/style.tsx +4 -0
  48. package/src/components/Toast/style.tsx +2 -2
  49. package/src/components/index.tsx +4 -0
  50. package/src/containers/FileDrive/actions.tsx +386 -0
  51. package/src/containers/FileDrive/constants.tsx +24 -0
  52. package/src/containers/FileDrive/index.tsx +7 -0
  53. package/src/containers/FileDrive/interfaces.tsx +59 -0
  54. package/src/containers/FileDrive/reducer.tsx +57 -0
  55. package/src/containers/FileDrive/utils.tsx +37 -0
  56. package/src/containers/Gallery/actions.tsx +1 -1
  57. package/src/containers/Gallery/interfaces.tsx +1 -1
  58. package/src/helpers/index.tsx +2 -0
  59. package/src/helpers/objects.tsx +6 -0
  60. package/src/modules/FileDrive/Breadcrumb/index.tsx +42 -0
  61. package/src/modules/FileDrive/Breadcrumb/style.tsx +18 -0
  62. package/src/modules/FileDrive/BulkGridHeader/GridHeader/index.tsx +37 -0
  63. package/src/modules/FileDrive/BulkGridHeader/GridHeader/style.tsx +19 -0
  64. package/src/modules/FileDrive/BulkGridHeader/index.tsx +35 -0
  65. package/src/modules/FileDrive/BulkGridHeader/style.tsx +17 -0
  66. package/src/modules/FileDrive/BulkListHeader/TableHeader/index.tsx +42 -0
  67. package/src/modules/FileDrive/BulkListHeader/TableHeader/style.tsx +53 -0
  68. package/src/modules/FileDrive/BulkListHeader/index.tsx +35 -0
  69. package/src/modules/FileDrive/BulkListHeader/style.tsx +17 -0
  70. package/src/modules/FileDrive/FileDragAndDrop/index.tsx +249 -0
  71. package/src/{components/Fields/FileField → modules/FileDrive}/FileDragAndDrop/style.tsx +50 -9
  72. package/src/modules/FileDrive/FileModal/DetailPanel/index.tsx +170 -0
  73. package/src/modules/FileDrive/FileModal/DetailPanel/style.tsx +81 -0
  74. package/src/modules/FileDrive/FileModal/index.tsx +129 -0
  75. package/src/modules/FileDrive/FileModal/style.tsx +112 -0
  76. package/src/modules/FileDrive/FolderItem/index.tsx +180 -0
  77. package/src/modules/FileDrive/FolderItem/style.tsx +39 -0
  78. package/src/modules/FileDrive/FolderTree/index.tsx +108 -0
  79. package/src/modules/FileDrive/FolderTree/style.tsx +69 -0
  80. package/src/modules/FileDrive/FolderTree/utils.tsx +91 -0
  81. package/src/modules/FileDrive/GridItem/index.tsx +167 -0
  82. package/src/modules/FileDrive/GridItem/style.tsx +76 -0
  83. package/src/modules/FileDrive/ListItem/index.tsx +180 -0
  84. package/src/modules/FileDrive/ListItem/style.tsx +88 -0
  85. package/src/modules/FileDrive/atoms.tsx +173 -0
  86. package/src/modules/FileDrive/helpers.tsx +19 -0
  87. package/src/modules/FileDrive/index.tsx +670 -0
  88. package/src/modules/FileDrive/style.tsx +145 -0
  89. package/src/modules/Sites/SitesList/index.tsx +0 -3
  90. package/src/routes/multisite.tsx +9 -0
  91. package/src/routes/site.tsx +9 -0
  92. package/src/types/index.tsx +63 -0
  93. package/src/components/Fields/FileField/FileDragAndDrop/index.tsx +0 -188
  94. package/src/components/Fields/FileField/store.tsx +0 -61
@@ -0,0 +1,304 @@
1
+ import React, { useEffect, useState, memo, useRef, useCallback, useLayoutEffect } from "react";
2
+ import { connect } from "react-redux";
3
+
4
+ import { IFile, IFilesFolder, IFolder, IFolderTree, IGetFolderParams, IRootState, ISite } from "@ax/types";
5
+ import {
6
+ Loader,
7
+ Tabs,
8
+ SearchField,
9
+ EmptyState,
10
+ ErrorToast,
11
+ Notification,
12
+ Tooltip,
13
+ Icon,
14
+ BackFolder,
15
+ } from "@ax/components";
16
+ import { fileDriveActions } from "@ax/containers/FileDrive";
17
+ import { usePermission } from "@ax/hooks";
18
+
19
+ import GalleryPanel from "./GalleryPanel";
20
+ import GridItem from "./GridItem";
21
+ import FolderItem from "./FolderItem";
22
+
23
+ import * as S from "./style";
24
+
25
+ // refactor
26
+ import Breadcrumb from "@ax/modules/FileDrive/Breadcrumb";
27
+ import FolderTree from "@ax/modules/FileDrive/FolderTree";
28
+
29
+ const FileGallery = (props: IProps): JSX.Element => {
30
+ const {
31
+ currentFolderContent,
32
+ site,
33
+ currentFolderID,
34
+ validFormats,
35
+ breadcrumb,
36
+ toggleModal,
37
+ getFolderContent,
38
+ getFoldersTree,
39
+ addFile,
40
+ updateCurrentFolder,
41
+ } = props;
42
+
43
+ const {
44
+ files: { items },
45
+ folders,
46
+ } = currentFolderContent || { files: { items: [] }, folders: [] };
47
+
48
+ const [selectedTab, setSelectedTab] = useState(site ? "local" : "global");
49
+ const [selectedFile, setSelectedFile] = useState<IFile | null>(null);
50
+ const [isPanelOpen, setPanelOpen] = useState(false);
51
+ const [isLoading, setIsLoading] = useState(false);
52
+ const isLocalTab = selectedTab === "local";
53
+ const isGlobalTab = selectedTab === "global";
54
+ const galleryScope = isLocalTab && site ? site.id : "global";
55
+ const hasFolders = !!folders.length;
56
+ const isRoot = !breadcrumb.length;
57
+
58
+ const galleryRef = useRef<HTMLDivElement>(null);
59
+
60
+ const [searchQuery, setSearchQuery] = useState<string>("");
61
+ const isSearching = searchQuery.length > 0;
62
+
63
+ const isSiteView = !!site;
64
+ const isTabGlobal = selectedTab === "global";
65
+ const siteID: number | "global" = !isSiteView || isTabGlobal ? "global" : site.id;
66
+
67
+ const allowedToAccessGlobalFromSite = usePermission("mediaGallery.accessToGlobalFileDriveFromSite");
68
+
69
+ const allowedToAddSiteFile = usePermission("mediaGallery.addFiles");
70
+ const allowedToAddGlobalFile = usePermission("global.mediaGallery.addGlobalFiles");
71
+ const allowedToAddGlobalFileFromSite = usePermission("mediaGallery.addGlobalFilesFromSite");
72
+ const allowedToAddFile = isTabGlobal
73
+ ? allowedToAddGlobalFileFromSite
74
+ : isSiteView
75
+ ? allowedToAddSiteFile
76
+ : allowedToAddGlobalFile;
77
+
78
+ const allowedToEditSiteFile = usePermission("mediaGallery.editFilesss");
79
+ const allowedToEditGlobalFile = usePermission("global.mediaGallery.editGlobalFiles");
80
+ const allowedToEditGlobalFileFromSite = usePermission("mediaGallery.editGlobalFilesInSite");
81
+ const allowedToEditFile = isTabGlobal
82
+ ? allowedToEditGlobalFileFromSite
83
+ : isSiteView
84
+ ? allowedToEditSiteFile
85
+ : allowedToEditGlobalFile;
86
+
87
+ const tabs: string[] = [];
88
+ if (isSiteView && allowedToAccessGlobalFromSite) {
89
+ tabs.unshift(...["local", "global"]);
90
+ }
91
+
92
+ const getParams = useCallback(() => {
93
+ const params = {
94
+ siteID,
95
+ folderID: currentFolderID,
96
+ search: searchQuery,
97
+ loading: false,
98
+ };
99
+
100
+ return params;
101
+ }, [currentFolderID, searchQuery, selectedTab]);
102
+
103
+ useLayoutEffect(() => {
104
+ return () => {
105
+ updateCurrentFolder(null);
106
+ };
107
+ }, []);
108
+
109
+ useEffect(() => {
110
+ const handleGetContent = async () => {
111
+ setIsLoading(true);
112
+ const params = getParams();
113
+ await getFolderContent(params);
114
+ setIsLoading(false);
115
+ };
116
+ handleGetContent();
117
+ // eslint-disable-next-line react-hooks/exhaustive-deps
118
+ }, [getParams]);
119
+
120
+ useEffect(() => {
121
+ const handleGetTree = async () => await getFoldersTree(siteID);
122
+ handleGetTree();
123
+ // eslint-disable-next-line react-hooks/exhaustive-deps
124
+ }, [selectedTab]);
125
+
126
+ const handleClick = (item: IFile) => {
127
+ if (item.id !== selectedFile?.id) {
128
+ setSelectedFile(item);
129
+ } else {
130
+ setSelectedFile(null);
131
+ }
132
+ };
133
+
134
+ const setFile = (fileData: any) => {
135
+ const updatedImage = { ...selectedFile, ...fileData };
136
+ addFile(updatedImage);
137
+ toggleModal();
138
+ };
139
+
140
+ const handleSelectedTab = (tab: string) => {
141
+ if (tab !== selectedTab) {
142
+ updateCurrentFolder(null);
143
+ setSelectedFile(null);
144
+ setSelectedTab(tab);
145
+ }
146
+ };
147
+
148
+ const togglePanel = () => setPanelOpen(!isPanelOpen);
149
+
150
+ const handleBackClick = () => {
151
+ const parentID = breadcrumb.length >= 2 ? breadcrumb[breadcrumb.length - 2].id : null;
152
+ updateCurrentFolder(parentID);
153
+ };
154
+
155
+ const handleUpload = async (file: IFile[]) => {
156
+ setSelectedFile(file[0]);
157
+ const params = getParams();
158
+ await getFolderContent(params);
159
+ };
160
+
161
+ const foldersIcon = isPanelOpen ? <Icon name="closePanel" size="24" /> : <Icon name="openPanel" size="24" />;
162
+
163
+ const emptySearchStateProps = {
164
+ icon: "search",
165
+ title: "Oh! No Results Found",
166
+ message: "We couldn’t find what you are looking for. Please, try another search.",
167
+ };
168
+
169
+ const emptyFolderStateProps = {
170
+ title: "Oh! This looks so empty",
171
+ message: "No documents found in this folder.",
172
+ };
173
+
174
+ return (
175
+ <S.Wrapper data-testid="file-gallery-wrapper">
176
+ <S.FolderPanel isOpen={isPanelOpen}>
177
+ <S.FolderPanelContent>
178
+ <FolderTree folderID={currentFolderID || 0} onClick={updateCurrentFolder} title="Folders" trimNames={true} />
179
+ </S.FolderPanelContent>
180
+ </S.FolderPanel>
181
+ <S.ContentWrapper>
182
+ {!!tabs.length && <S.Header>
183
+ {!!tabs.length && (
184
+ <S.TabsWrapper>
185
+ <Tabs tabs={tabs} active={selectedTab} setSelectedTab={handleSelectedTab} noMargins />
186
+ </S.TabsWrapper>
187
+ )}
188
+ <S.Filters></S.Filters>
189
+ </S.Header>}
190
+ <S.Search>
191
+ <SearchField onChange={setSearchQuery} placeholder="Type file’s name, title, or #tag" />
192
+ </S.Search>
193
+ <S.GalleryWrapper ref={galleryRef}>
194
+ {isGlobalTab && isSiteView && (
195
+ <S.NotificationWrapper>
196
+ <Notification
197
+ type="info"
198
+ text="This is a global Library. All the changes you make will be applied to all the sites."
199
+ />
200
+ </S.NotificationWrapper>
201
+ )}
202
+ <ErrorToast size="l" />
203
+ {isLoading ? (
204
+ <S.LoadingWrapper>
205
+ <Loader name="circle" />
206
+ </S.LoadingWrapper>
207
+ ) : (
208
+ <>
209
+ {!isRoot && !isSearching && <Breadcrumb breadcrumb={breadcrumb} onClick={updateCurrentFolder} />}
210
+ {(hasFolders || (!isRoot && !isSearching)) && (
211
+ <S.SectionWrapper>
212
+ <S.SectionHeader>
213
+ <S.SectionTitle>
214
+ <div>Folders</div>
215
+ <S.FoldersIconWrapper onClick={togglePanel}>
216
+ <Tooltip content="Open folder panel">{foldersIcon}</Tooltip>
217
+ </S.FoldersIconWrapper>
218
+ </S.SectionTitle>
219
+ </S.SectionHeader>
220
+ <S.FoldersWrapper>
221
+ {!isRoot && !isSearching && <BackFolder onClick={handleBackClick} size="S" />}
222
+ <S.FoldersGrid>
223
+ {folders.map((folder: IFolder) => (
224
+ <FolderItem folder={folder} onClick={updateCurrentFolder} key={folder.folderName} />
225
+ ))}
226
+ </S.FoldersGrid>
227
+ </S.FoldersWrapper>
228
+ </S.SectionWrapper>
229
+ )}
230
+ <S.SectionWrapper>
231
+ <S.SectionHeader>
232
+ <S.SectionTitle>Documents</S.SectionTitle>
233
+ </S.SectionHeader>
234
+ {!items.length ? (
235
+ <S.EmptyWrapper>
236
+ {isSearching ? (
237
+ <EmptyState {...emptySearchStateProps} />
238
+ ) : (
239
+ <EmptyState {...emptyFolderStateProps} />
240
+ )}
241
+ </S.EmptyWrapper>
242
+ ) : (
243
+ <S.Grid>
244
+ {items &&
245
+ items.map((item: IFile) => {
246
+ const isSelected = item.id === selectedFile?.id;
247
+ return (
248
+ <GridItem file={item} onClick={handleClick} key={item.fileName} isSelected={isSelected} />
249
+ );
250
+ })}
251
+ </S.Grid>
252
+ )}
253
+ </S.SectionWrapper>
254
+ </>
255
+ )}
256
+ </S.GalleryWrapper>
257
+ </S.ContentWrapper>
258
+ <GalleryPanel
259
+ selectedFile={selectedFile}
260
+ validFormats={validFormats}
261
+ setFile={setFile}
262
+ scope={galleryScope}
263
+ currentFolderID={currentFolderID}
264
+ handleUpload={handleUpload}
265
+ isAllowedToAdd={allowedToAddFile}
266
+ isAllowedToEdit={allowedToEditFile}
267
+ />
268
+ </S.Wrapper>
269
+ );
270
+ };
271
+
272
+ export interface IGalleryProps {
273
+ site: ISite | null;
274
+ currentFolderContent: IFilesFolder | null;
275
+ currentFolderID: number | null;
276
+ isLoading: boolean;
277
+ validFormats: string[];
278
+ breadcrumb: IFolderTree[];
279
+ toggleModal: () => void;
280
+ addFile: (file: IFile) => void;
281
+ }
282
+
283
+ const mapStateToProps = (state: IRootState) => ({
284
+ isLoading: state.app.isLoading,
285
+ currentFolderContent: state.fileDrive.currentFolderContent,
286
+ currentFolderID: state.fileDrive.currentFolderID,
287
+ breadcrumb: state.fileDrive.breadcrumb,
288
+ });
289
+
290
+ export interface IDispatchProps {
291
+ getFolderContent(params: IGetFolderParams): Promise<void>;
292
+ getFoldersTree(siteID: number | "global"): Promise<void>;
293
+ updateCurrentFolder(folderID: number | null): void;
294
+ }
295
+
296
+ const mapDispatchToProps = {
297
+ getFolderContent: fileDriveActions.getFolderContent,
298
+ getFoldersTree: fileDriveActions.getFoldersTree,
299
+ updateCurrentFolder: fileDriveActions.updateCurrentFolder,
300
+ };
301
+
302
+ type IProps = IGalleryProps & IDispatchProps;
303
+
304
+ export default connect(mapStateToProps, mapDispatchToProps)(memo(FileGallery));
@@ -0,0 +1,173 @@
1
+ import styled from "styled-components";
2
+
3
+ const Wrapper = styled.div`
4
+ display: flex;
5
+ height: 100%;
6
+ overflow: hidden;
7
+ `;
8
+
9
+ const FolderPanel = styled.div<{ isOpen: boolean }>`
10
+ background-color: ${(p) => p.theme.color.uiBackground02};
11
+ border-right: ${(p) => `1px solid ${p.theme.color.uiLine}`};
12
+ width: ${(p) => (p.isOpen ? "192px" : "0")};
13
+ overflow: hidden;
14
+ transition: width 0.8s ease-out;
15
+ flex-shrink: 0;
16
+ `;
17
+
18
+ const FolderPanelContent = styled.div`
19
+ display: flex;
20
+ flex-direction: column;
21
+ padding: ${(p) => p.theme.spacing.m};
22
+ width: 100%;
23
+ height: 100%;
24
+ overflow: auto;
25
+ `;
26
+
27
+ const ContentWrapper = styled.div`
28
+ display: flex;
29
+ flex-direction: column;
30
+ width: 100%;
31
+ height: 100%;
32
+ `;
33
+
34
+ const Header = styled.div`
35
+ width: 100%;
36
+ border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
37
+ border-right: 1px solid ${(p) => p.theme.color.uiLine};
38
+ padding: 0 ${(p) => p.theme.spacing.m};
39
+ background-color: ${(p) => p.theme.color.uiBackground02};
40
+ display: flex;
41
+ justify-content: space-between;
42
+ align-items: center;
43
+ `;
44
+
45
+ const Search = styled.div`
46
+ padding: ${(p) => p.theme.spacing.s} ${(p) => p.theme.spacing.m};
47
+ border-right: 1px solid ${(p) => p.theme.color.uiLine};
48
+ background-color: ${(p) => p.theme.color.uiBackground02};
49
+ `;
50
+
51
+ const Filters = styled.div`
52
+ display: flex;
53
+ height: ${(p) => p.theme.spacing.l};
54
+ align-items: center;
55
+
56
+ & > * {
57
+ &:not(:last-child) {
58
+ margin-right: ${(p) => p.theme.spacing.l};
59
+ }
60
+ }
61
+ `;
62
+
63
+ const TabsWrapper = styled.div`
64
+ width: ${(p) => `calc(${p.theme.spacing.xl} * 3)`};
65
+ `;
66
+
67
+ const GalleryWrapper = styled.div`
68
+ position: relative;
69
+ background-color: ${(p) => p.theme.color.uiBackground01};
70
+ overflow: auto;
71
+ `;
72
+
73
+ const Grid = styled.div`
74
+ display: grid;
75
+ grid-template-columns: repeat(auto-fill, minmax(165px, 1fr));
76
+ grid-template-rows: repeat(auto-fit, minmax(144px, 144px));
77
+ gap: ${(p) => p.theme.spacing.xxs};
78
+ width: 100%;
79
+ justify-content: start;
80
+ `;
81
+
82
+ const LoadingWrapper = styled.div`
83
+ position: relative;
84
+ width: 100%;
85
+ height: 100%;
86
+ svg {
87
+ position: absolute;
88
+ top: 50%;
89
+ left: 50%;
90
+ transform: translate(-50%, -50%);
91
+ }
92
+ `;
93
+
94
+ const EmptyWrapper = styled.div`
95
+ display: flex;
96
+ align-items: center;
97
+ margin: auto;
98
+ align-content: center;
99
+ `;
100
+
101
+ const NotificationWrapper = styled.div`
102
+ width: 100%;
103
+ position: absolute;
104
+ top: 0;
105
+ left: 0;
106
+ right: 0;
107
+ z-index: 2;
108
+ `;
109
+
110
+ const SectionWrapper = styled.div`
111
+ display: flex;
112
+ flex-direction: column;
113
+ width: 100%;
114
+ padding: ${(p) => p.theme.spacing.m};
115
+ `;
116
+
117
+ const SectionHeader = styled.div`
118
+ display: flex;
119
+ margin-bottom: ${(p) => p.theme.spacing.xs};
120
+ align-items: center;
121
+ justify-content: flex-end;
122
+ `;
123
+
124
+ const SectionTitle = styled.div`
125
+ ${(p) => p.theme.textStyle.uiM};
126
+ display: flex;
127
+ color: ${(p) => p.theme.colors.textHighEmphasis};
128
+ margin-right: auto;
129
+ font-weight: 600;
130
+ `;
131
+
132
+ const FoldersWrapper = styled.div`
133
+ width: 100%;
134
+ display: flex;
135
+ `;
136
+
137
+ const FoldersGrid = styled.div`
138
+ width: 100%;
139
+ display: grid;
140
+ grid-template-columns: repeat(auto-fill, minmax(165px, 1fr));
141
+ grid-template-rows: repeat(auto-fit, minmax(40px, 40px));
142
+ gap: ${(p) => p.theme.spacing.xxs};
143
+ justify-content: start;
144
+ `;
145
+
146
+ const FoldersIconWrapper = styled.div`
147
+ width: 24px;
148
+ height: 24px;
149
+ margin-left: ${(p) => p.theme.spacing.xs};
150
+ cursor: pointer;
151
+ `;
152
+
153
+ export {
154
+ Wrapper,
155
+ FolderPanel,
156
+ FolderPanelContent,
157
+ ContentWrapper,
158
+ Header,
159
+ Search,
160
+ Filters,
161
+ TabsWrapper,
162
+ GalleryWrapper,
163
+ Grid,
164
+ LoadingWrapper,
165
+ EmptyWrapper,
166
+ NotificationWrapper,
167
+ SectionWrapper,
168
+ SectionHeader,
169
+ SectionTitle,
170
+ FoldersGrid,
171
+ FoldersWrapper,
172
+ FoldersIconWrapper
173
+ };
@@ -0,0 +1,19 @@
1
+ const getFileIcon = (type: string) => {
2
+ switch (type) {
3
+ case "pdf":
4
+ return "pdf.png";
5
+ case "doc":
6
+ case "docx":
7
+ return "word.png";
8
+ case "xls":
9
+ case "xlsx":
10
+ case "csv":
11
+ return "excel.png";
12
+ case "zip":
13
+ return "zip.png";
14
+ default:
15
+ return "zip.png";
16
+ }
17
+ };
18
+
19
+ export { getFileIcon };
@@ -2,7 +2,7 @@ import React, { memo, useRef, useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
4
  import { galleryActions } from "@ax/containers/Gallery";
5
- import { IGetSiteImages, IImage, IRootState } from "@ax/types";
5
+ import { IImage, IRootState } from "@ax/types";
6
6
  import { Icon, DragAndDrop, ProgressBar } from "@ax/components";
7
7
 
8
8
  import * as S from "./style";
@@ -112,8 +112,8 @@ const GalleryDragAndDrop = (props: IProps) => {
112
112
  onDragLeave={handleDragLeave}
113
113
  validFormats={validFormats}
114
114
  >
115
- <S.StatusWrapper>
116
- <S.DragStatus>
115
+ <S.StatusWrapper onDragEnter={handleDragEnter} onDragLeave={handleDragLeave}>
116
+ <S.DragStatus onDragEnter={handleDragEnter} onDragLeave={handleDragLeave}>
117
117
  <S.DragIcon>
118
118
  <Icon name="image" size="36" />
119
119
  </S.DragIcon>
@@ -126,7 +126,7 @@ const GalleryDragAndDrop = (props: IProps) => {
126
126
  <S.DragSubtitle>Valid formats: {validFormats.join(", ")}</S.DragSubtitle>
127
127
  <S.DragSubtitle>Max. size: 10MB</S.DragSubtitle>
128
128
  </S.DragStatus>
129
- <S.DragOverStatus>
129
+ <S.DragOverStatus onDragEnter={handleDragEnter} onDragLeave={handleDragLeave}>
130
130
  <S.DragIcon>
131
131
  <Icon name="success" size="36" />
132
132
  </S.DragIcon>
@@ -205,14 +205,12 @@ const mapStateToProps = (state: IRootState) => ({
205
205
  });
206
206
 
207
207
  export interface IDispatchProps {
208
- getSiteImages(params: IGetSiteImages): Promise<void>;
209
208
  selectImage(item: IImage | null): void;
210
209
  uploadError: (error: boolean, msg?: string) => Promise<void>;
211
210
  uploadImage: (imageFiles: File | File[], site: number | string) => Promise<IImage>;
212
211
  }
213
212
 
214
213
  const mapDispatchToProps = {
215
- getSiteImages: galleryActions.getSiteImages,
216
214
  uploadError: galleryActions.uploadError,
217
215
  uploadImage: galleryActions.uploadImage,
218
216
  };
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ const SvgBack = (props) => (
3
+ <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} fill="none" {...props}>
4
+ <path
5
+ fill="#5057FF"
6
+ d="M7 19v-2h7.1c1.05 0 1.963-.333 2.737-1 .776-.667 1.163-1.5 1.163-2.5s-.387-1.833-1.163-2.5c-.774-.667-1.687-1-2.737-1H7.8l2.6 2.6L9 14 4 9l5-5 1.4 1.4L7.8 8h6.3c1.617 0 3.004.525 4.162 1.575C19.421 10.625 20 11.933 20 13.5c0 1.567-.58 2.875-1.738 3.925C17.104 18.475 15.717 19 14.1 19H7Z"
7
+ />
8
+ </svg>
9
+ );
10
+ export default SvgBack;
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ const SvgClosePanel = (props) => (
3
+ <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} fill="none" {...props}>
4
+ <path
5
+ fill="#5057FF"
6
+ fillRule="evenodd"
7
+ d="M3 20V4c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2v16c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2Zm12 0V4H5v16h10ZM11 9l.705.705L9.415 12l2.29 2.295L11 15l-3-3 3-3Z"
8
+ clipRule="evenodd"
9
+ />
10
+ </svg>
11
+ );
12
+ export default SvgClosePanel;
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ const SvgNewFolder = (props) => (
3
+ <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} fill="none" {...props}>
4
+ <path
5
+ fill="#5057FF"
6
+ d="M20 6h-8l-2-2H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2Zm0 12H4V6h5.17l2 2H20v10Zm-8-4h2v2h2v-2h2v-2h-2v-2h-2v2h-2v2Z"
7
+ />
8
+ </svg>
9
+ );
10
+ export default SvgNewFolder;
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ const SvgOpenPanel = (props) => (
3
+ <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} fill="none" {...props}>
4
+ <path
5
+ fill="#5057FF"
6
+ fillRule="evenodd"
7
+ d="M21 4v16c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2Zm-2 0H9v16h10V4Zm-6 11-.705-.705L14.585 12l-2.29-2.295L13 9l3 3-3 3Z"
8
+ clipRule="evenodd"
9
+ />
10
+ </svg>
11
+ );
12
+ export default SvgOpenPanel;
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M7 19V17H14.1C15.15 17 16.0625 16.6667 16.8375 16C17.6125 15.3333 18 14.5 18 13.5C18 12.5 17.6125 11.6667 16.8375 11C16.0625 10.3333 15.15 10 14.1 10H7.8L10.4 12.6L9 14L4 9L9 4L10.4 5.4L7.8 8H14.1C15.7167 8 17.1042 8.525 18.2625 9.575C19.4208 10.625 20 11.9333 20 13.5C20 15.0667 19.4208 16.375 18.2625 17.425C17.1042 18.475 15.7167 19 14.1 19H7Z" fill="#5057FF"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M3 20V4C3 2.9 3.9 2 5 2H19C20.1 2 21 2.9 21 4V20C21 21.1 20.1 22 19 22H5C3.9 22 3 21.1 3 20ZM15 20L15 4L5 4L5 20H15ZM11 9L11.705 9.705L9.415 12L11.705 14.295L11 15L8 12L11 9Z" fill="#5057FF"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M20 6H12L10 4H4C2.89 4 2.01 4.89 2.01 6L2 18C2 19.11 2.89 20 4 20H20C21.11 20 22 19.11 22 18V8C22 6.89 21.11 6 20 6ZM20 18H4V6H9.17L11.17 8H20V18ZM12 14H14V16H16V14H18V12H16V10H14V12H12V14Z" fill="#5057FF"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M21 4V20C21 21.1 20.1 22 19 22H5C3.9 22 3 21.1 3 20V4C3 2.9 3.9 2 5 2H19C20.1 2 21 2.9 21 4ZM19 4H9L9 20L19 20L19 4ZM13 15L12.295 14.295L14.585 12L12.295 9.705L13 9L16 12L13 15Z" fill="#5057FF"/>
3
+ </svg>
@@ -1,12 +1,12 @@
1
1
  import React, { memo } from "react";
2
2
  import { createPortal } from "react-dom";
3
3
  import { IconAction } from "@ax/components";
4
+ import Button from "../Button";
4
5
 
5
6
  import * as S from "./style";
6
- import Button from "../Button";
7
7
 
8
8
  const Modal = (props: IModalProps): JSX.Element | null => {
9
- const { isOpen, hide, children, title, size, mainAction, secondaryAction, overflow = "auto" } = props;
9
+ const { isOpen, hide, children, title, size, mainAction, secondaryAction, height, overflow = "auto", isChild } = props;
10
10
 
11
11
  const titleContent = title ? <S.Title>{title}</S.Title> : "";
12
12
 
@@ -39,9 +39,9 @@ const Modal = (props: IModalProps): JSX.Element | null => {
39
39
  return isOpen
40
40
  ? createPortal(
41
41
  <>
42
- <S.ModalOverlay />
43
- <S.ModalWrapper data-testid="modal-wrapper">
44
- <S.Modal size={size} data-testid="modal-component">
42
+ <S.ModalOverlay isChild={isChild} />
43
+ <S.ModalWrapper data-testid="modal-wrapper" isChild={isChild}>
44
+ <S.Modal size={size} height={height} data-testid="modal-component">
45
45
  <S.ModalHeader>
46
46
  {titleContent}
47
47
  <S.ButtonWrapper>
@@ -67,6 +67,8 @@ export interface IModalProps {
67
67
  overflow?: string;
68
68
  mainAction?: IAction;
69
69
  secondaryAction?: IAction;
70
+ height?: number;
71
+ isChild?: boolean;
70
72
  }
71
73
 
72
74
  interface IAction {