@griddo/ax 1.75.91 → 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
|
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
|
|
|
3
3
|
|
|
4
4
|
import { appActions } from "@ax/containers/App";
|
|
5
5
|
import { sitesActions } from "@ax/containers/Sites";
|
|
6
|
-
import { ICheck, IGetSitesParams, IRootState, ISettingsForm, ISite, IUser } from "@ax/types";
|
|
6
|
+
import { ICheck, IGetSitesParams, IRootState, ISettingsForm, ISite, ISiteListConfig, IUser } from "@ax/types";
|
|
7
7
|
import { useBulkSelection, useModal } from "@ax/hooks";
|
|
8
8
|
import { MainWrapper, Modal, ErrorToast, Icon, IconAction, TableList, EmptyState } from "@ax/components";
|
|
9
9
|
|
|
@@ -31,6 +31,8 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
31
31
|
getSites,
|
|
32
32
|
publishSitesBulk,
|
|
33
33
|
unpublishSitesBulk,
|
|
34
|
+
config,
|
|
35
|
+
setListConfig,
|
|
34
36
|
} = props;
|
|
35
37
|
|
|
36
38
|
const isMount = useIsMount();
|
|
@@ -47,11 +49,15 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
47
49
|
|
|
48
50
|
const [page, setPage] = useState(firstPage);
|
|
49
51
|
const [form, setForm] = useState(initialState);
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
+
const currentConfig = localStorage.getItem("sitesConfig")
|
|
53
|
+
? JSON.parse(localStorage.getItem("sitesConfig") || "{}")
|
|
54
|
+
: config;
|
|
55
|
+
const [isRecentSitesListDisplayed, setIsRecentSitesListDisplayed] = useState<boolean>(
|
|
56
|
+
currentConfig.displayRecentSites
|
|
57
|
+
);
|
|
58
|
+
const [displayMode, setDisplayMode] = useState<string | "list" | "grid">(currentConfig.mode);
|
|
52
59
|
const [searchQuery, setSearchQuery] = useState<string | null>("");
|
|
53
|
-
const [currentFilterQuery, setCurrentFilterQuery] = useState(
|
|
54
|
-
|
|
60
|
+
const [currentFilterQuery, setCurrentFilterQuery] = useState(currentConfig.filter);
|
|
55
61
|
const tableRef = useRef<HTMLDivElement>(null);
|
|
56
62
|
|
|
57
63
|
const pagination = {
|
|
@@ -69,8 +75,8 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
69
75
|
action: openModal,
|
|
70
76
|
};
|
|
71
77
|
|
|
72
|
-
const {
|
|
73
|
-
const { setFiltersSelection, setFilterQuery, filterValues } = useFilterQuery();
|
|
78
|
+
const { setSortedListStatus } = useSortedListStatus();
|
|
79
|
+
const { setFiltersSelection, setFilterQuery, filterValues } = useFilterQuery(currentConfig.filterValues);
|
|
74
80
|
|
|
75
81
|
useEffect(() => {
|
|
76
82
|
if (token) {
|
|
@@ -84,6 +90,7 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
84
90
|
filterQuery: currentFilterQuery,
|
|
85
91
|
searchQuery: query,
|
|
86
92
|
};
|
|
93
|
+
|
|
87
94
|
if (isMount) {
|
|
88
95
|
getSites({ ...params, token });
|
|
89
96
|
} else {
|
|
@@ -103,6 +110,8 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
103
110
|
useEffect(() => {
|
|
104
111
|
if (tableRef.current) {
|
|
105
112
|
tableRef.current.scrollTo(0, 0);
|
|
113
|
+
const updatedConfig = { ...currentConfig, filterValues };
|
|
114
|
+
setListConfig(updatedConfig);
|
|
106
115
|
}
|
|
107
116
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
108
117
|
}, [page, searchQuery, filterValues]);
|
|
@@ -124,10 +133,20 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
124
133
|
const secondaryAction = { title: "Cancel", onClick: toggleModal };
|
|
125
134
|
|
|
126
135
|
const userHasSite = (siteID: number) => currentUser.sites.includes("all") || currentUser.sites.includes(siteID);
|
|
127
|
-
|
|
136
|
+
|
|
137
|
+
const toggleRecentSites = () => {
|
|
138
|
+
const updatedConfig = { ...config, displayRecentSites: !isRecentSitesListDisplayed };
|
|
139
|
+
setListConfig(updatedConfig);
|
|
140
|
+
setIsRecentSitesListDisplayed(!isRecentSitesListDisplayed);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const changeDisplayMode = (mode: "grid" | "list") => {
|
|
144
|
+
const updatedConfig = { ...config, mode };
|
|
145
|
+
setListConfig(updatedConfig);
|
|
146
|
+
setDisplayMode(mode);
|
|
147
|
+
};
|
|
128
148
|
|
|
129
149
|
const sortItems = (orderPointer: string, isAscending: boolean) => {
|
|
130
|
-
setIsRecentSitesListDisplayed(false);
|
|
131
150
|
setPage(firstPage);
|
|
132
151
|
const orderMethod = isAscending ? "asc" : "desc";
|
|
133
152
|
const sortedState = getSortedListStatus(orderPointer, isAscending);
|
|
@@ -135,15 +154,18 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
135
154
|
const pointer = orderPointer === "title" ? "name" : orderPointer;
|
|
136
155
|
const filtersSelection = setFiltersSelection("order", pointer, orderMethod);
|
|
137
156
|
const filterQuery = setFilterQuery(filtersSelection);
|
|
138
|
-
|
|
157
|
+
const updatedConfig = { ...currentConfig, filter: filterQuery, sortedListStatus: sortedState };
|
|
158
|
+
setListConfig(updatedConfig);
|
|
139
159
|
setCurrentFilterQuery(filterQuery);
|
|
140
160
|
};
|
|
141
161
|
|
|
142
162
|
const filterItems = async (filterPointer: string, filtersSelected: string) => {
|
|
143
|
-
setIsRecentSitesListDisplayed(false);
|
|
144
163
|
setPage(firstPage);
|
|
145
164
|
const filtersSelection = setFiltersSelection(filterPointer, filtersSelected);
|
|
146
165
|
const filterQuery = setFilterQuery(filtersSelection);
|
|
166
|
+
const updatedConfig = { ...currentConfig, filter: filterQuery };
|
|
167
|
+
setListConfig(updatedConfig);
|
|
168
|
+
|
|
147
169
|
setCurrentFilterQuery(filterQuery);
|
|
148
170
|
};
|
|
149
171
|
|
|
@@ -189,11 +211,11 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
189
211
|
{displayMode === "grid" ? (
|
|
190
212
|
<S.FilterSelect data-testid="all-sites-grid-filter">
|
|
191
213
|
<S.FilterSelectLabel data-testid="all-sites-grid-filter-label">Sort by:</S.FilterSelectLabel>{" "}
|
|
192
|
-
<GridHeaderFilter sortItems={sortItems} sortedState={sortedListStatus} />{" "}
|
|
214
|
+
<GridHeaderFilter sortItems={sortItems} sortedState={currentConfig.sortedListStatus} />{" "}
|
|
193
215
|
</S.FilterSelect>
|
|
194
216
|
) : null}
|
|
195
|
-
<IconAction icon="Grid2" onClick={() =>
|
|
196
|
-
<IconAction icon="BulletList" onClick={() =>
|
|
217
|
+
<IconAction icon="Grid2" onClick={() => changeDisplayMode("grid")} active={displayMode === "grid"} />
|
|
218
|
+
<IconAction icon="BulletList" onClick={() => changeDisplayMode("list")} active={displayMode === "list"} />
|
|
197
219
|
</S.HeaderIconsWrapper>
|
|
198
220
|
</S.SectionHeader>
|
|
199
221
|
);
|
|
@@ -254,9 +276,9 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
254
276
|
totalItems={totalItems}
|
|
255
277
|
selectItems={selectItems}
|
|
256
278
|
sortItems={sortItems}
|
|
257
|
-
sortedListStatus={sortedListStatus}
|
|
279
|
+
sortedListStatus={currentConfig.sortedListStatus}
|
|
258
280
|
filterItems={filterItems}
|
|
259
|
-
filterValues={filterValues}
|
|
281
|
+
filterValues={currentConfig.filterValues}
|
|
260
282
|
/>
|
|
261
283
|
);
|
|
262
284
|
|
|
@@ -300,9 +322,11 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
300
322
|
return (
|
|
301
323
|
<MainWrapper title="Sites" rightButton={rightButtonProps} searchAction={setSearchQuery}>
|
|
302
324
|
<ErrorToast />
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
325
|
+
<S.SitesListWrapper>
|
|
326
|
+
{currentRecentSites?.length > 0 ? <RecentSitesList /> : null}
|
|
327
|
+
<AllSitesHeader />
|
|
328
|
+
<AllSitesList />
|
|
329
|
+
</S.SitesListWrapper>
|
|
306
330
|
<Modal
|
|
307
331
|
isOpen={isOpen}
|
|
308
332
|
hide={toggleModal}
|
|
@@ -323,6 +347,7 @@ interface ISitesProps {
|
|
|
323
347
|
currentUser: IUser;
|
|
324
348
|
totalItems: number;
|
|
325
349
|
token: string;
|
|
350
|
+
config: ISiteListConfig;
|
|
326
351
|
}
|
|
327
352
|
|
|
328
353
|
const mapStateToProps = (state: IRootState) => ({
|
|
@@ -331,6 +356,7 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
331
356
|
token: state.app.token,
|
|
332
357
|
sites: state.sites.sites,
|
|
333
358
|
recentSites: state.sites.recentSites,
|
|
359
|
+
config: state.sites.config,
|
|
334
360
|
});
|
|
335
361
|
|
|
336
362
|
interface IDispatchProps {
|
|
@@ -339,6 +365,7 @@ interface IDispatchProps {
|
|
|
339
365
|
getSites(params: IGetSitesParams): void;
|
|
340
366
|
publishSitesBulk(ids: number[]): void;
|
|
341
367
|
unpublishSitesBulk(ids: number[]): void;
|
|
368
|
+
setListConfig(config: ISiteListConfig): void;
|
|
342
369
|
}
|
|
343
370
|
|
|
344
371
|
const mapDispatchToProps = {
|
|
@@ -347,6 +374,7 @@ const mapDispatchToProps = {
|
|
|
347
374
|
getSites: sitesActions.getSites,
|
|
348
375
|
publishSitesBulk: sitesActions.publishSitesBulk,
|
|
349
376
|
unpublishSitesBulk: sitesActions.unpublishSitesBulk,
|
|
377
|
+
setListConfig: sitesActions.setListConfig,
|
|
350
378
|
};
|
|
351
379
|
|
|
352
380
|
export type ISitesListProps = ISitesProps & IDispatchProps;
|
|
@@ -98,7 +98,7 @@ const RecentSitesItemsWrapper = styled.div<{ isHidden: boolean }>`
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
@media (min-width:
|
|
101
|
+
@media (min-width: 1750px) {
|
|
102
102
|
div:nth-child(6),
|
|
103
103
|
div:nth-child(7) {
|
|
104
104
|
display: block;
|
|
@@ -106,10 +106,15 @@ const RecentSitesItemsWrapper = styled.div<{ isHidden: boolean }>`
|
|
|
106
106
|
}
|
|
107
107
|
`;
|
|
108
108
|
|
|
109
|
+
const SitesListWrapper = styled.div`
|
|
110
|
+
max-width: calc(100vw - calc(24px * 3));
|
|
111
|
+
`;
|
|
112
|
+
|
|
109
113
|
const GridList = styled.div<{ isEmpty: boolean; fullWidth: boolean }>`
|
|
110
114
|
padding-top: ${(p) => p.theme.spacing.s};
|
|
111
115
|
padding-bottom: ${(p) => p.theme.spacing.m};
|
|
112
116
|
margin: 0 ${(p) => p.theme.spacing.m};
|
|
117
|
+
max-width: calc(100vw - calc(24px * 3));
|
|
113
118
|
|
|
114
119
|
${({ isEmpty, theme, fullWidth }) =>
|
|
115
120
|
isEmpty
|
|
@@ -156,6 +161,7 @@ export {
|
|
|
156
161
|
FilterSelectLabel,
|
|
157
162
|
RecentSites,
|
|
158
163
|
RecentSitesItemsWrapper,
|
|
164
|
+
SitesListWrapper,
|
|
159
165
|
GridList,
|
|
160
166
|
EmptyStateWrapper,
|
|
161
167
|
ImageWrapper,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import React, { memo, useState } from "react";
|
|
1
|
+
import React, { memo, useRef, useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
|
+
import { useTheme } from "styled-components";
|
|
3
4
|
|
|
4
5
|
import { ICheck, IAvailableSites, ISavePageParams, ILanguage, IPageLanguage, IPage, IColumn } from "@ax/types";
|
|
5
6
|
import { getHumanLastModifiedDate, getStructuredDataTitle } from "@ax/helpers";
|
|
@@ -16,7 +17,7 @@ import {
|
|
|
16
17
|
CategoryCell,
|
|
17
18
|
} from "@ax/components";
|
|
18
19
|
import { pageEditorActions } from "@ax/containers/PageEditor";
|
|
19
|
-
import { useModal } from "@ax/hooks";
|
|
20
|
+
import { useAdaptiveText, useModal } from "@ax/hooks";
|
|
20
21
|
import { DeleteModal, DuplicateModal, UnpublishModal } from "./atoms";
|
|
21
22
|
import { getCurrentLanguages } from "./utils";
|
|
22
23
|
|
|
@@ -62,9 +63,13 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
62
63
|
const { isOpen: isUnpublishOpen, toggleModal: toggleUnpublishModal } = useModal();
|
|
63
64
|
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
64
65
|
|
|
66
|
+
const nameCellRef = useRef<HTMLDivElement>(null);
|
|
67
|
+
const theme: any = useTheme();
|
|
68
|
+
const nameCellPadding = Number(theme.spacing.s.slice(0, -2));
|
|
69
|
+
const title = useAdaptiveText(nameCellRef, globalPage.title, nameCellPadding);
|
|
70
|
+
|
|
65
71
|
const { locale } = lang;
|
|
66
72
|
const {
|
|
67
|
-
title,
|
|
68
73
|
pageLanguages,
|
|
69
74
|
metaDescription,
|
|
70
75
|
metaTitle,
|
|
@@ -351,8 +356,8 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
351
356
|
<S.CheckCell role="cell">
|
|
352
357
|
<CheckField name="check" value={globalPage.id} checked={isSelected} onChange={handleOnChange} />
|
|
353
358
|
</S.CheckCell>
|
|
354
|
-
<S.NameCell role="cell" onClick={_handleClick}>
|
|
355
|
-
{title}
|
|
359
|
+
<S.NameCell role="cell" onClick={_handleClick} ref={nameCellRef}>
|
|
360
|
+
<S.Title width={title.width}>{title.text}</S.Title>
|
|
356
361
|
</S.NameCell>
|
|
357
362
|
{isAllPages && activeColumns.includes("type") && (
|
|
358
363
|
<S.TypeCell role="cell">{structuredData && getStructuredDataTitle(structuredData)}</S.TypeCell>
|
|
@@ -399,7 +404,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
399
404
|
toggleModal={toggleDeleteModal}
|
|
400
405
|
mainModalAction={mainDeleteModalAction}
|
|
401
406
|
secondaryModalAction={secondaryDeleteModalAction}
|
|
402
|
-
{...{ title, isTranslated, deleteAllVersions, setDeleteAllVersions }}
|
|
407
|
+
{...{ title: globalPage.title, isTranslated, deleteAllVersions, setDeleteAllVersions }}
|
|
403
408
|
/>
|
|
404
409
|
<UnpublishModal
|
|
405
410
|
isOpen={isUnpublishOpen}
|
|
@@ -13,9 +13,17 @@ const CheckCell = styled(Cell)`
|
|
|
13
13
|
`;
|
|
14
14
|
|
|
15
15
|
const NameCell = styled(Cell)`
|
|
16
|
+
flex-grow: 1;
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const Title = styled.div<{ width: number }>`
|
|
16
20
|
${(p) => p.theme.textStyle.uiL};
|
|
17
21
|
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
18
|
-
|
|
22
|
+
display: inline;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
white-space: nowrap;
|
|
25
|
+
text-overflow: ellipsis;
|
|
26
|
+
width: ${(p) => `${p.width}px`};
|
|
19
27
|
`;
|
|
20
28
|
|
|
21
29
|
const TypeCell = styled(Cell)`
|
|
@@ -165,4 +173,5 @@ export {
|
|
|
165
173
|
StyledClose,
|
|
166
174
|
FloatingSeo,
|
|
167
175
|
ModalContent,
|
|
176
|
+
Title,
|
|
168
177
|
};
|
|
@@ -39,7 +39,7 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
39
39
|
const { locale } = lang;
|
|
40
40
|
const { dataLanguages } = structuredData;
|
|
41
41
|
|
|
42
|
-
const currentStructuredDataColumns: any = columns[currentStructuredData
|
|
42
|
+
const currentStructuredDataColumns: any = columns[currentStructuredData?.id] || columns["all"];
|
|
43
43
|
|
|
44
44
|
const activeColumns = currentStructuredDataColumns
|
|
45
45
|
? Object.keys(currentStructuredDataColumns).filter((col: string) => currentStructuredDataColumns[col].show)
|
|
@@ -124,6 +124,10 @@ const StructuredDataList = (props: IProps): JSX.Element => {
|
|
|
124
124
|
const [arePagesTranslated, setArePagesTranslated] = useState(false);
|
|
125
125
|
const { state: locationState } = useLocation<{ isFromEditor: boolean }>();
|
|
126
126
|
const { categoryColors, addCategoryColors } = useCategoryColors();
|
|
127
|
+
const [notification, setNotification] = useState<{
|
|
128
|
+
text: string;
|
|
129
|
+
subErrors?: { id: number; error: string }[];
|
|
130
|
+
} | null>(null);
|
|
127
131
|
|
|
128
132
|
const scope = currentSiteID ? "site" : "global";
|
|
129
133
|
|
|
@@ -357,7 +361,19 @@ const StructuredDataList = (props: IProps): JSX.Element => {
|
|
|
357
361
|
};
|
|
358
362
|
|
|
359
363
|
const bulkPublishPage = async (isPublish: boolean) => {
|
|
360
|
-
const { notPublished, published } = selectedItems;
|
|
364
|
+
const { notPublished, published, drafts } = selectedItems;
|
|
365
|
+
|
|
366
|
+
if (drafts && drafts.length > 0) {
|
|
367
|
+
const multiplePages = drafts.length > 1;
|
|
368
|
+
const getPage = (id: number) => currentSitePages.find((page) => page.id === id);
|
|
369
|
+
const getPageWarning = (pageId: number) =>
|
|
370
|
+
`The '${getPage(pageId)?.title}' page has a draft version. To publish it, you must do it from the editor.`;
|
|
371
|
+
const text = multiplePages
|
|
372
|
+
? `There are ${drafts.length} pages that cannot be published.`
|
|
373
|
+
: getPageWarning(drafts[0]);
|
|
374
|
+
const subErrors = multiplePages && drafts.map((draft) => ({ id: draft, error: getPageWarning(draft) }));
|
|
375
|
+
setNotification({ text, ...(subErrors && { subErrors }) });
|
|
376
|
+
}
|
|
361
377
|
|
|
362
378
|
const status = isPublish ? pageStatus.UPLOAD_PENDING : pageStatus.OFFLINE_PENDING;
|
|
363
379
|
|
|
@@ -582,6 +598,14 @@ const StructuredDataList = (props: IProps): JSX.Element => {
|
|
|
582
598
|
)}
|
|
583
599
|
<ErrorToast />
|
|
584
600
|
{!!currentSiteErrorPages.length && <Notification type="error" text={errorPagesText} />}
|
|
601
|
+
{notification && (
|
|
602
|
+
<Notification
|
|
603
|
+
type="warning"
|
|
604
|
+
text={notification.text}
|
|
605
|
+
subErrors={notification.subErrors}
|
|
606
|
+
resetError={() => setNotification(null)}
|
|
607
|
+
/>
|
|
608
|
+
)}
|
|
585
609
|
<TableList
|
|
586
610
|
tableHeader={TableHeader}
|
|
587
611
|
pagination={pagination}
|
|
@@ -82,18 +82,19 @@ const getCurrentFilter = (structuredData: any, filter: any) =>
|
|
|
82
82
|
const filterByStatus = (bulkSelection: number[], currentSitePages: IPage[]): Record<string, number[]> => {
|
|
83
83
|
const notPublishedItems: number[] = [];
|
|
84
84
|
const publishedItems: number[] = [];
|
|
85
|
+
const draftItems: number[] = [];
|
|
85
86
|
|
|
86
87
|
currentSitePages.forEach((page: IPage) => {
|
|
87
|
-
const { id, liveStatus } = page;
|
|
88
|
+
const { id, liveStatus, haveDraftPage } = page;
|
|
88
89
|
if (bulkSelection.includes(id)) {
|
|
89
90
|
switch (liveStatus.status) {
|
|
90
91
|
case pageStatus.OFFLINE_PENDING:
|
|
91
92
|
case pageStatus.OFFLINE:
|
|
92
93
|
case pageStatus.UPLOAD_PENDING:
|
|
93
|
-
notPublishedItems.push(id);
|
|
94
|
+
haveDraftPage ? draftItems.push(id) : notPublishedItems.push(id);
|
|
94
95
|
break;
|
|
95
96
|
case pageStatus.PUBLISHED:
|
|
96
|
-
publishedItems.push(id);
|
|
97
|
+
haveDraftPage ? draftItems.push(id) : publishedItems.push(id);
|
|
97
98
|
break;
|
|
98
99
|
}
|
|
99
100
|
}
|
|
@@ -103,6 +104,7 @@ const filterByStatus = (bulkSelection: number[], currentSitePages: IPage[]): Rec
|
|
|
103
104
|
all: bulkSelection,
|
|
104
105
|
notPublished: notPublishedItems,
|
|
105
106
|
published: publishedItems,
|
|
107
|
+
drafts: draftItems,
|
|
106
108
|
};
|
|
107
109
|
|
|
108
110
|
return filteredItems;
|
|
@@ -9,7 +9,7 @@ import SiteItem from "./SiteItem";
|
|
|
9
9
|
import * as S from "./style";
|
|
10
10
|
|
|
11
11
|
const UserCreate = (props: IProps) => {
|
|
12
|
-
const { setHistoryPush, createUser, sites, site, users, updateUser } = props;
|
|
12
|
+
const { setHistoryPush, createUser, sites, site, users, updateUser, isSaving } = props;
|
|
13
13
|
const isSiteView = !!site;
|
|
14
14
|
const initState: any = { name: "", email: "", sites: isSiteView ? [site.id] : ["all"] };
|
|
15
15
|
const getSortedSitesByName = (sites: any) =>
|
|
@@ -57,6 +57,7 @@ const UserCreate = (props: IProps) => {
|
|
|
57
57
|
const rightButtonProps = {
|
|
58
58
|
label: "Add User",
|
|
59
59
|
action: handleCreate,
|
|
60
|
+
disabled: isSaving,
|
|
60
61
|
};
|
|
61
62
|
|
|
62
63
|
const name = state.name.trim() === "" ? "Name" : state.name;
|
|
@@ -170,12 +171,14 @@ interface IProfileProps {
|
|
|
170
171
|
users: IUser[];
|
|
171
172
|
sites: ISite[];
|
|
172
173
|
site: ISite;
|
|
174
|
+
isSaving: boolean;
|
|
173
175
|
}
|
|
174
176
|
|
|
175
177
|
const mapStateToProps = (state: IRootState) => ({
|
|
176
178
|
users: state.users.users,
|
|
177
179
|
sites: state.sites.sites,
|
|
178
180
|
site: state.sites.currentSiteInfo,
|
|
181
|
+
isSaving: state.app.isSaving,
|
|
179
182
|
});
|
|
180
183
|
|
|
181
184
|
const mapDispatchToProps = {
|
package/src/types/index.tsx
CHANGED
|
@@ -76,8 +76,8 @@ export interface IAPIPage {
|
|
|
76
76
|
fullUrl: string;
|
|
77
77
|
fullPath: IFullPath;
|
|
78
78
|
templateConfig: any;
|
|
79
|
-
header: number | null
|
|
80
|
-
footer: number | null
|
|
79
|
+
header: number | null | Record<string, unknown>;
|
|
80
|
+
footer: number | null | Record<string, unknown>;
|
|
81
81
|
availableSites: ISite[];
|
|
82
82
|
structuredData: string;
|
|
83
83
|
origin: string;
|
|
@@ -134,6 +134,18 @@ export interface IRecentSite {
|
|
|
134
134
|
siteId: number;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
export interface ISiteListConfig {
|
|
138
|
+
displayRecentSites: boolean;
|
|
139
|
+
mode: string;
|
|
140
|
+
filter: string;
|
|
141
|
+
filterValues: { order: string; liveStatus: string };
|
|
142
|
+
sortedListStatus: {
|
|
143
|
+
isAscending: boolean;
|
|
144
|
+
sortedByDateCreated: boolean;
|
|
145
|
+
sortedByLastAccess: boolean;
|
|
146
|
+
sortedByTitle: boolean;
|
|
147
|
+
};
|
|
148
|
+
}
|
|
137
149
|
export interface ISchema {
|
|
138
150
|
title: string;
|
|
139
151
|
component: string;
|
|
@@ -776,6 +788,13 @@ export interface ILinkField {
|
|
|
776
788
|
modal: any;
|
|
777
789
|
}
|
|
778
790
|
|
|
791
|
+
export interface ICreatePasswordParams {
|
|
792
|
+
id: string;
|
|
793
|
+
token: string;
|
|
794
|
+
password: string;
|
|
795
|
+
retypedPassword: string;
|
|
796
|
+
}
|
|
797
|
+
|
|
779
798
|
export type Field =
|
|
780
799
|
| "AsyncCheckGroup"
|
|
781
800
|
| "AsyncSelect"
|