@griddo/ax 10.6.9 → 10.6.12
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/components/Fields/CheckField/index.tsx +16 -4
- package/src/components/Fields/DateField/index.tsx +9 -3
- package/src/components/Fields/TimeField/index.tsx +8 -2
- package/src/components/Icon/components/CancelEvent.js +10 -0
- package/src/components/Icon/svgs/cancel-event.svg +3 -0
- package/src/components/MainWrapper/AppBar/index.tsx +8 -1
- package/src/components/MainWrapper/AppBar/style.tsx +9 -1
- package/src/components/MainWrapper/index.tsx +1 -0
- package/src/components/Modal/index.tsx +17 -1
- package/src/components/ScheduleModal/index.tsx +100 -0
- package/src/components/ScheduleModal/style.tsx +19 -0
- package/src/components/TableFilters/LiveFilter/index.tsx +1 -1
- package/src/components/index.tsx +3 -0
- package/src/containers/PageEditor/actions.tsx +21 -1
- package/src/containers/PageEditor/interfaces.tsx +1 -0
- package/src/forms/validators.tsx +3 -2
- package/src/helpers/dates.tsx +6 -0
- package/src/helpers/index.tsx +2 -0
- package/src/hooks/bulk.tsx +5 -1
- package/src/modules/Categories/CategoriesList/BulkHeader/TableHeader/index.tsx +17 -12
- package/src/modules/Categories/CategoriesList/BulkHeader/index.tsx +5 -1
- package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +3 -1
- package/src/modules/Categories/CategoriesList/index.tsx +3 -0
- package/src/modules/Content/BulkHeader/TableHeader/index.tsx +15 -9
- package/src/modules/Content/BulkHeader/index.tsx +3 -0
- package/src/modules/Content/PageItem/index.tsx +10 -4
- package/src/modules/Content/index.tsx +4 -0
- package/src/modules/Content/utils.tsx +13 -10
- package/src/modules/FileDrive/BulkListHeader/TableHeader/index.tsx +15 -11
- package/src/modules/FileDrive/BulkListHeader/index.tsx +4 -1
- package/src/modules/FileDrive/ListItem/index.tsx +3 -1
- package/src/modules/FileDrive/index.tsx +6 -3
- package/src/modules/GlobalEditor/index.tsx +83 -3
- package/src/modules/GlobalEditor/style.tsx +12 -1
- package/src/modules/Navigation/Defaults/BulkHeader/TableHeader/index.tsx +18 -12
- package/src/modules/Navigation/Defaults/BulkHeader/index.tsx +11 -3
- package/src/modules/Navigation/Defaults/Item/index.tsx +9 -2
- package/src/modules/Navigation/Defaults/index.tsx +4 -0
- package/src/modules/PageEditor/index.tsx +82 -2
- package/src/modules/PageEditor/style.tsx +9 -1
- package/src/modules/Redirects/BulkHeader/TableHeader/index.tsx +17 -10
- package/src/modules/Redirects/BulkHeader/index.tsx +4 -0
- package/src/modules/Redirects/RedirectItem/index.tsx +8 -1
- package/src/modules/Redirects/index.tsx +3 -0
- package/src/modules/Settings/Integrations/BulkHeader/TableHeader/index.tsx +16 -11
- package/src/modules/Settings/Integrations/BulkHeader/index.tsx +5 -1
- package/src/modules/Settings/Integrations/IntegrationItem/index.tsx +3 -1
- package/src/modules/Settings/Integrations/index.tsx +3 -0
- package/src/modules/Sites/SitesList/ListView/BulkHeader/TableHeader/index.tsx +15 -10
- package/src/modules/Sites/SitesList/ListView/BulkHeader/index.tsx +3 -0
- package/src/modules/Sites/SitesList/ListView/ListSiteItem/index.tsx +14 -3
- package/src/modules/Sites/SitesList/index.tsx +3 -0
- package/src/modules/StructuredData/Form/index.tsx +72 -6
- package/src/modules/StructuredData/Form/style.tsx +17 -1
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +15 -9
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +3 -0
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +10 -3
- package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +13 -4
- package/src/modules/StructuredData/StructuredDataList/atoms.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/index.tsx +4 -0
- package/src/modules/Users/Roles/BulkHeader/TableHeader/index.tsx +24 -10
- package/src/modules/Users/Roles/BulkHeader/index.tsx +4 -0
- package/src/modules/Users/Roles/RoleItem/index.tsx +3 -2
- package/src/modules/Users/Roles/index.tsx +12 -2
- package/src/modules/Users/UserList/BulkHeader/TableHeader/index.tsx +17 -10
- package/src/modules/Users/UserList/BulkHeader/index.tsx +4 -0
- package/src/modules/Users/UserList/UserItem/index.tsx +3 -1
- package/src/modules/Users/UserList/index.tsx +24 -7
- package/src/types/index.tsx +2 -0
|
@@ -244,6 +244,7 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
244
244
|
checkState,
|
|
245
245
|
addToBulkSelection,
|
|
246
246
|
selectAllItems,
|
|
247
|
+
setHoverCheck,
|
|
247
248
|
} = useBulkSelection(sitesIds);
|
|
248
249
|
|
|
249
250
|
const bulkFilter = (bulkSelection: number[]) => filterByStatus(bulkSelection, sites);
|
|
@@ -285,6 +286,7 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
285
286
|
sortedListStatus={currentConfig.sortedListStatus}
|
|
286
287
|
filterItems={filterItems}
|
|
287
288
|
filterValues={currentConfig.filterValues}
|
|
289
|
+
setHoverCheck={setHoverCheck}
|
|
288
290
|
/>
|
|
289
291
|
);
|
|
290
292
|
|
|
@@ -301,6 +303,7 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
|
|
|
301
303
|
isSelected={isItemSelected}
|
|
302
304
|
onCheck={handleAddToBulk}
|
|
303
305
|
getParams={getParams}
|
|
306
|
+
hoverCheck={checkState.hoverCheck}
|
|
304
307
|
/>
|
|
305
308
|
);
|
|
306
309
|
})
|
|
@@ -3,11 +3,11 @@ import { connect } from "react-redux";
|
|
|
3
3
|
|
|
4
4
|
import { IDataPack, IErrorItem, ILanguage, INotification, IRootState, ISchemaField, ISite } from "@ax/types";
|
|
5
5
|
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
6
|
-
import { MainWrapper, ErrorToast, Notification, Loading } from "@ax/components";
|
|
7
|
-
import { getActivatedDataPacksIds, getDefaultTheme } from "@ax/helpers";
|
|
6
|
+
import { MainWrapper, ErrorToast, Notification, Loading, CancelScheduleModal, ScheduleModal } from "@ax/components";
|
|
7
|
+
import { dateToString, getActivatedDataPacksIds, getDefaultTheme } from "@ax/helpers";
|
|
8
8
|
import { appActions } from "@ax/containers/App";
|
|
9
9
|
import { RouteLeavingGuard } from "@ax/guards";
|
|
10
|
-
import { useIsDirty } from "@ax/hooks";
|
|
10
|
+
import { useIsDirty, useModal } from "@ax/hooks";
|
|
11
11
|
import { setIsSavedData } from "@ax/forms";
|
|
12
12
|
import { dataPacksActions } from "@ax/containers/Settings/DataPacks";
|
|
13
13
|
|
|
@@ -44,6 +44,9 @@ const Form = (props: IProps) => {
|
|
|
44
44
|
|
|
45
45
|
const [isNewStructuredData, setIsNewStructuredData] = useState(!currentStructuredDataId);
|
|
46
46
|
const [notification, setNotification] = useState<INotification | null>(null);
|
|
47
|
+
const [scheduleDate, setScheduleDate] = useState({ date: "", time: "" });
|
|
48
|
+
const { isOpen: isScheduleOpen, toggleModal: toggleScheduleModal } = useModal();
|
|
49
|
+
const { isOpen: isCancelScheduleOpen, toggleModal: toggleCancelScheduleModal } = useModal();
|
|
47
50
|
const { isDirty, resetDirty, setIsDirty } = useIsDirty(form);
|
|
48
51
|
|
|
49
52
|
const { fields } = schema;
|
|
@@ -62,6 +65,12 @@ const Form = (props: IProps) => {
|
|
|
62
65
|
currentStructuredData.local &&
|
|
63
66
|
!activatedDataPacksIds.some((pack: string) => currentStructuredData.dataPacks.includes(pack));
|
|
64
67
|
const isDataTranslatable = currentStructuredData && currentStructuredData.translate;
|
|
68
|
+
const isScheduled = !!form && !!form.publicationScheduled;
|
|
69
|
+
const status = isScheduled
|
|
70
|
+
? "scheduled"
|
|
71
|
+
: !form || form.draft === true || form.draft === undefined
|
|
72
|
+
? "offline"
|
|
73
|
+
: "active";
|
|
65
74
|
|
|
66
75
|
let title = "";
|
|
67
76
|
|
|
@@ -102,7 +111,7 @@ const Form = (props: IProps) => {
|
|
|
102
111
|
);
|
|
103
112
|
});
|
|
104
113
|
|
|
105
|
-
const handleSave = async (publish: boolean) => {
|
|
114
|
+
const handleSave = async (publish: boolean, scheduleDate?: string | null) => {
|
|
106
115
|
const validated = publish && !skipReviewOnPublish ? await validateForm(true) : true;
|
|
107
116
|
|
|
108
117
|
if (validated) {
|
|
@@ -114,6 +123,7 @@ const Form = (props: IProps) => {
|
|
|
114
123
|
structuredData: currentStructuredData ? currentStructuredData.id : null,
|
|
115
124
|
draft: publish === true ? false : status,
|
|
116
125
|
relatedSite: site ? site.id : null,
|
|
126
|
+
publicationScheduled: scheduleDate !== undefined ? scheduleDate : form.publicationScheduled,
|
|
117
127
|
};
|
|
118
128
|
|
|
119
129
|
let saved = false;
|
|
@@ -196,7 +206,7 @@ const Form = (props: IProps) => {
|
|
|
196
206
|
setHistoryPush("/sites/settings/content-types", false);
|
|
197
207
|
};
|
|
198
208
|
|
|
199
|
-
const removeItem =
|
|
209
|
+
const removeItem = () => {
|
|
200
210
|
const path = site ? "/sites/pages" : "/data";
|
|
201
211
|
deleteStructuredDataContent(form.id).then((deleted: boolean) => {
|
|
202
212
|
if (deleted) {
|
|
@@ -245,6 +255,19 @@ const Form = (props: IProps) => {
|
|
|
245
255
|
await validateForm();
|
|
246
256
|
};
|
|
247
257
|
|
|
258
|
+
const handleSchedulePublication = () => {
|
|
259
|
+
const date = new Date(`${scheduleDate.date} ${scheduleDate.time}`);
|
|
260
|
+
const dateString = dateToString(date, "dd/MM/yyyy HH:mm:ss");
|
|
261
|
+
handleSave(false, dateString);
|
|
262
|
+
toggleScheduleModal();
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const handleCancelSchedulePublication = () => {
|
|
266
|
+
handleSave(false, null);
|
|
267
|
+
setScheduleDate({ date: "", time: "" });
|
|
268
|
+
toggleCancelScheduleModal();
|
|
269
|
+
};
|
|
270
|
+
|
|
248
271
|
const downArrowMenu = {
|
|
249
272
|
displayed: true,
|
|
250
273
|
button: getPublishButton(form?.draft),
|
|
@@ -262,13 +285,41 @@ const Form = (props: IProps) => {
|
|
|
262
285
|
],
|
|
263
286
|
};
|
|
264
287
|
|
|
265
|
-
|
|
288
|
+
if (status === "offline" && !isScheduled) {
|
|
289
|
+
downArrowMenu.options.unshift({
|
|
290
|
+
label: "Schedule",
|
|
291
|
+
icon: "calendar",
|
|
292
|
+
action: toggleScheduleModal,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (isScheduled) {
|
|
297
|
+
downArrowMenu.options.unshift({
|
|
298
|
+
label: "Cancel Schedule",
|
|
299
|
+
icon: "cancelEvent",
|
|
300
|
+
action: toggleCancelScheduleModal,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
266
303
|
|
|
267
304
|
const languageProps = {
|
|
268
305
|
lang: isDataTranslatable ? lang : null,
|
|
269
306
|
languageActions: isDataTranslatable ? languageActions : null,
|
|
270
307
|
};
|
|
271
308
|
|
|
309
|
+
const mainScheduleModalAction = {
|
|
310
|
+
title: "Schedule",
|
|
311
|
+
onClick: handleSchedulePublication,
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const secondaryScheduleModalAction = { title: "Cancel", onClick: toggleScheduleModal };
|
|
315
|
+
|
|
316
|
+
const mainCancelScheduleModalAction = {
|
|
317
|
+
title: "Cancel Schedule",
|
|
318
|
+
onClick: handleCancelSchedulePublication,
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const secondaryCancelScheduleModalAction = { title: "Back", onClick: toggleCancelScheduleModal };
|
|
322
|
+
|
|
272
323
|
return isLoading ? (
|
|
273
324
|
<Loading />
|
|
274
325
|
) : (
|
|
@@ -289,6 +340,7 @@ const Form = (props: IProps) => {
|
|
|
289
340
|
isFromEditor={true}
|
|
290
341
|
currentPageID={form?.id}
|
|
291
342
|
errors={errors}
|
|
343
|
+
scheduledPublication={form?.publicationScheduled}
|
|
292
344
|
>
|
|
293
345
|
{isDisabled && (
|
|
294
346
|
<S.NotificationWrapper>
|
|
@@ -314,6 +366,20 @@ const Form = (props: IProps) => {
|
|
|
314
366
|
<ErrorToast size="l" />
|
|
315
367
|
<S.Wrapper>{Fields}</S.Wrapper>
|
|
316
368
|
</MainWrapper>
|
|
369
|
+
<ScheduleModal
|
|
370
|
+
isOpen={isScheduleOpen}
|
|
371
|
+
toggleModal={toggleScheduleModal}
|
|
372
|
+
mainModalAction={mainScheduleModalAction}
|
|
373
|
+
secondaryModalAction={secondaryScheduleModalAction}
|
|
374
|
+
scheduleDate={scheduleDate}
|
|
375
|
+
setScheduleDate={setScheduleDate}
|
|
376
|
+
/>
|
|
377
|
+
<CancelScheduleModal
|
|
378
|
+
isOpen={isCancelScheduleOpen}
|
|
379
|
+
toggleModal={toggleCancelScheduleModal}
|
|
380
|
+
mainModalAction={mainCancelScheduleModalAction}
|
|
381
|
+
secondaryModalAction={secondaryCancelScheduleModalAction}
|
|
382
|
+
/>
|
|
317
383
|
</>
|
|
318
384
|
);
|
|
319
385
|
};
|
|
@@ -14,4 +14,20 @@ const NotificationWrapper = styled.div`
|
|
|
14
14
|
z-index: 2;
|
|
15
15
|
`;
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const ModalContent = styled.div`
|
|
18
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
19
|
+
|
|
20
|
+
p {
|
|
21
|
+
margin-bottom: ${(p) => p.theme.spacing.m};
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
const ModalFields = styled.div`
|
|
26
|
+
display: flex;
|
|
27
|
+
width: 100%;
|
|
28
|
+
& > div:nth-child(odd) {
|
|
29
|
+
margin-right: ${(p) => p.theme.spacing.m};
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export { Wrapper, NotificationWrapper, ModalContent, ModalFields };
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
SiteFilter,
|
|
11
11
|
LiveFilter,
|
|
12
12
|
TranslationsFilter,
|
|
13
|
+
Tooltip,
|
|
13
14
|
} from "@ax/components";
|
|
14
15
|
import { IColumn, IQueryValue, ISchemaField, IStructuredDataQueryValues } from "@ax/types";
|
|
15
16
|
import { getGlobalPageTypes } from "@ax/helpers";
|
|
@@ -32,6 +33,7 @@ const TableHeader = (props: IProps): JSX.Element => {
|
|
|
32
33
|
columns,
|
|
33
34
|
setColumns,
|
|
34
35
|
maxColumns,
|
|
36
|
+
setHoverCheck,
|
|
35
37
|
} = props;
|
|
36
38
|
|
|
37
39
|
const activeColumns = columns.filter((col) => col.show).map((col) => col.id);
|
|
@@ -56,15 +58,18 @@ const TableHeader = (props: IProps): JSX.Element => {
|
|
|
56
58
|
return (
|
|
57
59
|
<S.TableHeader isScrolling={isScrolling}>
|
|
58
60
|
<S.CheckHeader>
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
<Tooltip content="Select All Pages" bottom>
|
|
62
|
+
<CheckField
|
|
63
|
+
key="selectAll"
|
|
64
|
+
name="selectAll"
|
|
65
|
+
value="selectAll"
|
|
66
|
+
onChange={selectAllItems}
|
|
67
|
+
disabled={false}
|
|
68
|
+
error={false}
|
|
69
|
+
checked={checkState.isAllSelected || checkState.hoverCheck}
|
|
70
|
+
setHoverCheck={setHoverCheck}
|
|
71
|
+
/>
|
|
72
|
+
</Tooltip>
|
|
68
73
|
</S.CheckHeader>
|
|
69
74
|
{isFromPage ? (
|
|
70
75
|
<>
|
|
@@ -141,6 +146,7 @@ interface IProps {
|
|
|
141
146
|
columns: IColumn[];
|
|
142
147
|
setColumns: (columns: IColumn[]) => void;
|
|
143
148
|
maxColumns: { value: number; text: string };
|
|
149
|
+
setHoverCheck: (state: boolean) => void;
|
|
144
150
|
}
|
|
145
151
|
|
|
146
152
|
export default TableHeader;
|
|
@@ -33,6 +33,7 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
33
33
|
setColumns,
|
|
34
34
|
maxColumns,
|
|
35
35
|
exportAction,
|
|
36
|
+
setHoverCheck,
|
|
36
37
|
} = props;
|
|
37
38
|
|
|
38
39
|
const isAllowedToPublishPages = usePermission("global.globalData.publishUnpublishAllGlobalData");
|
|
@@ -86,6 +87,7 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
86
87
|
columns={columns}
|
|
87
88
|
setColumns={setColumns}
|
|
88
89
|
maxColumns={maxColumns}
|
|
90
|
+
setHoverCheck={setHoverCheck}
|
|
89
91
|
/>
|
|
90
92
|
);
|
|
91
93
|
};
|
|
@@ -112,6 +114,7 @@ interface IProps {
|
|
|
112
114
|
setColumns: (columns: IColumn[]) => void;
|
|
113
115
|
maxColumns: { value: number; text: string };
|
|
114
116
|
exportAction?(formats: (number | string)[]): void;
|
|
117
|
+
setHoverCheck: (state: boolean) => void;
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
export default BulkHeader;
|
|
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
|
|
|
3
3
|
import { useTheme } from "styled-components";
|
|
4
4
|
|
|
5
5
|
import { ICheck, IAvailableSites, ISavePageParams, ILanguage, IPageLanguage, IPage, IColumn } from "@ax/types";
|
|
6
|
-
import { getHumanLastModifiedDate, getStructuredDataTitle, trimText } from "@ax/helpers";
|
|
6
|
+
import { getHumanLastModifiedDate, getScheduleFormatDate, getStructuredDataTitle, trimText } from "@ax/helpers";
|
|
7
7
|
import { appActions } from "@ax/containers/App";
|
|
8
8
|
import { pageStatus, ISetCurrentPageIDAction } from "@ax/containers/PageEditor/interfaces";
|
|
9
9
|
import {
|
|
@@ -52,6 +52,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
52
52
|
categoryColors,
|
|
53
53
|
addCategoryColors,
|
|
54
54
|
skipReview,
|
|
55
|
+
hoverCheck,
|
|
55
56
|
} = props;
|
|
56
57
|
|
|
57
58
|
const { locale } = lang;
|
|
@@ -64,9 +65,13 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
64
65
|
structuredData,
|
|
65
66
|
structuredDataContent,
|
|
66
67
|
fullPath,
|
|
68
|
+
publicationScheduled,
|
|
69
|
+
liveStatus,
|
|
70
|
+
haveDraftPage,
|
|
67
71
|
} = globalPage;
|
|
68
72
|
|
|
69
73
|
const activeColumns = columns.filter((col) => col.show).map((col) => col.id);
|
|
74
|
+
const isScheduledPub = !!publicationScheduled && liveStatus.status === pageStatus.SCHEDULED;
|
|
70
75
|
|
|
71
76
|
const initValue = { title: "", slug: "" };
|
|
72
77
|
const [duplicateModalState, setDuplicateModalState] = useState(initValue);
|
|
@@ -94,6 +99,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
94
99
|
offline: "Offline",
|
|
95
100
|
"offline-pending": "Offline pending",
|
|
96
101
|
modified: "Live & Modified",
|
|
102
|
+
scheduled: `Scheduled publication: ${isScheduledPub ? getScheduleFormatDate(publicationScheduled) : ""}`,
|
|
97
103
|
};
|
|
98
104
|
|
|
99
105
|
const _handleClick = () => {
|
|
@@ -346,7 +352,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
346
352
|
|
|
347
353
|
const availableSiteNames = availableSites && availableSites.map((site: IAvailableSites) => site.name);
|
|
348
354
|
|
|
349
|
-
const getLiveStatus = () => (
|
|
355
|
+
const getLiveStatus = () => (haveDraftPage ? "modified" : liveStatus.status);
|
|
350
356
|
|
|
351
357
|
const mainUnpublishAction = { title: "Ok", onClick: toggleUnpublishModal };
|
|
352
358
|
|
|
@@ -384,7 +390,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
|
|
|
384
390
|
<>
|
|
385
391
|
<S.StructuredDataRow role="rowgroup" selected={isSelected} disabled={!isEditable}>
|
|
386
392
|
<S.CheckCell role="cell">
|
|
387
|
-
<CheckField name="check" value={globalPage.id} checked={isSelected} onChange={handleOnChange} />
|
|
393
|
+
<CheckField name="check" value={globalPage.id} checked={isSelected || hoverCheck} onChange={handleOnChange} />
|
|
388
394
|
</S.CheckCell>
|
|
389
395
|
<S.NameCell role="cell" onClick={_handleClick} ref={nameCellRef}>
|
|
390
396
|
<Tooltip
|
|
@@ -485,6 +491,7 @@ interface IGlobalPageItemProps {
|
|
|
485
491
|
categoryColors: any;
|
|
486
492
|
addCategoryColors(cats: string[]): void;
|
|
487
493
|
skipReview?: boolean;
|
|
494
|
+
hoverCheck?: boolean;
|
|
488
495
|
}
|
|
489
496
|
|
|
490
497
|
const mapDispatchToProps = {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
IColumn,
|
|
13
13
|
ISite,
|
|
14
14
|
} from "@ax/types";
|
|
15
|
-
import { getActivatedDataPacksIds, getHumanLastModifiedDate } from "@ax/helpers";
|
|
15
|
+
import { getActivatedDataPacksIds, getHumanLastModifiedDate, getScheduleFormatDate } from "@ax/helpers";
|
|
16
16
|
import { setIsSavedData } from "@ax/forms";
|
|
17
17
|
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
18
18
|
import { appActions } from "@ax/containers/App";
|
|
@@ -46,6 +46,7 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
46
46
|
categoryColors,
|
|
47
47
|
addCategoryColors,
|
|
48
48
|
currentSiteInfo,
|
|
49
|
+
hoverCheck,
|
|
49
50
|
} = props;
|
|
50
51
|
|
|
51
52
|
const isAllowedToDuplicatePagesGlobal = usePermission("global.globalData.duplicateGlobalData");
|
|
@@ -72,8 +73,9 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
72
73
|
const title = useAdaptiveText(nameCellRef, structuredData.content.title, nameCellPadding);
|
|
73
74
|
|
|
74
75
|
const { locale } = lang;
|
|
75
|
-
const { dataLanguages } = structuredData;
|
|
76
|
+
const { dataLanguages, publicationScheduled } = structuredData;
|
|
76
77
|
|
|
78
|
+
const isScheduledPub = !!publicationScheduled && structuredData.draft;
|
|
77
79
|
const activeColumns = columns.filter((col) => col.show).map((col) => col.id);
|
|
78
80
|
|
|
79
81
|
const publishedTooltip: Record<string, string> = {
|
|
@@ -81,6 +83,7 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
81
83
|
"upload-pending": "Publication pending",
|
|
82
84
|
offline: "Offline",
|
|
83
85
|
"offline-pending": "Offline pending",
|
|
86
|
+
scheduled: `Scheduled publication: ${isScheduledPub ? getScheduleFormatDate(publicationScheduled) : ""}`,
|
|
84
87
|
};
|
|
85
88
|
|
|
86
89
|
const _handleClick = () => {
|
|
@@ -110,7 +113,7 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
110
113
|
};
|
|
111
114
|
|
|
112
115
|
const checkStatus = () => {
|
|
113
|
-
return structuredData.draft ? "offline" : "active";
|
|
116
|
+
return isScheduledPub ? "scheduled" : structuredData.draft ? "offline" : "active";
|
|
114
117
|
};
|
|
115
118
|
|
|
116
119
|
const getCurrentLanguages = () => {
|
|
@@ -236,7 +239,12 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
|
|
|
236
239
|
return (
|
|
237
240
|
<S.StructuredDataRow role="rowgroup" selected={isSelected} disabled={!isEditable}>
|
|
238
241
|
<S.CheckCell role="cell">
|
|
239
|
-
<CheckField
|
|
242
|
+
<CheckField
|
|
243
|
+
name="check"
|
|
244
|
+
value={structuredData.id}
|
|
245
|
+
checked={isSelected || hoverCheck}
|
|
246
|
+
onChange={handleOnChange}
|
|
247
|
+
/>
|
|
240
248
|
</S.CheckCell>
|
|
241
249
|
<S.NameCell role="cell" onClick={_handleClick} ref={nameCellRef}>
|
|
242
250
|
<Tooltip content={structuredData.content.title} left={0} top={1} expanded>
|
|
@@ -289,6 +297,7 @@ interface IStructuredDataItemProps {
|
|
|
289
297
|
addCategoryColors(cats: string[]): void;
|
|
290
298
|
setCurrentDataID(id: number | null): void;
|
|
291
299
|
currentSiteInfo: ISite | null;
|
|
300
|
+
hoverCheck?: boolean;
|
|
292
301
|
}
|
|
293
302
|
|
|
294
303
|
const mapStateToProps = (state: IRootState) => ({
|
|
@@ -181,6 +181,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
|
|
|
181
181
|
checkState,
|
|
182
182
|
addToBulkSelection,
|
|
183
183
|
selectAllItems,
|
|
184
|
+
setHoverCheck,
|
|
184
185
|
} = useBulkSelection(dataIds);
|
|
185
186
|
|
|
186
187
|
const getParams = useCallback(() => {
|
|
@@ -488,6 +489,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
|
|
|
488
489
|
setColumns={changeColumnsState}
|
|
489
490
|
maxColumns={maxColumns}
|
|
490
491
|
exportAction={exportContent}
|
|
492
|
+
setHoverCheck={setHoverCheck}
|
|
491
493
|
/>
|
|
492
494
|
);
|
|
493
495
|
|
|
@@ -558,6 +560,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
|
|
|
558
560
|
columns={currentDataColumnsState}
|
|
559
561
|
categoryColors={categoryColors}
|
|
560
562
|
addCategoryColors={addCategoryColors}
|
|
563
|
+
hoverCheck={checkState.hoverCheck}
|
|
561
564
|
/>
|
|
562
565
|
);
|
|
563
566
|
});
|
|
@@ -590,6 +593,7 @@ const StructuredDataList = (props: IProps): JSX.Element => {
|
|
|
590
593
|
categoryColors={categoryColors}
|
|
591
594
|
addCategoryColors={addCategoryColors}
|
|
592
595
|
skipReview={skipReviewOnPublish}
|
|
596
|
+
hoverCheck={checkState.hoverCheck}
|
|
593
597
|
/>
|
|
594
598
|
);
|
|
595
599
|
});
|
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import { CheckField, TableCounter, NameFilter, PermissionsFilter, UsersFilter } from "@ax/components";
|
|
3
|
+
import { CheckField, TableCounter, NameFilter, PermissionsFilter, UsersFilter, Tooltip } from "@ax/components";
|
|
4
4
|
import { IQueryValue } from "@ax/types";
|
|
5
5
|
|
|
6
6
|
import * as S from "./style";
|
|
7
7
|
|
|
8
8
|
const TableHeader = (props: IProps): JSX.Element => {
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
totalItems,
|
|
11
|
+
selectAllItems,
|
|
12
|
+
isScrolling,
|
|
13
|
+
sortItems,
|
|
14
|
+
sortedListStatus,
|
|
15
|
+
isSiteView,
|
|
16
|
+
checkState,
|
|
17
|
+
setHoverCheck,
|
|
18
|
+
} = props;
|
|
10
19
|
|
|
11
20
|
return (
|
|
12
21
|
<S.TableHeader isScrolling={isScrolling} data-testid="roles-table-header">
|
|
13
22
|
<S.CheckHeader>
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
<Tooltip content="Select All Roles" bottom>
|
|
24
|
+
<CheckField
|
|
25
|
+
key="selectAll"
|
|
26
|
+
name="selectAll"
|
|
27
|
+
value="selectAll"
|
|
28
|
+
onChange={selectAllItems}
|
|
29
|
+
checked={checkState.isAllSelected || checkState.hoverCheck}
|
|
30
|
+
error={false}
|
|
31
|
+
setHoverCheck={setHoverCheck}
|
|
32
|
+
/>
|
|
33
|
+
</Tooltip>
|
|
22
34
|
</S.CheckHeader>
|
|
23
35
|
<S.NameWrapper>
|
|
24
36
|
<NameFilter sortItems={sortItems} sortedState={sortedListStatus} pointer="name" />
|
|
@@ -47,6 +59,8 @@ interface IProps {
|
|
|
47
59
|
sortedListStatus: any;
|
|
48
60
|
filterValues: any;
|
|
49
61
|
isSiteView: boolean;
|
|
62
|
+
checkState: Record<string, boolean>;
|
|
63
|
+
setHoverCheck: (state: boolean) => void;
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
export default TableHeader;
|
|
@@ -18,6 +18,7 @@ const BulkHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
|
18
18
|
isSiteView,
|
|
19
19
|
roles,
|
|
20
20
|
selectedRoles,
|
|
21
|
+
setHoverCheck,
|
|
21
22
|
} = props;
|
|
22
23
|
|
|
23
24
|
const deactivatedSelectedRoles = roles.filter((role: IRole) => selectedRoles.includes(role.id) && !role.active);
|
|
@@ -48,6 +49,8 @@ const BulkHeader = (props: IBulkHeaderProps): JSX.Element => {
|
|
|
48
49
|
sortItems={sortItems}
|
|
49
50
|
sortedListStatus={sortedListStatus}
|
|
50
51
|
isSiteView={isSiteView}
|
|
52
|
+
checkState={checkState}
|
|
53
|
+
setHoverCheck={setHoverCheck}
|
|
51
54
|
/>
|
|
52
55
|
);
|
|
53
56
|
};
|
|
@@ -66,6 +69,7 @@ export interface IBulkHeaderProps {
|
|
|
66
69
|
isSiteView: boolean;
|
|
67
70
|
roles: IRole[];
|
|
68
71
|
selectedRoles: number[];
|
|
72
|
+
setHoverCheck: (state: boolean) => void;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
export default BulkHeader;
|
|
@@ -8,7 +8,7 @@ import { CheckField, ToggleField, Tag, Tooltip, Avatar } from "@ax/components";
|
|
|
8
8
|
import * as S from "./style";
|
|
9
9
|
|
|
10
10
|
const RoleItem = (props: IRoleItemProps): JSX.Element => {
|
|
11
|
-
const { role, users, isSelected, onChange, activateRole, siteId, onClick } = props;
|
|
11
|
+
const { role, users, isSelected, onChange, activateRole, siteId, onClick, hoverCheck } = props;
|
|
12
12
|
const isSiteView = siteId !== "global";
|
|
13
13
|
const [isOpen, setIsOpen] = useState(false);
|
|
14
14
|
|
|
@@ -41,7 +41,7 @@ const RoleItem = (props: IRoleItemProps): JSX.Element => {
|
|
|
41
41
|
<CheckField
|
|
42
42
|
name="check"
|
|
43
43
|
value={role.id ?? ""}
|
|
44
|
-
checked={isSelected}
|
|
44
|
+
checked={isSelected || (hoverCheck && role.editable)}
|
|
45
45
|
onChange={(value: ICheck) => onChange(value)}
|
|
46
46
|
disabled={!role.editable}
|
|
47
47
|
/>
|
|
@@ -92,6 +92,7 @@ interface IRoleItemProps {
|
|
|
92
92
|
users: IUser[];
|
|
93
93
|
isSelected: boolean;
|
|
94
94
|
siteId: string | number;
|
|
95
|
+
hoverCheck: boolean;
|
|
95
96
|
onChange: (value: ICheck) => void;
|
|
96
97
|
onClick: () => void;
|
|
97
98
|
activateRole(value: boolean): void;
|
|
@@ -47,6 +47,7 @@ const Roles = (props: IRolesProps): JSX.Element => {
|
|
|
47
47
|
addToBulkSelection,
|
|
48
48
|
selectAllItems,
|
|
49
49
|
selectedItems,
|
|
50
|
+
setHoverCheck,
|
|
50
51
|
} = useBulkSelection(rolesIds);
|
|
51
52
|
|
|
52
53
|
useEffect(() => {
|
|
@@ -67,9 +68,16 @@ const Roles = (props: IRolesProps): JSX.Element => {
|
|
|
67
68
|
|
|
68
69
|
const unselectAllItems = () => resetBulkSelection();
|
|
69
70
|
|
|
70
|
-
const
|
|
71
|
+
const checkAllEditableSelected = () => pageRoles.filter((role) => role.editable).length === selectedItems.all.length;
|
|
71
72
|
|
|
72
|
-
const
|
|
73
|
+
const selectItems = () => (checkAllEditableSelected() ? unselectAllItems() : handleSelectAll());
|
|
74
|
+
|
|
75
|
+
const bulkFilter = (bulkSelection: number[]) => {
|
|
76
|
+
const activeRoles = bulkSelection.filter((item) => pageRoles.find((role) => role.id === item)?.editable);
|
|
77
|
+
return { all: activeRoles };
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const handleSelectAll = () => selectAllItems(bulkFilter);
|
|
73
81
|
|
|
74
82
|
const onScroll = (e: any) => setIsScrolling(e.target.scrollTop > 0);
|
|
75
83
|
|
|
@@ -147,6 +155,7 @@ const Roles = (props: IRolesProps): JSX.Element => {
|
|
|
147
155
|
isSiteView={isSiteView}
|
|
148
156
|
roles={roles}
|
|
149
157
|
selectedRoles={selectedItems.all}
|
|
158
|
+
setHoverCheck={setHoverCheck}
|
|
150
159
|
/>
|
|
151
160
|
);
|
|
152
161
|
|
|
@@ -192,6 +201,7 @@ const Roles = (props: IRolesProps): JSX.Element => {
|
|
|
192
201
|
onClick={() => openSideModal(role)}
|
|
193
202
|
siteId={siteId}
|
|
194
203
|
activateRole={handleActivateRole}
|
|
204
|
+
hoverCheck={checkState.hoverCheck}
|
|
195
205
|
/>
|
|
196
206
|
);
|
|
197
207
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import { CheckField, TableCounter, SiteFilter, NameFilter, RoleFilter } from "@ax/components";
|
|
3
|
+
import { CheckField, TableCounter, SiteFilter, NameFilter, RoleFilter, Tooltip } from "@ax/components";
|
|
4
4
|
import { IQueryValue, IRole } from "@ax/types";
|
|
5
5
|
|
|
6
6
|
import * as S from "./style";
|
|
@@ -16,6 +16,8 @@ const TableHeader = (props: IProps): JSX.Element => {
|
|
|
16
16
|
filterValues,
|
|
17
17
|
isSiteView,
|
|
18
18
|
roles,
|
|
19
|
+
checkState,
|
|
20
|
+
setHoverCheck,
|
|
19
21
|
} = props;
|
|
20
22
|
|
|
21
23
|
const roleFilters = [
|
|
@@ -38,15 +40,18 @@ const TableHeader = (props: IProps): JSX.Element => {
|
|
|
38
40
|
return (
|
|
39
41
|
<S.TableHeader isScrolling={isScrolling}>
|
|
40
42
|
<S.CheckHeader>
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
<Tooltip content="Select All Users" bottom>
|
|
44
|
+
<CheckField
|
|
45
|
+
key="selectAll"
|
|
46
|
+
name="selectAll"
|
|
47
|
+
value="selectAll"
|
|
48
|
+
onChange={selectAllItems}
|
|
49
|
+
checked={checkState.isAllSelected || checkState.hoverCheck}
|
|
50
|
+
disabled={false}
|
|
51
|
+
error={false}
|
|
52
|
+
setHoverCheck={setHoverCheck}
|
|
53
|
+
/>
|
|
54
|
+
</Tooltip>
|
|
50
55
|
</S.CheckHeader>
|
|
51
56
|
<S.NameWrapper>
|
|
52
57
|
<NameFilter sortItems={sortItems} sortedState={sortedListStatus} pointer="name" />
|
|
@@ -91,6 +96,8 @@ interface IProps {
|
|
|
91
96
|
sortedListStatus: { isAscending: boolean; sortedByName: boolean; sortedByDateCreated: boolean };
|
|
92
97
|
filterValues: Record<string, IQueryValue[]>;
|
|
93
98
|
roles: IRole[];
|
|
99
|
+
checkState: Record<string, boolean>;
|
|
100
|
+
setHoverCheck: (state: boolean) => void;
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
export default TableHeader;
|
|
@@ -19,6 +19,7 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
19
19
|
filterValues,
|
|
20
20
|
isSiteView = false,
|
|
21
21
|
roles,
|
|
22
|
+
setHoverCheck,
|
|
22
23
|
} = props;
|
|
23
24
|
|
|
24
25
|
const isAllowedToRemoveUsers = usePermission("usersRoles.removeUsers");
|
|
@@ -51,6 +52,8 @@ const BulkHeader = (props: IProps): JSX.Element => {
|
|
|
51
52
|
sortedListStatus={sortedListStatus}
|
|
52
53
|
isSiteView={isSiteView}
|
|
53
54
|
roles={roles}
|
|
55
|
+
setHoverCheck={setHoverCheck}
|
|
56
|
+
checkState={checkState}
|
|
54
57
|
/>
|
|
55
58
|
);
|
|
56
59
|
};
|
|
@@ -69,6 +72,7 @@ interface IProps {
|
|
|
69
72
|
filterValues: Record<string, IQueryValue[]>;
|
|
70
73
|
filterItems: (filterPointer: string, filtersSelected: IQueryValue[]) => void;
|
|
71
74
|
roles: IRole[];
|
|
75
|
+
setHoverCheck: (state: boolean) => void;
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
export default BulkHeader;
|