@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.
- package/config/griddo-config/index.js +0 -1
- package/package.json +4 -3
- package/src/GlobalStore.tsx +35 -91
- package/src/__tests__/hooks/heartbeat.test.tsx +88 -0
- package/src/components/MainWrapper/index.tsx +2 -14
- package/src/containers/ActivityLog/{thunks.ts → actions.tsx} +89 -104
- package/src/containers/ActivityLog/constants.tsx +6 -0
- package/src/containers/ActivityLog/index.tsx +3 -16
- package/src/containers/ActivityLog/interfaces.tsx +12 -0
- package/src/containers/ActivityLog/reducer.tsx +24 -0
- package/src/containers/Analytics/actions.tsx +109 -0
- package/src/containers/Analytics/constants.tsx +5 -0
- package/src/containers/Analytics/index.tsx +3 -14
- package/src/containers/Analytics/interfaces.tsx +9 -0
- package/src/containers/Analytics/reducer.tsx +28 -0
- package/src/containers/Domains/actions.tsx +58 -0
- package/src/containers/Domains/constants.tsx +5 -0
- package/src/containers/Domains/index.tsx +3 -12
- package/src/containers/Domains/interfaces.tsx +9 -0
- package/src/containers/Domains/reducer.tsx +22 -0
- package/src/containers/Redirects/actions.tsx +190 -0
- package/src/containers/Redirects/constants.tsx +17 -1
- package/src/containers/Redirects/index.tsx +3 -14
- package/src/containers/Redirects/interfaces.tsx +23 -0
- package/src/containers/Redirects/reducer.tsx +35 -0
- package/src/containers/Settings/Languages/actions.tsx +88 -0
- package/src/containers/Settings/Languages/constants.tsx +6 -0
- package/src/containers/Settings/Languages/index.tsx +3 -15
- package/src/containers/Settings/Languages/reducer.tsx +31 -0
- package/src/containers/Settings/Social/actions.tsx +63 -0
- package/src/containers/Settings/Social/constants.tsx +3 -0
- package/src/containers/Settings/Social/index.tsx +3 -11
- package/src/containers/Settings/Social/interfaces.tsx +9 -0
- package/src/containers/Settings/Social/reducer.tsx +18 -0
- package/src/containers/Sites/actions.tsx +2 -6
- package/src/hooks/heartbeat.ts +32 -0
- package/src/hooks/index.tsx +2 -0
- package/src/index.tsx +6 -7
- package/src/modules/ActivityLog/ItemLog/EventItem/index.tsx +27 -13
- package/src/modules/ActivityLog/ItemLogUser/UserItem/EventItem/index.tsx +27 -13
- package/src/modules/ActivityLog/index.tsx +51 -22
- package/src/modules/Analytics/index.tsx +42 -33
- package/src/modules/App/Routing/index.tsx +4 -5
- package/src/modules/FileDrive/index.tsx +1 -1
- package/src/modules/GlobalEditor/index.tsx +6 -8
- package/src/modules/GlobalSettings/Robots/index.tsx +47 -24
- package/src/modules/MediaGallery/index.tsx +1 -1
- package/src/modules/PageEditor/index.tsx +5 -9
- package/src/modules/Redirects/RedirectItem/index.tsx +22 -9
- package/src/modules/Redirects/RedirectPanel/index.tsx +14 -13
- package/src/modules/Redirects/index.tsx +69 -26
- package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +3 -4
- package/src/modules/Settings/Languages/LanguagePanel/Form/ConnectedField/index.tsx +18 -11
- package/src/modules/Settings/Languages/LanguagePanel/Form/index.tsx +9 -7
- package/src/modules/Settings/Languages/LanguagePanel/index.tsx +44 -38
- package/src/modules/Settings/Languages/Table/Header/index.tsx +19 -12
- package/src/modules/Settings/Languages/Table/Item/index.tsx +36 -21
- package/src/modules/Settings/Languages/Table/index.tsx +14 -6
- package/src/modules/Settings/Languages/index.tsx +30 -18
- package/src/modules/Settings/SeoAnalyticsSettings/Analytics/index.tsx +52 -42
- package/src/modules/Settings/Social/index.tsx +12 -17
- package/src/modules/StructuredData/StructuredDataList/index.tsx +2 -3
- package/src/types/index.tsx +6 -5
- package/tsconfig.paths.json +0 -1
- package/src/__tests__/modules/ActivityLog/ActivityLog.uc.test.tsx +0 -132
- package/src/__tests__/modules/Analytics/Analytics.uc.test.tsx +0 -168
- package/src/__tests__/modules/GlobalSettings/Robots/Robots.test.tsx +0 -110
- package/src/__tests__/modules/GlobalSettings/Robots/Robots.uc.test.tsx +0 -125
- package/src/__tests__/modules/Redirects/Redirects.uc.test.tsx +0 -164
- package/src/__tests__/modules/Settings/Languages/Languages.uc.test.tsx +0 -213
- package/src/__tests__/modules/Settings/Social/Social.uc.test.tsx +0 -171
- package/src/__tests__/store/activityLog.test.ts +0 -301
- package/src/__tests__/store/analytics.test.ts +0 -134
- package/src/__tests__/store/domains.test.ts +0 -107
- package/src/__tests__/store/languages.test.ts +0 -129
- package/src/__tests__/store/persist.test.ts +0 -47
- package/src/__tests__/store/redirects.test.ts +0 -313
- package/src/__tests__/store/social.test.ts +0 -165
- package/src/containers/ActivityLog/slice.ts +0 -45
- package/src/containers/Analytics/slice.ts +0 -48
- package/src/containers/Analytics/thunks.ts +0 -103
- package/src/containers/Domains/slice.ts +0 -37
- package/src/containers/Domains/thunks.ts +0 -60
- package/src/containers/Redirects/slice.ts +0 -60
- package/src/containers/Redirects/thunks.ts +0 -196
- package/src/containers/Settings/Languages/slice.ts +0 -48
- package/src/containers/Settings/Languages/thunks.ts +0 -83
- package/src/containers/Settings/Social/slice.ts +0 -40
- package/src/containers/Settings/Social/thunks.ts +0 -68
- package/src/store/hooks.ts +0 -37
- package/src/store/index.ts +0 -2
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import * as languagesActions from "./actions";
|
|
2
|
+
import { languagesReducer } from "./reducer";
|
|
3
3
|
|
|
4
|
-
|
|
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 };
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import * as socialActions from "./actions";
|
|
2
|
+
import { socialReducer } from "./reducer";
|
|
3
3
|
|
|
4
|
-
|
|
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,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(
|
|
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
|
-
|
|
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 };
|
package/src/hooks/index.tsx
CHANGED
|
@@ -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
|
-
<
|
|
22
|
+
<ConnectedRouter history={history}>
|
|
24
23
|
<PersistGate loading={undefined} persistor={configStore.persistor}>
|
|
25
24
|
<App />
|
|
26
25
|
</PersistGate>
|
|
27
|
-
</
|
|
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 {
|
|
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
|
|
35
|
+
return await restorePage(id);
|
|
38
36
|
case eventKey.DELETED_HEADER:
|
|
39
|
-
return await
|
|
37
|
+
return await restoreNavigation(id, "header");
|
|
40
38
|
case eventKey.DELETED_FOOTER:
|
|
41
|
-
return await
|
|
39
|
+
return await restoreNavigation(id, "footer");
|
|
42
40
|
case eventKey.DELETED_CATEGORY:
|
|
43
41
|
case eventKey.DELETED_CONTENT_TYPE:
|
|
44
|
-
return await
|
|
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
|
-
|
|
86
|
+
goToLogContent(contentType, content, siteID);
|
|
89
87
|
};
|
|
90
88
|
|
|
91
89
|
const handleKeyDown = () => {
|
|
92
90
|
const siteID = site?.id || null;
|
|
93
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
36
|
+
return await restorePage(id);
|
|
39
37
|
case eventKey.DELETED_HEADER:
|
|
40
|
-
return await
|
|
38
|
+
return await restoreNavigation(id, "header");
|
|
41
39
|
case eventKey.DELETED_FOOTER:
|
|
42
|
-
return await
|
|
40
|
+
return await restoreNavigation(id, "footer");
|
|
43
41
|
case eventKey.DELETED_CATEGORY:
|
|
44
42
|
case eventKey.DELETED_CONTENT_TYPE:
|
|
45
|
-
return await
|
|
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
|
-
|
|
87
|
+
goToLogContent(contentType, content, siteID);
|
|
90
88
|
};
|
|
91
89
|
|
|
92
90
|
const handleKeyDown = () => {
|
|
93
91
|
const siteID = site?.id || null;
|
|
94
|
-
|
|
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
|
-
|
|
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
|
|
16
|
+
import DownloadModal from "./DownloadModal";
|
|
18
17
|
|
|
19
18
|
import * as S from "./style";
|
|
20
19
|
|
|
21
|
-
const ActivityLog = () => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
71
|
+
await getActivityLogByUser(params);
|
|
66
72
|
} else {
|
|
67
|
-
await
|
|
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
|
-
|
|
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
|
|
95
|
+
await getActivityLogByUser({ ...params, page: firstPage });
|
|
91
96
|
} else {
|
|
92
|
-
await
|
|
97
|
+
await getActivityLog({ ...params, page: firstPage });
|
|
93
98
|
}
|
|
94
|
-
|
|
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
|
|
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
|
-
|
|
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);
|