@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.
Files changed (48) hide show
  1. package/config/webpackSchemas.config.js +7 -0
  2. package/package.json +3 -2
  3. package/src/GlobalStore.tsx +3 -0
  4. package/src/api/index.tsx +2 -0
  5. package/src/api/redirects.tsx +71 -0
  6. package/src/api/sites.tsx +11 -25
  7. package/src/components/Fields/ReferenceField/Context/index.tsx +1 -1
  8. package/src/components/Fields/ReferenceField/ManualPanel/Item/index.tsx +4 -3
  9. package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +4 -2
  10. package/src/components/Fields/ReferenceField/index.tsx +2 -2
  11. package/src/components/Fields/TextArea/index.tsx +3 -1
  12. package/src/components/Fields/TextArea/style.tsx +11 -11
  13. package/src/components/FloatingPanel/style.tsx +7 -2
  14. package/src/components/TableFilters/SiteFilter/index.tsx +7 -6
  15. package/src/components/TableFilters/SiteFilter/style.tsx +2 -2
  16. package/src/containers/Redirects/actions.tsx +129 -0
  17. package/src/containers/Redirects/constants.tsx +18 -0
  18. package/src/containers/Redirects/index.tsx +4 -0
  19. package/src/containers/Redirects/interfaces.tsx +13 -0
  20. package/src/containers/Redirects/reducer.tsx +24 -0
  21. package/src/containers/Settings/DataPacks/constants.tsx +11 -11
  22. package/src/containers/Sites/actions.tsx +1 -25
  23. package/src/helpers/environment.tsx +5 -0
  24. package/src/helpers/index.tsx +3 -0
  25. package/src/helpers/thumbnails.tsx +3 -3
  26. package/src/modules/Content/PageItem/index.tsx +5 -8
  27. package/src/modules/Content/index.tsx +25 -35
  28. package/src/modules/GlobalSettings/Robots/Item/index.tsx +1 -1
  29. package/src/modules/GlobalSettings/Robots/index.tsx +5 -2
  30. package/src/modules/GlobalSettings/index.tsx +6 -0
  31. package/src/modules/Redirects/BulkHeader/TableHeader/index.tsx +44 -0
  32. package/src/modules/Redirects/BulkHeader/TableHeader/style.tsx +31 -0
  33. package/src/modules/Redirects/BulkHeader/index.tsx +59 -0
  34. package/src/modules/Redirects/RedirectItem/index.tsx +139 -0
  35. package/src/modules/Redirects/RedirectItem/style.tsx +50 -0
  36. package/src/modules/Redirects/RedirectPanel/index.tsx +117 -0
  37. package/src/modules/Redirects/RedirectPanel/style.tsx +13 -0
  38. package/src/modules/Redirects/index.tsx +310 -0
  39. package/src/modules/Redirects/style.tsx +52 -0
  40. package/src/modules/Settings/SeoSettings/index.tsx +25 -0
  41. package/src/modules/Sites/SitesList/SiteItem/index.tsx +6 -2
  42. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +1 -1
  43. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +3 -3
  44. package/src/modules/StructuredData/StructuredDataList/index.tsx +1 -0
  45. package/src/modules/StructuredData/StructuredDataList/utils.tsx +1 -1
  46. package/src/routes/multisite.tsx +6 -0
  47. package/src/routes/site.tsx +6 -0
  48. package/src/types/index.tsx +13 -0
@@ -1,17 +1,17 @@
1
- const NAME: string = "dataPacks";
1
+ const NAME = "dataPacks";
2
2
 
3
- const SET_ACTIVATED: string = `${NAME}/SET_ACTIVATED`;
4
- const SET_SELECTED: string = `${NAME}/SET_SELECTED`;
5
- const SET_CONFIG_FORM_DATA: string = `${NAME}/SET_CONFIG_FORM_DATA`;
6
- const SET_AVAILABLE: string = `${NAME}/SET_AVAILABLE`;
7
- const SET_CATEGORIES: string = `${NAME}/SET_CATEGORIES`;
8
- const SET_MODULES: string = `${NAME}/SET_MODULES`;
9
- const SET_TEMPLATES: string = `${NAME}/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,
@@ -0,0 +1,5 @@
1
+ const isDevelopment = (): boolean => {
2
+ return process.env.NODE_ENV === "development";
3
+ }
4
+
5
+ export { isDevelopment }
@@ -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 srcset = `${fallback}, ${imgDensity1x} `;
35
+ const srcSet = `${imgDensity1x} 1x, ${fallback} 2x`;
36
36
 
37
37
  return {
38
- srcset,
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, template, isHome, fullPath, canBeUnpublished, origin, manuallyImported } = page;
51
- const displayName = getTemplateDisplayName(template.templateType);
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
- let isTemplateActivated = true;
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 = page.template[col.from];
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
- siteID,
168
- dataID: typeof filter === "object" ? filter.value : filter,
169
- page,
170
- itemsPerPage,
171
- pagination: true,
172
- deleted: false,
173
- include_draft: true,
174
- query: searchQuery,
175
- }
176
- : {
177
- siteID,
178
- deleted: false,
179
- page,
180
- itemsPerPage,
181
- query: searchQuery,
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 { params, siteID };
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, siteID: number, filterQuery?: any) => {
197
+ const getPages = (params: any, filterQuery?: any) => {
198
198
  const isStructuredDataPage = filter !== "unique-pages";
199
- if (filterQuery && !isStructuredDataPage) {
200
- const { deleted, page, itemsPerPage, query } = params;
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 { params, siteID } = getParams();
214
- isStructuredData ? getStructuredDataContents(params, siteID) : getPages(params, siteID, filterQuery);
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
- }, [getDomainsRobots]);
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 };