@griddo/ax 1.66.1 → 1.66.4
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/api/pages.tsx +15 -3
- package/src/api/redirects.tsx +4 -2
- package/src/api/sites.tsx +4 -2
- package/src/components/Browser/index.tsx +3 -1
- package/src/components/Browser/style.tsx +2 -2
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +0 -1
- package/src/components/ErrorCenter/index.tsx +8 -5
- package/src/components/ErrorCenter/style.tsx +21 -8
- package/src/components/Fields/ColorPicker/index.tsx +1 -0
- package/src/components/Fields/LinkField/index.tsx +85 -0
- package/src/components/Fields/ReferenceField/ItemList/index.tsx +5 -1
- package/src/components/Fields/ReferenceField/index.tsx +18 -14
- package/src/components/Fields/UrlField/index.tsx +13 -1
- package/src/components/Fields/index.tsx +2 -0
- package/src/components/FieldsBehavior/index.tsx +14 -1
- package/src/components/Icon/components/Copy.js +14 -0
- package/src/components/Icon/svgs/Copy2.svg +3 -0
- package/src/components/Image/index.tsx +17 -9
- package/src/components/Image/utils.ts +55 -0
- package/src/components/MainWrapper/AppBar/index.tsx +21 -10
- package/src/components/MainWrapper/AppBar/style.tsx +11 -3
- package/src/components/MainWrapper/index.tsx +2 -0
- package/src/components/Modal/style.tsx +0 -1
- package/src/components/SearchField/index.tsx +36 -4
- package/src/components/SearchField/style.tsx +23 -10
- package/src/components/SideModal/style.tsx +6 -6
- package/src/components/TableFilters/StatusFilter/index.tsx +2 -2
- package/src/components/index.tsx +2 -0
- package/src/containers/App/actions.tsx +3 -7
- package/src/containers/PageEditor/actions.tsx +91 -22
- package/src/containers/PageEditor/constants.tsx +1 -1
- package/src/containers/PageEditor/interfaces.tsx +6 -6
- package/src/containers/PageEditor/reducer.tsx +4 -4
- package/src/containers/PageEditor/utils.tsx +2 -1
- package/src/containers/Sites/actions.tsx +35 -23
- package/src/containers/Sites/constants.tsx +1 -0
- package/src/containers/Sites/interfaces.tsx +6 -0
- package/src/containers/Sites/reducer.tsx +4 -0
- package/src/forms/editor.tsx +34 -1
- package/src/forms/errors.tsx +1 -0
- package/src/forms/index.tsx +15 -1
- package/src/forms/validators.tsx +168 -9
- package/src/guards/error/index.tsx +1 -1
- package/src/helpers/dataPacks.tsx +8 -1
- package/src/helpers/index.tsx +2 -1
- package/src/modules/Content/PageItem/index.tsx +54 -4
- package/src/modules/Content/atoms.tsx +41 -3
- package/src/modules/Content/index.tsx +111 -64
- package/src/modules/Content/style.tsx +8 -1
- package/src/modules/GlobalEditor/Editor/index.tsx +3 -1
- package/src/modules/GlobalEditor/PageBrowser/index.tsx +3 -0
- package/src/modules/GlobalEditor/index.tsx +8 -6
- package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +8 -0
- package/src/modules/PageEditor/Editor/index.tsx +6 -2
- package/src/modules/PageEditor/PageBrowser/index.tsx +3 -0
- package/src/modules/PageEditor/index.tsx +29 -15
- package/src/modules/Redirects/index.tsx +40 -10
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +1 -1
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/index.tsx +1 -1
- package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +1 -1
- package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +1 -1
- package/src/modules/Sites/index.tsx +3 -3
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/atoms.tsx +1 -1
- package/src/modules/Users/Profile/index.tsx +3 -4
- package/src/modules/Users/UserCreate/SiteItem/index.tsx +1 -1
- package/src/modules/Users/UserCreate/SiteItem/style.tsx +1 -1
- package/src/modules/Users/UserForm/style.tsx +3 -3
- package/src/modules/Users/UserList/UserItem/index.tsx +3 -1
- package/src/modules/Users/UserList/hooks.tsx +1 -1
- package/src/modules/Users/UserList/index.tsx +2 -2
- package/src/types/index.tsx +16 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import { IModal } from "@ax/types";
|
|
4
|
-
import { Modal, FieldsBehavior, Button } from "@ax/components";
|
|
3
|
+
import { IModal, ISite } from "@ax/types";
|
|
4
|
+
import { Modal, FieldsBehavior, Select, Button } from "@ax/components";
|
|
5
5
|
|
|
6
6
|
import * as S from "./style";
|
|
7
7
|
|
|
@@ -68,6 +68,38 @@ const DeleteModal = (props: IDeleteModal): JSX.Element => {
|
|
|
68
68
|
);
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
+
const CopyModal = (props: ICopyModal): JSX.Element => {
|
|
72
|
+
const { isOpen, toggleModal, mainModalAction, secondaryModalAction, setSite, sites, site } = props;
|
|
73
|
+
const sitesOptions = sites.map((site: ISite) => ({ label: site.name, value: site.id.toString() }));
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Modal
|
|
77
|
+
isOpen={isOpen}
|
|
78
|
+
hide={toggleModal}
|
|
79
|
+
size="S"
|
|
80
|
+
title="Copy page in another site"
|
|
81
|
+
mainAction={mainModalAction}
|
|
82
|
+
secondaryAction={secondaryModalAction}
|
|
83
|
+
>
|
|
84
|
+
<S.ModalContent>
|
|
85
|
+
<p>
|
|
86
|
+
<strong>Select a site to copy this page. </strong>
|
|
87
|
+
<br></br>
|
|
88
|
+
You can only select sites with the same language as this page.
|
|
89
|
+
</p>
|
|
90
|
+
<S.SelectWrapper>
|
|
91
|
+
<Select
|
|
92
|
+
name="select"
|
|
93
|
+
options={sitesOptions}
|
|
94
|
+
onChange={(value: string) => setSite(value)}
|
|
95
|
+
value={site?.toString() || ""}
|
|
96
|
+
mandatory={true}
|
|
97
|
+
/>
|
|
98
|
+
</S.SelectWrapper>
|
|
99
|
+
</S.ModalContent>
|
|
100
|
+
</Modal>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
71
103
|
const MainActionButton = (props: IActionButton): JSX.Element => (
|
|
72
104
|
<Button type="button" onClick={props.onClick}>
|
|
73
105
|
{props.title}
|
|
@@ -87,9 +119,15 @@ interface IDeleteModal extends IModal {
|
|
|
87
119
|
title?: string;
|
|
88
120
|
}
|
|
89
121
|
|
|
122
|
+
interface ICopyModal extends IModal {
|
|
123
|
+
setSite: React.Dispatch<React.SetStateAction<any>>;
|
|
124
|
+
sites: ISite[];
|
|
125
|
+
site: string | null;
|
|
126
|
+
}
|
|
127
|
+
|
|
90
128
|
interface IActionButton {
|
|
91
129
|
onClick: () => void;
|
|
92
130
|
title: string;
|
|
93
131
|
}
|
|
94
132
|
|
|
95
|
-
export { DeleteModal, MainActionButton, SecondaryActionButton };
|
|
133
|
+
export { DeleteModal, CopyModal, MainActionButton, SecondaryActionButton };
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
IGetSitePagesParams,
|
|
16
16
|
IColumn,
|
|
17
17
|
ISite,
|
|
18
|
+
IUser,
|
|
18
19
|
} from "@ax/types";
|
|
19
20
|
import { MainWrapper, Modal, TableList, ErrorToast, Toast, EmptyState, Notification } from "@ax/components";
|
|
20
21
|
import { getFilteredStructuredData, isGlobalStructuredData, isStructuredDataFromPage } from "@ax/helpers";
|
|
@@ -83,9 +84,14 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
83
84
|
resetPageEditor,
|
|
84
85
|
removePageFromSite,
|
|
85
86
|
importPageFromGlobal,
|
|
86
|
-
restorePage,
|
|
87
87
|
getDataPack,
|
|
88
|
+
getSitesByLang,
|
|
88
89
|
dataPacks,
|
|
90
|
+
restorePage,
|
|
91
|
+
getAvailableDataPacks,
|
|
92
|
+
sitesByLang,
|
|
93
|
+
user,
|
|
94
|
+
setCurrentDataID,
|
|
89
95
|
} = props;
|
|
90
96
|
|
|
91
97
|
const itemsPerPage = 50;
|
|
@@ -106,10 +112,12 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
106
112
|
const isDataEditable = !isStructuredData || (currentStructuredData && currentStructuredData.editable);
|
|
107
113
|
|
|
108
114
|
const pagesIds = currentSitePages && currentSitePages.map((page: any) => page.id);
|
|
115
|
+
const currentSitePagesTemplatesIds = currentSitePages && currentSitePages.map((page: any) => page.templateId);
|
|
109
116
|
const dataIds = currentDataContent && currentDataContent.map((data: any) => data.id);
|
|
110
117
|
const contentIds = isStructuredData ? dataIds : pagesIds;
|
|
111
|
-
const
|
|
112
|
-
|
|
118
|
+
const currentSitesByLang = sitesByLang?.filter(
|
|
119
|
+
(site) => user?.sites?.includes("all") || user.sites.includes(site.id)
|
|
120
|
+
);
|
|
113
121
|
const categoryColumns =
|
|
114
122
|
currentStructuredData && currentStructuredData.schema
|
|
115
123
|
? currentStructuredData.schema.fields.filter((field: any) => field.showList)
|
|
@@ -147,6 +155,7 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
147
155
|
const [deleteAllVersions, setDeleteAllVersions] = useState(false);
|
|
148
156
|
const [arePagesTranslated, setArePagesTranslated] = useState(false);
|
|
149
157
|
const [templateInstanceError, setTemplateInstanceError] = useState({ error: false, templateName: "" });
|
|
158
|
+
const [pagesTemplatesIds, setPagesTemplatesIds] = useState<any[]>([]);
|
|
150
159
|
|
|
151
160
|
const {
|
|
152
161
|
resetBulkSelection,
|
|
@@ -170,6 +179,12 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
170
179
|
setIsVisible: setIsVisibleDeletedToast,
|
|
171
180
|
} = useToast();
|
|
172
181
|
|
|
182
|
+
const {
|
|
183
|
+
isVisible: isVisibleCopiedToast,
|
|
184
|
+
toggleToast: toggleCopiedToast,
|
|
185
|
+
setIsVisible: setIsVisibleCopiedToast,
|
|
186
|
+
} = useToast();
|
|
187
|
+
|
|
173
188
|
const { categoryColors, addCategoryColors } = useCategoryColors();
|
|
174
189
|
|
|
175
190
|
const getParams = useCallback(() => {
|
|
@@ -231,11 +246,16 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
231
246
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
232
247
|
}, [filter]);
|
|
233
248
|
|
|
249
|
+
const fetchSitesByLang = async () => await getSitesByLang(lang.id);
|
|
250
|
+
|
|
234
251
|
useEffect(() => {
|
|
235
252
|
if (!locationState || locationState.isFromEditor !== true) {
|
|
236
253
|
setFilter("unique-pages");
|
|
237
254
|
}
|
|
238
255
|
resetPageEditor();
|
|
256
|
+
fetchSitesByLang();
|
|
257
|
+
setCurrentDataID(null);
|
|
258
|
+
getAvailableDataPacks(null);
|
|
239
259
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
240
260
|
}, []);
|
|
241
261
|
|
|
@@ -262,6 +282,12 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
262
282
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
263
283
|
}, [isLoading, currentSitePages]);
|
|
264
284
|
|
|
285
|
+
useEffect(() => {
|
|
286
|
+
if (pagesTemplatesIds?.length === 0) {
|
|
287
|
+
setPagesTemplatesIds(currentSitePagesTemplatesIds);
|
|
288
|
+
}
|
|
289
|
+
}, [currentSitePagesTemplatesIds]);
|
|
290
|
+
|
|
265
291
|
const bulkFilter = (bulkSelection: number[]) => filterByStatus(bulkSelection, currentSitePages);
|
|
266
292
|
|
|
267
293
|
const handleAddToBulk = (item: ICheck) => addToBulkSelection(item, bulkFilter);
|
|
@@ -530,13 +556,15 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
530
556
|
duplicatePage,
|
|
531
557
|
removePageFromSite,
|
|
532
558
|
languageActions: pageLanguageActions,
|
|
533
|
-
deleteBulk: deleteCurrentPageBulk,
|
|
534
559
|
getDataPack: getDataPack,
|
|
535
560
|
setTemplateInstanceError,
|
|
561
|
+
deleteBulk: deleteCurrentPageBulk,
|
|
562
|
+
toggleCopiedToast,
|
|
536
563
|
};
|
|
537
564
|
|
|
538
565
|
return (
|
|
539
566
|
<PageItem
|
|
567
|
+
sites={currentSitesByLang}
|
|
540
568
|
item={item}
|
|
541
569
|
key={pageItem.id}
|
|
542
570
|
functions={pageItemFunctions}
|
|
@@ -650,6 +678,11 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
650
678
|
message: "Page deleted.",
|
|
651
679
|
};
|
|
652
680
|
|
|
681
|
+
const copiedToastProps = {
|
|
682
|
+
setIsVisible: setIsVisibleCopiedToast,
|
|
683
|
+
message: "1 Page copied to another Site",
|
|
684
|
+
};
|
|
685
|
+
|
|
653
686
|
const addNewAction = filter === "unique-pages" || isGlobalPages ? toggleNewModal : addNewData;
|
|
654
687
|
|
|
655
688
|
return (
|
|
@@ -661,70 +694,74 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
661
694
|
rightButton={{ label: "New", action: addNewAction }}
|
|
662
695
|
searchAction={setSearchQuery}
|
|
663
696
|
>
|
|
664
|
-
|
|
665
|
-
<
|
|
666
|
-
|
|
667
|
-
<
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
<TableList
|
|
675
|
-
tableHeader={Header}
|
|
676
|
-
pagination={pagination}
|
|
677
|
-
onScroll={onScroll}
|
|
678
|
-
hasFixedHeader={true}
|
|
679
|
-
tableRef={tableRef}
|
|
680
|
-
>
|
|
681
|
-
{!isEmpty ? (
|
|
682
|
-
content
|
|
683
|
-
) : (
|
|
684
|
-
<S.EmptyWrapper>
|
|
685
|
-
<EmptyState {...emptyStateProps} />
|
|
686
|
-
</S.EmptyWrapper>
|
|
697
|
+
<>
|
|
698
|
+
<S.ContentListWrapper>
|
|
699
|
+
<ContentFilters current={filter} dynamicValues={structuredData} resetFilter={resetFilter} />
|
|
700
|
+
<S.TableWrapper>
|
|
701
|
+
<ErrorToast />
|
|
702
|
+
{templateInstanceError.error && (
|
|
703
|
+
<Notification
|
|
704
|
+
type="error"
|
|
705
|
+
text={`There can be only one ${templateInstanceError.templateName} page and you already have it.`}
|
|
706
|
+
/>
|
|
687
707
|
)}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
708
|
+
<TableList
|
|
709
|
+
tableHeader={Header}
|
|
710
|
+
pagination={pagination}
|
|
711
|
+
onScroll={onScroll}
|
|
712
|
+
hasFixedHeader={true}
|
|
713
|
+
tableRef={tableRef}
|
|
714
|
+
>
|
|
715
|
+
{!isEmpty ? (
|
|
716
|
+
content
|
|
717
|
+
) : (
|
|
718
|
+
<S.EmptyWrapper>
|
|
719
|
+
<EmptyState {...emptyStateProps} />
|
|
720
|
+
</S.EmptyWrapper>
|
|
721
|
+
)}
|
|
722
|
+
</TableList>
|
|
723
|
+
</S.TableWrapper>
|
|
724
|
+
</S.ContentListWrapper>
|
|
725
|
+
<Modal isOpen={isNewOpen} hide={toggleNewModal} size="M" title="New content">
|
|
726
|
+
<OptionTable
|
|
727
|
+
selectPage={addTemplate}
|
|
728
|
+
selectData={addNewStructuredData}
|
|
729
|
+
filters={options.filters}
|
|
730
|
+
values={options.values}
|
|
731
|
+
selectedValue={selectedOption}
|
|
732
|
+
theme={currentSiteInfo.theme}
|
|
733
|
+
mainAction={createContentAction}
|
|
734
|
+
secondaryAction={{ title: "Cancel", onClick: toggleNewModal }}
|
|
735
|
+
/>
|
|
736
|
+
</Modal>
|
|
737
|
+
<Modal
|
|
738
|
+
isOpen={isImporterOpen}
|
|
739
|
+
hide={toggleImporterModal}
|
|
740
|
+
size="M"
|
|
741
|
+
title="New content"
|
|
742
|
+
mainAction={{ title: "Add Pages", onClick: importPage }}
|
|
743
|
+
secondaryAction={{ title: "Cancel", onClick: toggleImporterModal }}
|
|
744
|
+
>
|
|
745
|
+
<PageImporter structuredData={selectedOptionType} {...{ setPagesToImport }} />
|
|
746
|
+
</Modal>
|
|
747
|
+
<DeleteModal
|
|
748
|
+
isOpen={isDeleteOpen}
|
|
749
|
+
toggleModal={toggleDeleteModal}
|
|
750
|
+
mainModalAction={mainDeleteModalAction}
|
|
751
|
+
secondaryModalAction={secondaryDeleteModalAction}
|
|
752
|
+
{...{ isTranslated: arePagesTranslated, deleteAllVersions, setDeleteAllVersions }}
|
|
701
753
|
/>
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
title="New content"
|
|
708
|
-
mainAction={{ title: "Add Pages", onClick: importPage }}
|
|
709
|
-
secondaryAction={{ title: "Cancel", onClick: toggleImporterModal }}
|
|
710
|
-
>
|
|
711
|
-
<PageImporter structuredData={selectedOptionType} {...{ setPagesToImport }} />
|
|
712
|
-
</Modal>
|
|
713
|
-
<DeleteModal
|
|
714
|
-
isOpen={isDeleteOpen}
|
|
715
|
-
toggleModal={toggleDeleteModal}
|
|
716
|
-
mainModalAction={mainDeleteModalAction}
|
|
717
|
-
secondaryModalAction={secondaryDeleteModalAction}
|
|
718
|
-
{...{ isTranslated: arePagesTranslated, deleteAllVersions, setDeleteAllVersions }}
|
|
719
|
-
/>
|
|
720
|
-
{isVisible && <Toast {...toastProps} />}
|
|
721
|
-
{isVisibleRemovedToast && <Toast {...removedToastProps} />}
|
|
722
|
-
{isVisibleDeletedToast && <Toast {...deletedToastProps} />}
|
|
754
|
+
{isVisible && <Toast {...toastProps} />}
|
|
755
|
+
{isVisibleRemovedToast && <Toast {...removedToastProps} />}
|
|
756
|
+
{isVisibleDeletedToast && <Toast {...deletedToastProps} />}
|
|
757
|
+
{isVisibleCopiedToast && <Toast {...copiedToastProps} />}
|
|
758
|
+
</>
|
|
723
759
|
</MainWrapper>
|
|
724
760
|
);
|
|
725
761
|
};
|
|
726
762
|
|
|
727
763
|
const mapStateToProps = (state: IRootState) => ({
|
|
764
|
+
sitesByLang: state.sites.sitesByLang,
|
|
728
765
|
currentSiteInfo: state.sites.currentSiteInfo,
|
|
729
766
|
currentSitePages: state.sites.currentSitePages,
|
|
730
767
|
filter: state.sites.currentFilter,
|
|
@@ -741,6 +778,7 @@ const mapStateToProps = (state: IRootState) => ({
|
|
|
741
778
|
activatedTemplates: state.dataPacks.templates,
|
|
742
779
|
isLoading: state.app.isLoading,
|
|
743
780
|
dataPacks: state.dataPacks.activated,
|
|
781
|
+
user: state.users.currentUser,
|
|
744
782
|
});
|
|
745
783
|
|
|
746
784
|
interface IDispatchProps {
|
|
@@ -760,7 +798,7 @@ interface IDispatchProps {
|
|
|
760
798
|
getStructuredDataContents(params: any, siteID: number): Promise<void>;
|
|
761
799
|
resetForm(): void;
|
|
762
800
|
deleteBulk(ids: any): Promise<boolean>;
|
|
763
|
-
duplicatePage(pageID: number, data
|
|
801
|
+
duplicatePage(pageID: number, data?: any, siteID?: number): Promise<boolean>;
|
|
764
802
|
deleteDataContent(dataID: number[]): Promise<boolean>;
|
|
765
803
|
restoreDataContent(catID: number | number[]): void;
|
|
766
804
|
setFilter(value: string): void;
|
|
@@ -768,14 +806,18 @@ interface IDispatchProps {
|
|
|
768
806
|
resetPageEditor(): Promise<void>;
|
|
769
807
|
removePageFromSite(pageID: number | number[], refresh?: boolean): Promise<boolean>;
|
|
770
808
|
importPageFromGlobal(pageID: number | number[]): Promise<boolean>;
|
|
771
|
-
restorePage(id: number | number[]): Promise<boolean>;
|
|
772
809
|
getDataPack: (id: string) => Promise<void>;
|
|
810
|
+
restorePage(id: number | number[]): Promise<boolean>;
|
|
811
|
+
getAvailableDataPacks: (queryParams: string | null) => void;
|
|
812
|
+
getSitesByLang(language: number): Promise<void>;
|
|
813
|
+
setCurrentDataID(id: number | null): void;
|
|
773
814
|
}
|
|
774
815
|
|
|
775
816
|
const mapDispatchToProps = {
|
|
776
817
|
setHistoryPush: appActions.setHistoryPush,
|
|
777
818
|
setLanguage: appActions.setLanguage,
|
|
778
819
|
getSitePages: sitesActions.getSitePages,
|
|
820
|
+
getSitesByLang: sitesActions.getSitesByLang,
|
|
779
821
|
setCurrentPageID: pageEditorActions.setCurrentPageID,
|
|
780
822
|
setCurrentPageStatus: pageEditorActions.setCurrentPageStatus,
|
|
781
823
|
setCurrentPageName: pageEditorActions.setCurrentPageName,
|
|
@@ -796,8 +838,10 @@ const mapDispatchToProps = {
|
|
|
796
838
|
resetPageEditor: pageEditorActions.resetPageEditor,
|
|
797
839
|
removePageFromSite: sitesActions.removePageFromSite,
|
|
798
840
|
importPageFromGlobal: sitesActions.importPageFromGlobal,
|
|
799
|
-
restorePage: pageEditorActions.restorePage,
|
|
800
841
|
getDataPack: dataPacksActions.getSiteDataPack,
|
|
842
|
+
restorePage: pageEditorActions.restorePage,
|
|
843
|
+
getAvailableDataPacks: dataPacksActions.getAvailableSiteDataPacks,
|
|
844
|
+
setCurrentDataID: structuredDataActions.setCurrentDataID,
|
|
801
845
|
};
|
|
802
846
|
|
|
803
847
|
interface IPagesProps {
|
|
@@ -819,6 +863,9 @@ interface IPagesProps {
|
|
|
819
863
|
activatedTemplates: any[];
|
|
820
864
|
isLoading: boolean;
|
|
821
865
|
dataPacks: IDataPack[];
|
|
866
|
+
sites: ISite[];
|
|
867
|
+
sitesByLang: ISite[];
|
|
868
|
+
user: IUser;
|
|
822
869
|
}
|
|
823
870
|
|
|
824
871
|
type IProps = IPagesProps & IDispatchProps;
|
|
@@ -35,4 +35,11 @@ const ModalContent = styled.div`
|
|
|
35
35
|
}
|
|
36
36
|
`;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
const SelectWrapper = styled.div`
|
|
39
|
+
& .react-select__control,
|
|
40
|
+
.react-select__menu {
|
|
41
|
+
min-width: 100%;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
export { ContentListWrapper, TableWrapper, PaginationWrapper, EmptyWrapper, ModalContent, SelectWrapper };
|
|
@@ -29,6 +29,7 @@ const Editor = (props: IProps) => {
|
|
|
29
29
|
copyModule,
|
|
30
30
|
pasteModule,
|
|
31
31
|
theme,
|
|
32
|
+
browserRef,
|
|
32
33
|
setNotification,
|
|
33
34
|
} = props;
|
|
34
35
|
|
|
@@ -47,7 +48,7 @@ const Editor = (props: IProps) => {
|
|
|
47
48
|
|
|
48
49
|
return (
|
|
49
50
|
<ResizePanel
|
|
50
|
-
leftPanel={<PageBrowser isReadOnly={isReadOnly} theme={theme} />}
|
|
51
|
+
leftPanel={<PageBrowser isReadOnly={isReadOnly} theme={theme} browserRef={browserRef} />}
|
|
51
52
|
rightPanel={
|
|
52
53
|
<ConfigPanel
|
|
53
54
|
schema={schema}
|
|
@@ -99,6 +100,7 @@ interface IPageBrowserDispatchProps {
|
|
|
99
100
|
isEditable: boolean;
|
|
100
101
|
isReadOnly: boolean;
|
|
101
102
|
theme: string;
|
|
103
|
+
browserRef: any;
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -18,6 +18,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
18
18
|
theme,
|
|
19
19
|
isReadOnly,
|
|
20
20
|
isPreview,
|
|
21
|
+
browserRef,
|
|
21
22
|
} = props;
|
|
22
23
|
|
|
23
24
|
const slugWithSlash = slug ? (slug.startsWith("/") ? slug : `/${slug}`) : "";
|
|
@@ -38,6 +39,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
38
39
|
disabled={isReadOnly}
|
|
39
40
|
siteID={canonicalSite}
|
|
40
41
|
isPreview={isPreview}
|
|
42
|
+
browserRef={browserRef}
|
|
41
43
|
/>
|
|
42
44
|
);
|
|
43
45
|
};
|
|
@@ -60,6 +62,7 @@ interface IPageBrowserDispatchProps {
|
|
|
60
62
|
theme: string;
|
|
61
63
|
isReadOnly: boolean;
|
|
62
64
|
isPreview?: boolean;
|
|
65
|
+
browserRef?: any;
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
1
|
+
import React, { useEffect, useState, useRef } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
3
|
import { RouteComponentProps } from "react-router-dom";
|
|
4
4
|
|
|
@@ -50,6 +50,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
50
50
|
const [selectedTab, setSelectedTab] = useState("edit");
|
|
51
51
|
const [notification, setNotification] = useState<INotification | null>(null);
|
|
52
52
|
const { isDirty, setIsDirty, resetDirty } = useIsDirty(editorContent.editorContent, isNewTranslation);
|
|
53
|
+
const browserRef = useRef<HTMLDivElement>(null);
|
|
53
54
|
|
|
54
55
|
const isPublished = props.pageStatus === pageStatus.PUBLISHED || props.pageStatus === pageStatus.UPLOAD_PENDING;
|
|
55
56
|
const isDraft = props.pageStatus === pageStatus.MODIFIED;
|
|
@@ -114,7 +115,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
114
115
|
const publishPage = async () => {
|
|
115
116
|
const { updatePageStatus, savePage, pageID, validatePage } = props;
|
|
116
117
|
|
|
117
|
-
const validated = await validatePage(true);
|
|
118
|
+
const validated = await validatePage(true, browserRef);
|
|
118
119
|
|
|
119
120
|
if (validated) {
|
|
120
121
|
const publishPage = {
|
|
@@ -134,7 +135,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
134
135
|
const publishChanges = async () => {
|
|
135
136
|
const { savePage, validatePage } = props;
|
|
136
137
|
|
|
137
|
-
const validated = await validatePage(true);
|
|
138
|
+
const validated = await validatePage(true, browserRef);
|
|
138
139
|
|
|
139
140
|
if (validated) {
|
|
140
141
|
const publishPage = {
|
|
@@ -163,13 +164,13 @@ const GlobalEditor = (props: IProps) => {
|
|
|
163
164
|
|
|
164
165
|
const reviewPage = () => {
|
|
165
166
|
const { validatePage } = props;
|
|
166
|
-
validatePage();
|
|
167
|
+
validatePage(false, browserRef);
|
|
167
168
|
};
|
|
168
169
|
|
|
169
170
|
const handlePublishDraft = async () => {
|
|
170
171
|
const { savePage, validatePage } = props;
|
|
171
172
|
|
|
172
|
-
const validated = await validatePage(true);
|
|
173
|
+
const validated = await validatePage(true, browserRef);
|
|
173
174
|
|
|
174
175
|
if (validated) {
|
|
175
176
|
const isSaved = await savePage(false, null, true);
|
|
@@ -462,6 +463,7 @@ const GlobalEditor = (props: IProps) => {
|
|
|
462
463
|
isEditable={isEditable}
|
|
463
464
|
isReadOnly={isReadOnly}
|
|
464
465
|
theme={theme}
|
|
466
|
+
browserRef={browserRef}
|
|
465
467
|
setNotification={setNotification}
|
|
466
468
|
/>
|
|
467
469
|
</S.Content>
|
|
@@ -567,7 +569,7 @@ interface IPageEditorDispatchProps {
|
|
|
567
569
|
getPage(pageID?: number, global?: boolean): Promise<void>;
|
|
568
570
|
savePage(createDraft: boolean, publishPage?: any, publishDraft?: boolean): Promise<boolean>;
|
|
569
571
|
deletePage(params?: ISavePageParams): Promise<boolean>;
|
|
570
|
-
validatePage(publish?: boolean): Promise<boolean>;
|
|
572
|
+
validatePage(publish?: boolean, browserRef?: any): Promise<boolean>;
|
|
571
573
|
updatePageStatus(id: number[], status: string): Promise<boolean>;
|
|
572
574
|
setHistoryPush(path: string, isEditor: boolean): void;
|
|
573
575
|
setLanguage?(lang: { locale: string; id: number | null }): void;
|
|
@@ -79,6 +79,14 @@ const Form = (props: IProps): JSX.Element => {
|
|
|
79
79
|
handlePanel={toggleSecondaryPanel}
|
|
80
80
|
inFloatingPanel={true}
|
|
81
81
|
/>
|
|
82
|
+
<FieldsBehavior
|
|
83
|
+
title="Image"
|
|
84
|
+
name="image"
|
|
85
|
+
fieldType="ImageField"
|
|
86
|
+
value={itemImage || null}
|
|
87
|
+
onChange={setImageValue}
|
|
88
|
+
setIsGalleryOpened={setIsGalleryOpened}
|
|
89
|
+
/>
|
|
82
90
|
</>
|
|
83
91
|
)}
|
|
84
92
|
</>
|
|
@@ -35,10 +35,11 @@ const Editor = (props: IProps) => {
|
|
|
35
35
|
isReadOnly,
|
|
36
36
|
userEditing,
|
|
37
37
|
site,
|
|
38
|
-
lastElementAddedId,
|
|
39
38
|
copyModule,
|
|
40
39
|
pasteModule,
|
|
41
40
|
setNotification,
|
|
41
|
+
lastElementAddedId,
|
|
42
|
+
browserRef,
|
|
42
43
|
} = props;
|
|
43
44
|
|
|
44
45
|
const actions = {
|
|
@@ -58,7 +59,9 @@ const Editor = (props: IProps) => {
|
|
|
58
59
|
|
|
59
60
|
return (
|
|
60
61
|
<ResizePanel
|
|
61
|
-
leftPanel={
|
|
62
|
+
leftPanel={
|
|
63
|
+
<PageBrowser isTemplateActivated={isTemplateActivated} isReadOnly={isReadOnly} browserRef={browserRef} />
|
|
64
|
+
}
|
|
62
65
|
rightPanel={
|
|
63
66
|
<ConfigPanel
|
|
64
67
|
schema={schema}
|
|
@@ -119,6 +122,7 @@ interface IPageBrowserDispatchProps {
|
|
|
119
122
|
isEditable: boolean;
|
|
120
123
|
pageTitle: string;
|
|
121
124
|
isReadOnly: boolean;
|
|
125
|
+
browserRef: any;
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|
|
@@ -21,6 +21,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
21
21
|
isTemplateActivated,
|
|
22
22
|
isReadOnly,
|
|
23
23
|
isPreview,
|
|
24
|
+
browserRef,
|
|
24
25
|
} = props;
|
|
25
26
|
|
|
26
27
|
const slugWithSlash = slug ? (slug.startsWith("/") ? slug : `/${slug}`) : "";
|
|
@@ -44,6 +45,7 @@ const PageBrowser = (props: IProps) => {
|
|
|
44
45
|
disabled={disabled}
|
|
45
46
|
siteID={siteID}
|
|
46
47
|
isPreview={isPreview}
|
|
48
|
+
browserRef={browserRef}
|
|
47
49
|
/>
|
|
48
50
|
);
|
|
49
51
|
};
|
|
@@ -67,6 +69,7 @@ interface IPageBrowserDispatchProps {
|
|
|
67
69
|
isTemplateActivated: boolean;
|
|
68
70
|
isReadOnly: boolean;
|
|
69
71
|
isPreview?: boolean;
|
|
72
|
+
browserRef?: any;
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
type IProps = IEditorStateProps & IPageBrowserDispatchProps;
|