@griddo/ax 1.59.8 → 1.60.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/config/webpackSchemas.config.js +7 -0
- package/package.json +3 -2
- package/src/GlobalStore.tsx +3 -0
- package/src/api/index.tsx +2 -0
- package/src/api/redirects.tsx +71 -0
- package/src/api/sites.tsx +11 -25
- package/src/components/Fields/ReferenceField/Context/index.tsx +1 -1
- package/src/components/Fields/ReferenceField/ManualPanel/Item/index.tsx +4 -3
- package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +4 -2
- package/src/components/Fields/ReferenceField/index.tsx +2 -2
- package/src/components/Fields/TextArea/index.tsx +3 -1
- package/src/components/Fields/TextArea/style.tsx +11 -11
- package/src/components/FloatingPanel/style.tsx +7 -2
- package/src/components/TableFilters/SiteFilter/index.tsx +7 -6
- package/src/components/TableFilters/SiteFilter/style.tsx +2 -2
- package/src/containers/Redirects/actions.tsx +129 -0
- package/src/containers/Redirects/constants.tsx +18 -0
- package/src/containers/Redirects/index.tsx +4 -0
- package/src/containers/Redirects/interfaces.tsx +13 -0
- package/src/containers/Redirects/reducer.tsx +24 -0
- package/src/containers/Settings/DataPacks/constants.tsx +11 -11
- package/src/containers/Sites/actions.tsx +1 -25
- package/src/helpers/environment.tsx +5 -0
- package/src/helpers/index.tsx +3 -0
- package/src/helpers/thumbnails.tsx +3 -3
- package/src/modules/Content/PageItem/index.tsx +5 -8
- package/src/modules/Content/index.tsx +25 -35
- package/src/modules/GlobalSettings/Robots/Item/index.tsx +1 -1
- package/src/modules/GlobalSettings/Robots/index.tsx +5 -2
- package/src/modules/GlobalSettings/index.tsx +6 -0
- package/src/modules/Redirects/BulkHeader/TableHeader/index.tsx +44 -0
- package/src/modules/Redirects/BulkHeader/TableHeader/style.tsx +31 -0
- package/src/modules/Redirects/BulkHeader/index.tsx +59 -0
- package/src/modules/Redirects/RedirectItem/index.tsx +139 -0
- package/src/modules/Redirects/RedirectItem/style.tsx +50 -0
- package/src/modules/Redirects/RedirectPanel/index.tsx +117 -0
- package/src/modules/Redirects/RedirectPanel/style.tsx +13 -0
- package/src/modules/Redirects/index.tsx +310 -0
- package/src/modules/Redirects/style.tsx +52 -0
- package/src/modules/Settings/SeoSettings/index.tsx +25 -0
- package/src/modules/Sites/SitesList/SiteItem/index.tsx +6 -2
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +3 -3
- package/src/modules/StructuredData/StructuredDataList/index.tsx +1 -0
- package/src/modules/StructuredData/StructuredDataList/utils.tsx +1 -1
- package/src/routes/multisite.tsx +6 -0
- package/src/routes/site.tsx +6 -0
- package/src/types/index.tsx +13 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
const NAME
|
|
1
|
+
const NAME = "dataPacks";
|
|
2
2
|
|
|
3
|
-
const SET_ACTIVATED
|
|
4
|
-
const SET_SELECTED
|
|
5
|
-
const SET_CONFIG_FORM_DATA
|
|
6
|
-
const SET_AVAILABLE
|
|
7
|
-
const SET_CATEGORIES
|
|
8
|
-
const SET_MODULES
|
|
9
|
-
const SET_TEMPLATES
|
|
3
|
+
const SET_ACTIVATED = `${NAME}/SET_ACTIVATED`;
|
|
4
|
+
const SET_SELECTED = `${NAME}/SET_SELECTED`;
|
|
5
|
+
const SET_CONFIG_FORM_DATA = `${NAME}/SET_CONFIG_FORM_DATA`;
|
|
6
|
+
const SET_AVAILABLE = `${NAME}/SET_AVAILABLE`;
|
|
7
|
+
const SET_CATEGORIES = `${NAME}/SET_CATEGORIES`;
|
|
8
|
+
const SET_MODULES = `${NAME}/SET_MODULES`;
|
|
9
|
+
const SET_TEMPLATES = `${NAME}/SET_TEMPLATES`;
|
|
10
10
|
|
|
11
11
|
// TODO ERROR DICTIONARY
|
|
12
12
|
const ERROR_CODE = {
|
|
13
|
-
isBeingUsed: 409
|
|
14
|
-
}
|
|
13
|
+
isBeingUsed: 409,
|
|
14
|
+
};
|
|
15
15
|
|
|
16
16
|
export {
|
|
17
17
|
SET_ACTIVATED,
|
|
@@ -21,5 +21,5 @@ export {
|
|
|
21
21
|
SET_CATEGORIES,
|
|
22
22
|
SET_MODULES,
|
|
23
23
|
SET_TEMPLATES,
|
|
24
|
-
ERROR_CODE
|
|
24
|
+
ERROR_CODE,
|
|
25
25
|
};
|
|
@@ -112,28 +112,6 @@ function saveSettings(form: ISettingsForm): (dispatch: Dispatch, getState: any)
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function getOrderedSitePages(siteId: number | string, query: string): (dispatch: any) => Promise<void> {
|
|
116
|
-
return async (dispatch) => {
|
|
117
|
-
try {
|
|
118
|
-
dispatch(setIsLoading(true));
|
|
119
|
-
const response: any = await sites.getOrderedSitePages(siteId, query);
|
|
120
|
-
|
|
121
|
-
if (isReqOk(response.status)) {
|
|
122
|
-
const { items, totalItems } = response.data;
|
|
123
|
-
dispatch(setCurrentSitePages(items));
|
|
124
|
-
dispatch(setTotalItems(totalItems));
|
|
125
|
-
dispatch(setIsLoading(false));
|
|
126
|
-
} else {
|
|
127
|
-
console.log("Error en getOrderedSitePages"); // FIXME: capturar errores mejor
|
|
128
|
-
dispatch(setIsLoading(false));
|
|
129
|
-
}
|
|
130
|
-
} catch (e) {
|
|
131
|
-
console.log("error");
|
|
132
|
-
console.log(e); // FIXME: capturar errores
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
115
|
function getGlobalPages(params: IGetGlobalPagesParams, filterQuery: string): (dispatch: any) => Promise<void> {
|
|
138
116
|
return async (dispatch) => {
|
|
139
117
|
try {
|
|
@@ -269,7 +247,7 @@ function getSitePages(
|
|
|
269
247
|
dispatch(setIsLoading(true));
|
|
270
248
|
const response: any = structuredData
|
|
271
249
|
? await sites.getStructuredSitePages(params, structuredData, filterQuery)
|
|
272
|
-
: await sites.getSitePages(params);
|
|
250
|
+
: await sites.getSitePages(params, filterQuery);
|
|
273
251
|
|
|
274
252
|
if (isReqOk(response.status)) {
|
|
275
253
|
const { items, totalItems } = response.data;
|
|
@@ -455,14 +433,12 @@ function removePageFromSite(
|
|
|
455
433
|
}
|
|
456
434
|
|
|
457
435
|
export {
|
|
458
|
-
// setSites,
|
|
459
436
|
setCurrentSiteInfo,
|
|
460
437
|
setCurrentSitePages,
|
|
461
438
|
setFilter,
|
|
462
439
|
setTotalItems,
|
|
463
440
|
setCurrentSiteLanguages,
|
|
464
441
|
getSites,
|
|
465
|
-
getOrderedSitePages,
|
|
466
442
|
setSiteInfo,
|
|
467
443
|
getFilteredContent,
|
|
468
444
|
getSitePages,
|
package/src/helpers/index.tsx
CHANGED
|
@@ -83,6 +83,8 @@ import { isEmptyArray, moveArrayElement } from "./arrays";
|
|
|
83
83
|
|
|
84
84
|
import { getActivatedDataPacksIds, isModuleDisabled } from "./dataPacks";
|
|
85
85
|
|
|
86
|
+
import { isDevelopment } from "./environment";
|
|
87
|
+
|
|
86
88
|
export {
|
|
87
89
|
isComponentEmpty,
|
|
88
90
|
setAsContainedComponent,
|
|
@@ -149,4 +151,5 @@ export {
|
|
|
149
151
|
isNumber,
|
|
150
152
|
getFileExtension,
|
|
151
153
|
moveArrayElement,
|
|
154
|
+
isDevelopment,
|
|
152
155
|
};
|
|
@@ -17,7 +17,7 @@ const getThumbnailProps = (option: any, template: boolean, path?: string) => {
|
|
|
17
17
|
if (path) {
|
|
18
18
|
PATH = `/img/${path}/${option}/thumbnails/`;
|
|
19
19
|
thumbnails["1x"] = imageExists(PATH) ? `${PATH}thumbnail@1x.png` : "/img/placeholder/thumbnail@1x.png";
|
|
20
|
-
thumbnails["2x"] = imageExists(PATH) ? `${PATH}thumbnail@2x.png` : "/img/placeholder/thumbnail@2x.png"
|
|
20
|
+
thumbnails["2x"] = imageExists(PATH) ? `${PATH}thumbnail@2x.png` : "/img/placeholder/thumbnail@2x.png";
|
|
21
21
|
} else {
|
|
22
22
|
if (template) {
|
|
23
23
|
thumbnails = getTemplateThumbnails(option);
|
|
@@ -32,10 +32,10 @@ const getThumbnailProps = (option: any, template: boolean, path?: string) => {
|
|
|
32
32
|
|
|
33
33
|
const fallback = thumbnails["2x"];
|
|
34
34
|
const imgDensity1x = thumbnails["1x"];
|
|
35
|
-
const
|
|
35
|
+
const srcSet = `${imgDensity1x} 1x, ${fallback} 2x`;
|
|
36
36
|
|
|
37
37
|
return {
|
|
38
|
-
|
|
38
|
+
srcSet,
|
|
39
39
|
src: fallback,
|
|
40
40
|
alt: option,
|
|
41
41
|
};
|
|
@@ -47,8 +47,8 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
47
47
|
removePageFromSite,
|
|
48
48
|
} = functions;
|
|
49
49
|
const { locale } = lang;
|
|
50
|
-
const { pageLanguages,
|
|
51
|
-
const displayName = getTemplateDisplayName(
|
|
50
|
+
const { pageLanguages, isHome, fullPath, canBeUnpublished, origin, manuallyImported, templateId, structuredDataContent } = page;
|
|
51
|
+
const displayName = getTemplateDisplayName(templateId);
|
|
52
52
|
|
|
53
53
|
const initValue = { title: "", slug: "" };
|
|
54
54
|
const [modalState, setModalState] = useState(initValue);
|
|
@@ -217,10 +217,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
217
217
|
|
|
218
218
|
const currentLanguages = getCurrentPageLanguages();
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
if (page && page.template) {
|
|
222
|
-
isTemplateActivated = activatedTemplates.find((temp: any) => temp.id === template.templateType) ? true : false;
|
|
223
|
-
}
|
|
220
|
+
const isTemplateActivated = activatedTemplates.some((temp: any) => temp.id === templateId);
|
|
224
221
|
|
|
225
222
|
let availableLanguages = siteLanguages;
|
|
226
223
|
|
|
@@ -372,8 +369,8 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
372
369
|
const CategoryColumns =
|
|
373
370
|
isGlobal &&
|
|
374
371
|
categoryColumns.map((col: any) => {
|
|
375
|
-
const type =
|
|
376
|
-
const categories = type && type.map((cat: any) => cat.title);
|
|
372
|
+
const type = structuredDataContent[col.from];
|
|
373
|
+
const categories = type && type.map((cat: any) => cat.label || cat.title);
|
|
377
374
|
return (
|
|
378
375
|
activeColumns.includes(col.key) && (
|
|
379
376
|
<CategoryCell
|
|
@@ -55,7 +55,6 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
55
55
|
setCurrentPageName,
|
|
56
56
|
addTemplate,
|
|
57
57
|
getSitePages,
|
|
58
|
-
getOrderedSitePages,
|
|
59
58
|
updatePageStatus,
|
|
60
59
|
deletePage,
|
|
61
60
|
setLanguage,
|
|
@@ -162,26 +161,27 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
162
161
|
|
|
163
162
|
const getParams = useCallback(() => {
|
|
164
163
|
const siteID = currentSiteInfo ? currentSiteInfo.id : null;
|
|
165
|
-
const params = isStructuredData
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
: {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
164
|
+
const params = isStructuredData ?
|
|
165
|
+
{
|
|
166
|
+
siteID,
|
|
167
|
+
dataID: typeof filter === "object" ? filter.value : filter,
|
|
168
|
+
page,
|
|
169
|
+
itemsPerPage,
|
|
170
|
+
pagination: true,
|
|
171
|
+
deleted: false,
|
|
172
|
+
include_draft: true,
|
|
173
|
+
query: searchQuery,
|
|
174
|
+
format: "list",
|
|
175
|
+
} : {
|
|
176
|
+
siteID,
|
|
177
|
+
deleted: false,
|
|
178
|
+
page,
|
|
179
|
+
itemsPerPage,
|
|
180
|
+
query: searchQuery,
|
|
181
|
+
format: "list",
|
|
182
|
+
};
|
|
183
183
|
|
|
184
|
-
return
|
|
184
|
+
return params;
|
|
185
185
|
}, [filter, currentSiteInfo, isStructuredData, page, searchQuery]);
|
|
186
186
|
|
|
187
187
|
const bulkFilter = (bulkSelection: number[]) => filterByStatus(bulkSelection, currentSitePages);
|
|
@@ -194,24 +194,16 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
194
194
|
|
|
195
195
|
const selectItems = () => (checkState.isAllSelected ? unselectAllItems() : handleSelectAll());
|
|
196
196
|
|
|
197
|
-
const getPages = (params: any,
|
|
197
|
+
const getPages = (params: any, filterQuery?: any) => {
|
|
198
198
|
const isStructuredDataPage = filter !== "unique-pages";
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const fullQuery = filterQuery.concat(
|
|
202
|
-
`&deleted=${deleted}&page=${page}&itemsPerPage=${itemsPerPage}&query=${query}`
|
|
203
|
-
);
|
|
204
|
-
getOrderedSitePages(siteID, fullQuery);
|
|
205
|
-
} else {
|
|
206
|
-
const pageFilter = isStructuredDataPage ? filter : undefined;
|
|
207
|
-
getSitePages(params, pageFilter, filterQuery);
|
|
208
|
-
}
|
|
199
|
+
const pageFilter = isStructuredDataPage ? filter : undefined;
|
|
200
|
+
getSitePages(params, pageFilter, filterQuery);
|
|
209
201
|
};
|
|
210
202
|
|
|
211
203
|
const getSiteContent = useCallback(
|
|
212
204
|
(filterQuery?: any) => {
|
|
213
|
-
const
|
|
214
|
-
isStructuredData ? getStructuredDataContents(params, siteID) : getPages(params,
|
|
205
|
+
const params = getParams();
|
|
206
|
+
isStructuredData ? getStructuredDataContents(params, params.siteID) : getPages(params, filterQuery);
|
|
215
207
|
},
|
|
216
208
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
217
209
|
[getParams, getSitePages, getStructuredDataContents, currentSiteInfo, isStructuredData, lang]
|
|
@@ -657,7 +649,6 @@ interface IDispatchProps {
|
|
|
657
649
|
resetForm(): void;
|
|
658
650
|
deleteBulk(ids: any): Promise<boolean>;
|
|
659
651
|
duplicatePage(pageID: number, data: any): Promise<void>;
|
|
660
|
-
getOrderedSitePages(siteID: number, query: string): Promise<void>;
|
|
661
652
|
deleteDataContent(dataID: number[]): Promise<boolean>;
|
|
662
653
|
restoreDataContent(catID: number | number[]): void;
|
|
663
654
|
setFilter(value: string): void;
|
|
@@ -670,7 +661,6 @@ interface IDispatchProps {
|
|
|
670
661
|
const mapDispatchToProps = {
|
|
671
662
|
setHistoryPush: appActions.setHistoryPush,
|
|
672
663
|
setLanguage: appActions.setLanguage,
|
|
673
|
-
getOrderedSitePages: sitesActions.getOrderedSitePages,
|
|
674
664
|
getSitePages: sitesActions.getSitePages,
|
|
675
665
|
setCurrentPageID: pageEditorActions.setCurrentPageID,
|
|
676
666
|
setCurrentPageStatus: pageEditorActions.setCurrentPageStatus,
|
|
@@ -13,7 +13,7 @@ const Item = (props: IProps): JSX.Element => {
|
|
|
13
13
|
|
|
14
14
|
const handleClick = () => toggleModal();
|
|
15
15
|
|
|
16
|
-
const buttonText = item.content.trim() !== "" ? "Edit robots.txt" : "Add robots.txt";
|
|
16
|
+
const buttonText = item.content && item.content.trim() !== "" ? "Edit robots.txt" : "Add robots.txt";
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
19
|
<>
|
|
@@ -24,14 +24,17 @@ const Robots = (props: IProps): JSX.Element => {
|
|
|
24
24
|
} = props;
|
|
25
25
|
|
|
26
26
|
const [robotItems, setRobotItems] = useState(robots);
|
|
27
|
-
const { isDirty, setIsDirty } = useIsDirty(robotItems);
|
|
27
|
+
const { isDirty, setIsDirty, resetDirty } = useIsDirty(robotItems);
|
|
28
28
|
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
getDomainsRobots();
|
|
31
|
-
|
|
31
|
+
resetDirty();
|
|
32
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
+
}, []);
|
|
32
34
|
|
|
33
35
|
useEffect(() => {
|
|
34
36
|
setRobotItems(robots);
|
|
37
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35
38
|
}, [robots]);
|
|
36
39
|
|
|
37
40
|
const handleSave = async () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Switch, Route } from "react-router-dom";
|
|
3
3
|
|
|
4
|
+
import Redirects from "../Redirects";
|
|
4
5
|
import Robots from "./Robots";
|
|
5
6
|
|
|
6
7
|
const navItems = [
|
|
@@ -9,6 +10,11 @@ const navItems = [
|
|
|
9
10
|
path: "/settings/robots",
|
|
10
11
|
component: Robots,
|
|
11
12
|
},
|
|
13
|
+
{
|
|
14
|
+
title: "URL Redirect Manager",
|
|
15
|
+
path: "/settings/redirects",
|
|
16
|
+
component: Redirects,
|
|
17
|
+
},
|
|
12
18
|
];
|
|
13
19
|
|
|
14
20
|
const GlobalSettings = (): JSX.Element => {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { CheckField, SiteFilter, TableCounter } from "@ax/components";
|
|
4
|
+
import * as S from "./style";
|
|
5
|
+
|
|
6
|
+
const TableHeader = (props: IProps) => {
|
|
7
|
+
const { totalItems, selectAllItems, isScrolling, filterItems, filterValues, isSiteItem } = props;
|
|
8
|
+
return (
|
|
9
|
+
<S.TableHeader isScrolling={isScrolling}>
|
|
10
|
+
<S.CheckHeader>
|
|
11
|
+
<CheckField
|
|
12
|
+
key="selectAll"
|
|
13
|
+
name="selectAll"
|
|
14
|
+
value="selectAll"
|
|
15
|
+
onChange={selectAllItems}
|
|
16
|
+
checked={false}
|
|
17
|
+
disabled={false}
|
|
18
|
+
error={false}
|
|
19
|
+
/>
|
|
20
|
+
</S.CheckHeader>
|
|
21
|
+
{!isSiteItem && (
|
|
22
|
+
<S.SiteHeader>
|
|
23
|
+
<SiteFilter filterItems={filterItems} value={filterValues} pointer="sites" center={false} />
|
|
24
|
+
</S.SiteHeader>
|
|
25
|
+
)}
|
|
26
|
+
<S.UrlHeader>Old URL</S.UrlHeader>
|
|
27
|
+
<S.UrlHeader>New URL</S.UrlHeader>
|
|
28
|
+
<S.ActionsHeader>
|
|
29
|
+
<TableCounter totalItems={totalItems} />
|
|
30
|
+
</S.ActionsHeader>
|
|
31
|
+
</S.TableHeader>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
interface IProps {
|
|
36
|
+
totalItems: number;
|
|
37
|
+
isScrolling: boolean;
|
|
38
|
+
selectAllItems: () => void;
|
|
39
|
+
filterItems: (filterPointer: string, filtersSelected: string) => void;
|
|
40
|
+
filterValues: any;
|
|
41
|
+
isSiteItem: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default TableHeader;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Header } from "@ax/components/TableList/style";
|
|
3
|
+
|
|
4
|
+
const TableHeader = styled.div<{ isScrolling?: boolean }>`
|
|
5
|
+
width: 100%;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: row;
|
|
8
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
9
|
+
border-bottom: ${(p) => (p.isScrolling ? `1px solid ${p.theme.color.uiLine};` : "")};
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
const CheckHeader = styled(Header)`
|
|
13
|
+
padding-left: ${(p) => p.theme.spacing.m};
|
|
14
|
+
width: 32px;
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
const SiteHeader = styled(Header)`
|
|
18
|
+
width: 270px;
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const UrlHeader = styled(Header)`
|
|
22
|
+
width: 50%;
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const ActionsHeader = styled(Header)`
|
|
26
|
+
width: 125px;
|
|
27
|
+
padding-right: 0;
|
|
28
|
+
justify-content: flex-end;
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
export { TableHeader, CheckHeader, SiteHeader, UrlHeader, ActionsHeader };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { BulkSelectionOptions } from "@ax/components";
|
|
3
|
+
import TableHeader from "./TableHeader";
|
|
4
|
+
|
|
5
|
+
const BulkHeader = (props: IProps): JSX.Element => {
|
|
6
|
+
const {
|
|
7
|
+
showBulk,
|
|
8
|
+
checkState,
|
|
9
|
+
bulkDelete,
|
|
10
|
+
selectItems,
|
|
11
|
+
selectAllItems,
|
|
12
|
+
totalItems,
|
|
13
|
+
isScrolling,
|
|
14
|
+
filterItems,
|
|
15
|
+
filterValues,
|
|
16
|
+
isSiteItem,
|
|
17
|
+
} = props;
|
|
18
|
+
|
|
19
|
+
const bulkActions = [
|
|
20
|
+
{
|
|
21
|
+
icon: "delete",
|
|
22
|
+
text: "delete",
|
|
23
|
+
action: bulkDelete,
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
return showBulk ? (
|
|
28
|
+
<BulkSelectionOptions
|
|
29
|
+
checkState={checkState}
|
|
30
|
+
actions={bulkActions}
|
|
31
|
+
selectItems={selectItems}
|
|
32
|
+
totalItems={totalItems}
|
|
33
|
+
/>
|
|
34
|
+
) : (
|
|
35
|
+
<TableHeader
|
|
36
|
+
totalItems={totalItems}
|
|
37
|
+
selectAllItems={selectAllItems}
|
|
38
|
+
isScrolling={isScrolling}
|
|
39
|
+
filterItems={filterItems}
|
|
40
|
+
filterValues={filterValues}
|
|
41
|
+
isSiteItem={isSiteItem}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
interface IProps {
|
|
47
|
+
showBulk: boolean;
|
|
48
|
+
checkState: any;
|
|
49
|
+
bulkDelete: () => void;
|
|
50
|
+
selectItems: () => void;
|
|
51
|
+
selectAllItems: () => void;
|
|
52
|
+
totalItems: number;
|
|
53
|
+
isScrolling: boolean;
|
|
54
|
+
filterItems: (filterPointer: string, filtersSelected: string) => void;
|
|
55
|
+
filterValues: any;
|
|
56
|
+
isSiteItem: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default BulkHeader;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { connect } from "react-redux";
|
|
3
|
+
|
|
4
|
+
import { useModal } from "@ax/hooks";
|
|
5
|
+
import { ICheck, IRedirect } from "@ax/types";
|
|
6
|
+
import { CheckField, ElementsTooltip, Modal } from "@ax/components";
|
|
7
|
+
import { redirectsActions } from "@ax/containers/Redirects";
|
|
8
|
+
import RedirectPanel from "../RedirectPanel";
|
|
9
|
+
|
|
10
|
+
import * as S from "./style";
|
|
11
|
+
|
|
12
|
+
const RedirectItem = (props: IRedirectItemProps): JSX.Element => {
|
|
13
|
+
const {
|
|
14
|
+
redirect,
|
|
15
|
+
isSelected,
|
|
16
|
+
onChange,
|
|
17
|
+
deleteRedirect,
|
|
18
|
+
toggleToast,
|
|
19
|
+
setFormValues,
|
|
20
|
+
formValues,
|
|
21
|
+
addRedirect,
|
|
22
|
+
currentFilter,
|
|
23
|
+
isSiteItem,
|
|
24
|
+
} = props;
|
|
25
|
+
|
|
26
|
+
const { isOpen, toggleModal } = useModal();
|
|
27
|
+
const [isOpenedSecond, setIsOpenedSecond] = useState(false);
|
|
28
|
+
const { isOpen: isOpenDelete, toggleModal: toggleModalDelete } = useModal();
|
|
29
|
+
|
|
30
|
+
const toggleSecondaryPanel = () => setIsOpenedSecond(!isOpenedSecond);
|
|
31
|
+
|
|
32
|
+
const handleClick = () => {
|
|
33
|
+
const mappedRedirect = { ...redirect, to: { ...redirect.to, linkTo: redirect.to.pageId, href: redirect.to.url } };
|
|
34
|
+
setFormValues(mappedRedirect);
|
|
35
|
+
setIsOpenedSecond(false);
|
|
36
|
+
toggleModal();
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const handleOnChange = (value: ICheck) => onChange(value);
|
|
40
|
+
|
|
41
|
+
const removeItem = async () => {
|
|
42
|
+
if (redirect.id) {
|
|
43
|
+
const deleted = await deleteRedirect(redirect.id, currentFilter);
|
|
44
|
+
if (deleted) {
|
|
45
|
+
toggleToast();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const menuOptions = [
|
|
51
|
+
{
|
|
52
|
+
label: "delete",
|
|
53
|
+
icon: "delete",
|
|
54
|
+
action: toggleModalDelete,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
const mainDeleteModalAction = {
|
|
59
|
+
title: "Delete redirect",
|
|
60
|
+
onClick: removeItem,
|
|
61
|
+
};
|
|
62
|
+
const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<>
|
|
66
|
+
<S.ItemRow role="rowgroup" selected={isSelected}>
|
|
67
|
+
<S.CheckCell role="cell">
|
|
68
|
+
<CheckField name="check" value={redirect.id ?? ""} checked={isSelected} onChange={handleOnChange} />
|
|
69
|
+
</S.CheckCell>
|
|
70
|
+
{!isSiteItem && (
|
|
71
|
+
<S.SiteCell role="cell" onClick={handleClick}>
|
|
72
|
+
{redirect.site && redirect.site.siteName && (
|
|
73
|
+
<ElementsTooltip elements={[redirect.site.siteName]} maxChar={20} />
|
|
74
|
+
)}
|
|
75
|
+
</S.SiteCell>
|
|
76
|
+
)}
|
|
77
|
+
<S.UrlCell role="cell" onClick={handleClick}>
|
|
78
|
+
{redirect.from}
|
|
79
|
+
</S.UrlCell>
|
|
80
|
+
<S.UrlCell role="cell" onClick={handleClick}>
|
|
81
|
+
{redirect.to?.url}
|
|
82
|
+
</S.UrlCell>
|
|
83
|
+
<S.ActionsCell role="cell">
|
|
84
|
+
<S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />
|
|
85
|
+
</S.ActionsCell>
|
|
86
|
+
</S.ItemRow>
|
|
87
|
+
{isOpen && (
|
|
88
|
+
<RedirectPanel
|
|
89
|
+
isOpen={isOpen}
|
|
90
|
+
isOpenedSecond={isOpenedSecond}
|
|
91
|
+
toggleModal={toggleModal}
|
|
92
|
+
toggleSecondaryPanel={toggleSecondaryPanel}
|
|
93
|
+
redirect={redirect}
|
|
94
|
+
setFormValues={setFormValues}
|
|
95
|
+
formValues={formValues}
|
|
96
|
+
addRedirect={addRedirect}
|
|
97
|
+
currentFilter={currentFilter}
|
|
98
|
+
/>
|
|
99
|
+
)}
|
|
100
|
+
<Modal
|
|
101
|
+
isOpen={isOpenDelete}
|
|
102
|
+
hide={toggleModalDelete}
|
|
103
|
+
title="Delete Redirect"
|
|
104
|
+
secondaryAction={secondaryDeleteModalAction}
|
|
105
|
+
mainAction={mainDeleteModalAction}
|
|
106
|
+
size="S"
|
|
107
|
+
>
|
|
108
|
+
<S.ModalContent>
|
|
109
|
+
Are you sure you want to delete <strong>{redirect.from} redirect</strong>? This action{" "}
|
|
110
|
+
<strong>cannot be undone</strong>.
|
|
111
|
+
</S.ModalContent>
|
|
112
|
+
</Modal>
|
|
113
|
+
</>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
interface IProps {
|
|
118
|
+
redirect: IRedirect;
|
|
119
|
+
isSelected: boolean;
|
|
120
|
+
onChange: (e: any) => void;
|
|
121
|
+
toggleToast: () => void;
|
|
122
|
+
setFormValues: (redirect: IRedirect) => void;
|
|
123
|
+
formValues: IRedirect;
|
|
124
|
+
addRedirect: (force?: boolean) => void;
|
|
125
|
+
currentFilter: string;
|
|
126
|
+
isSiteItem: boolean;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
interface IDispatchProps {
|
|
130
|
+
deleteRedirect(redirectID: number, filter?: string): Promise<boolean>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
type IRedirectItemProps = IProps & IDispatchProps;
|
|
134
|
+
|
|
135
|
+
const mapDispatchToProps = {
|
|
136
|
+
deleteRedirect: redirectsActions.deleteRedirect,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export default connect(null, mapDispatchToProps)(RedirectItem);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
|
|
3
|
+
import { Cell, Row } from "@ax/components/TableList/TableItem/style";
|
|
4
|
+
import { ActionMenu } from "@ax/components";
|
|
5
|
+
|
|
6
|
+
const CheckCell = styled(Cell)`
|
|
7
|
+
padding-left: ${(p) => p.theme.spacing.m};
|
|
8
|
+
width: 32px;
|
|
9
|
+
label {
|
|
10
|
+
margin-bottom: ${(p) => p.theme.spacing.s};
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
const SiteCell = styled(Cell)`
|
|
15
|
+
width: 270px;
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
const UrlCell = styled(Cell)`
|
|
19
|
+
${(p) => p.theme.textStyle.uiXS};
|
|
20
|
+
width: 50%;
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const ActionsCell = styled(Cell)`
|
|
24
|
+
width: 125px;
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
const StyledActionMenu = styled(ActionMenu)`
|
|
28
|
+
opacity: 0;
|
|
29
|
+
width: 32px;
|
|
30
|
+
display: flex;
|
|
31
|
+
margin-left: auto;
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const ItemRow = styled(Row)`
|
|
35
|
+
&:hover {
|
|
36
|
+
${StyledActionMenu} {
|
|
37
|
+
opacity: 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
const ModalContent = styled.div`
|
|
43
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
44
|
+
|
|
45
|
+
p {
|
|
46
|
+
margin-bottom: ${(p) => p.theme.spacing.m};
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
export { CheckCell, SiteCell, ActionsCell, UrlCell, StyledActionMenu, ItemRow, ModalContent };
|