@griddo/ax 11.7.13 → 11.8.0-rc.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 (95) hide show
  1. package/package.json +3 -2
  2. package/src/GlobalStore.tsx +3 -0
  3. package/src/api/index.tsx +4 -0
  4. package/src/api/logs.tsx +97 -0
  5. package/src/api/navigation.tsx +1 -1
  6. package/src/api/pages.tsx +1 -1
  7. package/src/api/schemas.tsx +18 -0
  8. package/src/api/users.tsx +17 -0
  9. package/src/components/ConfigPanel/Form/ConnectedField/NavConnectedField/index.tsx +3 -2
  10. package/src/components/ConfigPanel/Form/index.tsx +3 -1
  11. package/src/components/ConfigPanel/index.tsx +3 -0
  12. package/src/components/Fields/SummaryButton/index.tsx +6 -4
  13. package/src/components/Fields/TimeField/style.tsx +0 -1
  14. package/src/components/Fields/TranslateButton/index.tsx +3 -0
  15. package/src/components/FloatingMenu/index.tsx +25 -1
  16. package/src/components/FloatingMenu/style.tsx +3 -2
  17. package/src/components/LanguageMenu/index.tsx +1 -1
  18. package/src/components/MainWrapper/AppBar/index.tsx +4 -3
  19. package/src/components/RestoreModal/index.tsx +51 -0
  20. package/src/components/RestoreModal/style.tsx +7 -0
  21. package/src/components/SearchField/index.tsx +1 -1
  22. package/src/components/SearchField/style.tsx +4 -4
  23. package/src/components/TableFilters/CheckGroupFilter/index.tsx +42 -5
  24. package/src/components/TableFilters/CheckGroupFilter/style.tsx +8 -1
  25. package/src/components/TableFilters/SiteFilter/index.tsx +26 -57
  26. package/src/components/Tag/index.tsx +6 -3
  27. package/src/components/Tag/style.tsx +2 -2
  28. package/src/components/index.tsx +2 -0
  29. package/src/containers/ActivityLog/actions.tsx +262 -0
  30. package/src/containers/ActivityLog/constants.tsx +6 -0
  31. package/src/containers/ActivityLog/index.tsx +4 -0
  32. package/src/containers/ActivityLog/interfaces.tsx +12 -0
  33. package/src/containers/ActivityLog/reducer.tsx +25 -0
  34. package/src/containers/Navigation/Defaults/actions.tsx +4 -3
  35. package/src/containers/StructuredData/actions.tsx +7 -4
  36. package/src/containers/StructuredData/interfaces.tsx +2 -8
  37. package/src/containers/StructuredData/reducer.tsx +2 -8
  38. package/src/containers/Users/actions.tsx +22 -19
  39. package/src/modules/ActivityLog/DetailModal/index.tsx +108 -0
  40. package/src/modules/ActivityLog/DetailModal/style.tsx +52 -0
  41. package/src/modules/ActivityLog/DownloadModal/index.tsx +104 -0
  42. package/src/modules/ActivityLog/DownloadModal/style.tsx +12 -0
  43. package/src/modules/ActivityLog/ItemGroup/index.tsx +27 -0
  44. package/src/modules/ActivityLog/ItemGroup/style.tsx +39 -0
  45. package/src/modules/ActivityLog/ItemLog/EventItem/index.tsx +167 -0
  46. package/src/modules/ActivityLog/ItemLog/EventItem/style.tsx +79 -0
  47. package/src/modules/ActivityLog/ItemLog/index.tsx +24 -0
  48. package/src/modules/ActivityLog/ItemLogUser/UserItem/EventItem/index.tsx +170 -0
  49. package/src/modules/ActivityLog/ItemLogUser/UserItem/EventItem/style.tsx +79 -0
  50. package/src/modules/ActivityLog/ItemLogUser/UserItem/index.tsx +46 -0
  51. package/src/modules/ActivityLog/ItemLogUser/UserItem/style.tsx +60 -0
  52. package/src/modules/ActivityLog/ItemLogUser/index.tsx +25 -0
  53. package/src/modules/ActivityLog/LogFilters/ContentFilter/index.tsx +79 -0
  54. package/src/modules/ActivityLog/LogFilters/DateFilter/index.tsx +91 -0
  55. package/src/modules/ActivityLog/LogFilters/DateFilter/style.tsx +208 -0
  56. package/src/modules/ActivityLog/LogFilters/EventFilter/index.tsx +80 -0
  57. package/src/modules/ActivityLog/LogFilters/OrderFilter/index.tsx +49 -0
  58. package/src/modules/ActivityLog/LogFilters/OrderFilter/style.tsx +35 -0
  59. package/src/modules/ActivityLog/LogFilters/UserFilter/index.tsx +79 -0
  60. package/src/modules/ActivityLog/TableHeader/index.tsx +72 -0
  61. package/src/modules/ActivityLog/TableHeader/style.tsx +73 -0
  62. package/src/modules/ActivityLog/constants.tsx +10 -0
  63. package/src/modules/ActivityLog/hooks.tsx +53 -0
  64. package/src/modules/ActivityLog/index.tsx +313 -0
  65. package/src/modules/ActivityLog/style.tsx +57 -0
  66. package/src/modules/ActivityLog/utils.tsx +31 -0
  67. package/src/modules/Categories/CategoriesList/index.tsx +1 -1
  68. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/Form/index.tsx +3 -0
  69. package/src/modules/Forms/FormEditor/Editor/FormConfigPanel/index.tsx +3 -0
  70. package/src/modules/Forms/FormEditor/Editor/index.tsx +5 -2
  71. package/src/modules/Forms/FormEditor/index.tsx +20 -3
  72. package/src/modules/GlobalEditor/Editor/index.tsx +3 -0
  73. package/src/modules/GlobalEditor/index.tsx +48 -9
  74. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +3 -1
  75. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/index.tsx +4 -1
  76. package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +45 -6
  77. package/src/modules/PageEditor/Editor/index.tsx +4 -1
  78. package/src/modules/PageEditor/index.tsx +46 -7
  79. package/src/modules/Redirects/BulkHeader/TableHeader/style.tsx +1 -7
  80. package/src/modules/StructuredData/Form/index.tsx +56 -7
  81. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +2 -2
  82. package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +2 -8
  83. package/src/modules/StructuredData/StructuredDataList/hooks.tsx +9 -9
  84. package/src/modules/StructuredData/StructuredDataList/index.tsx +3 -4
  85. package/src/modules/Users/Roles/index.tsx +0 -2
  86. package/src/modules/Users/UserEdit/index.tsx +12 -28
  87. package/src/modules/Users/UserList/BulkHeader/TableHeader/style.tsx +1 -0
  88. package/src/modules/Users/UserList/UserItem/index.tsx +10 -25
  89. package/src/modules/Users/UserList/index.tsx +8 -10
  90. package/src/routes/multisite.tsx +9 -0
  91. package/src/themes/theme.json +2 -1
  92. package/src/types/forms.tsx +1 -0
  93. package/src/types/index.tsx +8 -0
  94. package/src/types/logs.tsx +12 -0
  95. package/src/components/TableFilters/SiteFilter/style.tsx +0 -28
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState } from "react";
2
- import { CheckGroup, FloatingMenu, Icon, ListTitle } from "@ax/components";
2
+ import { CheckGroup, FloatingMenu, Icon, ListTitle, SearchField } from "@ax/components";
3
3
  import { areEquals } from "@ax/helpers";
4
4
  import { IFilterValue, IQueryValue } from "@ax/types";
5
5
 
@@ -17,15 +17,24 @@ const CheckGroupFilter = (props: ITypeFilterProps): JSX.Element => {
17
17
  initialState,
18
18
  multipleSelection = true,
19
19
  menuPosition = "center",
20
+ search = false,
20
21
  } = props;
21
22
 
22
23
  const arrayValues = Array.isArray(value) && value.length ? value.map((val) => val.value) : initialState;
23
24
  const [selectedValue, setSelectedValue] = useState(arrayValues);
25
+ const [filteredOptions, setFilteredOptions] = useState(filters);
26
+ const [hasSearch, setHasSearch] = useState(search && !!filters.length);
24
27
 
25
28
  useEffect(() => {
26
29
  const arrayValues = Array.isArray(value) && value.length ? value.map((val) => val.value) : initialState;
27
30
  setSelectedValue(arrayValues);
28
- }, [value]);
31
+ }, [value, initialState]);
32
+
33
+ useEffect(() => {
34
+ setHasSearch(search && !!filters.length);
35
+ setFilteredOptions(filters);
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ }, [filters]);
29
38
 
30
39
  const setFilterQuery = (selection: any) => {
31
40
  if (!selection.length) {
@@ -39,6 +48,18 @@ const CheckGroupFilter = (props: ITypeFilterProps): JSX.Element => {
39
48
  filterItems(pointer, queryFilters);
40
49
  };
41
50
 
51
+ const filterOptions = (query: string) => {
52
+ const filteredSites =
53
+ query.trim().length > 0
54
+ ? filters.filter((value) =>
55
+ value.title.toLowerCase().replace(" ", "").includes(query.toLowerCase().replace(" ", ""))
56
+ )
57
+ : filters;
58
+ setFilteredOptions(filteredSites);
59
+ };
60
+
61
+ const cleanSearchOnClose = () => filterOptions("");
62
+
42
63
  const isActive = !areEquals(selectedValue, initialState);
43
64
 
44
65
  const Header = () => (
@@ -50,15 +71,30 @@ const CheckGroupFilter = (props: ITypeFilterProps): JSX.Element => {
50
71
  </S.StyledHeader>
51
72
  );
52
73
 
74
+ const hasAllOption = filteredOptions.find((opt) => opt.value === "all");
75
+
53
76
  return (
54
- <FloatingMenu Button={Header} closeOnSelect={!multipleSelection} isCheckGroup={true} position={menuPosition}>
77
+ <FloatingMenu
78
+ Button={Header}
79
+ closeOnSelect={!multipleSelection}
80
+ isCheckGroup={true}
81
+ position={menuPosition}
82
+ hasMargin={false}
83
+ fixedWidth={search ? 263 : undefined}
84
+ actionOnClose={cleanSearchOnClose}
85
+ >
55
86
  <ListTitle>{description}</ListTitle>
87
+ {hasSearch && (
88
+ <S.SearchWrapper>
89
+ <SearchField onChange={filterOptions} size="XXS" searchOnEnter={false} placeholder="Search" />
90
+ </S.SearchWrapper>
91
+ )}
56
92
  <S.ChecksWrapper>
57
93
  <CheckGroup
58
- options={filters}
94
+ options={filteredOptions}
59
95
  value={selectedValue}
60
96
  onChange={setFilterQuery}
61
- selectAllOption={selectAllOption}
97
+ selectAllOption={hasAllOption ? selectAllOption : undefined}
62
98
  multipleSelection={multipleSelection}
63
99
  />
64
100
  </S.ChecksWrapper>
@@ -77,6 +113,7 @@ interface ITypeFilterProps {
77
113
  initialState: string[];
78
114
  multipleSelection?: boolean;
79
115
  menuPosition?: string;
116
+ search?: boolean;
80
117
  }
81
118
 
82
119
  export default CheckGroupFilter;
@@ -35,6 +35,13 @@ const InteractiveArrow = styled.div`
35
35
 
36
36
  const ChecksWrapper = styled.div`
37
37
  padding: ${(p) => p.theme.spacing.xs} ${(p) => p.theme.spacing.s};
38
+ max-height: calc(${(p) => p.theme.spacing.xl} * 4);
39
+ overflow-y: scroll;
40
+ min-width: calc(${(p) => p.theme.spacing.l} * 4);
38
41
  `;
39
42
 
40
- export { StyledHeader, IconsWrapper, InteractiveArrow, ChecksWrapper };
43
+ const SearchWrapper = styled.div`
44
+ padding: ${(p) => p.theme.spacing.xxs} ${(p) => p.theme.spacing.s};
45
+ `;
46
+
47
+ export { StyledHeader, IconsWrapper, InteractiveArrow, ChecksWrapper, SearchWrapper };
@@ -1,20 +1,17 @@
1
- import React, { useEffect, useLayoutEffect, useState } from "react";
1
+ import React, { useEffect, useState } from "react";
2
2
 
3
- import { CheckGroup, FloatingMenu, Icon, ListTitle } from "@ax/components";
4
- import { areEquals, isReqOk } from "@ax/helpers";
3
+ import { CheckGroupFilter } from "@ax/components";
4
+ import { isReqOk } from "@ax/helpers";
5
5
  import { selects } from "@ax/api";
6
6
  import { IFilterValue, IQueryValue } from "@ax/types";
7
7
 
8
- import * as S from "./style";
9
-
10
8
  const SiteFilter = (props: ISiteFilterProps): JSX.Element => {
11
9
  const {
12
10
  filterItems,
13
11
  value,
14
12
  pointer,
15
- center = true,
16
13
  label = "Site",
17
- selectAllOption = "all",
14
+ addGlobal = false,
18
15
  filters = [
19
16
  {
20
17
  name: "all",
@@ -24,22 +21,15 @@ const SiteFilter = (props: ISiteFilterProps): JSX.Element => {
24
21
  ],
25
22
  } = props;
26
23
 
27
- const initialState = [selectAllOption];
28
- const parsedValue =
29
- Array.isArray(value[pointer]) && value[pointer].length
30
- ? value[pointer].map((val: IQueryValue) => val.value)
31
- : initialState;
32
- const [selectedValue, setSelectedValue] = useState(parsedValue);
33
24
  const [options, setOptions] = useState(filters);
34
25
 
35
- useLayoutEffect(() => {
36
- const parsedValue =
37
- Array.isArray(value[pointer]) && value[pointer].length
38
- ? value[pointer].map((val: IQueryValue) => val.value)
39
- : initialState;
40
- setSelectedValue(parsedValue);
41
- // eslint-disable-next-line react-hooks/exhaustive-deps
42
- }, [value]);
26
+ if (addGlobal) {
27
+ filters.push({
28
+ name: "global",
29
+ value: "global",
30
+ title: "Global",
31
+ });
32
+ }
43
33
 
44
34
  const getSelectSites = async () => {
45
35
  try {
@@ -72,53 +62,32 @@ const SiteFilter = (props: ISiteFilterProps): JSX.Element => {
72
62
  // eslint-disable-next-line react-hooks/exhaustive-deps
73
63
  }, []);
74
64
 
75
- const setQuery = (selection: any) => {
76
- if (!selection.length) {
77
- selection = initialState;
78
- }
79
- setSelectedValue(selection);
80
- const queryFilters: IQueryValue[] = selection.map((value: string | number) => {
81
- const label = options.find((opt: IFilterValue) => opt.value === value);
82
- return { value, label: label?.title || "" };
83
- });
84
- filterItems(pointer, queryFilters);
85
- };
86
-
87
- const isActive = !areEquals(selectedValue, initialState);
88
-
89
- const Header = () => (
90
- <S.Site isActive={isActive} center={center}>
91
- {label}
92
- <S.IconsWrapper>
93
- {isActive ? <Icon name="Filter" size="16" /> : <Icon name="DownArrow" size="16" />}
94
- </S.IconsWrapper>
95
- </S.Site>
96
- );
97
-
98
65
  return (
99
- <FloatingMenu Button={Header} position="left" closeOnSelect={false} isCheckGroup={true}>
100
- <ListTitle>Filter by Site</ListTitle>
101
- <S.ChecksWrapper>
102
- <CheckGroup
103
- options={options}
104
- value={selectedValue}
105
- onChange={setQuery}
106
- selectAllOption={selectAllOption}
107
- multipleSelection={true}
108
- />
109
- </S.ChecksWrapper>
110
- </FloatingMenu>
66
+ <CheckGroupFilter
67
+ filterItems={filterItems}
68
+ value={value[pointer]}
69
+ pointer={pointer}
70
+ label={label}
71
+ description="Filter by Site"
72
+ initialState={["all"]}
73
+ selectAllOption="all"
74
+ filters={options}
75
+ menuPosition="left"
76
+ multipleSelection={true}
77
+ search={true}
78
+ />
111
79
  );
112
80
  };
113
81
 
114
82
  export interface ISiteFilterProps {
115
83
  filterItems(pointer: string, filter: IQueryValue[]): void;
116
- value: any;
84
+ value: Record<string, IQueryValue[]>;
117
85
  pointer: string;
118
86
  center?: boolean;
119
87
  label?: string;
120
88
  selectAllOption?: string;
121
89
  filters?: IFilterValue[];
90
+ addGlobal?: boolean;
122
91
  }
123
92
 
124
93
  export default SiteFilter;
@@ -4,7 +4,7 @@ import { Icon } from "@ax/components";
4
4
  import * as S from "./style";
5
5
 
6
6
  const Tag = (props: ITagProps): JSX.Element => {
7
- const { type, text, color, icon, textColor, rounded = true, onDeleteAction, className } = props;
7
+ const { type, text, color, icon, textColor, rounded = true, onDeleteAction, className, small } = props;
8
8
 
9
9
  const handleClick = () => {
10
10
  if (onDeleteAction) {
@@ -18,6 +18,8 @@ const Tag = (props: ITagProps): JSX.Element => {
18
18
  </S.IconWrapper>
19
19
  ) : null;
20
20
 
21
+ if (!text) return <></>;
22
+
21
23
  switch (type) {
22
24
  case "status":
23
25
  return (
@@ -39,7 +41,7 @@ const Tag = (props: ITagProps): JSX.Element => {
39
41
  );
40
42
  default:
41
43
  return (
42
- <S.TagFixed color={color} rounded={rounded} className={className} data-testid="tag-fixed">
44
+ <S.TagFixed color={color} rounded={rounded} small={small} className={className} data-testid="tag-fixed">
43
45
  <S.TagText>
44
46
  <S.Title data-testid="tag-fixed-title">{text}</S.Title>
45
47
  {deleteIcon}
@@ -51,13 +53,14 @@ const Tag = (props: ITagProps): JSX.Element => {
51
53
 
52
54
  export interface ITagProps {
53
55
  type?: "status" | "fixed" | "interactive" | "square" | undefined;
54
- text: string;
56
+ text: string | undefined | null;
55
57
  color?: string;
56
58
  rounded?: boolean;
57
59
  icon?: string;
58
60
  textColor?: string;
59
61
  onDeleteAction?: () => void;
60
62
  className?: string;
63
+ small?: boolean;
61
64
  }
62
65
 
63
66
  export default Tag;
@@ -34,8 +34,8 @@ const Bullet = styled.span<{ color?: string }>`
34
34
  margin-right: 4px;
35
35
  `;
36
36
 
37
- const TagFixed = styled.div<{ color?: string; rounded: boolean }>`
38
- ${(p) => p.theme.textStyle.uiS};
37
+ const TagFixed = styled.div<{ color?: string; rounded: boolean; small?: boolean }>`
38
+ ${(p) => (p.small ? p.theme.textStyle.uiXS : p.theme.textStyle.uiS)};
39
39
  background-color: ${(p) => (p.color ? p.color : p.theme.color.interactive02)};
40
40
  border-radius: ${(p) => (p.rounded ? p.theme.spacing.s : "0")};
41
41
  box-sizing: border-box;
@@ -106,6 +106,7 @@ import Pagination from "./Pagination";
106
106
  import ProgressBar from "./ProgressBar";
107
107
  import ReorderArrows from "./ReorderArrows";
108
108
  import ResizePanel from "./ResizePanel";
109
+ import RestoreModal from "./RestoreModal";
109
110
  import { ScheduleModal, CancelScheduleModal } from "./ScheduleModal";
110
111
  import SearchField from "./SearchField";
111
112
  import SearchTagsBar from "./SearchTagsBar";
@@ -227,6 +228,7 @@ export {
227
228
  ProgressBar,
228
229
  ReorderArrows,
229
230
  ResizePanel,
231
+ RestoreModal,
230
232
  ScheduleModal,
231
233
  CancelScheduleModal,
232
234
  SearchField,
@@ -0,0 +1,262 @@
1
+ import { Dispatch } from "redux";
2
+ import { format } from "date-fns";
3
+
4
+ import {
5
+ LogActivityExportRequest,
6
+ LogActivityGroupedDayDTO,
7
+ LogActivityGroupedUserDTO,
8
+ LogActivityPaginationRequest,
9
+ LogContentDTO,
10
+ LogContentTypeDTO,
11
+ PaginationResponse,
12
+ } from "@griddo/api-types";
13
+ import { logs } from "@ax/api";
14
+ import { appActions } from "@ax/containers/App";
15
+ import { usersActions } from "@ax/containers/Users";
16
+ import { pageEditorActions } from "@ax/containers/PageEditor";
17
+ import { sitesActions } from "@ax/containers/Sites";
18
+ import { integrationsActions } from "@ax/containers/Integrations";
19
+ import { formsActions } from "@ax/containers/Forms";
20
+ import { navigationActions } from "@ax/containers/Navigation";
21
+ import { structuredDataActions } from "@ax/containers/StructuredData";
22
+ import { handleRequest } from "@ax/helpers";
23
+ import { ILogItemsByUser, IRootState } from "@ax/types";
24
+
25
+ import { SET_ACTIVITY_LOG, SET_LIST_MODE } from "./constants";
26
+ import { ISetActivityLog, ISetListMode } from "./interfaces";
27
+ import { ILogItemsByDay } from "src/types/logs";
28
+
29
+ function setActivityLog(activityLog: ILogItemsByDay | ILogItemsByUser): ISetActivityLog {
30
+ return { type: SET_ACTIVITY_LOG, payload: { activityLog } };
31
+ }
32
+
33
+ function setListMode(listMode: string): ISetListMode {
34
+ return { type: SET_LIST_MODE, payload: { listMode } };
35
+ }
36
+
37
+ function getActivityLog(params: LogActivityPaginationRequest): (dispatch: Dispatch) => Promise<void> {
38
+ return async (dispatch) => {
39
+ try {
40
+ const callback = async () => logs.getLogActivityTimelineByDay(params);
41
+
42
+ const responseActions = {
43
+ handleSuccess: (response: PaginationResponse<LogActivityGroupedDayDTO>) => {
44
+ dispatch(setActivityLog(response));
45
+ },
46
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
47
+ };
48
+
49
+ await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
50
+ } catch (e) {
51
+ console.log(e);
52
+ }
53
+ };
54
+ }
55
+
56
+ function getActivityLogByUser(params: LogActivityPaginationRequest): (dispatch: Dispatch) => Promise<void> {
57
+ return async (dispatch) => {
58
+ try {
59
+ const callback = async () => logs.getLogActivityTimelineByUser(params);
60
+
61
+ const responseActions = {
62
+ handleSuccess: (response: PaginationResponse<LogActivityGroupedUserDTO<LogActivityGroupedUserDTO[]>>) => {
63
+ dispatch(setActivityLog(response));
64
+ },
65
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
66
+ };
67
+
68
+ await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
69
+ } catch (e) {
70
+ console.log(e);
71
+ }
72
+ };
73
+ }
74
+
75
+ function downloadActivityLog(data: LogActivityExportRequest): (dispatch: Dispatch) => Promise<void> {
76
+ return async (dispatch) => {
77
+ try {
78
+ const responseActions = {
79
+ handleSuccess: (response: any) => {
80
+ const dateString = format(new Date(), "yyyy-MM-dd");
81
+ const url = window.URL.createObjectURL(new Blob([response]));
82
+ const a = document.createElement("a");
83
+ a.href = url;
84
+ a.download = `activity-log-${dateString}.${data.format[0]}`;
85
+ document.body.appendChild(a);
86
+ a.click();
87
+ window.URL.revokeObjectURL(url);
88
+ },
89
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
90
+ };
91
+
92
+ const callback = async () => logs.logExport(data);
93
+
94
+ await handleRequest(callback, responseActions, [])(dispatch);
95
+ } catch (e) {
96
+ console.log(e);
97
+ }
98
+ };
99
+ }
100
+
101
+ function goToLogContent(
102
+ contentType: LogContentTypeDTO | null,
103
+ content: LogContentDTO | null,
104
+ site: number | null
105
+ ): (dispatch: Dispatch, getState: () => IRootState) => void {
106
+ return async (dispatch, getState) => {
107
+ const {
108
+ app: { lang, globalLangs },
109
+ } = getState();
110
+
111
+ let language = lang;
112
+
113
+ if (content) {
114
+ if (content.language && content.language !== lang.id) {
115
+ const languageFound = globalLangs.find((lang) => lang.id === content.language);
116
+ if (languageFound) {
117
+ language = { locale: languageFound.locale, id: languageFound.id };
118
+ }
119
+ }
120
+
121
+ switch (content.type) {
122
+ case "user":
123
+ usersActions.getUser(content.id)(dispatch, getState);
124
+ appActions.setHistoryPush("/users/edit")(dispatch);
125
+ break;
126
+ case "category":
127
+ if (site) {
128
+ await sitesActions.getSite(site)(dispatch, getState);
129
+ dispatch(appActions.setLanguage(language));
130
+ appActions.setHistoryPush("/sites/categories")(dispatch);
131
+ } else {
132
+ dispatch(appActions.setLanguage(language));
133
+ appActions.setHistoryPush("/categories")(dispatch);
134
+ }
135
+ break;
136
+ case "site":
137
+ if (site) {
138
+ await sitesActions.getSite(site)(dispatch, getState);
139
+ appActions.setHistoryPush("/sites/pages")(dispatch);
140
+ }
141
+ break;
142
+ case "integrations":
143
+ if (site) {
144
+ await sitesActions.getSite(site)(dispatch, getState);
145
+ integrationsActions.getIntegration(content.id, site)(dispatch);
146
+ appActions.setHistoryPush("/sites/settings/addons/edit")(dispatch);
147
+ }
148
+ break;
149
+ case "redirects":
150
+ appActions.setHistoryPush("/settings/redirects")(dispatch);
151
+ break;
152
+ case "languages":
153
+ if (site) {
154
+ await sitesActions.getSite(site)(dispatch, getState);
155
+ appActions.setHistoryPush("/sites/settings/languages")(dispatch);
156
+ }
157
+ break;
158
+ case "file":
159
+ if (site) {
160
+ await sitesActions.getSite(site)(dispatch, getState);
161
+ appActions.setHistoryPush("/sites/media-assets/files")(dispatch);
162
+ } else {
163
+ appActions.setHistoryPush("/media-assets/files")(dispatch);
164
+ }
165
+ break;
166
+ case "image":
167
+ if (site) {
168
+ await sitesActions.getSite(site)(dispatch, getState);
169
+ appActions.setHistoryPush("/sites/media-assets/gallery")(dispatch);
170
+ } else {
171
+ appActions.setHistoryPush("/media-assets/gallery")(dispatch);
172
+ }
173
+ break;
174
+ case "form":
175
+ if (site) {
176
+ await sitesActions.getSite(site)(dispatch, getState);
177
+ dispatch(formsActions.setCurrentFormID(content.id));
178
+ dispatch(appActions.setLanguage(language));
179
+ appActions.setHistoryPush("/sites/forms/editor", true)(dispatch);
180
+ } else {
181
+ dispatch(formsActions.setCurrentFormID(content.id));
182
+ dispatch(appActions.setLanguage(language));
183
+ appActions.setHistoryPush("/forms/editor", true)(dispatch);
184
+ }
185
+ break;
186
+ case "data_pack":
187
+ if (site) {
188
+ await sitesActions.getSite(site)(dispatch, getState);
189
+ appActions.setHistoryPush("/sites/settings/content-types")(dispatch);
190
+ }
191
+ break;
192
+ case "menu":
193
+ if (site) {
194
+ await sitesActions.getSite(site)(dispatch, getState);
195
+ dispatch(appActions.setLanguage(language));
196
+ appActions.setHistoryPush("/sites/navigations/menus")(dispatch);
197
+ }
198
+ break;
199
+ case "header":
200
+ if (site) {
201
+ await sitesActions.getSite(site)(dispatch, getState);
202
+ dispatch(navigationActions.setSelectedDefault("Headers"));
203
+ dispatch(navigationActions.setHeader(content.id));
204
+ dispatch(appActions.setLanguage(language));
205
+ appActions.setHistoryPush("/sites/navigations/editor", true)(dispatch);
206
+ }
207
+ break;
208
+ case "footer":
209
+ if (site) {
210
+ await sitesActions.getSite(site)(dispatch, getState);
211
+ dispatch(navigationActions.setSelectedDefault("Footers"));
212
+ dispatch(navigationActions.setFooter(content.id));
213
+ dispatch(appActions.setLanguage(language));
214
+ appActions.setHistoryPush("/sites/navigations/editor", true)(dispatch);
215
+ }
216
+ break;
217
+ }
218
+ }
219
+
220
+ if (contentType) {
221
+ if (contentType.languageId && contentType.languageId !== lang.id) {
222
+ const languageFound = globalLangs.find((lang) => lang.id === contentType.languageId);
223
+ if (languageFound) {
224
+ language = { locale: languageFound.locale, id: languageFound.id };
225
+ }
226
+ }
227
+
228
+ switch (contentType.type) {
229
+ case "template":
230
+ if (site) {
231
+ await sitesActions.getSite(site)(dispatch, getState);
232
+ dispatch(pageEditorActions.setCurrentPageID(contentType.id));
233
+ dispatch(appActions.setLanguage(language));
234
+ appActions.setHistoryPush("/sites/pages/editor", true)(dispatch);
235
+ } else {
236
+ dispatch(pageEditorActions.setCurrentPageID(contentType.id));
237
+ dispatch(appActions.setLanguage(language));
238
+ appActions.setHistoryPush("/data/pages/editor", true)(dispatch);
239
+ }
240
+ break;
241
+ case "structuredData":
242
+ if (contentType.content) {
243
+ if (site) {
244
+ await sitesActions.getSite(site)(dispatch, getState);
245
+ structuredDataActions.setSelectedStructuredData(contentType.content.id, "site")(dispatch, getState);
246
+ dispatch(structuredDataActions.setCurrentDataID(contentType.id));
247
+ dispatch(appActions.setLanguage(language));
248
+ appActions.setHistoryPush(`/sites/data/${contentType.content.id}/editor`, true)(dispatch);
249
+ } else {
250
+ structuredDataActions.setSelectedStructuredData(contentType.content.id, "global")(dispatch, getState);
251
+ dispatch(structuredDataActions.setCurrentDataID(contentType.id));
252
+ dispatch(appActions.setLanguage(language));
253
+ appActions.setHistoryPush(`/data/${contentType.content.id}/editor`, true)(dispatch);
254
+ }
255
+ }
256
+ break;
257
+ }
258
+ }
259
+ };
260
+ }
261
+
262
+ export { getActivityLog, getActivityLogByUser, setListMode, downloadActivityLog, goToLogContent };
@@ -0,0 +1,6 @@
1
+ const NAME = "activityLog";
2
+
3
+ const SET_ACTIVITY_LOG = `${NAME}/SET_ACTIVITY_LOG`;
4
+ const SET_LIST_MODE = `${NAME}/SET_LIST_MODE`;
5
+
6
+ export { SET_ACTIVITY_LOG, SET_LIST_MODE };
@@ -0,0 +1,4 @@
1
+ import * as activityLogActions from "./actions";
2
+ import { activityLogReducer } from "./reducer";
3
+
4
+ export { activityLogActions, activityLogReducer };
@@ -0,0 +1,12 @@
1
+ import { ILogItemsByDay, ILogItemsByUser } from "@ax/types";
2
+ import { SET_ACTIVITY_LOG, SET_LIST_MODE } from "./constants";
3
+
4
+ export interface ISetActivityLog {
5
+ type: typeof SET_ACTIVITY_LOG;
6
+ payload: { activityLog: ILogItemsByDay | ILogItemsByUser };
7
+ }
8
+
9
+ export interface ISetListMode {
10
+ type: typeof SET_LIST_MODE;
11
+ payload: { listMode: string };
12
+ }
@@ -0,0 +1,25 @@
1
+ import { ILogItemsByUser } from "@ax/types";
2
+ import { SET_ACTIVITY_LOG, SET_LIST_MODE } from "./constants";
3
+ import { ILogItemsByDay } from "src/types/logs";
4
+
5
+ export interface IActivityLogState {
6
+ activityLog: ILogItemsByDay | ILogItemsByUser;
7
+ listMode: string;
8
+ }
9
+
10
+ export const initialState: IActivityLogState = {
11
+ activityLog: { totalItems: 0, items: [] },
12
+ listMode: "default",
13
+ };
14
+
15
+ export function reducer(state = initialState, action: any): IActivityLogState {
16
+ switch (action.type) {
17
+ case SET_ACTIVITY_LOG:
18
+ case SET_LIST_MODE:
19
+ return { ...state, ...action.payload };
20
+ default:
21
+ return state;
22
+ }
23
+ }
24
+
25
+ export { initialState as activityLogInitialState, reducer as activityLogReducer };
@@ -393,7 +393,7 @@ function deleteNavigation(
393
393
  function restoreNavigation(
394
394
  navID: number | number[],
395
395
  type: string
396
- ): (dispatch: Dispatch, getState: () => IRootState) => Promise<void> {
396
+ ): (dispatch: Dispatch, getState: () => IRootState) => Promise<boolean> {
397
397
  return async (dispatch, getState) => {
398
398
  try {
399
399
  const responseActions = {
@@ -411,9 +411,10 @@ function restoreNavigation(
411
411
  const callback = async () =>
412
412
  Array.isArray(navID) ? navigation.restoreNavigationBulk(navID) : navigation.restoreNavigation(navID);
413
413
 
414
- await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
414
+ return await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
415
415
  } catch (e) {
416
- console.log(e); // TODO: capturar error bien
416
+ console.log(e);
417
+ return false;
417
418
  }
418
419
  };
419
420
  }