@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
@@ -16,8 +16,19 @@ import {
16
16
  Tabs,
17
17
  BackFolder,
18
18
  SearchField,
19
+ SearchTagsBar,
20
+ FilterTagsBar,
19
21
  } from "@ax/components";
20
- import { IBulkAction, IFile, IFilesFolder, IFolder, IFolderTree, IGetFolderParams, IRootState } from "@ax/types";
22
+ import {
23
+ IBulkAction,
24
+ IFile,
25
+ IFilesFolder,
26
+ IFolder,
27
+ IFolderTree,
28
+ IGetFolderParams,
29
+ IQueryValue,
30
+ IRootState,
31
+ } from "@ax/types";
21
32
  import { useBulkSelection, useIsDirty, useModal, usePermission, useResizable, useToast } from "@ax/hooks";
22
33
  import { fileDriveActions } from "@ax/containers/FileDrive";
23
34
 
@@ -96,9 +107,8 @@ const FileDrive = (props: IProps) => {
96
107
 
97
108
  const initFolderState = { name: "", folderID: currentFolderID };
98
109
  const [folderForm, setFolderForm] = useState<IFolderFormState>(initFolderState);
99
- const { setFiltersSelection, setFilterQuery, filterValues } = useFilterQuery();
110
+ const { setFiltersSelection, resetFilterQuery, filterValues, filterQuery } = useFilterQuery();
100
111
  const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
101
- const [currentFilterQuery, setCurrentFilterQuery] = useState("");
102
112
  const [searchQuery, setSearchQuery] = useState<string>("");
103
113
  const isSearching = searchQuery.length > 0;
104
114
 
@@ -148,12 +158,12 @@ const FileDrive = (props: IProps) => {
148
158
  siteID,
149
159
  folderID: currentFolderID,
150
160
  search: searchQuery,
151
- query: currentFilterQuery,
161
+ query: filterQuery,
152
162
  loading: true,
153
163
  };
154
164
 
155
165
  return params;
156
- }, [currentFolderID, selectedTab, searchQuery, currentFilterQuery]);
166
+ }, [currentFolderID, selectedTab, searchQuery, filterQuery]);
157
167
 
158
168
  useLayoutEffect(() => {
159
169
  return () => {
@@ -366,20 +376,14 @@ const FileDrive = (props: IProps) => {
366
376
 
367
377
  const handleDownload = async (fileID: number, fileName: string) => await downloadFiles(fileID, false, fileName);
368
378
 
369
- const sortItems = async (orderPointer: string, isAscending: boolean) => {
370
- const sortedState = getSortedListStatus(orderPointer, isAscending);
379
+ const sortItems = (orderPointer: IQueryValue[], isAscending: boolean) => {
380
+ const sortedState = getSortedListStatus(orderPointer[0].value.toString(), isAscending);
371
381
  setSortedListStatus(sortedState);
372
-
373
- const filtersSelection = setFiltersSelection("order", orderPointer, isAscending);
374
- const filterQuery = setFilterQuery(filtersSelection);
375
- setCurrentFilterQuery(filterQuery);
382
+ setFiltersSelection("order", orderPointer, isAscending);
376
383
  };
377
384
 
378
- const filterItems = async (filterPointer: string, filtersSelected: string) => {
379
- const filtersSelection = setFiltersSelection(filterPointer, filtersSelected);
380
- const filterQuery = setFilterQuery(filtersSelection);
381
- setCurrentFilterQuery(filterQuery);
382
- };
385
+ const filterItems = (filterPointer: string, filtersSelected: IQueryValue[]) =>
386
+ setFiltersSelection(filterPointer, filtersSelected);
383
387
 
384
388
  let bulkActions: IBulkAction[] = [];
385
389
 
@@ -621,7 +625,16 @@ const FileDrive = (props: IProps) => {
621
625
  {isLoading ? (
622
626
  <Loading />
623
627
  ) : (
624
- <>
628
+ <S.FolderContent>
629
+ <S.SearchTags>
630
+ <SearchTagsBar query={searchQuery} setQuery={setSearchQuery} />
631
+ <FilterTagsBar
632
+ filters={filterValues}
633
+ setFilters={setFiltersSelection}
634
+ labels={{ filterType: "Type" }}
635
+ resetFilters={resetFilterQuery}
636
+ />
637
+ </S.SearchTags>
625
638
  {!isRoot && <Breadcrumb breadcrumb={breadcrumb} onClick={handleUpdateCurrentFolder} />}
626
639
  {(hasFolders || !isRoot) && (
627
640
  <S.SectionWrapper>
@@ -675,7 +688,7 @@ const FileDrive = (props: IProps) => {
675
688
  </S.EmptyStateWrapper>
676
689
  )}
677
690
  </S.BigSectionWrapper>
678
- </>
691
+ </S.FolderContent>
679
692
  )}
680
693
  </S.ContentWrapper>
681
694
  </S.Wrapper>
@@ -34,15 +34,23 @@ const ContentWrapper = styled.div`
34
34
  flex-direction: column;
35
35
  `;
36
36
 
37
+ const FolderContent = styled.div`
38
+ padding: ${(p) => `0 ${p.theme.spacing.m} ${p.theme.spacing.m} ${p.theme.spacing.m}`};
39
+ display: flex;
40
+ flex-direction: column;
41
+ flex-grow: 1;
42
+ `;
43
+
37
44
  const SectionWrapper = styled.div`
38
45
  width: 100%;
39
- padding: ${(p) => p.theme.spacing.m};
46
+ padding-top: ${(p) => p.theme.spacing.m};
40
47
  display: flex;
41
48
  flex-direction: column;
42
49
  `;
43
50
 
44
51
  const BigSectionWrapper = styled(SectionWrapper)`
45
52
  flex-grow: 1;
53
+ padding-top: ${(p) => p.theme.spacing.m};
46
54
  `;
47
55
 
48
56
  const SectionHeader = styled.div`
@@ -165,11 +173,21 @@ const ResizeHandle = styled.div`
165
173
  }
166
174
  `;
167
175
 
176
+ const SearchTags = styled.div`
177
+ & > div:nth-child(1){
178
+ margin-top: ${p => p.theme.spacing.m};
179
+ }
180
+ & > div:nth-child(2){
181
+ margin-top: ${p => p.theme.spacing.xs};
182
+ }
183
+ `;
184
+
168
185
  export {
169
186
  Wrapper,
170
187
  FolderPanel,
171
188
  FolderPanelContent,
172
189
  ContentWrapper,
190
+ FolderContent,
173
191
  SectionWrapper,
174
192
  SectionHeader,
175
193
  SectionTitle,
@@ -187,5 +205,6 @@ export {
187
205
  TabsWrapper,
188
206
  ResizeHandle,
189
207
  Filters,
208
+ SearchTags,
190
209
  BigSectionWrapper,
191
210
  };
@@ -52,6 +52,8 @@ const FlagsWrapper = styled.div`
52
52
  svg {
53
53
  margin-right: 2px;
54
54
  margin-bottom: -3px; // TODO
55
+ display: inline;
56
+ vertical-align: baseline;
55
57
  }
56
58
  `;
57
59
 
@@ -1,4 +1,4 @@
1
- import React, { useState } from "react";
1
+ import React from "react";
2
2
  import { connect } from "react-redux";
3
3
  import { NavLink } from "react-router-dom";
4
4
 
@@ -10,13 +10,11 @@ import { menuActions } from "@ax/containers/Navigation";
10
10
  import * as S from "./style";
11
11
 
12
12
  const Nav = (props: INav): JSX.Element => {
13
- const { getCurrentMenu, currentType, isDirty, currentMenus } = props;
14
- const [category, setCategory] = useState(currentType);
15
-
13
+ const { getCurrentMenu, currentType, setCurrentType, isDirty, currentMenus } = props;
16
14
  const { isOpen, toggleModal } = useModal();
17
15
 
18
16
  const discardChanges = () => {
19
- getCurrentMenu(category);
17
+ getCurrentMenu(currentType);
20
18
  toggleModal();
21
19
  };
22
20
 
@@ -25,21 +23,21 @@ const Nav = (props: INav): JSX.Element => {
25
23
  <GuardModal isOpen={isOpen} discardChanges={discardChanges} toggleModal={toggleModal} />
26
24
  <SubNav>
27
25
  {currentMenus &&
28
- currentMenus.map((category: any) => {
26
+ currentMenus.map((category: any, index: number) => {
29
27
  const _handleClick = () => {
30
- setCategory(category.name);
28
+ setCurrentType(category.name);
31
29
  isDirty ? toggleModal() : getCurrentMenu(category.name);
32
30
  };
33
31
 
34
- const isSelected = category.name === currentType;
32
+ const isEmpty = currentType === "" && index === 0;
33
+
34
+ const isSelected = isEmpty ? true : category.name === currentType;
35
35
  const selectedClass = isSelected ? "selected" : "";
36
36
 
37
37
  return (
38
38
  <MenuItem onClick={_handleClick} key={category.name}>
39
39
  <NavLink to="#" className={selectedClass}>
40
- <S.Link active={isSelected}>
41
- {category.title}
42
- </S.Link>
40
+ <S.Link active={isSelected}>{category.title}</S.Link>
43
41
  </NavLink>
44
42
  </MenuItem>
45
43
  );
@@ -53,6 +51,7 @@ interface IProps {
53
51
  currentType: string;
54
52
  isDirty: boolean;
55
53
  currentMenus: any[] | null;
54
+ setCurrentType(currentType: string): void;
56
55
  }
57
56
 
58
57
  interface IDispatchProps {
@@ -64,7 +63,6 @@ const mapDispatchToProps = {
64
63
  };
65
64
 
66
65
  const mapStateToProps = (state: IRootState) => ({
67
- currentType: state.menu.type,
68
66
  currentMenus: state.menu.savedMenus,
69
67
  });
70
68
 
@@ -90,7 +90,6 @@ const SidePanel = (props: IProps): JSX.Element => {
90
90
  const mapStateToProps = (state: IRootState) => ({
91
91
  form: state.menu.form,
92
92
  item: state.menu.item,
93
- type: state.menu.type,
94
93
  });
95
94
 
96
95
  const mapDispatchToProps = {
@@ -100,7 +99,6 @@ const mapDispatchToProps = {
100
99
 
101
100
  interface IStateProps {
102
101
  form: IMenuForm;
103
- type: string;
104
102
  item: IMenuItem | null;
105
103
  }
106
104
  interface ISidePanelProps {
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useCallback, memo } from "react";
1
+ import React, { useEffect, useCallback, memo, useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
4
  import { IGetSitePagesParams, IRootState, IMenuItem } from "@ax/types";
@@ -13,12 +13,15 @@ import Table from "./Table";
13
13
  import * as S from "./style";
14
14
 
15
15
  const List = (props: IMenuList): JSX.Element => {
16
- const { getMenus, lang, getSitePages, currentSiteID, editorMenu, savedMenu, currentType } = props;
16
+ const { getMenus, lang, getSitePages, currentSiteID, editorMenu, savedMenu, savedMenus } = props;
17
17
 
18
18
  if (!currentSiteID) {
19
19
  throw new Error(`ERROR: User reached Menu List with null site info`);
20
20
  }
21
21
 
22
+ const initialState = savedMenus && savedMenus.length ? savedMenus[0].name : "";
23
+ const [currentType, setCurrentType] = useState(initialState);
24
+
22
25
  const { isDirty } = useShouldBeSaved(editorMenu, savedMenu, currentType);
23
26
  const memoizedGetMenus = useCallback(() => getMenus(), [getMenus]);
24
27
  const memoizedGetSitePages = useCallback(
@@ -42,7 +45,7 @@ const List = (props: IMenuList): JSX.Element => {
42
45
 
43
46
  return (
44
47
  <S.ListWrapper>
45
- <Nav isDirty={isDirty} />
48
+ <Nav isDirty={isDirty} currentType={currentType} setCurrentType={setCurrentType} />
46
49
  <S.TableWrapper>
47
50
  <Table isDirty={isDirty} />
48
51
  </S.TableWrapper>
@@ -53,9 +56,9 @@ const List = (props: IMenuList): JSX.Element => {
53
56
  const mapStateToProps = (state: IRootState) => ({
54
57
  currentSiteID: state.sites.currentSiteInfo && state.sites.currentSiteInfo.id,
55
58
  lang: state.app.lang,
56
- currentType: state.menu.type,
57
59
  editorMenu: state.menu.editorMenu.elements,
58
60
  savedMenu: state.menu.savedMenu.elements,
61
+ savedMenus: state.menu.savedMenus,
59
62
  });
60
63
 
61
64
  const mapDispatchToProps = {
@@ -66,9 +69,9 @@ const mapDispatchToProps = {
66
69
  interface IStateProps {
67
70
  currentSiteID: number | null;
68
71
  lang: { locale: string; id: number | null };
69
- currentType: string;
70
72
  editorMenu: IMenuItem[] | undefined;
71
73
  savedMenu: IMenuItem[] | undefined;
74
+ savedMenus: IMenuItem[] | null;
72
75
  }
73
76
 
74
77
  interface IDispatchProps {
@@ -1,6 +1,8 @@
1
1
  import React from "react";
2
2
 
3
3
  import { CheckField, SiteFilter, TableCounter, DateFilter } from "@ax/components";
4
+ import { IQueryValue } from "@ax/types";
5
+
4
6
  import * as S from "./style";
5
7
 
6
8
  const TableHeader = (props: IProps): JSX.Element => {
@@ -47,10 +49,10 @@ interface IProps {
47
49
  totalItems: number;
48
50
  isScrolling: boolean;
49
51
  selectAllItems: () => void;
50
- filterItems: (filterPointer: string, filtersSelected: string) => void;
52
+ filterItems: (filterPointer: string, filtersSelected: IQueryValue[]) => void;
51
53
  filterValues: any;
52
54
  isSiteItem: boolean;
53
- sortItems: (orderPointer: string, isAscending: boolean) => void;
55
+ sortItems: (orderPointer: IQueryValue[], isAscending: boolean) => void;
54
56
  sortedListStatus: { isAscending: boolean; sortedByDate: boolean };
55
57
  }
56
58
 
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { BulkSelectionOptions } from "@ax/components";
3
+ import { IQueryValue } from "@ax/types";
3
4
  import TableHeader from "./TableHeader";
4
5
 
5
6
  const BulkHeader = (props: IProps): JSX.Element => {
@@ -55,10 +56,10 @@ interface IProps {
55
56
  selectAllItems: () => void;
56
57
  totalItems: number;
57
58
  isScrolling: boolean;
58
- filterItems: (filterPointer: string, filtersSelected: string) => void;
59
+ filterItems: (filterPointer: string, filtersSelected: IQueryValue[]) => void;
59
60
  filterValues: any;
60
61
  isSiteItem: boolean;
61
- sortItems: (orderPointer: string, isAscending: boolean) => void;
62
+ sortItems: (orderPointer: IQueryValue[], isAscending: boolean) => void;
62
63
  sortedListStatus: { isAscending: boolean; sortedByDate: boolean };
63
64
  }
64
65
 
@@ -1,7 +1,8 @@
1
1
  import { useState } from "react";
2
+ import { IQueryValue, ISite } from "@ax/types";
2
3
 
3
4
  const useSortedListStatus = () => {
4
- const sortedInitialState: { isAscending: boolean; sortedByDate: boolean; } = {
5
+ const sortedInitialState: { isAscending: boolean; sortedByDate: boolean } = {
5
6
  isAscending: false,
6
7
  sortedByDate: false,
7
8
  };
@@ -14,20 +15,25 @@ const useSortedListStatus = () => {
14
15
  };
15
16
  };
16
17
 
17
- const useFilterQuery = (currentSiteID: number | null) => {
18
- const initialQueryValues = {
19
- sites: currentSiteID || "all",
20
- order: "",
18
+ const useFilterQuery = (site: ISite | null) => {
19
+ const initialQueryValues: Record<string, IQueryValue[]> = {
20
+ sites: site ? [{ value: site.id, label: site.name }] : [{ value: "all", label: "All" }],
21
+ order: [],
21
22
  };
22
23
 
23
24
  const [query, setQuery] = useState(initialQueryValues);
25
+ const [currentFilterQuery, setCurrentFilterQuery] = useState(`&sites=${site?.id || "global"}`);
24
26
 
25
27
  const setFilterQuery = (filterValues: any) => {
26
28
  const { sites, order } = filterValues;
27
29
  let filterQuery = "";
28
30
 
29
- const currentQuery = (pointer: string, values: string) => {
30
- return filterQuery.concat(`&${pointer}=${values}`);
31
+ const currentQuery = (pointer: string, values: IQueryValue[]): string => {
32
+ const stringValues = Array.isArray(values)
33
+ ? values.map((value) => (value.value !== "all" ? value.value : "")).join(",")
34
+ : "";
35
+
36
+ return !stringValues.length ? filterQuery : filterQuery.concat(`&${pointer}=${stringValues}`);
31
37
  };
32
38
 
33
39
  if (sites) {
@@ -38,29 +44,31 @@ const useFilterQuery = (currentSiteID: number | null) => {
38
44
  filterQuery = currentQuery("order", order);
39
45
  }
40
46
 
41
- return filterQuery;
47
+ setCurrentFilterQuery(filterQuery);
42
48
  };
43
49
 
44
- const setFiltersSelection = (pointer: string, filter: string, isAscendent?: boolean) => {
50
+ const setFiltersSelection = (pointer: string, filter: IQueryValue[], isAscendent?: boolean) => {
45
51
  const { sites, order } = query;
46
52
  const orderMethod = isAscendent ? "asc" : "desc";
47
- const filterValues = {
53
+ const filterValues: Record<string, IQueryValue[]> = {
48
54
  sites: pointer === "sites" ? filter : sites,
49
- order: pointer === "order" ? `${filter}-${orderMethod}` : order,
55
+ order: pointer === "order" ? [{ value: `${filter[0].value}-${orderMethod}`, label: filter[0].label }] : order,
50
56
  };
51
57
 
52
58
  setQuery(filterValues);
53
-
54
- return filterValues;
59
+ setFilterQuery(filterValues);
55
60
  };
56
61
 
57
- const resetFilterQuery = () => setQuery(initialQueryValues);
62
+ const resetFilterQuery = () => {
63
+ setQuery(initialQueryValues);
64
+ setCurrentFilterQuery("");
65
+ }
58
66
 
59
67
  return {
60
68
  setFiltersSelection,
61
- setFilterQuery,
62
69
  resetFilterQuery,
63
70
  filterValues: query,
71
+ filterQuery: currentFilterQuery,
64
72
  };
65
73
  };
66
74
 
@@ -1,10 +1,19 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
- import { IEmptyStateProps, INavItem, IRedirect, IRootState } from "@ax/types";
4
+ import { IEmptyStateProps, INavItem, IQueryValue, IRedirect, IRootState, ISite } from "@ax/types";
5
5
  import { appActions } from "@ax/containers/App";
6
6
  import { redirectsActions } from "@ax/containers/Redirects";
7
- import { MainWrapper, ErrorToast, Nav, TableList, EmptyState, Toast } from "@ax/components";
7
+ import {
8
+ MainWrapper,
9
+ ErrorToast,
10
+ Nav,
11
+ TableList,
12
+ EmptyState,
13
+ Toast,
14
+ SearchTagsBar,
15
+ FilterTagsBar,
16
+ } from "@ax/components";
8
17
  import { useBulkSelection, useModal, useToast } from "@ax/hooks";
9
18
 
10
19
  import BulkHeader from "./BulkHeader";
@@ -26,7 +35,7 @@ const Redirects = (props: IProps): JSX.Element => {
26
35
  totalItems,
27
36
  deleteRedirect,
28
37
  addRedirect,
29
- currentSiteID,
38
+ currentSite,
30
39
  importRedirects,
31
40
  imports,
32
41
  totalImports,
@@ -35,7 +44,6 @@ const Redirects = (props: IProps): JSX.Element => {
35
44
 
36
45
  const itemsPerPage = 50;
37
46
  const firstPage = 1;
38
- const siteID = currentSiteID ? currentSiteID : "global";
39
47
  const [page, setPage] = useState(1);
40
48
  const [isScrolling, setIsScrolling] = useState(false);
41
49
  const [isOpenedSecond, setIsOpenedSecond] = useState(false);
@@ -43,8 +51,7 @@ const Redirects = (props: IProps): JSX.Element => {
43
51
  const { isOpen: isOpenDelete, toggleModal: toggleModalDelete } = useModal();
44
52
  const tableRef = useRef<HTMLDivElement>(null);
45
53
  const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
46
- const { setFiltersSelection, setFilterQuery, filterValues } = useFilterQuery(currentSiteID);
47
- const [currentFilterQuery, setCurrentFilterQuery] = useState(`&sites=${siteID}`);
54
+ const { setFiltersSelection, resetFilterQuery, filterValues, filterQuery } = useFilterQuery(currentSite);
48
55
  const { isVisible, toggleToast, setIsVisible } = useToast();
49
56
  const { isVisible: isImportVisible, toggleToast: toggleImportToast, setIsVisible: setIsImportVisible } = useToast();
50
57
  const { isOpen: isOpenOverwrite, toggleModal: toggleOverwriteModal } = useModal();
@@ -83,12 +90,12 @@ const Redirects = (props: IProps): JSX.Element => {
83
90
 
84
91
  useEffect(() => {
85
92
  const params = getParams();
86
- getRedirects(params, currentFilterQuery);
93
+ getRedirects(params, filterQuery);
87
94
  if (tableRef.current) {
88
95
  tableRef.current.scrollTo(0, 0);
89
96
  }
90
97
  // eslint-disable-next-line react-hooks/exhaustive-deps
91
- }, [page, currentFilterQuery, searchQuery, searchFilter]);
98
+ }, [page, filterQuery, searchQuery, searchFilter]);
92
99
 
93
100
  useEffect(() => {
94
101
  if (!isLoading) {
@@ -133,21 +140,17 @@ const Redirects = (props: IProps): JSX.Element => {
133
140
 
134
141
  const handleSelectAll = () => selectAllItems();
135
142
 
136
- const sortItems = async (orderPointer: string, isAscending: boolean) => {
143
+ const sortItems = async (orderPointer: IQueryValue[], isAscending: boolean) => {
137
144
  setPage(firstPage);
138
- const sortedState = getSortedListStatus(orderPointer, isAscending);
145
+ const sortedState = getSortedListStatus(orderPointer[0].value.toString(), isAscending);
139
146
  setSortedListStatus(sortedState);
140
147
 
141
- const filtersSelection = setFiltersSelection("order", orderPointer, isAscending);
142
- const filterQuery = setFilterQuery(filtersSelection);
143
- setCurrentFilterQuery(filterQuery);
148
+ setFiltersSelection("order", orderPointer, isAscending);
144
149
  };
145
150
 
146
- const filterItems = async (filterPointer: string, filtersSelected: string) => {
151
+ const filterItems = async (filterPointer: string, filtersSelected: IQueryValue[]) => {
147
152
  setPage(firstPage);
148
- const filtersSelection = setFiltersSelection(filterPointer, filtersSelected);
149
- const filterQuery = setFilterQuery(filtersSelection);
150
- setCurrentFilterQuery(filterQuery);
153
+ setFiltersSelection(filterPointer, filtersSelected);
151
154
  };
152
155
 
153
156
  const TableHeader = (
@@ -161,7 +164,7 @@ const Redirects = (props: IProps): JSX.Element => {
161
164
  isScrolling={isScrolling}
162
165
  filterItems={filterItems}
163
166
  filterValues={filterValues}
164
- isSiteItem={!!currentSiteID}
167
+ isSiteItem={!!currentSite}
165
168
  sortItems={sortItems}
166
169
  sortedListStatus={sortedListStatus}
167
170
  />
@@ -193,7 +196,7 @@ const Redirects = (props: IProps): JSX.Element => {
193
196
 
194
197
  const handleAddRedirect = async (force?: boolean) => {
195
198
  const toPage = formValues.to.pageId ? formValues.to.pageId : formValues.to.url;
196
- await addRedirect({ from: formValues.from, to: toPage }, toggleOverwriteModal, force, currentFilterQuery);
199
+ await addRedirect({ from: formValues.from, to: toPage }, toggleOverwriteModal, force, filterQuery);
197
200
  isOpen && toggleModal();
198
201
  };
199
202
 
@@ -270,6 +273,7 @@ const Redirects = (props: IProps): JSX.Element => {
270
273
  searchAction={setSearchQuery}
271
274
  filterSearchAction={setSearchFilter}
272
275
  searchFilters={searchFilters}
276
+ searchValue={searchQuery}
273
277
  >
274
278
  <S.Wrapper>
275
279
  <Nav current={currentNavItem} items={navItems} onClick={handleMenuClick} />
@@ -289,29 +293,42 @@ const Redirects = (props: IProps): JSX.Element => {
289
293
  hasFixedHeader={true}
290
294
  tableRef={tableRef}
291
295
  >
292
- {isEmpty ? (
293
- <S.EmptyWrapper>
294
- <EmptyState {...emptyStateProps} />
295
- </S.EmptyWrapper>
296
- ) : (
297
- redirects.map((redirect: any) => {
298
- const isItemSelected = isSelected(redirect.id);
299
- return (
300
- <RedirectItem
301
- key={redirect.id}
302
- redirect={redirect}
303
- isSelected={isItemSelected}
304
- onChange={addToBulkSelection}
305
- toggleToast={toggleToast}
306
- setFormValues={setFormValues}
307
- formValues={formValues}
308
- addRedirect={handleAddRedirect}
309
- currentFilter={currentFilterQuery}
310
- isSiteItem={!!currentSiteID}
296
+ <>
297
+ <S.SearchTags>
298
+ <SearchTagsBar query={searchQuery} setQuery={setSearchQuery} />
299
+ {!currentSite && (
300
+ <FilterTagsBar
301
+ filters={filterValues}
302
+ setFilters={setFiltersSelection}
303
+ resetFilters={resetFilterQuery}
304
+ labels={{ sites: "Site" }}
311
305
  />
312
- );
313
- })
314
- )}
306
+ )}
307
+ </S.SearchTags>
308
+ {isEmpty ? (
309
+ <S.EmptyWrapper>
310
+ <EmptyState {...emptyStateProps} />
311
+ </S.EmptyWrapper>
312
+ ) : (
313
+ redirects.map((redirect: any) => {
314
+ const isItemSelected = isSelected(redirect.id);
315
+ return (
316
+ <RedirectItem
317
+ key={redirect.id}
318
+ redirect={redirect}
319
+ isSelected={isItemSelected}
320
+ onChange={addToBulkSelection}
321
+ toggleToast={toggleToast}
322
+ setFormValues={setFormValues}
323
+ formValues={formValues}
324
+ addRedirect={handleAddRedirect}
325
+ currentFilter={filterQuery}
326
+ isSiteItem={!!currentSite}
327
+ />
328
+ );
329
+ })
330
+ )}
331
+ </>
315
332
  </TableList>
316
333
  </S.TableWrapper>
317
334
  {isVisible && <Toast {...toastProps} />}
@@ -327,7 +344,7 @@ const Redirects = (props: IProps): JSX.Element => {
327
344
  formValues={formValues}
328
345
  setFormValues={setFormValues}
329
346
  addRedirect={handleAddRedirect}
330
- currentFilter={currentFilterQuery}
347
+ currentFilter={filterQuery}
331
348
  />
332
349
  )}
333
350
  <DeleteModal
@@ -364,7 +381,7 @@ const Redirects = (props: IProps): JSX.Element => {
364
381
  const mapStateToProps = (state: IRootState) => ({
365
382
  redirects: state.redirects.redirects,
366
383
  totalItems: state.redirects.totalItems,
367
- currentSiteID: state.sites.currentSiteInfo && state.sites.currentSiteInfo.id,
384
+ currentSite: state.sites.currentSiteInfo,
368
385
  totalImports: state.redirects.totalImports,
369
386
  imports: state.redirects.imports,
370
387
  isLoading: state.app.isLoading,
@@ -382,7 +399,7 @@ interface IRedirectsProps {
382
399
  currentNavItem: INavItem;
383
400
  redirects: IRedirect[];
384
401
  totalItems: number;
385
- currentSiteID: number | null;
402
+ currentSite: ISite | null;
386
403
  totalImports: number;
387
404
  isLoading: boolean;
388
405
  imports: null | {
@@ -146,6 +146,15 @@ const ModalUrl = styled.div`
146
146
  width: 50%;
147
147
  `;
148
148
 
149
+ const SearchTags = styled.div`
150
+ & > div:nth-child(1) {
151
+ margin-bottom: ${(p) => p.theme.spacing.xs};
152
+ }
153
+ & > div:nth-child(2) {
154
+ margin-bottom: ${(p) => p.theme.spacing.xs};
155
+ }
156
+ `;
157
+
149
158
  export {
150
159
  Wrapper,
151
160
  ContentWrapper,
@@ -170,4 +179,5 @@ export {
170
179
  ModalUrl,
171
180
  ModalIconWrapper,
172
181
  ModalUploadingText,
182
+ SearchTags,
173
183
  };