@griddo/ax 1.58.7 → 1.59.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 (120) hide show
  1. package/package.json +2 -2
  2. package/src/GlobalStore.tsx +3 -1
  3. package/src/api/checkgroups.tsx +1 -1
  4. package/src/api/domains.tsx +26 -0
  5. package/src/api/index.tsx +3 -1
  6. package/src/api/sites.tsx +25 -8
  7. package/src/api/utils.tsx +1 -1
  8. package/src/components/Browser/index.tsx +8 -3
  9. package/src/components/ElementsTooltip/index.tsx +23 -8
  10. package/src/components/ElementsTooltip/style.tsx +4 -5
  11. package/src/components/ErrorCenter/index.tsx +11 -1
  12. package/src/components/ErrorCenter/style.tsx +4 -3
  13. package/src/components/Fields/CheckGroup/index.tsx +5 -4
  14. package/src/components/Fields/ComponentArray/MixableComponentArray/AddItemButton/index.tsx +1 -0
  15. package/src/components/Fields/ReferenceField/Context/index.tsx +10 -6
  16. package/src/components/Fields/ReferenceField/ItemList/Item/index.tsx +2 -2
  17. package/src/components/Fields/ReferenceField/ItemList/index.tsx +15 -14
  18. package/src/components/FieldsBehavior/index.tsx +2 -1
  19. package/src/components/FloatingMenu/index.tsx +3 -1
  20. package/src/components/FloatingMenu/style.tsx +7 -5
  21. package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +17 -19
  22. package/src/components/Gallery/GalleryPanel/DetailPanel/style.tsx +32 -19
  23. package/src/components/Gallery/style.tsx +1 -1
  24. package/src/components/Icon/components/Category.js +5 -6
  25. package/src/components/Icon/components/Refresh.js +12 -0
  26. package/src/components/Icon/svgs/Category.svg +1 -1
  27. package/src/components/Icon/svgs/Refresh.svg +3 -0
  28. package/src/components/Lists/style.tsx +10 -9
  29. package/src/components/MainWrapper/AppBar/index.tsx +16 -5
  30. package/src/components/MainWrapper/AppBar/style.tsx +2 -1
  31. package/src/components/SideModal/index.tsx +10 -4
  32. package/src/components/TableCounter/style.tsx +1 -4
  33. package/src/components/TableFilters/CategoryFilter/index.tsx +92 -0
  34. package/src/{modules/Content/HeaderMenus/Translations → components/TableFilters/CategoryFilter}/style.tsx +4 -3
  35. package/src/components/TableFilters/CustomizeFilters/index.tsx +52 -0
  36. package/src/components/TableFilters/CustomizeFilters/style.tsx +28 -0
  37. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Live → components/TableFilters/LiveFilter}/index.tsx +18 -6
  38. package/src/{modules/Content/HeaderMenus/Live → components/TableFilters/LiveFilter}/style.tsx +0 -0
  39. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Name → components/TableFilters/NameFilter}/index.tsx +18 -9
  40. package/src/{modules/Content/HeaderMenus/Name → components/TableFilters/NameFilter}/style.tsx +0 -0
  41. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Site → components/TableFilters/SiteFilter}/index.tsx +3 -3
  42. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Site → components/TableFilters/SiteFilter}/style.tsx +1 -1
  43. package/src/{modules/Content/HeaderMenus/Status → components/TableFilters/StatusFilter}/index.tsx +7 -4
  44. package/src/{modules/Content/HeaderMenus/Status → components/TableFilters/StatusFilter}/style.tsx +0 -0
  45. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Translations → components/TableFilters/TranslationsFilter}/index.tsx +4 -4
  46. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Translations → components/TableFilters/TranslationsFilter}/style.tsx +0 -0
  47. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Types → components/TableFilters/TypeFilter}/index.tsx +13 -9
  48. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Types → components/TableFilters/TypeFilter}/style.tsx +1 -1
  49. package/src/components/TableFilters/index.tsx +19 -0
  50. package/src/components/Tag/index.tsx +1 -1
  51. package/src/components/Tag/style.tsx +10 -11
  52. package/src/components/index.tsx +19 -0
  53. package/src/containers/Domains/actions.tsx +51 -0
  54. package/src/containers/Domains/constants.tsx +5 -0
  55. package/src/containers/Domains/index.tsx +4 -0
  56. package/src/containers/Domains/interfaces.tsx +9 -0
  57. package/src/containers/Domains/reducer.tsx +22 -0
  58. package/src/containers/Gallery/actions.tsx +0 -1
  59. package/src/containers/PageEditor/actions.tsx +7 -0
  60. package/src/containers/PageEditor/utils.tsx +1 -1
  61. package/src/containers/Settings/Languages/constants.tsx +3 -3
  62. package/src/containers/Settings/Languages/index.tsx +2 -5
  63. package/src/containers/Sites/actions.tsx +3 -2
  64. package/src/containers/StructuredData/actions.tsx +62 -3
  65. package/src/containers/StructuredData/constants.tsx +4 -0
  66. package/src/containers/StructuredData/interfaces.tsx +13 -1
  67. package/src/containers/StructuredData/reducer.tsx +9 -1
  68. package/src/forms/editor.tsx +4 -0
  69. package/src/forms/elements.tsx +2 -5
  70. package/src/forms/index.tsx +2 -1
  71. package/src/forms/validators.tsx +12 -5
  72. package/src/helpers/arrays.tsx +12 -1
  73. package/src/helpers/index.tsx +4 -1
  74. package/src/helpers/strings.tsx +7 -0
  75. package/src/hooks/content.tsx +41 -0
  76. package/src/hooks/index.tsx +3 -1
  77. package/src/modules/Categories/CategoriesList/CategoryNav/NavItem/style.tsx +9 -9
  78. package/src/modules/Content/BulkHeader/TableHeader/index.tsx +95 -24
  79. package/src/modules/Content/BulkHeader/TableHeader/style.tsx +6 -19
  80. package/src/modules/Content/BulkHeader/index.tsx +16 -0
  81. package/src/modules/Content/ContentFilters/index.tsx +4 -4
  82. package/src/modules/Content/OptionTable/style.tsx +1 -1
  83. package/src/modules/Content/PageItem/atoms.tsx +28 -0
  84. package/src/modules/Content/PageItem/index.tsx +67 -24
  85. package/src/modules/Content/PageItem/style.tsx +14 -7
  86. package/src/modules/Content/hooks.tsx +27 -17
  87. package/src/modules/Content/index.tsx +53 -6
  88. package/src/modules/GlobalEditor/index.tsx +5 -11
  89. package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/index.tsx +61 -0
  90. package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/style.tsx +30 -0
  91. package/src/modules/GlobalSettings/Robots/Item/index.tsx +33 -0
  92. package/src/modules/GlobalSettings/Robots/Item/style.tsx +28 -0
  93. package/src/modules/GlobalSettings/Robots/index.tsx +120 -0
  94. package/src/modules/GlobalSettings/Robots/style.tsx +32 -0
  95. package/src/modules/GlobalSettings/index.tsx +26 -0
  96. package/src/modules/PageEditor/index.tsx +2 -5
  97. package/src/modules/Settings/Globals/style.tsx +1 -1
  98. package/src/modules/StructuredData/Form/ConnectedField/index.tsx +10 -2
  99. package/src/modules/StructuredData/Form/index.tsx +48 -9
  100. package/src/modules/StructuredData/Form/style.tsx +3 -6
  101. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +84 -35
  102. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/style.tsx +6 -25
  103. package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +10 -1
  104. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/atoms.tsx +24 -3
  105. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +53 -22
  106. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/style.tsx +16 -9
  107. package/src/modules/StructuredData/StructuredDataList/OptionTable/style.tsx +1 -1
  108. package/src/modules/StructuredData/StructuredDataList/hooks.tsx +9 -2
  109. package/src/modules/StructuredData/StructuredDataList/index.tsx +45 -5
  110. package/src/routes/multisite.tsx +8 -0
  111. package/src/types/index.tsx +28 -11
  112. package/src/modules/Content/HeaderMenus/Live/index.tsx +0 -93
  113. package/src/modules/Content/HeaderMenus/Name/index.tsx +0 -52
  114. package/src/modules/Content/HeaderMenus/Translations/index.tsx +0 -62
  115. package/src/modules/Content/HeaderMenus/Types/index.tsx +0 -73
  116. package/src/modules/Content/HeaderMenus/Types/style.tsx +0 -34
  117. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Live/style.tsx +0 -37
  118. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Name/style.tsx +0 -29
  119. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Status/index.tsx +0 -47
  120. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Status/style.tsx +0 -30
@@ -23,7 +23,7 @@ import {
23
23
  replaceElements,
24
24
  } from "./elements";
25
25
  import { getInnerFields, getStructuredDataInnerFields } from "./fields";
26
- import { getValidity, findMandatoryFieldsErrors } from "./validators";
26
+ import { getValidity, findMandatoryFieldsErrors, findMandatoryStructuredDataErrors } from "./validators";
27
27
 
28
28
  export {
29
29
  parseData,
@@ -50,4 +50,5 @@ export {
50
50
  getParentKey,
51
51
  getValidity,
52
52
  findMandatoryFieldsErrors,
53
+ findMandatoryStructuredDataErrors,
53
54
  };
@@ -141,6 +141,8 @@ const isEmptyField = (value: any, fieldType: string) => {
141
141
  case "ComponentArray":
142
142
  case "ArrayFieldGroup":
143
143
  return !value || !value.length;
144
+ case "ReferenceField":
145
+ return value.fixed && !value.fixed.length;
144
146
  default:
145
147
  return typeof value === "string" && value.trim().length === 0;
146
148
  }
@@ -163,7 +165,7 @@ const getMandatoryFields = (fields: any[]): any[] => {
163
165
  return mandatory;
164
166
  };
165
167
 
166
- const getMandatoryFieldsErrors = (content: any, current: any, name: string, tab: string, template: boolean) => {
168
+ const getMandatoryFieldsErrors = (content: any, current: any, name: string | null, tab: string, template: boolean) => {
167
169
  let mandatoryFields = [];
168
170
  const errors: IErrorItem[] = [];
169
171
 
@@ -184,9 +186,9 @@ const getMandatoryFieldsErrors = (content: any, current: any, name: string, tab:
184
186
  type: "Error",
185
187
  message: "Empty Field",
186
188
  validator: { mandatory: true },
187
- editorID: current.editorID,
188
- component: current.component,
189
- name,
189
+ editorID: current.editorID ? current.editorID : null,
190
+ component: current.component ? current.component : null,
191
+ name: name ? name : field.title,
190
192
  key: field.key,
191
193
  tab,
192
194
  template,
@@ -244,9 +246,14 @@ const findMandatoryFieldsErrors = (content: any): IErrorItem[] => {
244
246
  return errors;
245
247
  };
246
248
 
249
+ const findMandatoryStructuredDataErrors = (content: any, schema: any): IErrorItem[] => {
250
+ const errors: IErrorItem[] = getMandatoryFieldsErrors(schema.fields, content, null, "", false);
251
+ return errors;
252
+ };
253
+
247
254
  interface IError {
248
255
  isValid: boolean;
249
256
  errorCode: string;
250
257
  }
251
258
 
252
- export { getValidity, findMandatoryFieldsErrors };
259
+ export { getValidity, findMandatoryFieldsErrors, findMandatoryStructuredDataErrors };
@@ -1,3 +1,14 @@
1
1
  const isEmptyArray = (arr: any[]) => arr && arr.length === 0;
2
2
 
3
- export { isEmptyArray };
3
+ const moveArrayElement = (element: unknown, arr: unknown[], isPush: boolean): Array<unknown> => {
4
+ const arrCopy = [...arr];
5
+ if (arrCopy.length <= 1) return arrCopy;
6
+ const elementIndex = arrCopy.findIndex((el: unknown) => el === element);
7
+ const newIndex = isPush ? elementIndex + 1 : elementIndex - 1;
8
+ const el = arrCopy[elementIndex];
9
+ arrCopy.splice(elementIndex, 1);
10
+ arrCopy.splice(newIndex, 0, el);
11
+ return arrCopy;
12
+ };
13
+
14
+ export { isEmptyArray, moveArrayElement };
@@ -16,6 +16,7 @@ import {
16
16
  trimText,
17
17
  decodeEntities,
18
18
  isNumber,
19
+ getFileExtension,
19
20
  } from "./strings";
20
21
 
21
22
  import {
@@ -78,7 +79,7 @@ import {
78
79
 
79
80
  import { imageResizeCropAndCompress, compressImage } from "./imageResize";
80
81
 
81
- import { isEmptyArray } from "./arrays";
82
+ import { isEmptyArray, moveArrayElement } from "./arrays";
82
83
 
83
84
  import { getActivatedDataPacksIds, isModuleDisabled } from "./dataPacks";
84
85
 
@@ -146,4 +147,6 @@ export {
146
147
  isStructuredDataFromPage,
147
148
  getGlobalPageTypes,
148
149
  isNumber,
150
+ getFileExtension,
151
+ moveArrayElement,
149
152
  };
@@ -75,6 +75,12 @@ const decodeEntities = (() => {
75
75
 
76
76
  const isNumber = (value: string): boolean => !isNaN(parseInt(value));
77
77
 
78
+ const getFileExtension = (fileName: string): string | null => {
79
+ const re = /\.[0-9a-z]+$/i;
80
+ const extension = fileName.match(re);
81
+ return extension && extension[0].slice(1);
82
+ };
83
+
78
84
  export {
79
85
  filterImageText,
80
86
  splitCamelCase,
@@ -86,4 +92,5 @@ export {
86
92
  trimText,
87
93
  decodeEntities,
88
94
  isNumber,
95
+ getFileExtension,
89
96
  };
@@ -0,0 +1,41 @@
1
+ import { useState } from "react";
2
+
3
+ const useCategoryColors = (): any => {
4
+ const fixedColors = [
5
+ "#FFE695",
6
+ "#C1F0FF",
7
+ "#C3FFC1",
8
+ "#DDBCFE",
9
+ "#FDCBF2",
10
+ "#FFB8B8",
11
+ "#9CF3D4",
12
+ "#E3CDB8",
13
+ "#CCDA76",
14
+ "#DBDDE9",
15
+ ];
16
+
17
+ const colors = [...fixedColors];
18
+ const [categoryColors, setCategoryColors] = useState({});
19
+
20
+ const getColor = () => {
21
+ return "hsl(" + 360 * Math.random() + "," + (25 + 70 * Math.random()) + "%," + (85 + 10 * Math.random()) + "%)";
22
+ };
23
+
24
+ const addCategoryColors = (cats: string[]) => {
25
+ cats &&
26
+ cats.forEach((cat: string) => {
27
+ const founded = Object.keys(categoryColors).find((catID: string) => cat === catID);
28
+ if (!founded) {
29
+ const color = colors.length ? colors.shift() : getColor();
30
+ setCategoryColors({ ...categoryColors, [cat]: color });
31
+ }
32
+ });
33
+ };
34
+
35
+ return {
36
+ categoryColors,
37
+ addCategoryColors,
38
+ };
39
+ };
40
+
41
+ export { useCategoryColors };
@@ -2,6 +2,7 @@ import { useBulkSelection } from "./bulk";
2
2
  import { useDebounce, useEqualStructured, useEqualValue, useIsDirty, usePrevious } from "./forms";
3
3
  import { useHandleClickOutside, useModal, useToast } from "./modals";
4
4
  import { useURLSearchParam } from "./location";
5
+ import { useCategoryColors } from "./content";
5
6
 
6
7
  export {
7
8
  useModal,
@@ -13,5 +14,6 @@ export {
13
14
  useIsDirty,
14
15
  useToast,
15
16
  useBulkSelection,
16
- useURLSearchParam
17
+ useURLSearchParam,
18
+ useCategoryColors,
17
19
  };
@@ -1,12 +1,12 @@
1
1
  import styled from "styled-components";
2
2
 
3
- const NavItemWrapper = styled.li`
3
+ const NavItemWrapper = styled.div`
4
4
  margin-bottom: ${(p) => p.theme.spacing.s};
5
5
  `;
6
6
 
7
7
  const NavLink = styled.div`
8
8
  display: flex;
9
- border-bottom: 1px solid ${p => p.theme.color.uiLine};
9
+ border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
10
10
  margin-bottom: ${(p) => p.theme.spacing.xxs};
11
11
  align-items: center;
12
12
  padding-bottom: ${(p) => p.theme.spacing.xs};
@@ -14,8 +14,8 @@ const NavLink = styled.div`
14
14
  `;
15
15
 
16
16
  const Title = styled.div`
17
- ${p => p.theme.textStyle.headingXXS};
18
- color: ${p => p.theme.color.textMediumEmphasis};
17
+ ${(p) => p.theme.textStyle.headingXXS};
18
+ color: ${(p) => p.theme.color.textMediumEmphasis};
19
19
  `;
20
20
 
21
21
  const Arrow = styled.div`
@@ -24,15 +24,15 @@ const Arrow = styled.div`
24
24
  width: ${(p) => p.theme.spacing.m};
25
25
  `;
26
26
 
27
- const Dropdown = styled.ul<{isOpen: boolean}>`
28
- display: ${(p) => p.isOpen ? "flex" : "none"};
29
- transition: all .5s ease-in-out;
30
- opacity: ${(p) => p.isOpen ? "1" : "0"};
27
+ const Dropdown = styled.ul<{ isOpen: boolean }>`
28
+ display: ${(p) => (p.isOpen ? "flex" : "none")};
29
+ transition: all 0.5s ease-in-out;
30
+ opacity: ${(p) => (p.isOpen ? "1" : "0")};
31
31
  flex-direction: column;
32
32
  `;
33
33
 
34
34
  const Link = styled.div<{ active: boolean }>`
35
- color: ${p => p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis};
35
+ color: ${(p) => (p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis)};
36
36
  `;
37
37
 
38
38
  export { NavItemWrapper, NavLink, Title, Arrow, Dropdown, Link };
@@ -1,15 +1,21 @@
1
1
  import React from "react";
2
2
 
3
- import { CheckField, TableCounter } from "@ax/components";
4
- import Name from "../../HeaderMenus/Name";
5
- import Status from "../../HeaderMenus/Status";
6
- import Types from "../../HeaderMenus/Types";
7
- import Translations from "../../HeaderMenus/Translations";
8
- import Live from "../../HeaderMenus/Live";
3
+ import {
4
+ CheckField,
5
+ TableCounter,
6
+ CustomizeFilters,
7
+ CategoryFilter,
8
+ NameFilter,
9
+ TypeFilter,
10
+ StatusFilter,
11
+ LiveFilter,
12
+ TranslationsFilter,
13
+ } from "@ax/components";
14
+ import { IColumn } from "@ax/types";
9
15
 
10
16
  import * as S from "./style";
11
17
 
12
- const TableHeader = (props: any): JSX.Element => {
18
+ const TableHeader = (props: IProps): JSX.Element => {
13
19
  const {
14
20
  isScrolling,
15
21
  isStructuredData,
@@ -19,8 +25,44 @@ const TableHeader = (props: any): JSX.Element => {
19
25
  filterItems,
20
26
  sortedListStatus,
21
27
  totalItems,
28
+ categoryColumns,
29
+ columns,
30
+ setColumns,
31
+ isGlobalPages,
32
+ filterValues,
22
33
  } = props;
23
34
 
35
+ const activeColumns = Object.keys(columns).filter((col: string) => columns[col].show);
36
+
37
+ const CategoryColumns =
38
+ isGlobalPages &&
39
+ categoryColumns.map(
40
+ (col: any) =>
41
+ activeColumns.includes(col.key) && (
42
+ <S.HeaderWrapper key={col.key}>
43
+ <CategoryFilter filterItems={filterItems} structuredData={col} value={filterValues.categories} />
44
+ </S.HeaderWrapper>
45
+ )
46
+ );
47
+
48
+ const typeFilters = [
49
+ {
50
+ name: "all",
51
+ value: "all",
52
+ title: "All content",
53
+ },
54
+ {
55
+ name: "unique",
56
+ value: "unique",
57
+ title: "Basic templates",
58
+ },
59
+ {
60
+ name: "structuredData",
61
+ value: "structuredData",
62
+ title: "Content types",
63
+ },
64
+ ];
65
+
24
66
  return (
25
67
  <S.TableHeader isScrolling={isScrolling}>
26
68
  <S.CheckHeader>
@@ -40,33 +82,62 @@ const TableHeader = (props: any): JSX.Element => {
40
82
  <S.LiveHeader>Live</S.LiveHeader>
41
83
  <S.StatusHeader>Status</S.StatusHeader>
42
84
  <S.TransHeader>Translations</S.TransHeader>
85
+ <S.ActionsHeader>
86
+ <TableCounter totalItems={totalItems} />
87
+ </S.ActionsHeader>
43
88
  </>
44
89
  ) : (
45
90
  <>
46
91
  <S.NameWrapper>
47
- <Name sortItems={sortItems} sortedState={sortedListStatus} />
92
+ <NameFilter sortItems={sortItems} sortedState={sortedListStatus} />
48
93
  </S.NameWrapper>
49
- <S.TypesWrapper>
50
- <Types filterItems={filterItems} />
51
- </S.TypesWrapper>
52
- <S.LiveWrapper>
53
- <Live filterItems={filterItems} />
54
- </S.LiveWrapper>
55
- <S.StatusWrapper>
56
- <Status sortItems={sortItems} sortedState={sortedListStatus} />
57
- </S.StatusWrapper>
58
- <S.TranslationsWrapper>
59
- <Translations filterItems={filterItems} />
60
- </S.TranslationsWrapper>
61
- <S.SeoHeader>SEO</S.SeoHeader>
94
+ {CategoryColumns}
95
+ {activeColumns.includes("type") && (
96
+ <S.HeaderWrapper>
97
+ <TypeFilter filterItems={filterItems} filters={typeFilters} pointer="type" />
98
+ </S.HeaderWrapper>
99
+ )}
100
+ {activeColumns.includes("live") && (
101
+ <S.HeaderWrapper>
102
+ <LiveFilter filterItems={filterItems} value={filterValues.liveStatus} />
103
+ </S.HeaderWrapper>
104
+ )}
105
+ {activeColumns.includes("status") && (
106
+ <S.HeaderWrapper>
107
+ <StatusFilter sortItems={sortItems} sortedState={sortedListStatus} />
108
+ </S.HeaderWrapper>
109
+ )}
110
+ {activeColumns.includes("translation") && (
111
+ <S.HeaderWrapper>
112
+ <TranslationsFilter filterItems={filterItems} value={filterValues.translated} />
113
+ </S.HeaderWrapper>
114
+ )}
115
+ {activeColumns.includes("seo") && <S.SeoHeader>SEO</S.SeoHeader>}
62
116
  <S.GlobalMark />
117
+ <S.ActionsHeader>
118
+ <TableCounter totalItems={totalItems} />
119
+ <CustomizeFilters columns={columns} setColumns={setColumns} value={activeColumns} />
120
+ </S.ActionsHeader>
63
121
  </>
64
122
  )}
65
- <S.ActionsHeader>
66
- <TableCounter totalItems={totalItems} />
67
- </S.ActionsHeader>
68
123
  </S.TableHeader>
69
124
  );
70
125
  };
71
126
 
127
+ interface IProps {
128
+ isScrolling: boolean;
129
+ isStructuredData: boolean;
130
+ totalItems: number;
131
+ selectAllItems: () => void;
132
+ checkState: Record<string, boolean>;
133
+ sortItems: (orderPointer: string, isAscending: boolean) => void;
134
+ filterItems: (filterPointer: string, filtersSelected: string) => void;
135
+ sortedListStatus: { isAscending: boolean; sortedByDate: boolean; sortedByTitle: boolean; sortedByURL: boolean };
136
+ categoryColumns: any[];
137
+ columns: Record<string, IColumn>;
138
+ setColumns: (columns: Record<string, IColumn>) => void;
139
+ isGlobalPages: boolean;
140
+ filterValues: any;
141
+ }
142
+
72
143
  export default TableHeader;
@@ -48,32 +48,22 @@ const SeoHeader = styled(Header)`
48
48
 
49
49
  const GlobalMark = styled(Header)`
50
50
  width: 24px;
51
+ flex: 0 0 24px;
51
52
  `;
52
53
 
53
54
  const ActionsHeader = styled(Header)`
54
- width: 92px;
55
+ width: 100px;
55
56
  padding-right: 0;
57
+ justify-content: flex-end;
58
+ align-items: center;
56
59
  `;
57
60
 
58
61
  const NameWrapper = styled.div`
59
- width: 40%;
60
62
  flex-grow: 1;
61
63
  position: relative;
62
64
  `;
63
65
 
64
- const TypesWrapper = styled.div`
65
- position: relative;
66
- `;
67
-
68
- const LiveWrapper = styled.div`
69
- position: relative;
70
- `;
71
-
72
- const StatusWrapper = styled.div`
73
- position: relative;
74
- `;
75
-
76
- const TranslationsWrapper = styled.div`
66
+ const HeaderWrapper = styled.div`
77
67
  position: relative;
78
68
  `;
79
69
 
@@ -87,9 +77,6 @@ export {
87
77
  SeoHeader,
88
78
  ActionsHeader,
89
79
  NameWrapper,
90
- LiveWrapper,
91
- TypesWrapper,
92
- StatusWrapper,
93
- TranslationsWrapper,
80
+ HeaderWrapper,
94
81
  GlobalMark,
95
82
  };
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { BulkSelectionOptions } from "@ax/components";
3
+ import { IColumn } from "@ax/types";
3
4
  import TableHeader from "./TableHeader";
4
5
 
5
6
  const BulkHeader = (props: IProps): JSX.Element => {
@@ -18,6 +19,11 @@ const BulkHeader = (props: IProps): JSX.Element => {
18
19
  filterItems,
19
20
  sortedListStatus,
20
21
  isEditable,
22
+ filterValues,
23
+ categoryColumns,
24
+ columns,
25
+ setColumns,
26
+ isGlobalPages,
21
27
  } = props;
22
28
 
23
29
  const deleteAction = {
@@ -59,6 +65,11 @@ const BulkHeader = (props: IProps): JSX.Element => {
59
65
  filterItems={filterItems}
60
66
  sortedListStatus={sortedListStatus}
61
67
  totalItems={totalItems}
68
+ filterValues={filterValues}
69
+ categoryColumns={categoryColumns}
70
+ columns={columns}
71
+ setColumns={setColumns}
72
+ isGlobalPages={isGlobalPages}
62
73
  />
63
74
  );
64
75
  };
@@ -78,6 +89,11 @@ interface IProps {
78
89
  filterItems: (filterPointer: string, filtersSelected: string) => void;
79
90
  sortedListStatus: any;
80
91
  isEditable?: boolean | null;
92
+ filterValues: any;
93
+ categoryColumns: any[];
94
+ columns: Record<string, IColumn>;
95
+ setColumns: (columns: Record<string, IColumn>) => void;
96
+ isGlobalPages: boolean;
81
97
  }
82
98
 
83
99
  export default BulkHeader;
@@ -15,7 +15,7 @@ import { getFilters } from "./utils";
15
15
  import * as S from "./style";
16
16
 
17
17
  const ContentFilters = (props: IProps): JSX.Element => {
18
- const { setContentFilter, current, dynamicValues, addTemplate, setSelectedStructuredData } = props;
18
+ const { setContentFilter, current, dynamicValues, addTemplate, setSelectedStructuredData, resetFilter } = props;
19
19
  const clonedStructure = deepClone(filterStructure);
20
20
  const filters = getFilters(clonedStructure, dynamicValues);
21
21
 
@@ -32,6 +32,7 @@ const ContentFilters = (props: IProps): JSX.Element => {
32
32
  const hasTemplate = fromPage && firstTemplate;
33
33
 
34
34
  const handleClick = () => {
35
+ resetFilter();
35
36
  setContentFilter(value);
36
37
  setSelectedStructuredData(value, "site");
37
38
  if (hasTemplate) {
@@ -47,9 +48,7 @@ const ContentFilters = (props: IProps): JSX.Element => {
47
48
  return (
48
49
  <MenuItem key={filterKey} onClick={handleClick}>
49
50
  <NavLink to="#" className={selectedClass}>
50
- <S.Link active={isSelected}>
51
- {name}
52
- </S.Link>
51
+ <S.Link active={isSelected}>{name}</S.Link>
53
52
  </NavLink>
54
53
  </MenuItem>
55
54
  );
@@ -67,6 +66,7 @@ interface IProps {
67
66
  addTemplate(template: string): void;
68
67
  dynamicValues: any;
69
68
  setSelectedStructuredData(id: string, scope: string): void;
69
+ resetFilter(): void;
70
70
  }
71
71
 
72
72
  const mapDispatchToProps = {
@@ -43,7 +43,7 @@ export const ThumbnailWrapper = styled.div`
43
43
  export const Thumbnail = styled.div<{backgroundUrl: string | boolean}>`
44
44
  background: ${p => p.backgroundUrl ? `url(${p.backgroundUrl}) no-repeat` : ""};
45
45
  background-size: cover;
46
- background-position: center;
46
+ background-position: top;
47
47
  border-radius: 4px;
48
48
  min-width: calc(${p => p.theme.spacing.l} * 3);
49
49
  height: 100%;
@@ -0,0 +1,28 @@
1
+ import React, { useEffect } from "react";
2
+
3
+ import { ElementsTooltip } from "@ax/components";
4
+
5
+ import * as S from "./style";
6
+
7
+ const CategoryCell = (props: ICategoryCellProps): JSX.Element => {
8
+ const { categories, categoryColors, addCategoryColors } = props;
9
+
10
+ useEffect(() => {
11
+ addCategoryColors(categories);
12
+ // eslint-disable-next-line react-hooks/exhaustive-deps
13
+ }, [categories]);
14
+
15
+ return (
16
+ <S.CategoryCell>
17
+ <ElementsTooltip elements={categories} colors={categoryColors} maxChar={30} rounded={true} />
18
+ </S.CategoryCell>
19
+ );
20
+ };
21
+
22
+ interface ICategoryCellProps {
23
+ categories: any;
24
+ categoryColors: any;
25
+ addCategoryColors(cats: string[]): void;
26
+ }
27
+
28
+ export { CategoryCell };
@@ -2,7 +2,7 @@ import React, { memo, useState } from "react";
2
2
 
3
3
  import { useModal } from "@ax/hooks";
4
4
  import { getHumanLastModifiedDate, getTemplateDisplayName, slugify } from "@ax/helpers";
5
- import { IPage, ISite, ISavePageParams, ICheck } from "@ax/types";
5
+ import { IPage, ISite, ISavePageParams, ICheck, IColumn } from "@ax/types";
6
6
  import { pageStatus, ISetCurrentPageIDAction } from "@ax/containers/PageEditor/interfaces";
7
7
 
8
8
  import {
@@ -17,10 +17,22 @@ import {
17
17
  Tooltip,
18
18
  } from "@ax/components";
19
19
 
20
+ import { CategoryCell } from "./atoms";
21
+
20
22
  import * as S from "./style";
21
23
 
22
24
  const PageItem = (props: IPageItemProps): JSX.Element => {
23
- const { functions, item, activatedTemplates, toggleToast, setRemovedPage } = props;
25
+ const {
26
+ functions,
27
+ item,
28
+ activatedTemplates,
29
+ toggleToast,
30
+ setRemovedPage,
31
+ columns,
32
+ categoryColumns,
33
+ categoryColors,
34
+ addCategoryColors,
35
+ } = props;
24
36
  const { isSelected, siteLanguages, page, lang } = item;
25
37
  const {
26
38
  onClick,
@@ -45,6 +57,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
45
57
  const { isOpen: isUnpublishOpen, toggleModal: toggleUnpublishModal } = useModal();
46
58
 
47
59
  const isGlobal = origin === "GLOBAL";
60
+ const activeColumns = Object.keys(columns).filter((col: string) => columns[col].show);
48
61
 
49
62
  const publishedTooltip: any = {
50
63
  active: "Live",
@@ -356,6 +369,23 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
356
369
 
357
370
  const mainUnpublishAction = { title: "Ok", onClick: toggleUnpublishModal };
358
371
 
372
+ const CategoryColumns =
373
+ isGlobal &&
374
+ categoryColumns.map((col: any) => {
375
+ const type = page.template[col.from];
376
+ const categories = type && type.map((cat: any) => cat.title);
377
+ return (
378
+ activeColumns.includes(col.key) && (
379
+ <CategoryCell
380
+ key={col.key}
381
+ categories={categories}
382
+ categoryColors={categoryColors}
383
+ addCategoryColors={addCategoryColors}
384
+ />
385
+ )
386
+ );
387
+ });
388
+
359
389
  return (
360
390
  <>
361
391
  <S.PageRow role="rowgroup" selected={isSelected} global={isGlobal}>
@@ -369,28 +399,37 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
369
399
  </S.Title>
370
400
  <S.Slug>{fullPath.page}</S.Slug>
371
401
  </S.NameCell>
372
- <S.TypeCell role="cell" onClick={goToPage}>
373
- {displayName}
374
- </S.TypeCell>
375
- <S.LiveCell role="cell" onClick={goToPage}>
376
- <Tooltip content={publishedTooltip[getLiveStatus()]}>
377
- <Icon name={getLiveStatus()} />
378
- </Tooltip>
379
- </S.LiveCell>
380
- <S.StatusCell role="cell" onClick={goToPage}>
381
- {checkWorkflowStatus()}
382
- <S.ModDate>{`Mod. ${getHumanLastModifiedDate(page.modified)}`}</S.ModDate>
383
- </S.StatusCell>
384
- <S.TransCell role="cell">
385
- <FloatingMenu Button={FlagsButton}>
386
- {languageMenu()}
387
- </FloatingMenu>
388
- </S.TransCell>
389
- <S.SeoCell role="cell">
390
- <SeoItems.Index />
391
- {SeoTitleMenu()}
392
- {SeoDescriptionMenu()}
393
- </S.SeoCell>
402
+ {CategoryColumns}
403
+ {activeColumns.includes("type") && (
404
+ <S.TypeCell role="cell" onClick={goToPage}>
405
+ {displayName}
406
+ </S.TypeCell>
407
+ )}
408
+ {activeColumns.includes("live") && (
409
+ <S.LiveCell role="cell" onClick={goToPage}>
410
+ <Tooltip content={publishedTooltip[getLiveStatus()]}>
411
+ <Icon name={getLiveStatus()} />
412
+ </Tooltip>
413
+ </S.LiveCell>
414
+ )}
415
+ {activeColumns.includes("status") && (
416
+ <S.StatusCell role="cell" onClick={goToPage}>
417
+ {checkWorkflowStatus()}
418
+ <S.ModDate>{`Mod. ${getHumanLastModifiedDate(page.modified)}`}</S.ModDate>
419
+ </S.StatusCell>
420
+ )}
421
+ {activeColumns.includes("translation") && (
422
+ <S.TransCell role="cell">
423
+ <FloatingMenu Button={FlagsButton}>{languageMenu()}</FloatingMenu>
424
+ </S.TransCell>
425
+ )}
426
+ {activeColumns.includes("seo") && (
427
+ <S.SeoCell role="cell">
428
+ <SeoItems.Index />
429
+ {SeoTitleMenu()}
430
+ {SeoDescriptionMenu()}
431
+ </S.SeoCell>
432
+ )}
394
433
  <S.GlobalCell>{isGlobal && <GlobalMark />}</S.GlobalCell>
395
434
  <S.ActionsCell role="cell">
396
435
  <S.StyledActionMenu icon="more" options={menuOptions} tooltip="Page actions" />
@@ -499,6 +538,10 @@ interface IPageItemProps {
499
538
  activatedTemplates: any[];
500
539
  toggleToast(): void;
501
540
  setRemovedPage(pageID: number): void;
541
+ categoryColumns: any[];
542
+ columns: Record<string, IColumn>;
543
+ categoryColors: any;
544
+ addCategoryColors(cats: string[]): void;
502
545
  }
503
546
 
504
547
  export default memo(PageItem);