@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,59 +1,73 @@
1
1
  import React from "react";
2
2
  import styled from "styled-components";
3
- import { Button } from "@ax/components";
3
+ import Button from "@ax/components/Button";
4
4
 
5
- export const Wrapper = styled.div<{ hidden: boolean }>`
5
+ const Wrapper = styled.div<{ inverse: boolean }>`
6
+ background-color: ${(p) => (p.inverse ? p.theme.color.overlay : p.theme.color.uiBarBackground)};
6
7
  position: relative;
7
- opacity: ${(p) => (p.hidden ? "0" : "1")};
8
- display: ${(p) => (p.hidden ? "none" : "block")};
9
8
  transition: opacity 0.1s;
10
9
  height: 100%;
11
10
  width: 100%;
12
11
  padding: ${(p) => p.theme.spacing.m};
13
- background-color: ${(p) => p.theme.color.uiBarBackground};
14
12
  `;
15
13
 
16
- export const StatusWrapper = styled.div`
14
+ const StatusWrapper = styled.div`
17
15
  position: absolute;
18
16
  top: 50%;
19
17
  left: 50%;
20
18
  transform: translate(-50%, -50%);
21
19
  text-align: center;
22
- width: calc(100% - ${(p) => p.theme.spacing.m} * 4);
23
20
  `;
24
21
 
25
- export const ProgressBar = styled.div`
26
- margin-bottom: ${(p) => p.theme.spacing.xs};
27
- `;
28
-
29
- export const DragStatus = styled.div`
22
+ const DragStatus = styled.div`
30
23
  transition: opacity 0.1s;
31
24
  `;
32
25
 
33
- export const DragTitle = styled.div`
26
+ const DragTitle = styled.div`
34
27
  ${(p) => p.theme.textStyle.fieldLabel};
35
- color: ${(p) => p.theme.color.interactive01};
36
28
  margin-bottom: ${(p) => p.theme.spacing.xxs};
37
29
  `;
38
30
 
39
- export const DragSubtitle = styled.div`
31
+ const DragSubtitle = styled.div`
40
32
  ${(p) => p.theme.textStyle.uiXS};
41
- color: ${(p) => p.theme.color.textMediumEmphasis};
42
33
  margin-bottom: ${(p) => p.theme.spacing.xxs};
43
- white-space: nowrap;
44
34
  `;
45
35
 
46
- export const DragIcon = styled.div`
36
+ const DragIcon = styled.div`
37
+ height: ${(p) => p.theme.spacing.l};
47
38
  margin-bottom: ${(p) => p.theme.spacing.s};
48
39
  display: flex;
49
40
  justify-content: center;
50
41
  `;
51
42
 
52
- export const UploadingStatus = styled.div`
43
+ const DropIcon = styled.div`
44
+ height: ${(p) => p.theme.spacing.l};
45
+ width: ${(p) => p.theme.spacing.l};
46
+ margin: ${(p) => `0 auto ${p.theme.spacing.s} auto`};
47
+ svg {
48
+ path {
49
+ fill: ${(p) => p.theme.color.interactiveInverse};
50
+ }
51
+ }
52
+ `;
53
+
54
+ const SuccessIcon = styled.div`
55
+ display: flex;
56
+ justify-content: center;
57
+ height: ${(p) => p.theme.spacing.l};
58
+ margin-bottom: ${(p) => p.theme.spacing.s};
59
+ svg {
60
+ path {
61
+ fill: ${(p) => p.theme.color.online};
62
+ }
63
+ }
64
+ `;
65
+
66
+ const UploadingStatus = styled.div`
53
67
  transition: opacity 0.1s;
54
68
  `;
55
69
 
56
- export const SuccessStatus = styled.div`
70
+ const SuccessStatus = styled.div`
57
71
  transition: opacity 0.1s;
58
72
  ${DragIcon} {
59
73
  svg {
@@ -67,7 +81,9 @@ export const SuccessStatus = styled.div`
67
81
  }
68
82
  `;
69
83
 
70
- export const ErrorStatus = styled.div`
84
+ const ErrorStatus = styled.div`
85
+ display: flex;
86
+ justify-content: center;
71
87
  transition: opacity 0.1s;
72
88
  ${DragIcon} {
73
89
  svg {
@@ -81,7 +97,7 @@ export const ErrorStatus = styled.div`
81
97
  }
82
98
  `;
83
99
 
84
- export const DragOverStatus = styled.div`
100
+ const DragOverStatus = styled.div`
85
101
  transition: opacity 0.1s;
86
102
  ${DragIcon} {
87
103
  svg {
@@ -92,15 +108,18 @@ export const DragOverStatus = styled.div`
92
108
  }
93
109
  `;
94
110
 
95
- export const DragAndDropWrapper = styled.div<{
111
+ const DragAndDropWrapper = styled.div<{
96
112
  inDropZone: boolean;
97
113
  uploading: boolean;
98
114
  success: boolean;
99
115
  error: boolean;
116
+ inverse: boolean;
100
117
  }>`
101
- border: ${(p) => `2px dashed ${p.inDropZone ? p.theme.color.interactiveInverse : p.theme.color.interactive01}`};
118
+ border: ${(p) =>
119
+ `2px dashed ${p.inDropZone || p.inverse ? p.theme.color.interactiveInverse : p.theme.color.interactive01}`};
102
120
  border-radius: 4px;
103
- background-color: ${(p) => (p.inDropZone ? p.theme.color.interactive01 : p.theme.color.uiBarBackground)};
121
+ background-color: ${(p) =>
122
+ p.inDropZone ? p.theme.color.interactive01 : p.inverse ? "transparent" : p.theme.color.uiBarBackground};
104
123
  width: 100%;
105
124
  height: 100%;
106
125
  opacity: ${(p) => (p.uploading || p.success || p.error ? "0" : "1")};
@@ -118,23 +137,33 @@ export const DragAndDropWrapper = styled.div<{
118
137
  }
119
138
 
120
139
  ${DragTitle} {
121
- color: ${(p) => (p.inDropZone ? p.theme.color.interactiveInverse : p.theme.color.interactive01)};
140
+ color: ${(p) => (p.inDropZone || p.inverse ? p.theme.color.interactiveInverse : p.theme.color.interactive01)};
122
141
  }
123
142
 
124
143
  ${DragSubtitle} {
125
- color: ${(p) => (p.inDropZone ? p.theme.color.textMediumEmphasisInverse : p.theme.color.textMediumEmphasis)};
144
+ color: ${(p) =>
145
+ p.inDropZone || p.inverse ? p.theme.color.textMediumEmphasisInverse : p.theme.color.textMediumEmphasis};
146
+ }
147
+
148
+ ${DragIcon} {
149
+ svg {
150
+ path {
151
+ fill: ${(p) => (p.inverse ? p.theme.color.interactiveInverse : p.theme.color.interactive01)};
152
+ }
153
+ }
126
154
  }
127
155
  `;
128
156
 
129
- export const UploadingWrapper = styled.div<{
157
+ const UploadingWrapper = styled.div<{
130
158
  inDropZone: boolean;
131
159
  uploading: boolean;
132
160
  success: boolean;
133
161
  error: boolean;
162
+ inverse: boolean;
134
163
  }>`
135
164
  border: ${(p) => (p.success || p.error ? `none` : `2px dashed ${p.theme.color.interactive01}`)};
136
165
  border-radius: 4px;
137
- background-color: ${(p) => p.theme.color.uiBackground01};
166
+ background-color: ${(p) => (p.inverse ? "transparent" : p.theme.color.uiBackground01)};
138
167
  padding: ${(p) => p.theme.spacing.m};
139
168
  width: 100%;
140
169
  height: 100%;
@@ -156,24 +185,76 @@ export const UploadingWrapper = styled.div<{
156
185
  opacity: ${(p) => (p.error ? "1" : "0")};
157
186
  display: ${(p) => (p.error ? "block" : "none")};
158
187
  }
188
+
189
+ ${DragTitle} {
190
+ color: ${(p) => (p.inverse ? p.theme.color.interactiveInverse : p.theme.color.interactive01)};
191
+ }
192
+
193
+ ${DragIcon} {
194
+ svg {
195
+ path {
196
+ fill: ${(p) => (p.inverse ? p.theme.color.interactiveInverse : p.theme.color.interactive01)};
197
+ }
198
+ }
199
+ }
159
200
  `;
160
201
 
161
- export const ErrorMsg = styled.div`
202
+ const ErrorMsg = styled.div`
162
203
  ${(p) => p.theme.textStyle.uiXS};
163
204
  color: ${(p) => p.theme.color.textMediumEmphasis};
164
205
  margin-top: ${(p) => p.theme.spacing.xxs};
165
206
  `;
166
207
 
167
- export const StyledButton = styled((props) => <Button {...props} />)`
208
+ const StyledButton = styled((props) => <Button {...props} />)`
168
209
  margin-top: ${(p) => p.theme.spacing.s};
169
210
  `;
170
211
 
171
- export const FilesInput = styled.input<{ ref: any }>`
212
+ const FilesInput = styled.input<{ ref: any }>`
172
213
  display: none;
173
214
  `;
174
215
 
175
216
  const _Button: any = React.forwardRef((props: any, ref?: React.Ref<HTMLDivElement>) => <Button {...props} />);
176
- export const FilesButton = styled(_Button)`
217
+ const FilesButton = styled(_Button)`
177
218
  margin-top: ${(p) => p.theme.spacing.xs};
178
219
  margin-bottom: ${(p) => p.theme.spacing.xs};
220
+
221
+ &.inverse {
222
+ background-color: transparent;
223
+
224
+ :hover:before {
225
+ background-color: ${(p) => p.theme.color.overlay};
226
+ }
227
+ :focus:before {
228
+ background-color: ${(p) => p.theme.color.overlay};
229
+ }
230
+ :active:before {
231
+ background-color: ${(p) => p.theme.color.overlay};
232
+ }
233
+ }
179
234
  `;
235
+
236
+ const ProgressBar = styled.div`
237
+ margin-bottom: ${(p) => p.theme.spacing.xs};
238
+ `;
239
+
240
+ export {
241
+ Wrapper,
242
+ StatusWrapper,
243
+ DragStatus,
244
+ DragTitle,
245
+ DragSubtitle,
246
+ DragIcon,
247
+ DropIcon,
248
+ SuccessIcon,
249
+ UploadingStatus,
250
+ SuccessStatus,
251
+ ErrorStatus,
252
+ DragOverStatus,
253
+ DragAndDropWrapper,
254
+ UploadingWrapper,
255
+ ErrorMsg,
256
+ StyledButton,
257
+ FilesInput,
258
+ FilesButton,
259
+ ProgressBar,
260
+ };
@@ -3,11 +3,12 @@ import styled from "styled-components";
3
3
  import { Header } from "@ax/components/TableList/style";
4
4
 
5
5
  const Orientation = styled((props) => <Header {...props} />)<{ isActive: boolean }>`
6
- width: 90px;
7
6
  justify-content: center;
8
7
  flex-wrap: nowrap;
9
8
  align-items: center;
10
9
  cursor: pointer;
10
+ flex-shrink: 0;
11
+ min-width: 120px;
11
12
  &:hover {
12
13
  color: ${(p) => p.theme.color.interactive01};
13
14
  }
@@ -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
  }
@@ -9,6 +9,7 @@ const Type = styled((props) => <Header {...props} />)<{ isActive: boolean }>`
9
9
  flex-wrap: nowrap;
10
10
  align-items: center;
11
11
  cursor: pointer;
12
+ flex-shrink: 0;
12
13
  &:hover {
13
14
  color: ${(p) => p.theme.color.interactive01};
14
15
  }
@@ -0,0 +1,75 @@
1
+ import React, { useEffect, useState } from "react";
2
+
3
+ import { Icon, FloatingMenu, ListTitle, ListItem } from "@ax/components";
4
+ import { IQueryValue } from "@ax/types";
5
+
6
+ import * as S from "./style";
7
+
8
+ const UsageFilter = (props: IProps): JSX.Element => {
9
+ const { value, filterItems } = props;
10
+
11
+ const initialState = value && value.length ? value[0].value.toString() : "all";
12
+ const [selectedValue, setSelectedValue] = useState<string>(initialState);
13
+
14
+ const isFilterActived = selectedValue !== "all";
15
+
16
+ const filters: Record<string, string> = {
17
+ all: "All",
18
+ used: "Used",
19
+ unused: "Unused",
20
+ };
21
+
22
+ useEffect(() => {
23
+ const filterValue = value && value.length ? value[0].value.toString() : "all";
24
+ value && setSelectedValue(filterValue);
25
+ }, [value]);
26
+
27
+ const setFilterQuery = (selection: any) => {
28
+ if (!selection.length) {
29
+ selection = "";
30
+ }
31
+ setSelectedValue(selection);
32
+ filterItems("usage", [{ value: selection, label: filters[selection] }]);
33
+ };
34
+
35
+ const filterAllStates = () => setFilterQuery("all");
36
+ const filterUsedState = () => setFilterQuery("used");
37
+ const filterUnusedState = () => setFilterQuery("unused");
38
+
39
+ const Header = () => (
40
+ <S.State isActive={isFilterActived}>
41
+ Usage
42
+ <S.IconsWrapper>
43
+ {isFilterActived ? (
44
+ <Icon name="Filter" size="16" />
45
+ ) : (
46
+ <S.InteractiveArrow>
47
+ <Icon name="DownArrow" size="16" />
48
+ </S.InteractiveArrow>
49
+ )}
50
+ </S.IconsWrapper>
51
+ </S.State>
52
+ );
53
+
54
+ return (
55
+ <FloatingMenu Button={Header} position="center">
56
+ <ListTitle>Filter by usage</ListTitle>
57
+ <ListItem isSelected={!isFilterActived} onClick={filterAllStates}>
58
+ All
59
+ </ListItem>
60
+ <ListItem isSelected={selectedValue === "used"} onClick={filterUsedState}>
61
+ Show images in use
62
+ </ListItem>
63
+ <ListItem isSelected={selectedValue === "unused"} onClick={filterUnusedState}>
64
+ Show unused images
65
+ </ListItem>
66
+ </FloatingMenu>
67
+ );
68
+ };
69
+
70
+ interface IProps {
71
+ filterItems(pointer: string, filter: IQueryValue[]): void;
72
+ value: IQueryValue[];
73
+ }
74
+
75
+ export default UsageFilter;
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+ import styled from "styled-components";
3
+ import { Header } from "@ax/components/TableList/style";
4
+
5
+ const State = styled((props) => <Header {...props} />)<{ isActive: boolean }>`
6
+ width: 170px;
7
+ &:hover {
8
+ color: ${(p) => p.theme.color.interactive01};
9
+ }
10
+ `;
11
+
12
+ const IconsWrapper = styled.div`
13
+ display: flex;
14
+ align-items: center;
15
+ flex-direction: row;
16
+ svg {
17
+ margin-left: 4px;
18
+ }
19
+ `;
20
+
21
+ const InteractiveArrow = styled.div`
22
+ display: flex;
23
+ svg {
24
+ path {
25
+ fill: ${(p) => p.theme.color.interactive01};
26
+ }
27
+ }
28
+ `;
29
+
30
+ export { State, IconsWrapper, InteractiveArrow };
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+ import { getFormattedDateWithTimezone } from "@ax/helpers";
3
+ import { Tooltip } from "@ax/components";
4
+
5
+ import * as S from "./style";
6
+
7
+ const Item = (props: IItemProps): JSX.Element => {
8
+ const { title, type, date, disabled = false, onClick } = props;
9
+
10
+ const notAllowed = "You are not allowed to access this page";
11
+
12
+ return (
13
+ <Tooltip content={disabled ? notAllowed : undefined} bottom>
14
+ <S.ListItem onClick={onClick} disabled={disabled}>
15
+ <S.Content>
16
+ <S.Header>
17
+ <S.Type>{type}</S.Type>
18
+ <S.Date>{getFormattedDateWithTimezone(date, "d MMM Y")}</S.Date>
19
+ </S.Header>
20
+ <S.Title>{title}</S.Title>
21
+ </S.Content>
22
+ </S.ListItem>
23
+ </Tooltip>
24
+ );
25
+ };
26
+
27
+ interface IItemProps {
28
+ title: string;
29
+ type: string;
30
+ date: Date;
31
+ disabled?: boolean;
32
+ onClick: () => void;
33
+ }
34
+
35
+ export default Item;
@@ -0,0 +1,43 @@
1
+ import styled from "styled-components";
2
+
3
+ const Title = styled.div`
4
+ ${(p) => p.theme.textStyle.fieldContent}
5
+ `;
6
+
7
+ const Header = styled.div`
8
+ display: flex;
9
+ margin-bottom: ${(p) => p.theme.spacing.xxs};
10
+ `;
11
+
12
+ const Type = styled.div`
13
+ ${(p) => p.theme.textStyle.headingXS};
14
+ `;
15
+
16
+ const Date = styled.div`
17
+ ${(p) => p.theme.textStyle.uiXS};
18
+ margin-left: auto;
19
+ `;
20
+
21
+ const ListItem = styled.li<{ disabled: boolean }>`
22
+ display: flex;
23
+ width: 100%;
24
+ padding: ${(p) => p.theme.spacing.s};
25
+ background-color: ${(p) => p.theme.color.uiBarBackground};
26
+ border: 1px solid ${(p) => p.theme.color.uiLine};
27
+ border-radius: ${(p) => p.theme.radii.s};
28
+ margin-bottom: ${(p) => p.theme.spacing.xs};
29
+ pointer-events: ${(p) => (p.disabled ? "none" : "auto")};
30
+ :hover {
31
+ background-color: ${(p) => p.theme.color.overlayHoverPrimary};
32
+ cursor: pointer;
33
+ }
34
+ ${Title}, ${Type}, ${Date} {
35
+ color: ${(p) => (p.disabled ? p.theme.colors.interactiveDisabled : p.theme.colors.textHighEmphasis)};
36
+ }
37
+ `;
38
+
39
+ const Content = styled.div`
40
+ width: 100%;
41
+ `;
42
+
43
+ export { ListItem, Title, Header, Type, Date, Content };
@@ -0,0 +1,44 @@
1
+ import React, { useState } from "react";
2
+ import Item from "../Item";
3
+ import { IImageUseItem } from "..";
4
+
5
+ import * as S from "./style";
6
+
7
+ const ItemGroup = (props: IItemGroupProps): React.ReactElement => {
8
+ const { title, items, disabled, 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) => {
20
+ const handleClick = () => onClick(item);
21
+ return (
22
+ <Item
23
+ title={item.title}
24
+ date={item.date}
25
+ type={item.structuredData?.title || "Page"}
26
+ key={item.id}
27
+ onClick={handleClick}
28
+ disabled={disabled}
29
+ />
30
+ );
31
+ })}
32
+ </S.Content>
33
+ </S.Wrapper>
34
+ );
35
+ };
36
+
37
+ interface IItemGroupProps {
38
+ title: string;
39
+ items: IImageUseItem[];
40
+ disabled?: boolean;
41
+ onClick(item: IImageUseItem): void;
42
+ }
43
+
44
+ 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 };