@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.
- package/package.json +2 -2
- package/src/GlobalStore.tsx +3 -1
- package/src/api/checkgroups.tsx +1 -1
- package/src/api/domains.tsx +26 -0
- package/src/api/index.tsx +3 -1
- package/src/api/sites.tsx +25 -8
- package/src/api/utils.tsx +1 -1
- package/src/components/Browser/index.tsx +8 -3
- package/src/components/ElementsTooltip/index.tsx +23 -8
- package/src/components/ElementsTooltip/style.tsx +4 -5
- package/src/components/ErrorCenter/index.tsx +11 -1
- package/src/components/ErrorCenter/style.tsx +4 -3
- package/src/components/Fields/CheckGroup/index.tsx +5 -4
- package/src/components/Fields/ComponentArray/MixableComponentArray/AddItemButton/index.tsx +1 -0
- package/src/components/Fields/ReferenceField/Context/index.tsx +10 -6
- package/src/components/Fields/ReferenceField/ItemList/Item/index.tsx +2 -2
- package/src/components/Fields/ReferenceField/ItemList/index.tsx +15 -14
- package/src/components/FieldsBehavior/index.tsx +2 -1
- package/src/components/FloatingMenu/index.tsx +3 -1
- package/src/components/FloatingMenu/style.tsx +7 -5
- package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +17 -19
- package/src/components/Gallery/GalleryPanel/DetailPanel/style.tsx +32 -19
- package/src/components/Gallery/style.tsx +1 -1
- package/src/components/Icon/components/Category.js +5 -6
- package/src/components/Icon/components/Refresh.js +12 -0
- package/src/components/Icon/svgs/Category.svg +1 -1
- package/src/components/Icon/svgs/Refresh.svg +3 -0
- package/src/components/Lists/style.tsx +10 -9
- package/src/components/MainWrapper/AppBar/index.tsx +16 -5
- package/src/components/MainWrapper/AppBar/style.tsx +2 -1
- package/src/components/SideModal/index.tsx +10 -4
- package/src/components/TableCounter/style.tsx +1 -4
- package/src/components/TableFilters/CategoryFilter/index.tsx +92 -0
- package/src/{modules/Content/HeaderMenus/Translations → components/TableFilters/CategoryFilter}/style.tsx +4 -3
- package/src/components/TableFilters/CustomizeFilters/index.tsx +52 -0
- package/src/components/TableFilters/CustomizeFilters/style.tsx +28 -0
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Live → components/TableFilters/LiveFilter}/index.tsx +18 -6
- package/src/{modules/Content/HeaderMenus/Live → components/TableFilters/LiveFilter}/style.tsx +0 -0
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Name → components/TableFilters/NameFilter}/index.tsx +18 -9
- package/src/{modules/Content/HeaderMenus/Name → components/TableFilters/NameFilter}/style.tsx +0 -0
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Site → components/TableFilters/SiteFilter}/index.tsx +3 -3
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Site → components/TableFilters/SiteFilter}/style.tsx +1 -1
- package/src/{modules/Content/HeaderMenus/Status → components/TableFilters/StatusFilter}/index.tsx +7 -4
- package/src/{modules/Content/HeaderMenus/Status → components/TableFilters/StatusFilter}/style.tsx +0 -0
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Translations → components/TableFilters/TranslationsFilter}/index.tsx +4 -4
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Translations → components/TableFilters/TranslationsFilter}/style.tsx +0 -0
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Types → components/TableFilters/TypeFilter}/index.tsx +13 -9
- package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Types → components/TableFilters/TypeFilter}/style.tsx +1 -1
- package/src/components/TableFilters/index.tsx +19 -0
- package/src/components/Tag/index.tsx +1 -1
- package/src/components/Tag/style.tsx +10 -11
- package/src/components/index.tsx +19 -0
- package/src/containers/Domains/actions.tsx +51 -0
- package/src/containers/Domains/constants.tsx +5 -0
- package/src/containers/Domains/index.tsx +4 -0
- package/src/containers/Domains/interfaces.tsx +9 -0
- package/src/containers/Domains/reducer.tsx +22 -0
- package/src/containers/Gallery/actions.tsx +0 -1
- package/src/containers/PageEditor/actions.tsx +7 -0
- package/src/containers/PageEditor/utils.tsx +1 -1
- package/src/containers/Settings/Languages/constants.tsx +3 -3
- package/src/containers/Settings/Languages/index.tsx +2 -5
- package/src/containers/Sites/actions.tsx +3 -2
- package/src/containers/StructuredData/actions.tsx +62 -3
- package/src/containers/StructuredData/constants.tsx +4 -0
- package/src/containers/StructuredData/interfaces.tsx +13 -1
- package/src/containers/StructuredData/reducer.tsx +9 -1
- package/src/forms/editor.tsx +4 -0
- package/src/forms/elements.tsx +2 -5
- package/src/forms/index.tsx +2 -1
- package/src/forms/validators.tsx +12 -5
- package/src/helpers/arrays.tsx +12 -1
- package/src/helpers/index.tsx +4 -1
- package/src/helpers/strings.tsx +7 -0
- package/src/hooks/content.tsx +41 -0
- package/src/hooks/index.tsx +3 -1
- package/src/modules/Categories/CategoriesList/CategoryNav/NavItem/style.tsx +9 -9
- package/src/modules/Content/BulkHeader/TableHeader/index.tsx +95 -24
- package/src/modules/Content/BulkHeader/TableHeader/style.tsx +6 -19
- package/src/modules/Content/BulkHeader/index.tsx +16 -0
- package/src/modules/Content/ContentFilters/index.tsx +4 -4
- package/src/modules/Content/OptionTable/style.tsx +1 -1
- package/src/modules/Content/PageItem/atoms.tsx +28 -0
- package/src/modules/Content/PageItem/index.tsx +67 -24
- package/src/modules/Content/PageItem/style.tsx +14 -7
- package/src/modules/Content/hooks.tsx +27 -17
- package/src/modules/Content/index.tsx +53 -6
- package/src/modules/GlobalEditor/index.tsx +5 -11
- package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/index.tsx +61 -0
- package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/style.tsx +30 -0
- package/src/modules/GlobalSettings/Robots/Item/index.tsx +33 -0
- package/src/modules/GlobalSettings/Robots/Item/style.tsx +28 -0
- package/src/modules/GlobalSettings/Robots/index.tsx +120 -0
- package/src/modules/GlobalSettings/Robots/style.tsx +32 -0
- package/src/modules/GlobalSettings/index.tsx +26 -0
- package/src/modules/PageEditor/index.tsx +2 -5
- package/src/modules/Settings/Globals/style.tsx +1 -1
- package/src/modules/StructuredData/Form/ConnectedField/index.tsx +10 -2
- package/src/modules/StructuredData/Form/index.tsx +48 -9
- package/src/modules/StructuredData/Form/style.tsx +3 -6
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +84 -35
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/style.tsx +6 -25
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +10 -1
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/atoms.tsx +24 -3
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +53 -22
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/style.tsx +16 -9
- package/src/modules/StructuredData/StructuredDataList/OptionTable/style.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/hooks.tsx +9 -2
- package/src/modules/StructuredData/StructuredDataList/index.tsx +45 -5
- package/src/routes/multisite.tsx +8 -0
- package/src/types/index.tsx +28 -11
- package/src/modules/Content/HeaderMenus/Live/index.tsx +0 -93
- package/src/modules/Content/HeaderMenus/Name/index.tsx +0 -52
- package/src/modules/Content/HeaderMenus/Translations/index.tsx +0 -62
- package/src/modules/Content/HeaderMenus/Types/index.tsx +0 -73
- package/src/modules/Content/HeaderMenus/Types/style.tsx +0 -34
- package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Live/style.tsx +0 -37
- package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Name/style.tsx +0 -29
- package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Status/index.tsx +0 -47
- package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Status/style.tsx +0 -30
|
@@ -15,7 +15,6 @@ const CheckCell = styled(Cell)`
|
|
|
15
15
|
`;
|
|
16
16
|
|
|
17
17
|
const NameCell = styled(Cell)`
|
|
18
|
-
width: 35%;
|
|
19
18
|
flex-grow: 1;
|
|
20
19
|
svg {
|
|
21
20
|
height: ${(p) => p.theme.spacing.s};
|
|
@@ -35,12 +34,12 @@ const Title = styled.div`
|
|
|
35
34
|
const Slug = styled.div``;
|
|
36
35
|
|
|
37
36
|
const TypeCell = styled(Cell)`
|
|
38
|
-
|
|
37
|
+
flex: 0 0 170px;
|
|
39
38
|
align-items: center;
|
|
40
39
|
`;
|
|
41
40
|
|
|
42
41
|
const LiveCell = styled(Cell)`
|
|
43
|
-
|
|
42
|
+
flex: 0 0 80px;
|
|
44
43
|
align-items: center;
|
|
45
44
|
svg {
|
|
46
45
|
width: ${(p) => p.theme.spacing.m};
|
|
@@ -49,7 +48,7 @@ const LiveCell = styled(Cell)`
|
|
|
49
48
|
`;
|
|
50
49
|
|
|
51
50
|
const StatusCell = styled(Cell)`
|
|
52
|
-
|
|
51
|
+
flex: 0 0 170px;
|
|
53
52
|
align-items: center;
|
|
54
53
|
div:nth-child(2) {
|
|
55
54
|
margin-top: ${(p) => p.theme.spacing.xs};
|
|
@@ -58,18 +57,19 @@ const StatusCell = styled(Cell)`
|
|
|
58
57
|
|
|
59
58
|
const TransCell = styled(Cell)`
|
|
60
59
|
${(p) => p.theme.textStyle.uiXS};
|
|
61
|
-
|
|
60
|
+
flex: 0 0 115px;
|
|
62
61
|
position: relative;
|
|
63
62
|
align-items: center;
|
|
64
63
|
`;
|
|
65
64
|
|
|
66
65
|
const SeoCell = styled(Cell)`
|
|
67
66
|
${(p) => p.theme.textStyle.uiXS};
|
|
68
|
-
|
|
67
|
+
flex: 0 0 124px;
|
|
69
68
|
`;
|
|
70
69
|
|
|
71
70
|
const GlobalCell = styled(Cell)`
|
|
72
71
|
width: 24px;
|
|
72
|
+
flex: 0 0 24px;
|
|
73
73
|
`;
|
|
74
74
|
|
|
75
75
|
const Mark = styled.div`
|
|
@@ -89,7 +89,13 @@ const Wrapper = styled.div`
|
|
|
89
89
|
`;
|
|
90
90
|
|
|
91
91
|
const ActionsCell = styled(Cell)`
|
|
92
|
-
|
|
92
|
+
flex: 0 0 100px;
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
const CategoryCell = styled(Cell)`
|
|
96
|
+
flex: 0 0 150px;
|
|
97
|
+
align-items: center;
|
|
98
|
+
position: relative;
|
|
93
99
|
`;
|
|
94
100
|
|
|
95
101
|
const StyledActionMenu = styled(ActionMenu)`
|
|
@@ -191,4 +197,5 @@ export {
|
|
|
191
197
|
ModalContent,
|
|
192
198
|
GlobalCell,
|
|
193
199
|
Mark,
|
|
200
|
+
CategoryCell,
|
|
194
201
|
};
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
|
|
3
3
|
const useSortedListStatus = () => {
|
|
4
|
-
const sortedInitialState: {
|
|
4
|
+
const sortedInitialState: {
|
|
5
|
+
isAscending: boolean;
|
|
6
|
+
sortedByTitle: boolean;
|
|
7
|
+
sortedByURL: boolean;
|
|
8
|
+
sortedByDate: boolean;
|
|
9
|
+
} = {
|
|
5
10
|
isAscending: false,
|
|
6
11
|
sortedByTitle: false,
|
|
7
12
|
sortedByURL: false,
|
|
8
|
-
sortedByDate: false
|
|
13
|
+
sortedByDate: false,
|
|
9
14
|
};
|
|
10
15
|
|
|
11
|
-
const [
|
|
16
|
+
const [sortedListStatus, setSortedListStatus] = useState(sortedInitialState);
|
|
12
17
|
|
|
13
18
|
return {
|
|
14
19
|
sortedListStatus,
|
|
15
|
-
setSortedListStatus
|
|
20
|
+
setSortedListStatus,
|
|
16
21
|
};
|
|
17
22
|
};
|
|
18
23
|
|
|
@@ -20,20 +25,19 @@ const useFilterQuery = () => {
|
|
|
20
25
|
const initialQueryValues = {
|
|
21
26
|
type: "",
|
|
22
27
|
translated: "",
|
|
23
|
-
liveStatus: "",
|
|
24
|
-
order: ""
|
|
28
|
+
liveStatus: "all",
|
|
29
|
+
order: "",
|
|
30
|
+
categories: "all",
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
const [query, setQuery] = useState(initialQueryValues);
|
|
28
34
|
|
|
29
35
|
const setFilterQuery = (filterValues: any) => {
|
|
30
|
-
const { type, translated, liveStatus, order } = filterValues;
|
|
36
|
+
const { type, translated, liveStatus, order, categories } = filterValues;
|
|
31
37
|
let filterQuery = "";
|
|
32
38
|
|
|
33
39
|
const currentQuery = (pointer: string, values: string) => {
|
|
34
|
-
return filterQuery
|
|
35
|
-
? filterQuery.concat(`&${pointer}=${values}`)
|
|
36
|
-
: `?${pointer}=${values}`;
|
|
40
|
+
return filterQuery ? filterQuery.concat(`&${pointer}=${values}`) : `?${pointer}=${values}`;
|
|
37
41
|
};
|
|
38
42
|
|
|
39
43
|
if (type) {
|
|
@@ -52,17 +56,22 @@ const useFilterQuery = () => {
|
|
|
52
56
|
filterQuery = currentQuery("order", order);
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
if (categories) {
|
|
60
|
+
filterQuery = currentQuery("categories", categories);
|
|
61
|
+
}
|
|
62
|
+
|
|
55
63
|
return filterQuery;
|
|
56
64
|
};
|
|
57
65
|
|
|
58
66
|
const setFiltersSelection = (pointer: string, filter: string, isAscendent?: boolean) => {
|
|
59
|
-
const { type, translated, liveStatus, order } = query;
|
|
67
|
+
const { type, translated, liveStatus, order, categories } = query;
|
|
60
68
|
const orderMethod = isAscendent ? "asc" : "desc";
|
|
61
69
|
const filterValues = {
|
|
62
70
|
type: pointer === "type" ? filter : type,
|
|
63
71
|
translated: pointer === "translated" ? filter : translated,
|
|
64
72
|
liveStatus: pointer === "liveStatus" ? filter : liveStatus,
|
|
65
|
-
order: pointer === "order" ? `${filter}-${orderMethod}` : order
|
|
73
|
+
order: pointer === "order" ? `${filter}-${orderMethod}` : order,
|
|
74
|
+
categories: pointer === "categories" ? filter : categories,
|
|
66
75
|
};
|
|
67
76
|
|
|
68
77
|
setQuery(filterValues);
|
|
@@ -70,13 +79,14 @@ const useFilterQuery = () => {
|
|
|
70
79
|
return filterValues;
|
|
71
80
|
};
|
|
72
81
|
|
|
82
|
+
const resetFilterQuery = () => setQuery(initialQueryValues);
|
|
83
|
+
|
|
73
84
|
return {
|
|
74
85
|
setFiltersSelection,
|
|
75
|
-
setFilterQuery
|
|
86
|
+
setFilterQuery,
|
|
87
|
+
resetFilterQuery,
|
|
88
|
+
filterValues: query,
|
|
76
89
|
};
|
|
77
90
|
};
|
|
78
91
|
|
|
79
|
-
export {
|
|
80
|
-
useSortedListStatus,
|
|
81
|
-
useFilterQuery
|
|
82
|
-
};
|
|
92
|
+
export { useSortedListStatus, useFilterQuery };
|
|
@@ -2,7 +2,7 @@ import React, { useEffect, useCallback, useState, useRef } from "react";
|
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
import { useLocation } from "react-router-dom";
|
|
4
4
|
|
|
5
|
-
import { useModal, useBulkSelection, useToast } from "@ax/hooks";
|
|
5
|
+
import { useModal, useBulkSelection, useToast, useCategoryColors } from "@ax/hooks";
|
|
6
6
|
import {
|
|
7
7
|
IRootState,
|
|
8
8
|
IPage,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
IEmptyStateProps,
|
|
13
13
|
ICheck,
|
|
14
14
|
IGetSitePagesParams,
|
|
15
|
+
IColumn,
|
|
15
16
|
} from "@ax/types";
|
|
16
17
|
import { MainWrapper, Modal, TableList, ErrorToast, Toast, EmptyState } from "@ax/components";
|
|
17
18
|
import { getFilteredStructuredData, isStructuredDataFromPage } from "@ax/helpers";
|
|
@@ -87,18 +88,43 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
87
88
|
const { isOpen: isNewOpen, toggleModal: toggleNewModal } = useModal();
|
|
88
89
|
const { isOpen: isImporterOpen, toggleModal: toggleImporterModal } = useModal();
|
|
89
90
|
const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
|
|
90
|
-
const { setFiltersSelection, setFilterQuery } = useFilterQuery();
|
|
91
|
+
const { setFiltersSelection, setFilterQuery, resetFilterQuery, filterValues } = useFilterQuery();
|
|
91
92
|
const { state: locationState } = useLocation<{ isFromEditor: boolean }>();
|
|
92
93
|
|
|
93
94
|
const currentFilter = getCurrentFilter(structuredData, filter);
|
|
94
95
|
const checkFromPage = currentFilter ? currentFilter.fromPage : undefined;
|
|
95
96
|
const isStructuredData = filter !== "unique-pages" && !checkFromPage;
|
|
97
|
+
const isGlobalPages = filter !== "unique-pages" && checkFromPage;
|
|
96
98
|
const isDataEditable = !isStructuredData || (currentStructuredData && currentStructuredData.editable);
|
|
97
99
|
|
|
98
100
|
const pagesIds = currentSitePages && currentSitePages.map((page: any) => page.id);
|
|
99
101
|
const dataIds = currentDataContent && currentDataContent.map((data: any) => data.id);
|
|
100
102
|
const contentIds = isStructuredData ? dataIds : pagesIds;
|
|
101
103
|
|
|
104
|
+
const categoryColumns =
|
|
105
|
+
currentStructuredData && currentStructuredData.schema
|
|
106
|
+
? currentStructuredData.schema.fields.filter((field: any) => field.showList)
|
|
107
|
+
: [];
|
|
108
|
+
|
|
109
|
+
const defaultColumns: Record<string, IColumn> = {
|
|
110
|
+
type: { title: "Types", show: true },
|
|
111
|
+
live: { title: "Live", show: true },
|
|
112
|
+
status: { title: "Status", show: true },
|
|
113
|
+
translation: { title: "Trans.", show: true },
|
|
114
|
+
seo: { title: "SEO", show: true },
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const extraColumns = categoryColumns.reduce((acc: Record<string, IColumn>, cur: any) => {
|
|
118
|
+
acc[cur.key] = { title: cur.title, show: false };
|
|
119
|
+
return acc;
|
|
120
|
+
}, {});
|
|
121
|
+
|
|
122
|
+
const filterColumns = { ...extraColumns, ...defaultColumns };
|
|
123
|
+
|
|
124
|
+
const initialColumns = isGlobalPages ? filterColumns : defaultColumns;
|
|
125
|
+
|
|
126
|
+
const [columnsState, setColumnsState] = useState(initialColumns);
|
|
127
|
+
|
|
102
128
|
const {
|
|
103
129
|
resetBulkSelection,
|
|
104
130
|
selectedItems,
|
|
@@ -132,6 +158,8 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
132
158
|
setIsVisible: setIsVisibleRemovedToast,
|
|
133
159
|
} = useToast();
|
|
134
160
|
|
|
161
|
+
const { categoryColors, addCategoryColors } = useCategoryColors();
|
|
162
|
+
|
|
135
163
|
const getParams = useCallback(() => {
|
|
136
164
|
const siteID = currentSiteInfo ? currentSiteInfo.id : null;
|
|
137
165
|
const params = isStructuredData
|
|
@@ -176,7 +204,7 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
176
204
|
getOrderedSitePages(siteID, fullQuery);
|
|
177
205
|
} else {
|
|
178
206
|
const pageFilter = isStructuredDataPage ? filter : undefined;
|
|
179
|
-
getSitePages(params, pageFilter);
|
|
207
|
+
getSitePages(params, pageFilter, filterQuery);
|
|
180
208
|
}
|
|
181
209
|
};
|
|
182
210
|
|
|
@@ -198,7 +226,12 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
198
226
|
// eslint-disable-next-line
|
|
199
227
|
}, [page, filter, currentFilterQuery, searchQuery]);
|
|
200
228
|
|
|
201
|
-
useEffect(() =>
|
|
229
|
+
useEffect(() => {
|
|
230
|
+
setPage(firstPage);
|
|
231
|
+
const initialColumns = filter !== "unique-pages" ? filterColumns : defaultColumns;
|
|
232
|
+
setColumnsState(initialColumns);
|
|
233
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
234
|
+
}, [filter]);
|
|
202
235
|
|
|
203
236
|
useEffect(() => {
|
|
204
237
|
if (!locationState || locationState.isFromEditor !== true) {
|
|
@@ -342,6 +375,11 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
342
375
|
sortedListStatus={sortedListStatus}
|
|
343
376
|
filterItems={filterItems}
|
|
344
377
|
isEditable={isDataEditable}
|
|
378
|
+
filterValues={filterValues}
|
|
379
|
+
categoryColumns={categoryColumns}
|
|
380
|
+
columns={columnsState}
|
|
381
|
+
setColumns={setColumnsState}
|
|
382
|
+
isGlobalPages={isGlobalPages}
|
|
345
383
|
/>
|
|
346
384
|
);
|
|
347
385
|
|
|
@@ -445,6 +483,10 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
445
483
|
activatedTemplates={activatedTemplates}
|
|
446
484
|
toggleToast={toggleRemovedToast}
|
|
447
485
|
setRemovedPage={setRemovedPage}
|
|
486
|
+
categoryColumns={categoryColumns}
|
|
487
|
+
columns={columnsState}
|
|
488
|
+
categoryColors={categoryColors}
|
|
489
|
+
addCategoryColors={addCategoryColors}
|
|
448
490
|
/>
|
|
449
491
|
);
|
|
450
492
|
});
|
|
@@ -519,6 +561,11 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
519
561
|
? { onClick: handleImport, title: "NEXT" }
|
|
520
562
|
: { onClick: createContent, title: "ADD" };
|
|
521
563
|
|
|
564
|
+
const resetFilter = () => {
|
|
565
|
+
resetFilterQuery();
|
|
566
|
+
setCurrentFilterQuery("");
|
|
567
|
+
};
|
|
568
|
+
|
|
522
569
|
return (
|
|
523
570
|
<MainWrapper
|
|
524
571
|
title={title}
|
|
@@ -529,7 +576,7 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
529
576
|
searchAction={setSearchQuery}
|
|
530
577
|
>
|
|
531
578
|
<S.ContentListWrapper>
|
|
532
|
-
<ContentFilters current={filter} dynamicValues={structuredData} />
|
|
579
|
+
<ContentFilters current={filter} dynamicValues={structuredData} resetFilter={resetFilter} />
|
|
533
580
|
<S.TableWrapper>
|
|
534
581
|
<ErrorToast />
|
|
535
582
|
<TableList
|
|
@@ -599,7 +646,7 @@ interface IDispatchProps {
|
|
|
599
646
|
setCurrentPageStatus(currentPageStatus: string | null): ISetCurrentPageStatusAction;
|
|
600
647
|
setCurrentPageName(currentPageName: string): ISetCurrentPageNameAction;
|
|
601
648
|
addTemplate(template: string): void;
|
|
602
|
-
getSitePages(params: IGetSitePagesParams, structuredData?: string | undefined): Promise<void>;
|
|
649
|
+
getSitePages(params: IGetSitePagesParams, structuredData?: string | undefined, filterQuery?: string): Promise<void>;
|
|
603
650
|
updatePageStatus(ids: number[], status: string, updatePageStatus?: boolean): Promise<boolean>;
|
|
604
651
|
deletePage(params?: ISavePageParams): any;
|
|
605
652
|
setHistoryPush(page: string, isEditor: boolean): any;
|
|
@@ -147,12 +147,8 @@ const GlobalEditor = (props: IProps) => {
|
|
|
147
147
|
|
|
148
148
|
const handlePublishDraft = async () => {
|
|
149
149
|
const { savePage } = props;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (isSaved) {
|
|
153
|
-
resetDirty();
|
|
154
|
-
}
|
|
155
|
-
});
|
|
150
|
+
const isSaved = await savePage(false, null, true);
|
|
151
|
+
if (isSaved) resetDirty();
|
|
156
152
|
};
|
|
157
153
|
|
|
158
154
|
const handleDiscardDraft = async () => {
|
|
@@ -254,11 +250,9 @@ const GlobalEditor = (props: IProps) => {
|
|
|
254
250
|
|
|
255
251
|
const createDraft = isPublished && !hasDraft;
|
|
256
252
|
const status = props.pageStatus === pageStatus.PUBLISHED && !createDraft ? publishPage : undefined;
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
});
|
|
253
|
+
|
|
254
|
+
const isSaved = await savePage(createDraft, status);
|
|
255
|
+
if (isSaved) resetDirty();
|
|
262
256
|
};
|
|
263
257
|
|
|
264
258
|
const goToPages = (path: string) => setRoute(path);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { IDomainRobot } from "@ax/types";
|
|
4
|
+
import { FloatingPanel, Button, FieldsBehavior } from "@ax/components";
|
|
5
|
+
|
|
6
|
+
import * as S from "./style";
|
|
7
|
+
|
|
8
|
+
const RobotsPanel = (props: IProps): JSX.Element => {
|
|
9
|
+
const { isOpen, toggleModal, item, setItemContent } = props;
|
|
10
|
+
|
|
11
|
+
const [value, setValue] = useState(item.content);
|
|
12
|
+
|
|
13
|
+
const editItemAction = () => {
|
|
14
|
+
setItemContent(value);
|
|
15
|
+
toggleModal();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const resetItem = () => setValue("");
|
|
19
|
+
|
|
20
|
+
const title = item.content ? "Update Robots.txt" : "Add Robots.txt";
|
|
21
|
+
|
|
22
|
+
const editButton = {
|
|
23
|
+
label: title,
|
|
24
|
+
action: editItemAction,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const placeholder = "User-agent: * \nDisallow: *";
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<FloatingPanel title={title} toggleModal={toggleModal} isOpen={isOpen}>
|
|
31
|
+
<S.Item>
|
|
32
|
+
<S.ItemHeader>You are editing</S.ItemHeader>
|
|
33
|
+
<S.ItemContent>{item.fullUrl}</S.ItemContent>
|
|
34
|
+
</S.Item>
|
|
35
|
+
<FieldsBehavior
|
|
36
|
+
fieldType="TextArea"
|
|
37
|
+
onChange={setValue}
|
|
38
|
+
value={value}
|
|
39
|
+
title="Robots.txt"
|
|
40
|
+
placeholder={placeholder}
|
|
41
|
+
/>
|
|
42
|
+
<Button buttonStyle="text" type="button" icon="refresh" disabled={!value} onClick={resetItem}>
|
|
43
|
+
Reset to default
|
|
44
|
+
</Button>
|
|
45
|
+
<S.Footer>
|
|
46
|
+
<Button className="button" type="button" onClick={editButton.action}>
|
|
47
|
+
{editButton.label}
|
|
48
|
+
</Button>
|
|
49
|
+
</S.Footer>
|
|
50
|
+
</FloatingPanel>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
interface IProps {
|
|
55
|
+
item: IDomainRobot;
|
|
56
|
+
isOpen: boolean;
|
|
57
|
+
toggleModal(): any;
|
|
58
|
+
setItemContent(content: string): void;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default RobotsPanel;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
|
|
3
|
+
const Item = styled.div`
|
|
4
|
+
background-color: ${(p) => p.theme.color.uiBarBackground};
|
|
5
|
+
padding: ${(p) => p.theme.spacing.s};
|
|
6
|
+
margin-bottom: ${(p) => p.theme.spacing.m};
|
|
7
|
+
border: 1px solid ${(p) => p.theme.color.uiLine};
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
border-radius: ${(p) => p.theme.radii.s};
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
const ItemHeader = styled.div`
|
|
13
|
+
${(p) => p.theme.textStyle.headingXXS};
|
|
14
|
+
color: ${(p) => p.theme.color.textLowEmphasis};
|
|
15
|
+
margin-bottom: ${(p) => p.theme.spacing.xxs};
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
const ItemContent = styled.div`
|
|
19
|
+
${(p) => p.theme.textStyle.fieldContent};
|
|
20
|
+
display: flex;
|
|
21
|
+
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
const Footer = styled.div`
|
|
25
|
+
position: absolute;
|
|
26
|
+
bottom: ${(p) => p.theme.spacing.m};
|
|
27
|
+
right: ${(p) => p.theme.spacing.m};
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
export { Item, ItemHeader, ItemContent, Footer };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { IDomainRobot } from "@ax/types";
|
|
4
|
+
import { useModal } from "@ax/hooks";
|
|
5
|
+
import RobotsPanel from "./RobotsPanel";
|
|
6
|
+
|
|
7
|
+
import * as S from "./style";
|
|
8
|
+
|
|
9
|
+
const Item = (props: IProps): JSX.Element => {
|
|
10
|
+
const { item, setItemContent } = props;
|
|
11
|
+
|
|
12
|
+
const { isOpen, toggleModal } = useModal();
|
|
13
|
+
|
|
14
|
+
const handleClick = () => toggleModal();
|
|
15
|
+
|
|
16
|
+
const buttonText = item.content.trim() !== "" ? "Edit robots.txt" : "Add robots.txt";
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
<S.Component onClick={handleClick}>
|
|
21
|
+
{item.fullUrl} <S.Button>{buttonText}</S.Button>
|
|
22
|
+
</S.Component>
|
|
23
|
+
<RobotsPanel item={item} isOpen={isOpen} toggleModal={toggleModal} setItemContent={setItemContent} />
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
interface IProps {
|
|
29
|
+
item: IDomainRobot;
|
|
30
|
+
setItemContent(content: string): void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default Item;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
|
|
3
|
+
const Component = styled.div`
|
|
4
|
+
${(p) => p.theme.textStyle.fieldLabel};
|
|
5
|
+
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
6
|
+
position: relative;
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
width: 100%;
|
|
10
|
+
height: ${(p) => p.theme.spacing.l};
|
|
11
|
+
background: ${(p) => p.theme.color.uiBackground02};
|
|
12
|
+
border: 1px solid transparent;
|
|
13
|
+
margin-bottom: ${(p) => p.theme.spacing.xs};
|
|
14
|
+
padding: 0 ${(p) => p.theme.spacing.s};
|
|
15
|
+
border-radius: ${(p) => p.theme.radii.s};
|
|
16
|
+
box-shadow: ${(p) => p.theme.shadow.shadowS};
|
|
17
|
+
text-align: left;
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const Button = styled.div`
|
|
22
|
+
${(p) => p.theme.textStyle.uiXS};
|
|
23
|
+
display: flex;
|
|
24
|
+
color: ${(p) => p.theme.color.interactive01};
|
|
25
|
+
margin-left: auto;
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
export { Component, Button };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { connect } from "react-redux";
|
|
3
|
+
|
|
4
|
+
import { IDomainRobot, INavItem, IRootState } from "@ax/types";
|
|
5
|
+
import { appActions } from "@ax/containers/App";
|
|
6
|
+
import { domainsActions } from "@ax/containers/Domains";
|
|
7
|
+
import { MainWrapper, ErrorToast, Nav, Loading } from "@ax/components";
|
|
8
|
+
import { RouteLeavingGuard } from "@ax/guards";
|
|
9
|
+
import { useIsDirty } from "@ax/hooks";
|
|
10
|
+
import Item from "./Item";
|
|
11
|
+
|
|
12
|
+
import * as S from "./style";
|
|
13
|
+
|
|
14
|
+
const Robots = (props: IProps): JSX.Element => {
|
|
15
|
+
const {
|
|
16
|
+
isSaving,
|
|
17
|
+
isLoading,
|
|
18
|
+
navItems,
|
|
19
|
+
currentNavItem,
|
|
20
|
+
robots,
|
|
21
|
+
getDomainsRobots,
|
|
22
|
+
setHistoryPush,
|
|
23
|
+
updateDomainRobots,
|
|
24
|
+
} = props;
|
|
25
|
+
|
|
26
|
+
const [robotItems, setRobotItems] = useState(robots);
|
|
27
|
+
const { isDirty, setIsDirty } = useIsDirty(robotItems);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
getDomainsRobots();
|
|
31
|
+
}, [getDomainsRobots]);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setRobotItems(robots);
|
|
35
|
+
}, [robots]);
|
|
36
|
+
|
|
37
|
+
const handleSave = async () => {
|
|
38
|
+
const isSaved = await updateDomainRobots(robotItems);
|
|
39
|
+
if (isSaved) {
|
|
40
|
+
setIsDirty(false);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const rightButtonProps = {
|
|
45
|
+
label: isSaving ? "Saving" : "Save",
|
|
46
|
+
disabled: isSaving,
|
|
47
|
+
action: () => handleSave(),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handleMenuClick = (path: string) => {
|
|
51
|
+
setHistoryPush(path);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const mapItemList = (items: IDomainRobot[]) =>
|
|
55
|
+
Array.isArray(items) &&
|
|
56
|
+
items.map((item: IDomainRobot, i: number) => {
|
|
57
|
+
const handleSetItem = (newContent: string) => {
|
|
58
|
+
const newItems = [...robotItems];
|
|
59
|
+
newItems[i].content = newContent;
|
|
60
|
+
setRobotItems(newItems);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return <Item key={`${item.path}${i}`} item={item} setItemContent={handleSetItem} />;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const setRoute = (path: string) => setHistoryPush(path);
|
|
67
|
+
const modalText = (
|
|
68
|
+
<>
|
|
69
|
+
Some robots <strong>are not saved</strong>.{" "}
|
|
70
|
+
</>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<>
|
|
75
|
+
<RouteLeavingGuard when={isDirty} action={setRoute} text={modalText} />
|
|
76
|
+
<MainWrapper backLink={false} title="SEO Settings" rightButton={rightButtonProps}>
|
|
77
|
+
<S.Wrapper>
|
|
78
|
+
<Nav current={currentNavItem} items={navItems} onClick={handleMenuClick} />
|
|
79
|
+
<S.ContentWrapper>
|
|
80
|
+
<ErrorToast />
|
|
81
|
+
<S.Title>Robots.txt editor</S.Title>
|
|
82
|
+
<S.Description>
|
|
83
|
+
You can edit your robots.txt files to show search engines which pages on your site to track.
|
|
84
|
+
</S.Description>
|
|
85
|
+
{isLoading ? <Loading /> : <S.Table>{robotItems && mapItemList(robotItems)}</S.Table>}
|
|
86
|
+
</S.ContentWrapper>
|
|
87
|
+
</S.Wrapper>
|
|
88
|
+
</MainWrapper>
|
|
89
|
+
</>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const mapStateToProps = (state: IRootState) => ({
|
|
94
|
+
isSaving: state.app.isSaving,
|
|
95
|
+
isLoading: state.app.isLoading,
|
|
96
|
+
robots: state.domains.robots,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const mapDispatchToProps = {
|
|
100
|
+
setHistoryPush: appActions.setHistoryPush,
|
|
101
|
+
getDomainsRobots: domainsActions.getDomainsRobots,
|
|
102
|
+
updateDomainRobots: domainsActions.updateDomainsRobots,
|
|
103
|
+
};
|
|
104
|
+
interface IRobotsProps {
|
|
105
|
+
isSaving: boolean;
|
|
106
|
+
isLoading: boolean;
|
|
107
|
+
navItems: INavItem[];
|
|
108
|
+
currentNavItem: INavItem;
|
|
109
|
+
robots: IDomainRobot[];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface IDispatchProps {
|
|
113
|
+
getDomainsRobots(): void;
|
|
114
|
+
setHistoryPush(path: string, isEditor?: boolean): void;
|
|
115
|
+
updateDomainRobots(robots: IDomainRobot[]): Promise<boolean>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
type IProps = IRobotsProps & IDispatchProps;
|
|
119
|
+
|
|
120
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Robots);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
|
|
3
|
+
const Wrapper = styled.div`
|
|
4
|
+
display: flex;
|
|
5
|
+
height: 100%;
|
|
6
|
+
`;
|
|
7
|
+
|
|
8
|
+
const ContentWrapper = styled.div`
|
|
9
|
+
display: flex;
|
|
10
|
+
overflow: auto;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
width: 100%;
|
|
13
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
const Table = styled.div`
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
width: 100%;
|
|
20
|
+
margin-top: ${(p) => p.theme.spacing.m};
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const Title = styled.div`
|
|
24
|
+
${(p) => p.theme.textStyle.headingXS};
|
|
25
|
+
margin-bottom: ${(p) => p.theme.spacing.xs};
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
const Description = styled.div`
|
|
29
|
+
${(p) => p.theme.textStyle.uiM};
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
export { Wrapper, ContentWrapper, Table, Title, Description };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Switch, Route } from "react-router-dom";
|
|
3
|
+
|
|
4
|
+
import Robots from "./Robots";
|
|
5
|
+
|
|
6
|
+
const navItems = [
|
|
7
|
+
{
|
|
8
|
+
title: "Robots.txt Editor",
|
|
9
|
+
path: "/settings/robots",
|
|
10
|
+
component: Robots,
|
|
11
|
+
},
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const GlobalSettings = (): JSX.Element => {
|
|
15
|
+
return (
|
|
16
|
+
<Switch>
|
|
17
|
+
{navItems.map((item, index) => (
|
|
18
|
+
<Route exact path={item.path} key={index}>
|
|
19
|
+
{React.createElement(item.component, { navItems, currentNavItem: item }, null)}
|
|
20
|
+
</Route>
|
|
21
|
+
))}
|
|
22
|
+
</Switch>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default GlobalSettings;
|
|
@@ -154,11 +154,8 @@ const PageEditor = (props: IProps) => {
|
|
|
154
154
|
|
|
155
155
|
const handlePublishDraft = async () => {
|
|
156
156
|
const { savePage } = props;
|
|
157
|
-
await savePage(false, null, true)
|
|
158
|
-
|
|
159
|
-
resetDirty();
|
|
160
|
-
}
|
|
161
|
-
});
|
|
157
|
+
const isSaved = await savePage(false, null, true);
|
|
158
|
+
if (isSaved) resetDirty();
|
|
162
159
|
};
|
|
163
160
|
|
|
164
161
|
const handleDiscardDraft = async () => {
|