@griddo/ax 12.6.1 → 12.6.2

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 (91) hide show
  1. package/config/griddo-config/index.js +0 -1
  2. package/package.json +4 -3
  3. package/src/GlobalStore.tsx +35 -91
  4. package/src/__tests__/hooks/heartbeat.test.tsx +88 -0
  5. package/src/components/MainWrapper/index.tsx +2 -14
  6. package/src/containers/ActivityLog/{thunks.ts → actions.tsx} +89 -104
  7. package/src/containers/ActivityLog/constants.tsx +6 -0
  8. package/src/containers/ActivityLog/index.tsx +3 -16
  9. package/src/containers/ActivityLog/interfaces.tsx +12 -0
  10. package/src/containers/ActivityLog/reducer.tsx +24 -0
  11. package/src/containers/Analytics/actions.tsx +109 -0
  12. package/src/containers/Analytics/constants.tsx +5 -0
  13. package/src/containers/Analytics/index.tsx +3 -14
  14. package/src/containers/Analytics/interfaces.tsx +9 -0
  15. package/src/containers/Analytics/reducer.tsx +28 -0
  16. package/src/containers/Domains/actions.tsx +58 -0
  17. package/src/containers/Domains/constants.tsx +5 -0
  18. package/src/containers/Domains/index.tsx +3 -12
  19. package/src/containers/Domains/interfaces.tsx +9 -0
  20. package/src/containers/Domains/reducer.tsx +22 -0
  21. package/src/containers/Redirects/actions.tsx +190 -0
  22. package/src/containers/Redirects/constants.tsx +17 -1
  23. package/src/containers/Redirects/index.tsx +3 -14
  24. package/src/containers/Redirects/interfaces.tsx +23 -0
  25. package/src/containers/Redirects/reducer.tsx +35 -0
  26. package/src/containers/Settings/Languages/actions.tsx +88 -0
  27. package/src/containers/Settings/Languages/constants.tsx +6 -0
  28. package/src/containers/Settings/Languages/index.tsx +3 -15
  29. package/src/containers/Settings/Languages/reducer.tsx +31 -0
  30. package/src/containers/Settings/Social/actions.tsx +63 -0
  31. package/src/containers/Settings/Social/constants.tsx +3 -0
  32. package/src/containers/Settings/Social/index.tsx +3 -11
  33. package/src/containers/Settings/Social/interfaces.tsx +9 -0
  34. package/src/containers/Settings/Social/reducer.tsx +18 -0
  35. package/src/containers/Sites/actions.tsx +2 -6
  36. package/src/hooks/heartbeat.ts +32 -0
  37. package/src/hooks/index.tsx +2 -0
  38. package/src/index.tsx +6 -7
  39. package/src/modules/ActivityLog/ItemLog/EventItem/index.tsx +27 -13
  40. package/src/modules/ActivityLog/ItemLogUser/UserItem/EventItem/index.tsx +27 -13
  41. package/src/modules/ActivityLog/index.tsx +51 -22
  42. package/src/modules/Analytics/index.tsx +42 -33
  43. package/src/modules/App/Routing/index.tsx +4 -5
  44. package/src/modules/FileDrive/index.tsx +1 -1
  45. package/src/modules/GlobalEditor/index.tsx +6 -8
  46. package/src/modules/GlobalSettings/Robots/index.tsx +47 -24
  47. package/src/modules/MediaGallery/index.tsx +1 -1
  48. package/src/modules/PageEditor/index.tsx +5 -9
  49. package/src/modules/Redirects/RedirectItem/index.tsx +22 -9
  50. package/src/modules/Redirects/RedirectPanel/index.tsx +14 -13
  51. package/src/modules/Redirects/index.tsx +69 -26
  52. package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +3 -4
  53. package/src/modules/Settings/Languages/LanguagePanel/Form/ConnectedField/index.tsx +18 -11
  54. package/src/modules/Settings/Languages/LanguagePanel/Form/index.tsx +9 -7
  55. package/src/modules/Settings/Languages/LanguagePanel/index.tsx +44 -38
  56. package/src/modules/Settings/Languages/Table/Header/index.tsx +19 -12
  57. package/src/modules/Settings/Languages/Table/Item/index.tsx +36 -21
  58. package/src/modules/Settings/Languages/Table/index.tsx +14 -6
  59. package/src/modules/Settings/Languages/index.tsx +30 -18
  60. package/src/modules/Settings/SeoAnalyticsSettings/Analytics/index.tsx +52 -42
  61. package/src/modules/Settings/Social/index.tsx +12 -17
  62. package/src/modules/StructuredData/StructuredDataList/index.tsx +2 -3
  63. package/src/types/index.tsx +6 -5
  64. package/tsconfig.paths.json +0 -1
  65. package/src/__tests__/modules/ActivityLog/ActivityLog.uc.test.tsx +0 -132
  66. package/src/__tests__/modules/Analytics/Analytics.uc.test.tsx +0 -168
  67. package/src/__tests__/modules/GlobalSettings/Robots/Robots.test.tsx +0 -110
  68. package/src/__tests__/modules/GlobalSettings/Robots/Robots.uc.test.tsx +0 -125
  69. package/src/__tests__/modules/Redirects/Redirects.uc.test.tsx +0 -164
  70. package/src/__tests__/modules/Settings/Languages/Languages.uc.test.tsx +0 -213
  71. package/src/__tests__/modules/Settings/Social/Social.uc.test.tsx +0 -171
  72. package/src/__tests__/store/activityLog.test.ts +0 -301
  73. package/src/__tests__/store/analytics.test.ts +0 -134
  74. package/src/__tests__/store/domains.test.ts +0 -107
  75. package/src/__tests__/store/languages.test.ts +0 -129
  76. package/src/__tests__/store/persist.test.ts +0 -47
  77. package/src/__tests__/store/redirects.test.ts +0 -313
  78. package/src/__tests__/store/social.test.ts +0 -165
  79. package/src/containers/ActivityLog/slice.ts +0 -45
  80. package/src/containers/Analytics/slice.ts +0 -48
  81. package/src/containers/Analytics/thunks.ts +0 -103
  82. package/src/containers/Domains/slice.ts +0 -37
  83. package/src/containers/Domains/thunks.ts +0 -60
  84. package/src/containers/Redirects/slice.ts +0 -60
  85. package/src/containers/Redirects/thunks.ts +0 -196
  86. package/src/containers/Settings/Languages/slice.ts +0 -48
  87. package/src/containers/Settings/Languages/thunks.ts +0 -83
  88. package/src/containers/Settings/Social/slice.ts +0 -40
  89. package/src/containers/Settings/Social/thunks.ts +0 -68
  90. package/src/store/hooks.ts +0 -37
  91. package/src/store/index.ts +0 -2
@@ -1,16 +1,4 @@
1
- import { resetForm, setForm, updateFormValue } from "./slice";
2
- import { createSiteLanguage, deleteSiteLanguage, updateSiteLanguage } from "./thunks";
1
+ import * as languagesActions from "./actions";
2
+ import { languagesReducer } from "./reducer";
3
3
 
4
- const languagesActions = {
5
- setForm,
6
- updateFormValue,
7
- resetForm,
8
- createSiteLanguage,
9
- updateSiteLanguage,
10
- deleteSiteLanguage,
11
- };
12
-
13
- export { languagesActions };
14
-
15
- export type { ILanguageState } from "./slice";
16
- export { languagesInitialState, languagesReducer } from "./slice";
4
+ export { languagesActions, languagesReducer };
@@ -0,0 +1,31 @@
1
+ import { CREATE_FORM, UPDATE_FORM } from "./constants";
2
+
3
+ export interface ILanguageState {
4
+ form: {
5
+ language: number | null;
6
+ path: string;
7
+ domain: number | null;
8
+ isDefault: boolean;
9
+ };
10
+ }
11
+
12
+ export const initialState = {
13
+ form: {
14
+ language: null,
15
+ path: "",
16
+ domain: null,
17
+ isDefault: false,
18
+ },
19
+ };
20
+
21
+ export function reducer(state = initialState, action: any): ILanguageState {
22
+ switch (action.type) {
23
+ case CREATE_FORM:
24
+ case UPDATE_FORM:
25
+ return { ...state, ...action.payload };
26
+ default:
27
+ return state;
28
+ }
29
+ }
30
+
31
+ export { initialState as languagesInitialState, reducer as languagesReducer };
@@ -0,0 +1,63 @@
1
+ import type { Dispatch } from "redux";
2
+
3
+ import { SET_SOCIAL } from "./constants";
4
+
5
+ import type { ISetSocialAction } from "./interfaces";
6
+
7
+ import { appActions } from "@ax/containers/App";
8
+ import { handleRequest } from "@ax/helpers";
9
+ import { social } from "@ax/api";
10
+
11
+ function setSocial(socialInfo: any): ISetSocialAction {
12
+ return { type: SET_SOCIAL, payload: { ...socialInfo } };
13
+ }
14
+
15
+ function saveSocial(form: Record<string, string>): (dispatch: Dispatch, getState: any) => Promise<boolean> {
16
+ return async (dispatch, getState) => {
17
+ try {
18
+ const {
19
+ sites: { currentSiteInfo },
20
+ } = getState();
21
+
22
+ const responseActions = {
23
+ handleSuccess: (data: Record<string, string>) => {
24
+ dispatch(setSocial(data));
25
+ return true;
26
+ },
27
+ handleError: (data: any) => appActions.handleError(data)(dispatch),
28
+ };
29
+
30
+ const callback = async () => social.updateSocial(currentSiteInfo.id, form);
31
+
32
+ return await handleRequest(callback, responseActions, [appActions.setIsSaving])(dispatch);
33
+ } catch (e) {
34
+ console.log(e);
35
+ return false;
36
+ }
37
+ };
38
+ }
39
+
40
+ function getSocial(): (dispatch: any, getState: any) => Promise<void> {
41
+ return async (dispatch, getState) => {
42
+ try {
43
+ const {
44
+ sites: { currentSiteInfo },
45
+ } = getState();
46
+
47
+ const responseActions = {
48
+ handleSuccess: (data: Record<string, string>) => {
49
+ dispatch(setSocial(data));
50
+ },
51
+ handleError: () => console.log("Error en getSocial"),
52
+ };
53
+
54
+ const callback = () => social.getSocial(currentSiteInfo.id);
55
+
56
+ await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
57
+ } catch (e) {
58
+ console.log(e);
59
+ }
60
+ };
61
+ }
62
+
63
+ export { getSocial, saveSocial, setSocial };
@@ -0,0 +1,3 @@
1
+ export const NAME = "social";
2
+
3
+ export const SET_SOCIAL = `${NAME}/SET_SOCIAL`;
@@ -1,12 +1,4 @@
1
- import { setSocial } from "./slice";
2
- import { getSocial, saveSocial } from "./thunks";
1
+ import * as socialActions from "./actions";
2
+ import { socialReducer } from "./reducer";
3
3
 
4
- const socialActions = {
5
- setSocial,
6
- getSocial,
7
- saveSocial,
8
- };
9
-
10
- export { socialActions };
11
-
12
- export { socialInitialState, socialReducer } from "./slice";
4
+ export { socialActions, socialReducer };
@@ -0,0 +1,9 @@
1
+ import type { SET_SOCIAL } from "./constants";
2
+ import type { ISocialState } from "@ax/types";
3
+
4
+ export interface ISetSocialAction {
5
+ type: typeof SET_SOCIAL;
6
+ payload: ISocialState;
7
+ }
8
+
9
+ export type SocialActionsCreators = ISetSocialAction;
@@ -0,0 +1,18 @@
1
+ import { SET_SOCIAL } from "./constants";
2
+
3
+ import type { ISocialState } from "@ax/types";
4
+
5
+ import type { SocialActionsCreators } from "./interfaces";
6
+
7
+ export const initialState = {};
8
+
9
+ export function reducer(state = initialState, action: SocialActionsCreators): ISocialState {
10
+ switch (action.type) {
11
+ case SET_SOCIAL:
12
+ return { ...action.payload };
13
+ default:
14
+ return state;
15
+ }
16
+ }
17
+
18
+ export { initialState as socialInitialState, reducer as socialReducer };
@@ -9,7 +9,6 @@ import { socialActions } from "@ax/containers/Settings/Social";
9
9
  import { structuredDataActions } from "@ax/containers/StructuredData";
10
10
  import { usersActions } from "@ax/containers/Users";
11
11
  import { getDefaultTheme, getThemeElements, handleRequest, isReqOk, sortBy } from "@ax/helpers";
12
- import type { AppDispatch } from "@ax/store";
13
12
  import type {
14
13
  IGetGlobalPagesParams,
15
14
  IGetSitePagesParams,
@@ -358,7 +357,7 @@ function setSiteInfo(currentSiteInfo: ISite): (dispatch: Dispatch, getState: ()
358
357
 
359
358
  // get analytics
360
359
  const analyticsResponse: any = await analytics.getAnalytics(currentSiteInfo.id);
361
- if (isReqOk(analyticsResponse.status)) {
360
+ if (isReqOk(socialResponse.status)) {
362
361
  dispatch(analyticsActions.setAnalytics(analyticsResponse.data));
363
362
  } else {
364
363
  console.log("Error en sites getAnalytics");
@@ -570,10 +569,7 @@ function resetSiteValues(siteID: number): (dispatch: Dispatch) => void {
570
569
  resetMenuValues(dispatch);
571
570
  dispatch(setCurrentSitePages([]));
572
571
  dispatch(setTotalItems(0));
573
- // `analytics` is already on RTK while `sites` is not (wave 3), so its thunk is
574
- // dispatched, not invoked by hand: a createAsyncThunk expects the full
575
- // (dispatch, getState, extra) triple. The cast is the seam between the two.
576
- (dispatch as AppDispatch)(getAnalytics(siteID));
572
+ getAnalytics(siteID)(dispatch);
577
573
  dispatch(setCurrentSearch(""));
578
574
  dispatch(setThemeElements(null));
579
575
  };
@@ -0,0 +1,32 @@
1
+ import { useEffect } from "react";
2
+
3
+ /**
4
+ * Keeps the edit lock of the page being edited alive, renewing it every 30 seconds.
5
+ *
6
+ * sc-118275: this used to live inside each editor's mount effect, whose dependency list is empty,
7
+ * so the interval kept pinging whichever id it captured on mount. Creating a translation from
8
+ * inside the editor moves the store to the new page but never remounts, so the lock stayed on the
9
+ * original page for as long as the editor was open — and the translation, the one actually being
10
+ * edited, was left unlocked. Keeping pageID in the dependency list is what makes the heartbeat
11
+ * follow the page.
12
+ *
13
+ * The leading ping is not redundant with the interval: on a page switch the new id would otherwise
14
+ * sit unlocked for 30 seconds, because savePage dispatches setUserEditing(page.editing) with a null
15
+ * payload when nobody else holds the page, and the editors' [userEditing] effect only pings when
16
+ * that reference changes.
17
+ *
18
+ * sendPagePing has to keep a stable reference across renders; both editors get it from an object
19
+ * literal mapDispatchToProps, so connect binds it once. If it ever started changing on every
20
+ * render the effect would re-run, the cleanup would clear the interval before it could fire and
21
+ * there would be no heartbeat at all.
22
+ */
23
+ const useEditingHeartbeat = (pageID: number | null, sendPagePing: (pageID: number) => void): void => {
24
+ useEffect(() => {
25
+ if (!pageID) return;
26
+ sendPagePing(pageID);
27
+ const interval = setInterval(() => sendPagePing(pageID), 30000);
28
+ return () => clearInterval(interval);
29
+ }, [pageID, sendPagePing]);
30
+ };
31
+
32
+ export { useEditingHeartbeat };
@@ -8,6 +8,7 @@ import {
8
8
  usePrevious,
9
9
  useShouldBeSaved,
10
10
  } from "./forms";
11
+ import { useEditingHeartbeat } from "./heartbeat";
11
12
  import { useOnMessageReceivedFromIframe, useOnMessageReceivedFromOutside } from "./iframe";
12
13
  import { useURLSearchParam } from "./location";
13
14
  import { useContextMenu, useHandleClickOutside, useModal, useModals, useToast } from "./modals";
@@ -29,6 +30,7 @@ export {
29
30
  useContextMenu,
30
31
  useDebounce,
31
32
  useDebouncedCallback,
33
+ useEditingHeartbeat,
32
34
  useEmptyState,
33
35
  useEqualStructured,
34
36
  useFirefoxScrollLock,
package/src/index.tsx CHANGED
@@ -1,18 +1,17 @@
1
1
  import React from "react";
2
- import { Provider } from "react-redux";
3
- import { Router } from "react-router-dom";
4
-
5
2
  import ReactDOM from "react-dom/client";
3
+ import { Provider } from "react-redux";
6
4
  import { PersistGate } from "redux-persist/integration/react";
5
+ import history from "./routes/history";
6
+ import { ConnectedRouter } from "connected-react-router";
7
7
 
8
8
  import { GlobalStore } from "./GlobalStore";
9
9
  import App from "./modules/App";
10
- import history from "./routes/history";
11
10
 
12
11
  export class Main {
13
12
  public static start(): void {
14
13
  const globalStore = new GlobalStore();
15
- const configStore = globalStore.configureStore();
14
+ const configStore = globalStore.configureStore(history);
16
15
 
17
16
  const container = document.getElementById("root");
18
17
  if (!container) throw new Error("Failed to find the root element");
@@ -20,11 +19,11 @@ export class Main {
20
19
 
21
20
  root.render(
22
21
  <Provider store={configStore.store}>
23
- <Router history={history}>
22
+ <ConnectedRouter history={history}>
24
23
  <PersistGate loading={undefined} persistor={configStore.persistor}>
25
24
  <App />
26
25
  </PersistGate>
27
- </Router>
26
+ </ConnectedRouter>
28
27
  </Provider>,
29
28
  );
30
29
  }
@@ -1,5 +1,6 @@
1
1
  import type React from "react";
2
2
  import { useState } from "react";
3
+ import { connect } from "react-redux";
3
4
 
4
5
  import { Avatar, RestoreModal, Tag, TruncatedTooltip } from "@ax/components";
5
6
  import { activityLogActions } from "@ax/containers/ActivityLog";
@@ -7,9 +8,9 @@ import { navigationActions } from "@ax/containers/Navigation";
7
8
  import { pageEditorActions } from "@ax/containers/PageEditor";
8
9
  import { structuredDataActions } from "@ax/containers/StructuredData";
9
10
  import { useModal } from "@ax/hooks";
10
- import { useAppDispatch, useAppSelector } from "@ax/store";
11
+ import type { IRootState } from "@ax/types";
11
12
 
12
- import type { LogActivityDTO } from "@griddo/api-types";
13
+ import type { LogActivityDTO, LogContentDTO, LogContentTypeDTO } from "@griddo/api-types";
13
14
 
14
15
  import { eventKey } from "../../constants";
15
16
  import DetailModal from "../../DetailModal";
@@ -18,12 +19,9 @@ import { getContentTypeSchemaVersion, getPageSchemaVersion } from "../../utils";
18
19
  import * as S from "./style";
19
20
 
20
21
  const EventItem = (props: IEventItemProps) => {
21
- const { item, getLog } = props;
22
+ const { item, schemaVersion, restorePage, restoreNavigation, restoreStructuredData, goToLogContent, getLog } = props;
22
23
  const { user, created, site, contentType, content, eventType } = item;
23
24
 
24
- const dispatch = useAppDispatch();
25
- const schemaVersion = useAppSelector((state) => state.structuredData.schemaVersion);
26
-
27
25
  const { isOpen: isDetailOpen, toggleModal: toggleDetailModal } = useModal();
28
26
  const { isOpen: isRestoreOpen, toggleModal: toggleRestoreModal } = useModal();
29
27
  const [schemaChange, setSchemaChange] = useState(false);
@@ -34,14 +32,14 @@ const EventItem = (props: IEventItemProps) => {
34
32
  switch (type) {
35
33
  case eventKey.DELETED_PAGE:
36
34
  case eventKey.DELETED_CONTENT_TYPE_PAGE:
37
- return await dispatch(pageEditorActions.restorePage(id));
35
+ return await restorePage(id);
38
36
  case eventKey.DELETED_HEADER:
39
- return await dispatch(navigationActions.restoreNavigation(id, "header"));
37
+ return await restoreNavigation(id, "header");
40
38
  case eventKey.DELETED_FOOTER:
41
- return await dispatch(navigationActions.restoreNavigation(id, "footer"));
39
+ return await restoreNavigation(id, "footer");
42
40
  case eventKey.DELETED_CATEGORY:
43
41
  case eventKey.DELETED_CONTENT_TYPE:
44
- return await dispatch(structuredDataActions.restoreStructuredDataContent(id));
42
+ return await restoreStructuredData(id);
45
43
  default:
46
44
  return false;
47
45
  }
@@ -85,12 +83,12 @@ const EventItem = (props: IEventItemProps) => {
85
83
  const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
86
84
  e.stopPropagation();
87
85
  const siteID = site?.id || null;
88
- dispatch(activityLogActions.goToLogContent({ contentType, content, site: siteID }));
86
+ goToLogContent(contentType, content, siteID);
89
87
  };
90
88
 
91
89
  const handleKeyDown = () => {
92
90
  const siteID = site?.id || null;
93
- dispatch(activityLogActions.goToLogContent({ contentType, content, site: siteID }));
91
+ goToLogContent(contentType, content, siteID);
94
92
  };
95
93
 
96
94
  return (
@@ -154,7 +152,23 @@ const EventItem = (props: IEventItemProps) => {
154
152
 
155
153
  interface IEventItemProps {
156
154
  item: LogActivityDTO;
155
+ schemaVersion: string;
156
+ restorePage(id: number): Promise<boolean>;
157
+ restoreNavigation(navID: number, type: string): Promise<boolean>;
158
+ restoreStructuredData(dataID: number): Promise<boolean>;
159
+ goToLogContent(contentType: LogContentTypeDTO | null, content: LogContentDTO | null, site: number | null): void;
157
160
  getLog(): void;
158
161
  }
159
162
 
160
- export default EventItem;
163
+ const mapStateToProps = (state: IRootState) => ({
164
+ schemaVersion: state.structuredData.schemaVersion,
165
+ });
166
+
167
+ const mapDispatchToProps = {
168
+ restorePage: pageEditorActions.restorePage,
169
+ restoreNavigation: navigationActions.restoreNavigation,
170
+ restoreStructuredData: structuredDataActions.restoreStructuredDataContent,
171
+ goToLogContent: activityLogActions.goToLogContent,
172
+ };
173
+
174
+ export default connect(mapStateToProps, mapDispatchToProps)(EventItem);
@@ -1,5 +1,6 @@
1
1
  import type React from "react";
2
2
  import { useState } from "react";
3
+ import { connect } from "react-redux";
3
4
 
4
5
  import { RestoreModal } from "@ax/components";
5
6
  import { activityLogActions } from "@ax/containers/ActivityLog";
@@ -7,9 +8,9 @@ import { navigationActions } from "@ax/containers/Navigation";
7
8
  import { pageEditorActions } from "@ax/containers/PageEditor";
8
9
  import { structuredDataActions } from "@ax/containers/StructuredData";
9
10
  import { useModal } from "@ax/hooks";
10
- import { useAppDispatch, useAppSelector } from "@ax/store";
11
+ import type { IRootState } from "@ax/types";
11
12
 
12
- import type { LogActivityDTO } from "@griddo/api-types";
13
+ import type { LogActivityDTO, LogContentDTO, LogContentTypeDTO } from "@griddo/api-types";
13
14
 
14
15
  import { eventKey } from "./../../../constants";
15
16
  import DetailModal from "./../../../DetailModal";
@@ -18,10 +19,7 @@ import { getContentTypeSchemaVersion, getPageSchemaVersion } from "./../../../ut
18
19
  import * as S from "./style";
19
20
 
20
21
  const EventItem = (props: IEventItemProps) => {
21
- const { item, getLog } = props;
22
-
23
- const dispatch = useAppDispatch();
24
- const schemaVersion = useAppSelector((state) => state.structuredData.schemaVersion);
22
+ const { item, schemaVersion, restorePage, restoreNavigation, restoreStructuredData, goToLogContent, getLog } = props;
25
23
 
26
24
  const { created, site, contentType, content, eventType } = item;
27
25
 
@@ -35,14 +33,14 @@ const EventItem = (props: IEventItemProps) => {
35
33
  switch (type) {
36
34
  case eventKey.DELETED_PAGE:
37
35
  case eventKey.DELETED_CONTENT_TYPE_PAGE:
38
- return await dispatch(pageEditorActions.restorePage(id));
36
+ return await restorePage(id);
39
37
  case eventKey.DELETED_HEADER:
40
- return await dispatch(navigationActions.restoreNavigation(id, "header"));
38
+ return await restoreNavigation(id, "header");
41
39
  case eventKey.DELETED_FOOTER:
42
- return await dispatch(navigationActions.restoreNavigation(id, "footer"));
40
+ return await restoreNavigation(id, "footer");
43
41
  case eventKey.DELETED_CATEGORY:
44
42
  case eventKey.DELETED_CONTENT_TYPE:
45
- return await dispatch(structuredDataActions.restoreStructuredDataContent(id));
43
+ return await restoreStructuredData(id);
46
44
  default:
47
45
  return false;
48
46
  }
@@ -86,12 +84,12 @@ const EventItem = (props: IEventItemProps) => {
86
84
  const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
87
85
  e.stopPropagation();
88
86
  const siteID = site?.id || null;
89
- dispatch(activityLogActions.goToLogContent({ contentType, content, site: siteID }));
87
+ goToLogContent(contentType, content, siteID);
90
88
  };
91
89
 
92
90
  const handleKeyDown = () => {
93
91
  const siteID = site?.id || null;
94
- dispatch(activityLogActions.goToLogContent({ contentType, content, site: siteID }));
92
+ goToLogContent(contentType, content, siteID);
95
93
  };
96
94
 
97
95
  return (
@@ -153,7 +151,23 @@ const EventItem = (props: IEventItemProps) => {
153
151
 
154
152
  interface IEventItemProps {
155
153
  item: LogActivityDTO;
154
+ schemaVersion: string;
155
+ restorePage(id: number): Promise<boolean>;
156
+ restoreNavigation(navID: number, type: string): Promise<boolean>;
157
+ restoreStructuredData(dataID: number): Promise<boolean>;
158
+ goToLogContent(contentType: LogContentTypeDTO | null, content: LogContentDTO | null, site: number | null): void;
156
159
  getLog(): void;
157
160
  }
158
161
 
159
- export default EventItem;
162
+ const mapStateToProps = (state: IRootState) => ({
163
+ schemaVersion: state.structuredData.schemaVersion,
164
+ });
165
+
166
+ const mapDispatchToProps = {
167
+ restorePage: pageEditorActions.restorePage,
168
+ restoreNavigation: navigationActions.restoreNavigation,
169
+ restoreStructuredData: structuredDataActions.restoreStructuredDataContent,
170
+ goToLogContent: activityLogActions.goToLogContent,
171
+ };
172
+
173
+ export default connect(mapStateToProps, mapDispatchToProps)(EventItem);
@@ -1,27 +1,33 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from "react";
2
+ import { connect } from "react-redux";
3
+ import { format, subDays } from "date-fns";
2
4
 
5
+ import type { LogActivityExportRequest, LogActivityPaginationRequest } from "@griddo/api-types";
6
+ import type { ILogItemsByDay, ILogItemsByUser, IQueryValue, IRootState, IStructuredData } from "@ax/types";
3
7
  import { EmptyState, ErrorToast, FilterTagsBar, MainWrapper, SearchTagsBar, Select, TableList } from "@ax/components";
4
8
  import { activityLogActions } from "@ax/containers/ActivityLog";
5
9
  import { structuredDataActions } from "@ax/containers/StructuredData";
6
10
  import { useModal } from "@ax/hooks";
7
- import { useAppDispatch, useAppSelector } from "@ax/store";
8
- import type { ILogItemsByDay, ILogItemsByUser, IQueryValue } from "@ax/types";
9
11
 
10
- import type { LogActivityExportRequest, LogActivityPaginationRequest } from "@griddo/api-types";
11
- import { format, subDays } from "date-fns";
12
-
13
- import DownloadModal from "./DownloadModal";
14
12
  import { useFilterQuery } from "./hooks";
13
+ import TableHeader from "./TableHeader";
15
14
  import ItemLog from "./ItemLog";
16
15
  import ItemLogUser from "./ItemLogUser";
17
- import TableHeader from "./TableHeader";
16
+ import DownloadModal from "./DownloadModal";
18
17
 
19
18
  import * as S from "./style";
20
19
 
21
- const ActivityLog = () => {
22
- const dispatch = useAppDispatch();
23
- const activityLog = useAppSelector((state) => state.activityLog.activityLog);
24
- const listMode = useAppSelector((state) => state.activityLog.listMode);
20
+ const ActivityLog = (props: IActivityLogProps) => {
21
+ const {
22
+ activityLog,
23
+ listMode,
24
+ setListMode,
25
+ getActivityLog,
26
+ getActivityLogByUser,
27
+ downloadActivityLog,
28
+ getStructuredData,
29
+ setCurrentData,
30
+ } = props;
25
31
 
26
32
  const itemsPerPage = 100;
27
33
  const firstPage = 1;
@@ -62,14 +68,13 @@ const ActivityLog = () => {
62
68
  const handleGetLog = async () => {
63
69
  const params = getParams();
64
70
  if (isModeUser) {
65
- await dispatch(activityLogActions.getActivityLogByUser(params));
71
+ await getActivityLogByUser(params);
66
72
  } else {
67
- await dispatch(activityLogActions.getActivityLog(params));
73
+ await getActivityLog(params);
68
74
  }
69
75
  };
70
76
 
71
- const handleUpdateStructuredDate = async () =>
72
- await dispatch(structuredDataActions.getStructuredData(null, null, false));
77
+ const handleUpdateStructuredDate = async () => await getStructuredData(null, null, false);
73
78
 
74
79
  // biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
75
80
  useEffect(() => {
@@ -79,7 +84,7 @@ const ActivityLog = () => {
79
84
  // biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
80
85
  useEffect(() => {
81
86
  handleUpdateStructuredDate();
82
- dispatch(structuredDataActions.setCurrentData(null));
87
+ setCurrentData(null);
83
88
  }, []);
84
89
 
85
90
  const onScroll = (e: any) => setIsScrolling(e.target.scrollTop > 0);
@@ -87,11 +92,11 @@ const ActivityLog = () => {
87
92
  const handleSelectChange = async (value: string) => {
88
93
  const params = getParams();
89
94
  if (value === "user") {
90
- await dispatch(activityLogActions.getActivityLogByUser({ ...params, page: firstPage }));
95
+ await getActivityLogByUser({ ...params, page: firstPage });
91
96
  } else {
92
- await dispatch(activityLogActions.getActivityLog({ ...params, page: firstPage }));
97
+ await getActivityLog({ ...params, page: firstPage });
93
98
  }
94
- dispatch(activityLogActions.setListMode(value));
99
+ setListMode(value);
95
100
  };
96
101
 
97
102
  const sortItems = async (isAscending: boolean) => {
@@ -134,7 +139,7 @@ const ActivityLog = () => {
134
139
  format: [downloadForm.format],
135
140
  };
136
141
 
137
- await dispatch(activityLogActions.downloadActivityLog(data));
142
+ await downloadActivityLog(data);
138
143
 
139
144
  toggleDownloadModal();
140
145
  setDownloadForm(initialState);
@@ -206,7 +211,6 @@ const ActivityLog = () => {
206
211
  return (
207
212
  <MainWrapper
208
213
  title="Logs"
209
- screen="activity-log"
210
214
  rightButton={rightButtonProps}
211
215
  rightLineButton={rightLineButtonProps}
212
216
  searchAction={handleSearch}
@@ -290,4 +294,29 @@ export interface IDownloadFormState {
290
294
  endDate: string | null;
291
295
  }
292
296
 
293
- export default ActivityLog;
297
+ interface IActivityLogProps {
298
+ activityLog: ILogItemsByDay | ILogItemsByUser;
299
+ listMode: string;
300
+ getActivityLog(params: LogActivityPaginationRequest): Promise<void>;
301
+ getActivityLogByUser(params: LogActivityPaginationRequest): Promise<void>;
302
+ setListMode(listMode: string): void;
303
+ downloadActivityLog(data: LogActivityExportRequest): Promise<void>;
304
+ getStructuredData(token: string | null, siteID?: number | null, hasLoading?: boolean): Promise<void>;
305
+ setCurrentData(currentStructuredData: IStructuredData | null): void;
306
+ }
307
+
308
+ const mapStateToProps = (state: IRootState) => ({
309
+ activityLog: state.activityLog.activityLog,
310
+ listMode: state.activityLog.listMode,
311
+ });
312
+
313
+ const mapDispatchToProps = {
314
+ getActivityLog: activityLogActions.getActivityLog,
315
+ getActivityLogByUser: activityLogActions.getActivityLogByUser,
316
+ setListMode: activityLogActions.setListMode,
317
+ downloadActivityLog: activityLogActions.downloadActivityLog,
318
+ getStructuredData: structuredDataActions.getStructuredData,
319
+ setCurrentData: structuredDataActions.setCurrentData,
320
+ };
321
+
322
+ export default connect(mapStateToProps, mapDispatchToProps)(ActivityLog);