@griddo/ax 10.3.23 → 10.3.25

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 (126) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/Gallery/GalleryFilters/Orientation/Orientation.test.tsx +5 -2
  3. package/src/__tests__/components/Gallery/GalleryFilters/SortBy/SortBy.test.tsx +5 -4
  4. package/src/__tests__/components/Gallery/GalleryFilters/Type/Type.test.tsx +5 -2
  5. package/src/__tests__/components/TableFilters/CategoryFilter/CategoryFilter.test.tsx +12 -11
  6. package/src/__tests__/components/TableFilters/DateFilter/DateFilter.test.tsx +17 -16
  7. package/src/__tests__/components/TableFilters/LiveFilter/LiveFilter.test.tsx +14 -13
  8. package/src/__tests__/components/TableFilters/NameFilter/NameFilter.test.tsx +21 -20
  9. package/src/__tests__/components/TableFilters/RoleFilter/RoleFilter.test.tsx +6 -5
  10. package/src/__tests__/components/TableFilters/SiteFilter/SiteFilter.test.tsx +8 -7
  11. package/src/__tests__/components/TableFilters/StatusFilter/StatusFilter.test.tsx +21 -20
  12. package/src/__tests__/components/TableFilters/TranslationsFilter/TranslationsFilter.test.tsx +24 -23
  13. package/src/__tests__/components/TableFilters/TypeFilter/TypeFilter.test.tsx +6 -5
  14. package/src/__tests__/components/TableFilters/UsersFilter/UsersFilter.test.tsx +17 -16
  15. package/src/api/sites.tsx +5 -9
  16. package/src/components/Button/index.tsx +3 -1
  17. package/src/components/Button/style.tsx +6 -0
  18. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/TemplateManager/index.tsx +2 -2
  19. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +1 -1
  20. package/src/components/Fields/ArrayFieldGroup/ArrayFieldInline/index.tsx +3 -2
  21. package/src/components/Fields/ArrayFieldGroup/ArrayFieldItem/index.tsx +3 -1
  22. package/src/components/Fields/ArrayFieldGroup/index.tsx +5 -2
  23. package/src/components/Fields/CheckField/style.tsx +2 -2
  24. package/src/components/Fields/ColorPicker/index.tsx +4 -2
  25. package/src/components/Fields/ColorPicker/style.tsx +4 -0
  26. package/src/components/Fields/DateField/DatePickerInput/index.tsx +1 -1
  27. package/src/components/Fields/FileField/index.tsx +3 -1
  28. package/src/components/Fields/FileField/style.tsx +9 -4
  29. package/src/components/Fields/SliderField/index.tsx +4 -2
  30. package/src/components/Fields/SliderField/style.tsx +53 -4
  31. package/src/components/Fields/TimeField/style.tsx +6 -5
  32. package/src/components/FileGallery/index.tsx +26 -16
  33. package/src/components/FileGallery/style.tsx +12 -1
  34. package/src/components/FilterTagsBar/index.tsx +61 -0
  35. package/src/components/FilterTagsBar/style.tsx +30 -0
  36. package/src/components/FloatingMenu/index.tsx +5 -1
  37. package/src/components/Gallery/GalleryFilters/Orientation/index.tsx +14 -6
  38. package/src/components/Gallery/GalleryFilters/SortBy/index.tsx +24 -8
  39. package/src/components/Gallery/GalleryFilters/Type/index.tsx +22 -9
  40. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/style.tsx +2 -1
  41. package/src/components/Gallery/hooks.tsx +37 -23
  42. package/src/components/Gallery/index.tsx +38 -20
  43. package/src/components/Gallery/style.tsx +15 -2
  44. package/src/components/MainWrapper/AppBar/index.tsx +3 -0
  45. package/src/components/MainWrapper/index.tsx +1 -0
  46. package/src/components/SearchTagsBar/index.tsx +43 -0
  47. package/src/components/SearchTagsBar/style.tsx +30 -0
  48. package/src/components/TableFilters/CategoryFilter/index.tsx +17 -10
  49. package/src/components/TableFilters/CheckGroupFilter/index.tsx +12 -9
  50. package/src/components/TableFilters/DateFilter/index.tsx +3 -2
  51. package/src/components/TableFilters/LastAccessFilter/index.tsx +4 -4
  52. package/src/components/TableFilters/LiveFilter/index.tsx +26 -22
  53. package/src/components/TableFilters/NameFilter/index.tsx +4 -3
  54. package/src/components/TableFilters/PermissionsFilter/index.tsx +4 -3
  55. package/src/components/TableFilters/RoleFilter/index.tsx +17 -7
  56. package/src/components/TableFilters/SiteFilter/index.tsx +23 -8
  57. package/src/components/TableFilters/StateFilter/index.tsx +15 -6
  58. package/src/components/TableFilters/StatusFilter/index.tsx +3 -2
  59. package/src/components/TableFilters/TranslationsFilter/index.tsx +19 -11
  60. package/src/components/TableFilters/TypeFilter/index.tsx +9 -5
  61. package/src/components/TableFilters/UsersFilter/index.tsx +4 -3
  62. package/src/components/Tag/index.tsx +5 -4
  63. package/src/components/index.tsx +4 -0
  64. package/src/containers/Navigation/Menu/actions.tsx +1 -13
  65. package/src/containers/Navigation/Menu/constants.tsx +0 -1
  66. package/src/containers/Navigation/Menu/interfaces.tsx +1 -7
  67. package/src/containers/Navigation/Menu/reducer.tsx +0 -4
  68. package/src/containers/Sites/actions.tsx +2 -1
  69. package/src/containers/Sites/interfaces.tsx +2 -2
  70. package/src/containers/Sites/reducer.tsx +2 -2
  71. package/src/containers/StructuredData/actions.tsx +2 -1
  72. package/src/forms/editor.tsx +1 -1
  73. package/src/modules/Categories/CategoriesList/CategoryItem/style.tsx +2 -0
  74. package/src/modules/Content/BulkHeader/TableHeader/index.tsx +26 -14
  75. package/src/modules/Content/BulkHeader/index.tsx +3 -3
  76. package/src/modules/Content/PageItem/index.tsx +21 -23
  77. package/src/modules/Content/PageItem/style.tsx +2 -0
  78. package/src/modules/Content/hooks.tsx +23 -13
  79. package/src/modules/Content/index.tsx +44 -11
  80. package/src/modules/Content/style.tsx +19 -1
  81. package/src/modules/FileDrive/Breadcrumb/style.tsx +1 -1
  82. package/src/modules/FileDrive/FileDragAndDrop/index.tsx +7 -6
  83. package/src/modules/FileDrive/FileDragAndDrop/style.tsx +2 -0
  84. package/src/modules/FileDrive/FileFilters/SortBy/index.tsx +24 -8
  85. package/src/modules/FileDrive/FileFilters/Type/index.tsx +26 -22
  86. package/src/modules/FileDrive/hooks.tsx +28 -13
  87. package/src/modules/FileDrive/index.tsx +31 -18
  88. package/src/modules/FileDrive/style.tsx +20 -1
  89. package/src/modules/Navigation/Defaults/Item/style.tsx +2 -0
  90. package/src/modules/Navigation/Menus/List/Nav/index.tsx +10 -12
  91. package/src/modules/Navigation/Menus/List/Table/SidePanel/index.tsx +0 -2
  92. package/src/modules/Navigation/Menus/List/index.tsx +8 -5
  93. package/src/modules/Redirects/BulkHeader/TableHeader/index.tsx +4 -2
  94. package/src/modules/Redirects/BulkHeader/index.tsx +3 -2
  95. package/src/modules/Redirects/hooks.tsx +23 -15
  96. package/src/modules/Redirects/index.tsx +61 -44
  97. package/src/modules/Redirects/style.tsx +10 -0
  98. package/src/modules/Settings/Integrations/BulkHeader/TableHeader/index.tsx +7 -11
  99. package/src/modules/Settings/Integrations/BulkHeader/index.tsx +4 -8
  100. package/src/modules/Settings/Integrations/hooks.tsx +23 -19
  101. package/src/modules/Settings/Integrations/index.tsx +22 -26
  102. package/src/modules/Settings/Integrations/style.tsx +7 -0
  103. package/src/modules/Sites/SitesList/GridView/GridHeaderFilter/index.tsx +8 -7
  104. package/src/modules/Sites/SitesList/ListView/BulkHeader/TableHeader/index.tsx +10 -5
  105. package/src/modules/Sites/SitesList/ListView/BulkHeader/index.tsx +4 -3
  106. package/src/modules/Sites/SitesList/hooks.tsx +26 -20
  107. package/src/modules/Sites/SitesList/index.tsx +53 -22
  108. package/src/modules/Sites/SitesList/style.tsx +16 -0
  109. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +3 -3
  110. package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +3 -3
  111. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +3 -3
  112. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/style.tsx +2 -0
  113. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/style.tsx +2 -0
  114. package/src/modules/StructuredData/StructuredDataList/hooks.tsx +25 -15
  115. package/src/modules/StructuredData/StructuredDataList/index.tsx +57 -14
  116. package/src/modules/StructuredData/StructuredDataList/style.tsx +10 -1
  117. package/src/modules/Users/Roles/BulkHeader/TableHeader/index.tsx +2 -2
  118. package/src/modules/Users/Roles/BulkHeader/index.tsx +2 -5
  119. package/src/modules/Users/Roles/hooks.tsx +24 -15
  120. package/src/modules/Users/Roles/index.tsx +7 -18
  121. package/src/modules/Users/UserList/BulkHeader/TableHeader/index.tsx +5 -18
  122. package/src/modules/Users/UserList/BulkHeader/index.tsx +15 -13
  123. package/src/modules/Users/UserList/hooks.tsx +27 -25
  124. package/src/modules/Users/UserList/index.tsx +69 -43
  125. package/src/modules/Users/UserList/style.tsx +10 -1
  126. package/src/types/index.tsx +19 -13
@@ -47,11 +47,13 @@ const FileField = (props: IFileFieldProps): JSX.Element => {
47
47
  label: "replace",
48
48
  icon: "change",
49
49
  action: replaceFile,
50
+ disabled,
50
51
  },
51
52
  {
52
53
  label: "delete",
53
54
  icon: "delete",
54
55
  action: removeFile,
56
+ disabled,
55
57
  },
56
58
  ];
57
59
 
@@ -82,7 +84,7 @@ const FileField = (props: IFileFieldProps): JSX.Element => {
82
84
  )}
83
85
  {!value && (
84
86
  <>
85
- <S.Field onClick={handleClick} data-testid="field-icon-wrapper">
87
+ <S.Field onClick={handleClick} data-testid="field-icon-wrapper" disabled={disabled}>
86
88
  <S.IconWrapper>
87
89
  <Icon name="File" size="24" />
88
90
  </S.IconWrapper>
@@ -2,20 +2,25 @@ import React from "react";
2
2
  import styled from "styled-components";
3
3
  import ActionMenu from "@ax/components/ActionMenu";
4
4
 
5
- const Field = styled.div`
5
+ const Field = styled.div<{ disabled?: boolean }>`
6
6
  display: flex;
7
7
  width: 100%;
8
8
  height: ${(p) => p.theme.spacing.l};
9
- background-color: ${(p) => p.theme.color.interactiveBackground};
9
+ background-color: ${(p) => (p.disabled ? p.theme.color.uiBackground03 : p.theme.color.interactiveBackground)};
10
10
  box-shadow: ${(p) => p.theme.shadow.shadowS};
11
11
  border-radius: ${(p) => p.theme.radii.s};
12
12
  justify-content: center;
13
13
  align-items: center;
14
- cursor: pointer;
14
+ cursor: ${(p) => (p.disabled ? "default" : "pointer")};
15
15
  margin-bottom: ${(p) => p.theme.spacing.xxs};
16
16
  margin-top: ${(p) => p.theme.spacing.s};
17
17
  :hover {
18
- background-color: ${(p) => p.theme.colors.overlayHoverPrimary};
18
+ background-color: ${(p) => (p.disabled ? p.theme.color.uiBackground03 : p.theme.colors.overlayHoverPrimary)};
19
+ }
20
+ svg {
21
+ path {
22
+ fill: ${(p) => (p.disabled ? p.theme.color.interactiveDisabled : p.theme.color.interactive01)};
23
+ }
19
24
  }
20
25
  `;
21
26
 
@@ -3,7 +3,7 @@ import React, { memo, useEffect, useRef } from "react";
3
3
  import * as S from "./style";
4
4
 
5
5
  const SliderField = (props: ITextFieldProps): JSX.Element => {
6
- const { value, min = 0, max = 100, defaultValue = min, step, prefix, suffix, onChange } = props;
6
+ const { value, min = 0, max = 100, defaultValue = min, step, prefix, suffix, onChange, disabled } = props;
7
7
  const bubbleRef = useRef<HTMLOutputElement>(null);
8
8
 
9
9
  const val = typeof value === "undefined" || value === null ? defaultValue : value;
@@ -32,7 +32,7 @@ const SliderField = (props: ITextFieldProps): JSX.Element => {
32
32
 
33
33
  return (
34
34
  <S.Slider data-testid="slider-component">
35
- <S.Bubble data-testid="bubble-component" ref={bubbleRef}>
35
+ <S.Bubble data-testid="bubble-component" ref={bubbleRef} disabled={disabled}>
36
36
  {prefix && `${prefix} `}
37
37
  {val}
38
38
  {suffix && ` ${suffix}`}
@@ -44,6 +44,7 @@ const SliderField = (props: ITextFieldProps): JSX.Element => {
44
44
  max={max}
45
45
  step={step}
46
46
  onChange={handleChange}
47
+ disabled={disabled}
47
48
  />
48
49
  </S.Slider>
49
50
  );
@@ -60,6 +61,7 @@ export interface ITextFieldProps {
60
61
  suffix?: string;
61
62
  helptext?: string;
62
63
  onChange: (value: number) => void;
64
+ disabled?: boolean;
63
65
  }
64
66
 
65
67
  export default memo(SliderField);
@@ -135,23 +135,72 @@ const Input = styled.input.attrs({ type: "range" })`
135
135
  &:focus::-ms-fill-upper {
136
136
  background: ${(p) => p.theme.color.interactive01};
137
137
  }
138
+
139
+ &:disabled {
140
+ &::-webkit-slider-runnable-track {
141
+ pointer: default;
142
+ background: ${(p) => p.theme.color.interactiveDisabled};
143
+ }
144
+ &::-moz-range-track {
145
+ pointer: default;
146
+ background: ${(p) => p.theme.color.interactiveDisabled};
147
+ }
148
+ &::-ms-fill-lower {
149
+ background: ${(p) => p.theme.color.interactiveDisabled};
150
+ }
151
+
152
+ &::-ms-fill-upper {
153
+ background: ${(p) => p.theme.color.interactiveDisabled};
154
+ }
155
+
156
+ &::-webkit-slider-thumb {
157
+ pointer: default;
158
+ border-color: ${(p) => p.theme.color.interactiveDisabled};
159
+ &:hover {
160
+ box-shadow: none;
161
+ }
162
+ &:active {
163
+ background: ${(p) => p.theme.color.interactiveBackground};
164
+ }
165
+ }
166
+ &::-moz-range-thumb {
167
+ pointer: default;
168
+ border-color: ${(p) => p.theme.color.interactiveDisabled};
169
+ &:hover {
170
+ box-shadow: none;
171
+ }
172
+ &:active {
173
+ background: ${(p) => p.theme.color.interactiveBackground};
174
+ }
175
+ }
176
+ &::-ms-thumb {
177
+ pointer: default;
178
+ border-color: ${(p) => p.theme.color.interactiveDisabled};
179
+ &:hover {
180
+ box-shadow: none;
181
+ }
182
+ &:active {
183
+ background: ${(p) => p.theme.color.interactiveBackground};
184
+ }
185
+ }
186
+ }
138
187
  `;
139
188
 
140
- const Bubble = styled.output`
189
+ const Bubble = styled.output<{ disabled?: boolean }>`
141
190
  position: absolute;
142
191
  top: 0;
143
- background-color: ${(p) => p.theme.color.interactive01};
192
+ background-color: ${(p) => (p.disabled ? p.theme.color.interactiveDisabled : p.theme.color.interactive01)};
144
193
  color: ${(p) => p.theme.color.textHighEmphasisInverse};
145
194
  border-radius: ${(p) => p.theme.radii.s};
146
195
  padding: ${(p) => p.theme.spacing.xxs};
147
196
  transform: translateX(-50%);
148
197
 
149
198
  &::after {
150
- content: '';
199
+ content: "";
151
200
  position: absolute;
152
201
  transform: translateX(-50%);
153
202
  border-style: solid;
154
- border-color: ${(p) => p.theme.color.interactive01} transparent;
203
+ border-color: ${(p) => (p.disabled ? p.theme.color.interactiveDisabled : p.theme.color.interactive01)} transparent;
155
204
  border-width: 3px 3px 0 3px;
156
205
  bottom: -3px;
157
206
  left: 50%;
@@ -16,17 +16,18 @@ const FieldWrapper = styled.div<{ error?: boolean; disabled?: boolean }>`
16
16
  &:focus-within {
17
17
  border-color: ${(p) => (p.error ? p.theme.color.error : p.theme.color.interactive01)};
18
18
  }
19
+
20
+ svg {
21
+ path {
22
+ fill: ${(p) => (p.disabled ? p.theme.color.interactiveDisabled : p.theme.color.interactive01)};
23
+ }
24
+ }
19
25
  `;
20
26
 
21
27
  const IconWrapper = styled.div`
22
28
  width: ${(p) => p.theme.spacing.m};
23
29
  height: ${(p) => p.theme.spacing.m};
24
30
  margin-left: auto;
25
- svg {
26
- path {
27
- fill: ${(p) => p.theme.color.interactive01};
28
- }
29
- }
30
31
  `;
31
32
 
32
33
  const SelectWrapper = styled.div`
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect, useState, memo, useRef, useCallback, useLayoutEffect } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
- import { IFile, IFilesFolder, IFolder, IFolderTree, IGetFolderParams, IRootState, ISite } from "@ax/types";
4
+ import { IFile, IFilesFolder, IFolder, IFolderTree, IGetFolderParams, IQueryValue, IRootState, ISite } from "@ax/types";
5
5
  import {
6
6
  Loader,
7
7
  Tabs,
@@ -12,6 +12,8 @@ import {
12
12
  Tooltip,
13
13
  Icon,
14
14
  BackFolder,
15
+ SearchTagsBar,
16
+ FilterTagsBar,
15
17
  } from "@ax/components";
16
18
  import { fileDriveActions } from "@ax/containers/FileDrive";
17
19
  import { usePermission, useResizable } from "@ax/hooks";
@@ -63,9 +65,8 @@ const FileGallery = (props: IProps): JSX.Element => {
63
65
 
64
66
  const [ref] = useResizable();
65
67
 
66
- const { setFiltersSelection, setFilterQuery, filterValues } = useFilterQuery();
68
+ const { setFiltersSelection, resetFilterQuery, filterValues, filterQuery } = useFilterQuery();
67
69
  const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
68
- const [currentFilterQuery, setCurrentFilterQuery] = useState("");
69
70
  const [searchQuery, setSearchQuery] = useState<string>("");
70
71
  const isSearching = searchQuery.length > 0;
71
72
 
@@ -104,11 +105,11 @@ const FileGallery = (props: IProps): JSX.Element => {
104
105
  folderID: currentFolderID,
105
106
  search: searchQuery,
106
107
  loading: false,
107
- query: currentFilterQuery,
108
+ query: filterQuery,
108
109
  };
109
110
 
110
111
  return params;
111
- }, [currentFolderID, searchQuery, selectedTab, currentFilterQuery]);
112
+ }, [currentFolderID, searchQuery, selectedTab, filterQuery]);
112
113
 
113
114
  useLayoutEffect(() => {
114
115
  return () => {
@@ -168,20 +169,15 @@ const FileGallery = (props: IProps): JSX.Element => {
168
169
  await getFolderContent(params);
169
170
  };
170
171
 
171
- const sortItems = async (orderPointer: string, isAscending: boolean) => {
172
- const sortedState = getSortedListStatus(orderPointer, isAscending);
172
+ const sortItems = async (orderPointer: IQueryValue[], isAscending: boolean) => {
173
+ const sortedState = getSortedListStatus(orderPointer[0].value.toString(), isAscending);
173
174
  setSortedListStatus(sortedState);
174
175
 
175
- const filtersSelection = setFiltersSelection("order", orderPointer, isAscending);
176
- const filterQuery = setFilterQuery(filtersSelection);
177
- setCurrentFilterQuery(filterQuery);
176
+ setFiltersSelection("order", orderPointer, isAscending);
178
177
  };
179
178
 
180
- const filterItems = async (filterPointer: string, filtersSelected: string) => {
181
- const filtersSelection = setFiltersSelection(filterPointer, filtersSelected);
182
- const filterQuery = setFilterQuery(filtersSelection);
183
- setCurrentFilterQuery(filterQuery);
184
- };
179
+ const filterItems = async (filterPointer: string, filtersSelected: IQueryValue[]) =>
180
+ setFiltersSelection(filterPointer, filtersSelected);
185
181
 
186
182
  const foldersIcon = isPanelOpen ? <Icon name="closePanel" size="24" /> : <Icon name="openPanel" size="24" />;
187
183
 
@@ -219,7 +215,12 @@ const FileGallery = (props: IProps): JSX.Element => {
219
215
  </S.Header>
220
216
  )}
221
217
  <S.Search>
222
- <SearchField onChange={setSearchQuery} placeholder="Type file’s name, title, or #tag" autoFocus={false} />
218
+ <SearchField
219
+ onChange={setSearchQuery}
220
+ value={searchQuery}
221
+ placeholder="Type file’s name, title, or #tag"
222
+ autoFocus={false}
223
+ />
223
224
  </S.Search>
224
225
  <S.GalleryWrapper ref={galleryRef}>
225
226
  {isGlobalTab && isSiteView && (
@@ -237,6 +238,15 @@ const FileGallery = (props: IProps): JSX.Element => {
237
238
  </S.LoadingWrapper>
238
239
  ) : (
239
240
  <>
241
+ <S.SearchTags>
242
+ <SearchTagsBar query={searchQuery} setQuery={setSearchQuery} />
243
+ <FilterTagsBar
244
+ filters={filterValues}
245
+ setFilters={setFiltersSelection}
246
+ labels={{ filterType: "Type" }}
247
+ resetFilters={resetFilterQuery}
248
+ />
249
+ </S.SearchTags>
240
250
  {!isRoot && !isSearching && <Breadcrumb breadcrumb={breadcrumb} onClick={updateCurrentFolder} />}
241
251
  {(hasFolders || (!isRoot && !isSearching)) && (
242
252
  <S.SectionWrapper>
@@ -70,6 +70,7 @@ const GalleryWrapper = styled.div`
70
70
  position: relative;
71
71
  background-color: ${(p) => p.theme.color.uiBackground01};
72
72
  overflow: auto;
73
+ padding: ${(p) => `0 ${p.theme.spacing.m} ${p.theme.spacing.m} ${p.theme.spacing.m}`};
73
74
  `;
74
75
 
75
76
  const Grid = styled.div`
@@ -113,7 +114,7 @@ const SectionWrapper = styled.div`
113
114
  display: flex;
114
115
  flex-direction: column;
115
116
  width: 100%;
116
- padding: ${(p) => p.theme.spacing.m};
117
+ padding-top: ${(p) => p.theme.spacing.m};
117
118
  `;
118
119
 
119
120
  const SectionHeader = styled.div`
@@ -165,6 +166,15 @@ const ResizeHandle = styled.div`
165
166
  }
166
167
  `;
167
168
 
169
+ const SearchTags = styled.div`
170
+ & > div:nth-child(1){
171
+ margin-top: ${p => p.theme.spacing.m};
172
+ }
173
+ & > div:nth-child(2){
174
+ margin-top: ${p => p.theme.spacing.xs};
175
+ }
176
+ `;
177
+
168
178
  export {
169
179
  Wrapper,
170
180
  FolderPanel,
@@ -186,4 +196,5 @@ export {
186
196
  FoldersWrapper,
187
197
  FoldersIconWrapper,
188
198
  ResizeHandle,
199
+ SearchTags,
189
200
  };
@@ -0,0 +1,61 @@
1
+ import React from "react";
2
+ import { IQueryValue } from "@ax/types";
3
+ import Button from "../Button";
4
+
5
+ import * as S from "./style";
6
+
7
+ const FilterTagsBar = (props: IFilterTagsBarProps): JSX.Element => {
8
+ const { filters, labels, setFilters, resetFilters } = props;
9
+
10
+ const tags: string[] = [];
11
+ filters &&
12
+ Object.keys(filters)
13
+ .filter((key: string) => Object.keys(labels).includes(key))
14
+ .forEach((key: string) => {
15
+ Array.isArray(filters[key]) &&
16
+ filters[key].forEach((filter: IQueryValue) => {
17
+ if (filter && filter.value !== "all") {
18
+ tags.push(`${labels[key]}: ${filter.label}`);
19
+ }
20
+ });
21
+ });
22
+
23
+ const deleteTag = (tagText: string) => {
24
+ const values = tagText.split(":");
25
+ const key = Object.keys(labels).find((key) => labels[key] === values[0]);
26
+ if (key) {
27
+ const newFilters: IQueryValue[] = filters[key].filter((filter: IQueryValue) => filter.label !== values[1].trim());
28
+ setFilters(key, newFilters);
29
+ }
30
+ };
31
+
32
+ const handleDeleteAll = () => resetFilters();
33
+
34
+ return tags.length > 0 ? (
35
+ <S.Wrapper>
36
+ <S.Text>Selected filters</S.Text>
37
+ <S.TagList>
38
+ {tags.map((tag: string, index: number) => {
39
+ const handleDeleteTag = () => deleteTag(tag);
40
+ return <S.StyledTag key={index} text={tag} color="#FFFFFF" onDeleteAction={handleDeleteTag} />;
41
+ })}
42
+ </S.TagList>
43
+ <S.ButtonWrapper>
44
+ <Button type="button" buttonStyle="minimal" icon="close" onClick={handleDeleteAll}>
45
+ Clear All
46
+ </Button>
47
+ </S.ButtonWrapper>
48
+ </S.Wrapper>
49
+ ) : (
50
+ <></>
51
+ );
52
+ };
53
+
54
+ export interface IFilterTagsBarProps {
55
+ filters: Record<string, any>;
56
+ labels: Record<string, string | undefined>;
57
+ setFilters: (pointer: string, filter: IQueryValue[], isAscendent?: boolean) => void;
58
+ resetFilters: () => void;
59
+ }
60
+
61
+ export default FilterTagsBar;
@@ -0,0 +1,30 @@
1
+ import styled from "styled-components";
2
+ import Tag from "../Tag";
3
+
4
+ const Wrapper = styled.div`
5
+ display: flex;
6
+ background-color: ${(p) => p.theme.color.uiBackground03};
7
+ width: 100%;
8
+ padding: ${(p) => `${p.theme.spacing.xs} ${p.theme.spacing.m}`};
9
+ align-items: center;
10
+ `;
11
+
12
+ const Text = styled.div`
13
+ ${(p) => p.theme.textStyle.uiS};
14
+ color: ${(p) => p.theme.color.textHighEmphasis};
15
+ margin-right: ${(p) => p.theme.spacing.xs};
16
+ flex-shrink: 0;
17
+ `;
18
+
19
+ const StyledTag = styled(Tag)`
20
+ margin-right: ${(p) => p.theme.spacing.xs};
21
+ `;
22
+
23
+ const TagList = styled.div``;
24
+
25
+ const ButtonWrapper = styled.div`
26
+ margin-left: auto;
27
+ flex-shrink: 0;
28
+ `;
29
+
30
+ export { Wrapper, TagList, Text, StyledTag, ButtonWrapper }
@@ -22,10 +22,14 @@ const FloatingMenu = (props: IFloatingProps): JSX.Element => {
22
22
 
23
23
  useEffect(() => {
24
24
  if (isOpen && menuOptions?.current) {
25
- const bounding = menuOptions.current.getBoundingClientRect();
25
+ const bounding = menuOptions.current.children[0].getBoundingClientRect();
26
+ const boundingChild = menuOptions.current.children[0] && menuOptions.current.children[0].getBoundingClientRect();
26
27
  if (bounding.bottom > (window.innerHeight || document.documentElement.clientHeight)) {
27
28
  menuOptions.current.scrollIntoView({ block: "end", behavior: "smooth" });
28
29
  }
30
+ if (boundingChild && boundingChild.right > window.innerWidth) {
31
+ menuOptions.current.style.right = "130px";
32
+ }
29
33
  }
30
34
  // eslint-disable-next-line react-hooks/exhaustive-deps
31
35
  }, [isOpen]);
@@ -1,22 +1,30 @@
1
1
  import React, { useState } from "react";
2
2
 
3
3
  import { FloatingMenu, Icon, ListTitle, ListItem } from "@ax/components";
4
-
5
4
  import { areEquals } from "@ax/helpers";
5
+ import { IQueryValue } from "@ax/types";
6
6
 
7
7
  import * as S from "./style";
8
8
 
9
9
  const Orientation = ({ filterItems }: IOrientationProps): JSX.Element => {
10
+ const selectAllOption = "all";
10
11
  const initialState = ["all"];
12
+ const pointer = "orientation";
11
13
  const [selectedValue, setSelectedValue] = useState(initialState);
12
14
 
13
- const setQuery = (selection: any) => {
15
+ const filters: Record<string, string> = {
16
+ all: "All",
17
+ landscape: "Horizontal",
18
+ portrait: "Vertical",
19
+ square: "Square",
20
+ };
21
+
22
+ const setQuery = (selection: string) => {
14
23
  if (!selection.length) {
15
- selection = initialState;
24
+ selection = selectAllOption;
16
25
  }
17
26
  setSelectedValue([selection]);
18
- const pointer = "orientation";
19
- filterItems(pointer, selection);
27
+ filterItems(pointer, [{ value: selection, label: filters[selection] }]);
20
28
  };
21
29
 
22
30
  const isActive = !areEquals(selectedValue, initialState);
@@ -53,7 +61,7 @@ const Orientation = ({ filterItems }: IOrientationProps): JSX.Element => {
53
61
  };
54
62
 
55
63
  export interface IOrientationProps {
56
- filterItems(pointer: string, filter: string): void;
64
+ filterItems(pointer: string, filter: IQueryValue[]): void;
57
65
  }
58
66
 
59
67
  export default Orientation;
@@ -1,12 +1,16 @@
1
1
  import React from "react";
2
2
 
3
3
  import { Icon, FloatingMenu, ListTitle, ListItem } from "@ax/components";
4
+ import { IQueryValue } from "@ax/types";
4
5
 
5
6
  import * as S from "./style";
6
7
 
7
8
  const SortBy = ({ sortItems, sortedState }: ISortByProps): JSX.Element => {
8
9
  const { isAscending, sortedByName, sortedByDate, sortedBySize } = sortedState;
9
- const sortBy = (pointer: string, isAscending: boolean) => sortItems(pointer, isAscending);
10
+
11
+ const sortBy = (pointer: string, isAscending: boolean) =>
12
+ sortItems([{ value: pointer, label: pointer }], isAscending);
13
+
10
14
  const sortAscendingName = () => sortBy("name", true);
11
15
  const sortDescendingName = () => sortBy("name", false);
12
16
  const sortAscendingDate = () => sortBy("date", true);
@@ -33,21 +37,33 @@ const SortBy = ({ sortItems, sortedState }: ISortByProps): JSX.Element => {
33
37
  return (
34
38
  <FloatingMenu Button={Header} position="center">
35
39
  <ListTitle>Name Sorting</ListTitle>
36
- <ListItem isSelected={sortedByName && isAscending} onClick={sortAscendingName}>Ascendent</ListItem>
37
- <ListItem isSelected={sortedByName && !isAscending} onClick={sortDescendingName}>Descendent</ListItem>
40
+ <ListItem isSelected={sortedByName && isAscending} onClick={sortAscendingName}>
41
+ Ascendent
42
+ </ListItem>
43
+ <ListItem isSelected={sortedByName && !isAscending} onClick={sortDescendingName}>
44
+ Descendent
45
+ </ListItem>
38
46
  <ListTitle>Date sorting</ListTitle>
39
- <ListItem isSelected={sortedByDate && !isAscending} onClick={sortDescendingDate}>Newest first</ListItem>
40
- <ListItem isSelected={sortedByDate && isAscending} onClick={sortAscendingDate}>Oldest first</ListItem>
47
+ <ListItem isSelected={sortedByDate && !isAscending} onClick={sortDescendingDate}>
48
+ Newest first
49
+ </ListItem>
50
+ <ListItem isSelected={sortedByDate && isAscending} onClick={sortAscendingDate}>
51
+ Oldest first
52
+ </ListItem>
41
53
  <ListTitle>Size sorting</ListTitle>
42
- <ListItem isSelected={sortedBySize && isAscending} onClick={sortAscendingSize}>Ascendent</ListItem>
43
- <ListItem isSelected={sortedBySize && !isAscending} onClick={sortDescendingSize}>Descendent</ListItem>
54
+ <ListItem isSelected={sortedBySize && isAscending} onClick={sortAscendingSize}>
55
+ Ascendent
56
+ </ListItem>
57
+ <ListItem isSelected={sortedBySize && !isAscending} onClick={sortDescendingSize}>
58
+ Descendent
59
+ </ListItem>
44
60
  </FloatingMenu>
45
61
  );
46
62
  };
47
63
 
48
64
  export interface ISortByProps {
49
65
  sortedState: ISortedListStatus;
50
- sortItems(orderPointer: string, isAscendent: boolean): void;
66
+ sortItems(orderPointer: IQueryValue[], isAscendent: boolean): void;
51
67
  }
52
68
 
53
69
  interface ISortedListStatus {
@@ -1,22 +1,29 @@
1
1
  import React, { useState } from "react";
2
2
 
3
3
  import { FloatingMenu, Icon, ListTitle, ListItem } from "@ax/components";
4
-
5
4
  import { areEquals } from "@ax/helpers";
5
+ import { IQueryValue } from "@ax/types";
6
6
 
7
7
  import * as S from "./style";
8
8
 
9
9
  const Type = ({ filterItems }: ITypeProps): JSX.Element => {
10
+ const selectAllOption = "all";
10
11
  const initialState = ["all"];
12
+ const pointer = "format";
11
13
  const [selectedValue, setSelectedValue] = useState(initialState);
12
14
 
13
- const setQuery = (selection: any) => {
15
+ const filters: Record<string, string> = {
16
+ all: "All",
17
+ bitmap: "Image",
18
+ vectorial: "Icons",
19
+ };
20
+
21
+ const setQuery = (selection: string) => {
14
22
  if (!selection.length) {
15
- selection = initialState;
23
+ selection = selectAllOption;
16
24
  }
17
25
  setSelectedValue([selection]);
18
- const pointer = "format";
19
- filterItems(pointer, selection);
26
+ filterItems(pointer, [{ value: selection, label: filters[selection] }]);
20
27
  };
21
28
 
22
29
  const isActive = !areEquals(selectedValue, initialState);
@@ -36,15 +43,21 @@ const Type = ({ filterItems }: ITypeProps): JSX.Element => {
36
43
  return (
37
44
  <FloatingMenu Button={Header} position="center" closeOnSelect={true}>
38
45
  <ListTitle>Filter by type</ListTitle>
39
- <ListItem isSelected={selectedValue.includes("all")} onClick={() => setQuery("all")}>All</ListItem>
40
- <ListItem isSelected={selectedValue.includes("bitmap")} onClick={() => setQuery("bitmap")}>Image</ListItem>
41
- <ListItem isSelected={selectedValue.includes("vectorial")} onClick={() => setQuery("vectorial")}>Icons</ListItem>
46
+ <ListItem isSelected={selectedValue.includes("all")} onClick={() => setQuery("all")}>
47
+ All
48
+ </ListItem>
49
+ <ListItem isSelected={selectedValue.includes("bitmap")} onClick={() => setQuery("bitmap")}>
50
+ Image
51
+ </ListItem>
52
+ <ListItem isSelected={selectedValue.includes("vectorial")} onClick={() => setQuery("vectorial")}>
53
+ Icons
54
+ </ListItem>
42
55
  </FloatingMenu>
43
56
  );
44
57
  };
45
58
 
46
59
  export interface ITypeProps {
47
- filterItems(pointer: string, filter: string): void;
60
+ filterItems(pointer: string, filter: IQueryValue[]): void;
48
61
  }
49
62
 
50
63
  export default Type;
@@ -44,9 +44,10 @@ export const DragSubtitle = styled.div`
44
44
 
45
45
  export const DragIcon = styled.div`
46
46
  margin-bottom: ${(p) => p.theme.spacing.s};
47
+ display: flex;
48
+ justify-content: center;
47
49
  `;
48
50
 
49
-
50
51
  export const UploadingStatus = styled.div`
51
52
  transition: opacity 0.1s;
52
53
  `;