@griddo/ax 1.75.92 → 1.75.93
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/package.json +2 -2
- package/src/__mocks__/store/SitesList.ts +24 -0
- package/src/__tests__/components/Avatar/__snapshots__/Avatar.test.tsx.snap +10 -10
- package/src/__tests__/modules/Sites/Sites.test.tsx +3 -0
- package/src/__tests__/modules/Sites/SitesList/SitesList.test.tsx +8 -1
- package/src/components/ErrorCenter/index.tsx +10 -1
- package/src/components/Fields/ComponentContainer/index.tsx +1 -1
- package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +34 -19
- package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/style.tsx +5 -0
- package/src/components/Notification/style.tsx +2 -2
- package/src/components/Tooltip/style.tsx +1 -1
- package/src/containers/App/actions.tsx +2 -0
- package/src/containers/Gallery/actions.tsx +19 -10
- package/src/containers/PageEditor/actions.tsx +19 -22
- package/src/containers/PageEditor/utils.tsx +5 -5
- package/src/containers/Sites/actions.tsx +35 -8
- package/src/containers/Sites/constants.tsx +1 -0
- package/src/containers/Sites/interfaces.tsx +8 -2
- package/src/containers/Sites/reducer.tsx +18 -1
- package/src/containers/Users/actions.tsx +23 -2
- package/src/forms/validators.tsx +1 -3
- package/src/helpers/requests.tsx +1 -1
- package/src/hooks/bulk.tsx +2 -1
- package/src/hooks/content.tsx +27 -2
- package/src/hooks/index.tsx +4 -1
- package/src/hooks/window.ts +16 -0
- package/src/modules/App/Routing/NavMenu/index.tsx +3 -2
- package/src/modules/App/Routing/NavMenu/style.tsx +2 -2
- package/src/modules/Content/PageItem/index.tsx +18 -10
- package/src/modules/Content/PageItem/style.tsx +26 -4
- package/src/modules/Content/index.tsx +41 -5
- package/src/modules/Content/utils.tsx +5 -2
- package/src/modules/CreatePass/index.tsx +8 -11
- package/src/modules/FramePreview/index.tsx +2 -6
- package/src/modules/GlobalEditor/PageBrowser/index.tsx +2 -4
- package/src/modules/GlobalEditor/index.tsx +13 -15
- package/src/modules/PageEditor/Editor/index.tsx +1 -3
- package/src/modules/PageEditor/PageBrowser/index.tsx +2 -6
- package/src/modules/PageEditor/index.tsx +23 -20
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/index.tsx +1 -1
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +3 -3
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/index.tsx +17 -10
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +23 -25
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/style.tsx +3 -3
- package/src/modules/Sites/SitesList/GridView/GridHeaderFilter/index.tsx +2 -2
- package/src/modules/Sites/SitesList/GridView/GridSiteItem/index.tsx +1 -1
- package/src/modules/Sites/SitesList/atoms.tsx +1 -1
- package/src/modules/Sites/SitesList/hooks.tsx +3 -4
- package/src/modules/Sites/SitesList/index.tsx +47 -19
- package/src/modules/Sites/SitesList/style.tsx +7 -1
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +11 -6
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/style.tsx +10 -1
- package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/index.tsx +25 -1
- package/src/modules/StructuredData/StructuredDataList/utils.tsx +5 -3
- package/src/modules/Users/UserCreate/index.tsx +4 -1
- package/src/types/index.tsx +21 -2
|
@@ -13,6 +13,7 @@ export const SET_INITIAL_VALUES = `${NAME}/SET_INITIAL_VALUES`;
|
|
|
13
13
|
export const SET_SAVED_SITE_INFO = `${NAME}/SET_SAVED_SITE_INFO`;
|
|
14
14
|
export const SET_CURRENT_SITE_ERROR_PAGES = `${NAME}/SET_CURRENT_SITE_ERROR_PAGES`;
|
|
15
15
|
export const SET_CONTENT_FILTERS = `${NAME}/SET_CONTENT_FILTERS`;
|
|
16
|
+
export const SET_CONFIG = `${NAME}/SET_CONFIG`;
|
|
16
17
|
|
|
17
18
|
export const ITEMS_PER_PAGE = 50;
|
|
18
19
|
|
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
SET_CURRENT_SITE_ERROR_PAGES,
|
|
13
13
|
SET_CONTENT_FILTERS,
|
|
14
14
|
SET_SITES_TOTAL_ITEMS,
|
|
15
|
+
SET_CONFIG
|
|
15
16
|
} from "./constants";
|
|
16
|
-
import { ISite } from "@ax/types";
|
|
17
|
+
import { ISite, ISiteListConfig } from "@ax/types";
|
|
17
18
|
|
|
18
19
|
export interface ISetFilter {
|
|
19
20
|
type: typeof SET_FILTER;
|
|
@@ -77,7 +78,12 @@ export interface ISetCurrentSiteErrorPages {
|
|
|
77
78
|
|
|
78
79
|
export interface ISetContentFilters {
|
|
79
80
|
type: typeof SET_CONTENT_FILTERS;
|
|
80
|
-
payload: { contentFilters: Record<string,string> | null };
|
|
81
|
+
payload: { contentFilters: Record<string, string> | null };
|
|
82
|
+
}
|
|
83
|
+
export interface ISetConfig {
|
|
84
|
+
type: typeof SET_CONFIG;
|
|
85
|
+
payload: { config: ISiteListConfig };
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
export type SitesActionsCreators = ISetSitesAction & ISetCurrentSiteInfoAction;
|
|
89
|
+
|
|
@@ -12,9 +12,10 @@ import {
|
|
|
12
12
|
SET_SAVED_SITE_INFO,
|
|
13
13
|
SET_CURRENT_SITE_ERROR_PAGES,
|
|
14
14
|
SET_CONTENT_FILTERS,
|
|
15
|
+
SET_CONFIG,
|
|
15
16
|
} from "./constants";
|
|
16
17
|
|
|
17
|
-
import { ISite, IPage, ILanguage } from "@ax/types";
|
|
18
|
+
import { ISite, IPage, ILanguage, ISiteListConfig } from "@ax/types";
|
|
18
19
|
|
|
19
20
|
import { SitesActionsCreators } from "./interfaces";
|
|
20
21
|
|
|
@@ -32,8 +33,22 @@ export interface ISitesState {
|
|
|
32
33
|
savedSiteInfo: any;
|
|
33
34
|
currentSiteErrorPages: number[];
|
|
34
35
|
contentFilters: Record<string, string> | null;
|
|
36
|
+
config: ISiteListConfig;
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
const config = {
|
|
40
|
+
displayRecentSites: false,
|
|
41
|
+
mode: "grid",
|
|
42
|
+
filter: "&order=lastAccess-desc",
|
|
43
|
+
filterValues: { order: "desc", liveStatus: "all" },
|
|
44
|
+
sortedListStatus: {
|
|
45
|
+
isAscending: false,
|
|
46
|
+
sortedByDateCreated: false,
|
|
47
|
+
sortedByLastAccess: true,
|
|
48
|
+
sortedByTitle: false,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
37
52
|
export const initialState = {
|
|
38
53
|
currentSiteName: null,
|
|
39
54
|
currentSitePages: [],
|
|
@@ -48,6 +63,7 @@ export const initialState = {
|
|
|
48
63
|
savedSiteInfo: null,
|
|
49
64
|
currentSiteErrorPages: [],
|
|
50
65
|
contentFilters: null,
|
|
66
|
+
config,
|
|
51
67
|
};
|
|
52
68
|
|
|
53
69
|
export function reducer(state = initialState, action: SitesActionsCreators): ISitesState {
|
|
@@ -65,6 +81,7 @@ export function reducer(state = initialState, action: SitesActionsCreators): ISi
|
|
|
65
81
|
case SET_SAVED_SITE_INFO:
|
|
66
82
|
case SET_CURRENT_SITE_ERROR_PAGES:
|
|
67
83
|
case SET_CONTENT_FILTERS:
|
|
84
|
+
case SET_CONFIG:
|
|
68
85
|
return { ...state, ...action.payload };
|
|
69
86
|
default:
|
|
70
87
|
return state;
|
|
@@ -2,8 +2,8 @@ import { Dispatch } from "redux";
|
|
|
2
2
|
import { SET_USERS, SET_USER_FORM, SET_CURRENT_USER } from "./constants";
|
|
3
3
|
|
|
4
4
|
import { ISetUsers, ISetCurrentUser, ISetUserForm } from "./interfaces";
|
|
5
|
-
import { IUser } from "@ax/types";
|
|
6
|
-
import { users } from "@ax/api";
|
|
5
|
+
import { ICreatePasswordParams, IUser } from "@ax/types";
|
|
6
|
+
import { global, users } from "@ax/api";
|
|
7
7
|
import { appActions } from "@ax/containers/App";
|
|
8
8
|
import { handleRequest, isReqOk } from "@ax/helpers";
|
|
9
9
|
|
|
@@ -130,6 +130,26 @@ function createUser(data: { name: string; email: string; sites: any[] }): (dispa
|
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
function createPassword(id: string, params: ICreatePasswordParams): (dispatch: Dispatch) => Promise<boolean> {
|
|
134
|
+
return async (dispatch) => {
|
|
135
|
+
try {
|
|
136
|
+
const callback = async () => global.createPassword(id, params);
|
|
137
|
+
|
|
138
|
+
const responseActions = {
|
|
139
|
+
handleSuccess: async (response: any) => {
|
|
140
|
+
await getUser("me", response.token)(dispatch);
|
|
141
|
+
},
|
|
142
|
+
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
return await handleRequest(callback, responseActions, [appActions.setIsSaving])(dispatch);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
console.log(e); // TODO: capturar error bien
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
133
153
|
function deleteUser(id: number | number[]): (dispatch: Dispatch) => Promise<boolean> {
|
|
134
154
|
return async (dispatch) => {
|
|
135
155
|
try {
|
|
@@ -201,4 +221,5 @@ export {
|
|
|
201
221
|
setCurrentUser,
|
|
202
222
|
deleteUser,
|
|
203
223
|
resendInvitation,
|
|
224
|
+
createPassword,
|
|
204
225
|
};
|
package/src/forms/validators.tsx
CHANGED
|
@@ -338,9 +338,7 @@ const findPackagesActivationErrors = (
|
|
|
338
338
|
let isCurrentTemplateActivated = true;
|
|
339
339
|
let hasDeactivatedModules = false;
|
|
340
340
|
|
|
341
|
-
const {
|
|
342
|
-
editorContent: { template },
|
|
343
|
-
} = pageEditor?.editorContent;
|
|
341
|
+
const { template } = pageEditor?.editorContent;
|
|
344
342
|
|
|
345
343
|
if (template && !isGlobal) {
|
|
346
344
|
const mainContentModules = template?.mainContent?.modules;
|
package/src/helpers/requests.tsx
CHANGED
package/src/hooks/bulk.tsx
CHANGED
|
@@ -4,10 +4,11 @@ import { areEquals } from "@ax/helpers";
|
|
|
4
4
|
import { ICheck } from "@ax/types";
|
|
5
5
|
|
|
6
6
|
const useBulkSelection = (itemIDs: any[]) => {
|
|
7
|
-
const selectedItemsInitialState: { all: any[]; notPublished: any[]; published: any[] } = {
|
|
7
|
+
const selectedItemsInitialState: { all: any[]; notPublished: any[]; published: any[]; drafts: any[] } = {
|
|
8
8
|
all: [],
|
|
9
9
|
notPublished: [],
|
|
10
10
|
published: [],
|
|
11
|
+
drafts: [],
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
const [items, setItems] = useState<any[]>([]);
|
package/src/hooks/content.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
1
|
+
import { useEffect, useLayoutEffect, useState } from "react";
|
|
2
|
+
import { useWindowSize } from "./window";
|
|
2
3
|
|
|
3
4
|
const useCategoryColors = (): any => {
|
|
4
5
|
const fixedColors = [
|
|
@@ -38,4 +39,28 @@ const useCategoryColors = (): any => {
|
|
|
38
39
|
};
|
|
39
40
|
};
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
const useAdaptiveText = (
|
|
43
|
+
containerRef: React.RefObject<HTMLDivElement>,
|
|
44
|
+
fullText: string,
|
|
45
|
+
padding = 0
|
|
46
|
+
): { text: string; width: number } => {
|
|
47
|
+
const [output, setTitle] = useState({ text: "", width: 0 });
|
|
48
|
+
|
|
49
|
+
const [width] = useWindowSize();
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
setTitle({ text: "", width: 0 });
|
|
53
|
+
}, [width]);
|
|
54
|
+
|
|
55
|
+
useLayoutEffect(() => {
|
|
56
|
+
if (containerRef.current) {
|
|
57
|
+
const cellWidth = containerRef.current.offsetWidth;
|
|
58
|
+
const cellPadding = padding * 2;
|
|
59
|
+
setTitle({ text: fullText, width: cellWidth - cellPadding });
|
|
60
|
+
}
|
|
61
|
+
}, [containerRef, fullText, output.width, padding]);
|
|
62
|
+
|
|
63
|
+
return output;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export { useCategoryColors, useAdaptiveText };
|
package/src/hooks/index.tsx
CHANGED
|
@@ -2,7 +2,8 @@ import { useBulkSelection } from "./bulk";
|
|
|
2
2
|
import { useDebounce, useEqualStructured, useIsDirty, usePrevious } from "./forms";
|
|
3
3
|
import { useHandleClickOutside, useModal, useToast } from "./modals";
|
|
4
4
|
import { useURLSearchParam } from "./location";
|
|
5
|
-
import { useCategoryColors } from "./content";
|
|
5
|
+
import { useCategoryColors, useAdaptiveText } from "./content";
|
|
6
|
+
import { useWindowSize } from "./window";
|
|
6
7
|
import { useOnMessageReceivedFromIframe, useOnMessageReceivedFromOutside } from "./iframe";
|
|
7
8
|
|
|
8
9
|
export {
|
|
@@ -16,6 +17,8 @@ export {
|
|
|
16
17
|
useBulkSelection,
|
|
17
18
|
useURLSearchParam,
|
|
18
19
|
useCategoryColors,
|
|
20
|
+
useWindowSize,
|
|
21
|
+
useAdaptiveText,
|
|
19
22
|
useOnMessageReceivedFromIframe,
|
|
20
23
|
useOnMessageReceivedFromOutside,
|
|
21
24
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useLayoutEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
const useWindowSize = (): number[] => {
|
|
4
|
+
const [size, setSize] = useState([0, 0]);
|
|
5
|
+
useLayoutEffect(() => {
|
|
6
|
+
const updateSize = () => {
|
|
7
|
+
setSize([window.innerWidth, window.innerHeight]);
|
|
8
|
+
};
|
|
9
|
+
window.addEventListener("resize", updateSize);
|
|
10
|
+
updateSize();
|
|
11
|
+
return () => window.removeEventListener("resize", updateSize);
|
|
12
|
+
}, []);
|
|
13
|
+
return size;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { useWindowSize };
|
|
@@ -40,6 +40,7 @@ const NavMenu = (props: IProps) => {
|
|
|
40
40
|
|
|
41
41
|
const sitesPath = "/sites/";
|
|
42
42
|
const isSite = location.pathname.includes(sitesPath) && location.pathname.length > sitesPath.length;
|
|
43
|
+
const siteSelector = location.pathname === "/sites";
|
|
43
44
|
|
|
44
45
|
const goToPublishedSite = () => {
|
|
45
46
|
const language = siteLanguages.find((l) => l.id === lang.id);
|
|
@@ -49,7 +50,7 @@ const NavMenu = (props: IProps) => {
|
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
const goToSites = () => {
|
|
52
|
-
|
|
53
|
+
!siteSelector && setHistoryPush("/sites");
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
const goToProfile = () => {
|
|
@@ -125,7 +126,7 @@ const NavMenu = (props: IProps) => {
|
|
|
125
126
|
return (
|
|
126
127
|
<NavProvider value={{ state, toggleSubmenu }}>
|
|
127
128
|
<S.NavWrapper type={config.type} isOpened={isOpened}>
|
|
128
|
-
<S.Home type={config.type} onClick={goToSites} isSite={isSite} isOpened={isOpened}>
|
|
129
|
+
<S.Home type={config.type} onClick={goToSites} isSite={isSite} isOpened={isOpened} siteSelector={siteSelector}>
|
|
129
130
|
{isSite && (
|
|
130
131
|
<S.GoBack>
|
|
131
132
|
<Icon name="LeftArrow" />
|
|
@@ -14,7 +14,7 @@ export const GoBack = styled.div`
|
|
|
14
14
|
width: auto;
|
|
15
15
|
`;
|
|
16
16
|
|
|
17
|
-
export const Home = styled.div<{ type: string; isSite: boolean; isOpened: boolean }>`
|
|
17
|
+
export const Home = styled.div<{ type: string; isSite: boolean; isOpened: boolean; siteSelector: boolean }>`
|
|
18
18
|
padding: ${(p) => `${p.theme.spacing.xs} 12px`};
|
|
19
19
|
background-color: ${(p) =>
|
|
20
20
|
p.type === "multisite" ? p.theme.color.uiMainMenuBackground : p.theme.color.uiBarBackground};
|
|
@@ -28,7 +28,7 @@ export const Home = styled.div<{ type: string; isSite: boolean; isOpened: boolea
|
|
|
28
28
|
& + ul {
|
|
29
29
|
margin-top: ${(p) => p.theme.spacing.s};
|
|
30
30
|
}
|
|
31
|
-
cursor: ${(p) => (p.
|
|
31
|
+
cursor: ${(p) => (p.siteSelector ? "default" : "pointer")};
|
|
32
32
|
|
|
33
33
|
&:hover {
|
|
34
34
|
& > ${NavLink} {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import React, { memo, useState } from "react";
|
|
2
|
-
|
|
1
|
+
import React, { memo, useRef, useState } from "react";
|
|
3
2
|
import { schemas } from "components";
|
|
3
|
+
import { useTheme } from "styled-components";
|
|
4
4
|
|
|
5
|
-
import { useModal } from "@ax/hooks";
|
|
5
|
+
import { useAdaptiveText, useModal } from "@ax/hooks";
|
|
6
6
|
import { getHumanLastModifiedDate, getTemplateDisplayName, slugify } from "@ax/helpers";
|
|
7
7
|
import { IPage, ISite, ISavePageParams, ICheck, IColumn, IPageLanguage, IDataPack } from "@ax/types";
|
|
8
8
|
import { pageStatus, ISetCurrentPageIDAction } from "@ax/containers/PageEditor/interfaces";
|
|
9
|
-
|
|
10
9
|
import {
|
|
11
10
|
CheckField,
|
|
12
11
|
FieldsBehavior,
|
|
@@ -81,6 +80,12 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
81
80
|
const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
|
|
82
81
|
const { isOpen: isCopyOpen, toggleModal: toggleCopyModal } = useModal();
|
|
83
82
|
|
|
83
|
+
const nameCellRef = useRef<HTMLDivElement>(null);
|
|
84
|
+
const theme: any = useTheme();
|
|
85
|
+
const nameCellPadding = Number(theme.spacing.s.slice(0, -2));
|
|
86
|
+
const title = useAdaptiveText(nameCellRef, page.title, nameCellPadding);
|
|
87
|
+
const path = useAdaptiveText(nameCellRef, fullPath.page, nameCellPadding);
|
|
88
|
+
|
|
84
89
|
const currentTemplateDataPacks = schemas.templates[templateId].dataPacks;
|
|
85
90
|
|
|
86
91
|
const isCopyable = !currentTemplateDataPacks;
|
|
@@ -472,12 +477,15 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
472
477
|
<S.CheckCell role="cell">
|
|
473
478
|
<CheckField name="check" value={page.id} checked={isSelected} onChange={handleOnChange} />
|
|
474
479
|
</S.CheckCell>
|
|
475
|
-
<S.NameCell role="cell" onClick={goToPage}>
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
480
|
+
<S.NameCell role="cell" onClick={goToPage} ref={nameCellRef}>
|
|
481
|
+
{isHome && (
|
|
482
|
+
<S.Home>
|
|
483
|
+
<Icon name="home" />
|
|
484
|
+
Home
|
|
485
|
+
</S.Home>
|
|
486
|
+
)}
|
|
487
|
+
<S.Title width={title.width}>{title.text}</S.Title>
|
|
488
|
+
{!isHome && <S.Slug width={path.width}>{path.text}</S.Slug>}
|
|
481
489
|
</S.NameCell>
|
|
482
490
|
{CategoryColumns}
|
|
483
491
|
{activeColumns.includes("type") && (
|
|
@@ -24,14 +24,23 @@ const NameCell = styled(Cell)`
|
|
|
24
24
|
}
|
|
25
25
|
`;
|
|
26
26
|
|
|
27
|
-
const Title = styled.div
|
|
27
|
+
const Title = styled.div<{ width: number }>`
|
|
28
28
|
${(p) => p.theme.textStyle.uiL};
|
|
29
29
|
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
30
|
-
display:
|
|
31
|
-
|
|
30
|
+
display: inline;
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
text-overflow: ellipsis;
|
|
34
|
+
width: ${(p) => `${p.width}px`};
|
|
32
35
|
`;
|
|
33
36
|
|
|
34
|
-
const Slug = styled.div
|
|
37
|
+
const Slug = styled.div<{ width: number }>`
|
|
38
|
+
display: inline;
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
text-overflow: ellipsis;
|
|
42
|
+
width: ${(p) => `${p.width}px`};
|
|
43
|
+
`;
|
|
35
44
|
|
|
36
45
|
const TypeCell = styled(Cell)`
|
|
37
46
|
flex: 0 0 170px;
|
|
@@ -84,6 +93,18 @@ const Mark = styled.div`
|
|
|
84
93
|
align-items: center;
|
|
85
94
|
`;
|
|
86
95
|
|
|
96
|
+
const Home = styled.span`
|
|
97
|
+
${(p) => p.theme.textStyle.uiXS};
|
|
98
|
+
width: 63px;
|
|
99
|
+
height: 20px;
|
|
100
|
+
margin-bottom: 8px;
|
|
101
|
+
background-color: ${(p) => p.theme.color.uiBackground03};
|
|
102
|
+
display: flex;
|
|
103
|
+
justify-content: center;
|
|
104
|
+
align-items: center;
|
|
105
|
+
padding: 2px 10px 2px 4px;
|
|
106
|
+
`;
|
|
107
|
+
|
|
87
108
|
const Wrapper = styled.div`
|
|
88
109
|
cursor: pointer;
|
|
89
110
|
`;
|
|
@@ -191,4 +212,5 @@ export {
|
|
|
191
212
|
ModalContent,
|
|
192
213
|
GlobalCell,
|
|
193
214
|
Mark,
|
|
215
|
+
Home,
|
|
194
216
|
};
|
|
@@ -119,6 +119,10 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
119
119
|
query: currentFilterQuery,
|
|
120
120
|
} = useFilterQuery(contentFilters);
|
|
121
121
|
const { state: locationState } = useLocation<{ isFromEditor: boolean }>();
|
|
122
|
+
const [notification, setNotification] = useState<{
|
|
123
|
+
text: string;
|
|
124
|
+
subErrors?: { id: number; error: string }[];
|
|
125
|
+
} | null>(null);
|
|
122
126
|
|
|
123
127
|
const currentFilter = getCurrentFilter(structuredData, filter);
|
|
124
128
|
const checkFromPage = currentFilter ? currentFilter.fromPage : undefined;
|
|
@@ -169,6 +173,7 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
169
173
|
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
170
174
|
const [arePagesTranslated, setArePagesTranslated] = useState(false);
|
|
171
175
|
const [templateInstanceError, setTemplateInstanceError] = useState({ error: false, templateName: "" });
|
|
176
|
+
const [pagesSelected, setPagesSelected] = useState<any[]>([]);
|
|
172
177
|
|
|
173
178
|
const {
|
|
174
179
|
resetBulkSelection,
|
|
@@ -302,11 +307,22 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
302
307
|
|
|
303
308
|
const bulkFilter = (bulkSelection: number[]) => filterByStatus(bulkSelection, currentSitePages);
|
|
304
309
|
|
|
305
|
-
const handleAddToBulk = (item: ICheck) =>
|
|
310
|
+
const handleAddToBulk = (item: ICheck) => {
|
|
311
|
+
const page = currentSitePages.find((page: IPage) => page.id === item.value);
|
|
312
|
+
|
|
313
|
+
item.isChecked && !pagesSelected.includes(item)
|
|
314
|
+
? setPagesSelected((pagesSelected) => [...pagesSelected, page])
|
|
315
|
+
: setPagesSelected(pagesSelected.filter((page: IPage) => page.id !== item.value));
|
|
316
|
+
|
|
317
|
+
addToBulkSelection(item, bulkFilter);
|
|
318
|
+
};
|
|
306
319
|
|
|
307
320
|
const handleSelectAll = () => selectAllItems(bulkFilter);
|
|
308
321
|
|
|
309
|
-
const unselectAllItems = () =>
|
|
322
|
+
const unselectAllItems = () => {
|
|
323
|
+
resetBulkSelection();
|
|
324
|
+
setPagesSelected([]);
|
|
325
|
+
};
|
|
310
326
|
|
|
311
327
|
const selectItems = () => (checkState.isAllSelected ? unselectAllItems() : handleSelectAll());
|
|
312
328
|
|
|
@@ -345,11 +361,11 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
345
361
|
};
|
|
346
362
|
|
|
347
363
|
const handleBulkDelete = async (pageIds: number[]) => {
|
|
348
|
-
const globalPageIds =
|
|
364
|
+
const globalPageIds = pagesSelected
|
|
349
365
|
.filter((page: IPage) => pageIds.includes(page.id) && page.origin === "GLOBAL")
|
|
350
366
|
.map((page: IPage) => page.id);
|
|
351
367
|
|
|
352
|
-
const filteredPageIds =
|
|
368
|
+
const filteredPageIds = pagesSelected
|
|
353
369
|
.filter((page: IPage) => pageIds.includes(page.id) && page.origin !== "GLOBAL")
|
|
354
370
|
.map((page: IPage) => page.id);
|
|
355
371
|
|
|
@@ -385,7 +401,19 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
385
401
|
};
|
|
386
402
|
|
|
387
403
|
const bulkPublishAction = async (isPublish: boolean) => {
|
|
388
|
-
const { notPublished, published } = selectedItems;
|
|
404
|
+
const { notPublished, published, drafts } = selectedItems;
|
|
405
|
+
|
|
406
|
+
if (drafts && drafts.length > 0) {
|
|
407
|
+
const multiplePages = drafts.length > 1;
|
|
408
|
+
const getPage = (id: number) => currentSitePages.find((page) => page.id === id);
|
|
409
|
+
const getPageWarning = (pageId: number) =>
|
|
410
|
+
`The '${getPage(pageId)?.title}' page has a draft version. To publish it, you must do it from the editor.`;
|
|
411
|
+
const text = multiplePages
|
|
412
|
+
? `There are ${drafts.length} pages that cannot be published.`
|
|
413
|
+
: getPageWarning(drafts[0]);
|
|
414
|
+
const subErrors = multiplePages && drafts.map((draft) => ({ id: draft, error: getPageWarning(draft) }));
|
|
415
|
+
setNotification({ text, ...(subErrors && { subErrors }) });
|
|
416
|
+
}
|
|
389
417
|
|
|
390
418
|
const status = isPublish ? pageStatus.UPLOAD_PENDING : pageStatus.OFFLINE_PENDING;
|
|
391
419
|
|
|
@@ -713,6 +741,14 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
713
741
|
/>
|
|
714
742
|
)}
|
|
715
743
|
{(!!currentSiteErrorPages.length || errors.length > 0) && <Notification type="error" text={errorPagesText} />}
|
|
744
|
+
{notification && (
|
|
745
|
+
<Notification
|
|
746
|
+
type="warning"
|
|
747
|
+
text={notification.text}
|
|
748
|
+
subErrors={notification.subErrors}
|
|
749
|
+
resetError={() => setNotification(null)}
|
|
750
|
+
/>
|
|
751
|
+
)}
|
|
716
752
|
<TableList
|
|
717
753
|
tableHeader={Header}
|
|
718
754
|
pagination={pagination}
|
|
@@ -103,18 +103,20 @@ const getCurrentFilter = (structuredData: any, filter: any) =>
|
|
|
103
103
|
const filterByStatus = (bulkSelection: number[], currentSitePages: IPage[]): Record<string, number[]> => {
|
|
104
104
|
const notPublishedItems: number[] = [];
|
|
105
105
|
const publishedItems: number[] = [];
|
|
106
|
+
const draftItems: number[] = [];
|
|
106
107
|
|
|
107
108
|
currentSitePages.forEach((page: IPage) => {
|
|
108
|
-
const { id, liveStatus } = page;
|
|
109
|
+
const { id, liveStatus, haveDraftPage } = page;
|
|
109
110
|
if (bulkSelection.includes(id)) {
|
|
110
111
|
switch (liveStatus.status) {
|
|
111
112
|
case pageStatus.OFFLINE_PENDING:
|
|
112
113
|
case pageStatus.OFFLINE:
|
|
113
114
|
case pageStatus.UPLOAD_PENDING:
|
|
114
115
|
notPublishedItems.push(id);
|
|
116
|
+
haveDraftPage ? draftItems.push(id) : notPublishedItems.push(id);
|
|
115
117
|
break;
|
|
116
118
|
case pageStatus.PUBLISHED:
|
|
117
|
-
publishedItems.push(id);
|
|
119
|
+
haveDraftPage ? draftItems.push(id) : publishedItems.push(id);
|
|
118
120
|
break;
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -124,6 +126,7 @@ const filterByStatus = (bulkSelection: number[], currentSitePages: IPage[]): Rec
|
|
|
124
126
|
all: bulkSelection,
|
|
125
127
|
notPublished: notPublishedItems,
|
|
126
128
|
published: publishedItems,
|
|
129
|
+
drafts: draftItems,
|
|
127
130
|
};
|
|
128
131
|
|
|
129
132
|
return filteredItems;
|
|
@@ -2,16 +2,15 @@ import React, { useState } from "react";
|
|
|
2
2
|
import { useParams } from "react-router-dom";
|
|
3
3
|
import { connect } from "react-redux";
|
|
4
4
|
|
|
5
|
-
import { isReqOk } from "@ax/helpers";
|
|
6
|
-
import { global } from "@ax/api";
|
|
7
5
|
import { appActions } from "@ax/containers/App";
|
|
8
6
|
import { usersActions } from "@ax/containers/Users";
|
|
9
7
|
import { Button, FieldsBehavior, ErrorToast } from "@ax/components";
|
|
8
|
+
import { ICreatePasswordParams } from "@ax/types";
|
|
10
9
|
|
|
11
10
|
import * as S from "./style";
|
|
12
11
|
|
|
13
12
|
const CreatePass = (props: IProps) => {
|
|
14
|
-
const { setHistoryPush,
|
|
13
|
+
const { setHistoryPush, createPassword } = props;
|
|
15
14
|
|
|
16
15
|
const { id, token } = useParams<{ id: string; token: string }>();
|
|
17
16
|
|
|
@@ -36,12 +35,8 @@ const CreatePass = (props: IProps) => {
|
|
|
36
35
|
retypedPassword: state.pass2,
|
|
37
36
|
};
|
|
38
37
|
|
|
39
|
-
const
|
|
40
|
-
if (
|
|
41
|
-
const {
|
|
42
|
-
data: { token },
|
|
43
|
-
} = response;
|
|
44
|
-
await getUser("me", token);
|
|
38
|
+
const passCreated = await createPassword(id, params);
|
|
39
|
+
if (passCreated) {
|
|
45
40
|
setHistoryPush("/profile?init=true");
|
|
46
41
|
}
|
|
47
42
|
};
|
|
@@ -65,6 +60,7 @@ const CreatePass = (props: IProps) => {
|
|
|
65
60
|
value={state.pass1}
|
|
66
61
|
onChange={handlePass1Change}
|
|
67
62
|
validators={{ mandatory: true }}
|
|
63
|
+
autoComplete="off"
|
|
68
64
|
/>
|
|
69
65
|
<FieldsBehavior
|
|
70
66
|
fieldType="TextField"
|
|
@@ -74,6 +70,7 @@ const CreatePass = (props: IProps) => {
|
|
|
74
70
|
value={state.pass2}
|
|
75
71
|
onChange={handlePass2Change}
|
|
76
72
|
validators={{ isSamePass: state.pass1, mandatory: true }}
|
|
73
|
+
autoComplete="off"
|
|
77
74
|
/>
|
|
78
75
|
<Button type="submit" disabled={!validPasswords}>
|
|
79
76
|
Create and log in
|
|
@@ -86,12 +83,12 @@ const CreatePass = (props: IProps) => {
|
|
|
86
83
|
|
|
87
84
|
interface IProps {
|
|
88
85
|
setHistoryPush(path: string): any;
|
|
89
|
-
|
|
86
|
+
createPassword(id: string, params: ICreatePasswordParams): Promise<boolean>;
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
const mapDispatchToProps = {
|
|
93
90
|
setHistoryPush: appActions.setHistoryPush,
|
|
94
|
-
|
|
91
|
+
createPassword: usersActions.createPassword,
|
|
95
92
|
};
|
|
96
93
|
|
|
97
94
|
export default connect(null, mapDispatchToProps)(CreatePass);
|
|
@@ -30,11 +30,7 @@ const FramePreview = (props: IProps) => {
|
|
|
30
30
|
|
|
31
31
|
useOnMessageReceivedFromOutside(setEditorContent, setSelectedContent);
|
|
32
32
|
|
|
33
|
-
const {
|
|
34
|
-
editorContent: { canonicalSite, language, pageLanguages },
|
|
35
|
-
header,
|
|
36
|
-
footer,
|
|
37
|
-
} = content;
|
|
33
|
+
const { canonicalSite, language, pageLanguages, header, footer } = content;
|
|
38
34
|
|
|
39
35
|
document.body.classList.add("preview");
|
|
40
36
|
|
|
@@ -87,7 +83,7 @@ const FramePreview = (props: IProps) => {
|
|
|
87
83
|
selectEditorID={selectEditorID}
|
|
88
84
|
siteID={siteID}
|
|
89
85
|
isPage={true}
|
|
90
|
-
content={content
|
|
86
|
+
content={content}
|
|
91
87
|
header={currentSiteInfo && header}
|
|
92
88
|
footer={currentSiteInfo && footer}
|
|
93
89
|
languageID={language}
|
|
@@ -9,9 +9,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
9
9
|
const {
|
|
10
10
|
socials,
|
|
11
11
|
cloudinaryName,
|
|
12
|
-
content: {
|
|
13
|
-
editorContent: { path, slug, canonicalSite },
|
|
14
|
-
},
|
|
12
|
+
content: { path, slug, canonicalSite },
|
|
15
13
|
setSelectedContent,
|
|
16
14
|
globalLangs,
|
|
17
15
|
theme,
|
|
@@ -35,7 +33,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
35
33
|
return (
|
|
36
34
|
<Browser
|
|
37
35
|
isPage={true}
|
|
38
|
-
content={props.content
|
|
36
|
+
content={props.content}
|
|
39
37
|
socials={socials}
|
|
40
38
|
url={url}
|
|
41
39
|
theme={theme}
|