@griddo/ax 1.62.6 → 1.63.0
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 +6 -5
- package/src/GlobalStore.tsx +1 -1
- package/src/Style/index.tsx +2 -0
- package/src/api/pages.tsx +20 -0
- package/src/api/utils.tsx +5 -2
- package/src/components/Browser/index.tsx +144 -39
- package/src/components/Browser/style.tsx +47 -11
- package/src/components/ConfigPanel/index.tsx +3 -3
- package/src/components/Fields/RichText/index.tsx +2 -2
- package/src/components/Fields/UrlField/utils.tsx +10 -1
- package/src/components/Icon/components/Desktop.js +9 -4
- package/src/components/Icon/components/Phone.js +4 -4
- package/src/components/Icon/components/Share.js +12 -0
- package/src/components/Icon/components/Tablet.js +4 -4
- package/src/components/Icon/svgs/Share.svg +3 -0
- package/src/components/MainWrapper/AppBar/index.tsx +19 -7
- package/src/components/MainWrapper/AppBar/style.tsx +20 -4
- package/src/components/MainWrapper/index.tsx +1 -1
- package/src/components/SideModal/index.tsx +1 -1
- package/src/components/TableFilters/DateFilter/index.tsx +48 -0
- package/src/components/TableFilters/DateFilter/style.tsx +29 -0
- package/src/components/TableFilters/index.tsx +2 -0
- package/src/components/Tabs/index.tsx +17 -7
- package/src/components/Tabs/style.tsx +29 -16
- package/src/components/Tooltip/index.tsx +1 -1
- package/src/components/Tooltip/style.tsx +2 -0
- package/src/components/index.tsx +2 -0
- package/src/containers/App/reducer.tsx +3 -1
- package/src/containers/Navigation/Defaults/actions.tsx +2 -1
- package/src/containers/PageEditor/actions.tsx +65 -10
- package/src/containers/Settings/DataPacks/actions.tsx +4 -1
- package/src/containers/Sites/actions.tsx +3 -1
- package/src/helpers/dates.tsx +3 -4
- package/src/helpers/index.tsx +2 -0
- package/src/helpers/strings.tsx +38 -7
- package/src/hooks/forms.tsx +1 -2
- package/src/index.tsx +2 -2
- package/src/modules/Content/OptionTable/index.tsx +29 -2
- package/src/modules/Content/PageItem/index.tsx +11 -2
- package/src/modules/Content/index.tsx +9 -0
- package/src/modules/GlobalEditor/Editor/index.tsx +7 -9
- package/src/modules/GlobalEditor/{Editor/PageBrowser → PageBrowser}/index.tsx +14 -6
- package/src/modules/GlobalEditor/Preview/index.tsx +19 -0
- package/src/modules/GlobalEditor/Preview/style.tsx +9 -0
- package/src/modules/GlobalEditor/index.tsx +41 -9
- package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +5 -1
- package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +9 -7
- package/src/modules/PageEditor/Editor/index.tsx +5 -5
- package/src/modules/PageEditor/{Editor/PageBrowser → PageBrowser}/index.tsx +11 -4
- package/src/modules/PageEditor/Preview/index.tsx +14 -0
- package/src/modules/PageEditor/Preview/style.tsx +9 -0
- package/src/modules/PageEditor/index.tsx +40 -16
- package/src/modules/PublicPreview/index.tsx +92 -0
- package/src/modules/PublicPreview/style.tsx +18 -0
- package/src/modules/Redirects/BulkHeader/TableHeader/index.tsx +16 -3
- package/src/modules/Redirects/BulkHeader/TableHeader/style.tsx +9 -3
- package/src/modules/Redirects/BulkHeader/index.tsx +7 -1
- package/src/modules/Redirects/RedirectItem/index.tsx +4 -0
- package/src/modules/Redirects/RedirectItem/style.tsx +19 -3
- package/src/modules/Redirects/atoms.tsx +0 -1
- package/src/modules/Redirects/hooks.tsx +67 -0
- package/src/modules/Redirects/index.tsx +23 -9
- package/src/modules/Redirects/utils.tsx +10 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/index.tsx +107 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/Field/style.tsx +54 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/index.tsx +66 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/ConfigPanel/style.tsx +42 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +58 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +41 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/index.tsx +93 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/style.tsx +25 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/index.tsx +48 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/style.tsx +53 -0
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +40 -36
- package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/style.tsx +4 -5
- package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +4 -4
- package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +5 -1
- package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/atoms.tsx +0 -0
- package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/index.tsx +20 -11
- package/src/modules/Settings/{Analytics → SeoAnalyticsSettings/Analytics}/style.tsx +6 -0
- package/src/modules/Settings/{SeoSettings → SeoAnalyticsSettings}/index.tsx +11 -4
- package/src/routes/publicRoutes.tsx +3 -1
- package/src/routes/site.tsx +14 -10
- package/src/types/index.tsx +9 -0
|
@@ -2,17 +2,32 @@ import styled from "styled-components";
|
|
|
2
2
|
|
|
3
3
|
const ActionMenu = styled.ul``;
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const WrapperTabs = styled.div`
|
|
6
6
|
display: flex;
|
|
7
7
|
flex-direction: row;
|
|
8
8
|
align-items: center;
|
|
9
|
+
margin-right: auto;
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
const WrapperEnd = styled.div`
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: row;
|
|
15
|
+
align-items: center;
|
|
16
|
+
margin-left: auto;
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const WrapperTitle = styled.div`
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: row;
|
|
22
|
+
align-items: center;
|
|
23
|
+
width: 600px;
|
|
24
|
+
margin-right: ${(p) => p.theme.spacing.xl};
|
|
9
25
|
`;
|
|
10
26
|
|
|
11
27
|
const Title = styled.h1`
|
|
12
28
|
margin: 0;
|
|
13
29
|
${(p) => p.theme.textStyle.headingM};
|
|
14
30
|
padding-left: ${(p) => p.theme.spacing.m};
|
|
15
|
-
margin-right: calc(${(p) => p.theme.spacing.m} * 3);
|
|
16
31
|
`;
|
|
17
32
|
|
|
18
33
|
const Subtitle = styled.span`
|
|
@@ -97,7 +112,6 @@ const Header = styled.section<{ inversed?: boolean }>`
|
|
|
97
112
|
min-height: ${(p) => p.theme.spacing.xl};
|
|
98
113
|
background: ${(p) => (p.inversed ? p.theme.color.uiMainMenuBackground : p.theme.color.uiBackground02)};
|
|
99
114
|
display: flex;
|
|
100
|
-
justify-content: space-between;
|
|
101
115
|
padding-right: ${(p) => p.theme.spacing.s};
|
|
102
116
|
|
|
103
117
|
button:first-child {
|
|
@@ -160,7 +174,7 @@ const SearchWrapper = styled.div`
|
|
|
160
174
|
export {
|
|
161
175
|
ActionMenu,
|
|
162
176
|
Header,
|
|
163
|
-
|
|
177
|
+
WrapperTabs,
|
|
164
178
|
Title,
|
|
165
179
|
Subtitle,
|
|
166
180
|
ActionText,
|
|
@@ -175,4 +189,6 @@ export {
|
|
|
175
189
|
IconWrapper,
|
|
176
190
|
ErrorWrapper,
|
|
177
191
|
SearchWrapper,
|
|
192
|
+
WrapperEnd,
|
|
193
|
+
WrapperTitle,
|
|
178
194
|
};
|
|
@@ -26,7 +26,7 @@ interface IWrapperProps {
|
|
|
26
26
|
fixedAppBar?: boolean;
|
|
27
27
|
additionalClass?: string;
|
|
28
28
|
downArrowMenu?: { displayed: boolean; options: any; button: any };
|
|
29
|
-
tabs?: { tabSet
|
|
29
|
+
tabs?: { tabSet?: any; icons?: { name: string; text: string }[]; selectedTab: string; action: (e: any) => void };
|
|
30
30
|
pageStatus?: string;
|
|
31
31
|
language?: { locale: string; id: number | null } | null;
|
|
32
32
|
availableLanguages?: any[] | null;
|
|
@@ -140,7 +140,7 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
|
|
|
140
140
|
<S.Wrapper ref={node} optionsType={optionsType}>
|
|
141
141
|
<S.Header>
|
|
142
142
|
<S.Title>{optionsType}</S.Title>
|
|
143
|
-
{showSearch && (
|
|
143
|
+
{showSearch && optionsType !== "components" && (
|
|
144
144
|
<S.SearchWrapper>
|
|
145
145
|
<SearchField onChange={setSearchQuery} closeOnInactive />
|
|
146
146
|
</S.SearchWrapper>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { Icon, FloatingMenu, ListTitle, ListItem } from "@ax/components";
|
|
4
|
+
|
|
5
|
+
import * as S from "./style";
|
|
6
|
+
|
|
7
|
+
const DateFilter = (props: IStatusFilterProps): JSX.Element => {
|
|
8
|
+
const { sortItems, sortedState } = props;
|
|
9
|
+
const { isAscending, sortedByDate } = sortedState;
|
|
10
|
+
const sortByModifiedDate = (isAscending: boolean) => sortItems("date", isAscending);
|
|
11
|
+
|
|
12
|
+
const sortOldestModifiedDate = () => sortByModifiedDate(true);
|
|
13
|
+
const sortMostRecentModifiedDate = () => sortByModifiedDate(false);
|
|
14
|
+
|
|
15
|
+
const SortedStateArrow = () =>
|
|
16
|
+
isAscending ? <Icon name="FullArrowUp" size="16" /> : <Icon name="FullArrowDown" size="16" />;
|
|
17
|
+
|
|
18
|
+
const Header = () => (
|
|
19
|
+
<S.Date isActive={sortedByDate}>
|
|
20
|
+
Date
|
|
21
|
+
<S.IconsWrapper>
|
|
22
|
+
{sortedByDate && <SortedStateArrow />}
|
|
23
|
+
<S.InteractiveArrow>
|
|
24
|
+
<Icon name="DownArrow" size="16" />
|
|
25
|
+
</S.InteractiveArrow>
|
|
26
|
+
</S.IconsWrapper>
|
|
27
|
+
</S.Date>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<FloatingMenu Button={Header} position="center">
|
|
32
|
+
<ListTitle>Sort by creation date</ListTitle>
|
|
33
|
+
<ListItem isSelected={sortedByDate && !isAscending} onClick={sortMostRecentModifiedDate}>
|
|
34
|
+
Most recent
|
|
35
|
+
</ListItem>
|
|
36
|
+
<ListItem isSelected={sortedByDate && isAscending} onClick={sortOldestModifiedDate}>
|
|
37
|
+
Oldest
|
|
38
|
+
</ListItem>
|
|
39
|
+
</FloatingMenu>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
interface IStatusFilterProps {
|
|
44
|
+
sortedState: any;
|
|
45
|
+
sortItems(orderPointer: string, isAscendent: boolean): any;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default DateFilter;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Header } from "@ax/components/TableList/style";
|
|
3
|
+
|
|
4
|
+
const Date = styled(Header) <{ isActive: boolean }>`
|
|
5
|
+
width: 100px;
|
|
6
|
+
&:hover {
|
|
7
|
+
color: ${(p) => p.theme.color.interactive01};
|
|
8
|
+
}
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
const IconsWrapper = styled.div`
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
flex-direction: row;
|
|
15
|
+
svg {
|
|
16
|
+
margin-left: 4px;
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
const InteractiveArrow = styled.div`
|
|
21
|
+
display: flex;
|
|
22
|
+
svg {
|
|
23
|
+
path {
|
|
24
|
+
fill: ${(p) => p.theme.color.interactive01};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
export { Date, IconsWrapper, InteractiveArrow };
|
|
@@ -6,6 +6,7 @@ import SiteFilter from "./SiteFilter";
|
|
|
6
6
|
import StatusFilter from "./StatusFilter";
|
|
7
7
|
import TranslationsFilter from "./TranslationsFilter";
|
|
8
8
|
import TypeFilter from "./TypeFilter";
|
|
9
|
+
import DateFilter from "./DateFilter";
|
|
9
10
|
|
|
10
11
|
export {
|
|
11
12
|
CategoryFilter,
|
|
@@ -16,4 +17,5 @@ export {
|
|
|
16
17
|
StatusFilter,
|
|
17
18
|
TranslationsFilter,
|
|
18
19
|
TypeFilter,
|
|
20
|
+
DateFilter,
|
|
19
21
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
-
import { Icon } from "@ax/components";
|
|
2
|
+
import { Icon, Tooltip } from "@ax/components";
|
|
3
3
|
|
|
4
4
|
import * as S from "./style";
|
|
5
5
|
|
|
6
|
-
const Tabs = (
|
|
6
|
+
const Tabs = (props: ITabsProps): JSX.Element => {
|
|
7
|
+
const { tabs, icons, active, setSelectedTab, isInAppBar, noMargins, inversed } = props;
|
|
8
|
+
|
|
7
9
|
useEffect(() => {
|
|
8
10
|
tabs && tabs.length === 1 && setSelectedTab(tabs[0]);
|
|
9
11
|
}, [tabs, setSelectedTab]);
|
|
@@ -26,12 +28,14 @@ const Tabs = ({ tabs, icons, active, setSelectedTab, isInAppBar, noMargins }: IT
|
|
|
26
28
|
if (icons) {
|
|
27
29
|
return (
|
|
28
30
|
<S.TabsRow icons={true} isInAppBar={isInAppBar}>
|
|
29
|
-
{icons.map((tab:
|
|
30
|
-
const handleClick = () => setSelectedTab(tab);
|
|
31
|
+
{icons.map((tab: ITabIcon) => {
|
|
32
|
+
const handleClick = () => setSelectedTab(tab.name);
|
|
31
33
|
return (
|
|
32
|
-
<S.TabItem key={tab} active={tab === active} onClick={handleClick}>
|
|
34
|
+
<S.TabItem key={tab.name} active={tab.name === active} onClick={handleClick} inversed={inversed}>
|
|
33
35
|
<S.TabIcon>
|
|
34
|
-
<
|
|
36
|
+
<Tooltip content={tab.text} bottom>
|
|
37
|
+
<Icon name={tab.name} />
|
|
38
|
+
</Tooltip>
|
|
35
39
|
</S.TabIcon>
|
|
36
40
|
</S.TabItem>
|
|
37
41
|
);
|
|
@@ -45,11 +49,17 @@ const Tabs = ({ tabs, icons, active, setSelectedTab, isInAppBar, noMargins }: IT
|
|
|
45
49
|
|
|
46
50
|
interface ITabsProps {
|
|
47
51
|
tabs?: any[];
|
|
48
|
-
icons?:
|
|
52
|
+
icons?: ITabIcon[];
|
|
49
53
|
isInAppBar?: boolean;
|
|
50
54
|
active: string;
|
|
51
55
|
setSelectedTab: any;
|
|
52
56
|
noMargins?: boolean;
|
|
57
|
+
inversed?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface ITabIcon {
|
|
61
|
+
name: string;
|
|
62
|
+
text: string;
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
export default Tabs;
|
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const TabsRow = styled.div<{ icons?: boolean; isInAppBar?: boolean; noMargins?: boolean }>`
|
|
4
4
|
display: flex;
|
|
5
|
-
border-bottom: ${p => (p.icons || p.isInAppBar || p.noMargins ? "none" : `1px solid ${p.theme.color.uiLine}`)};
|
|
6
|
-
margin-bottom: ${p => (p.isInAppBar || p.noMargins ? 0 : p.theme.spacing.m)
|
|
5
|
+
border-bottom: ${(p) => (p.icons || p.isInAppBar || p.noMargins ? "none" : `1px solid ${p.theme.color.uiLine}`)};
|
|
6
|
+
margin-bottom: ${(p) => (p.isInAppBar || p.noMargins ? 0 : p.theme.spacing.m)};
|
|
7
7
|
align-self: flex-end;
|
|
8
|
-
height: ${p => p.noMargins ? "auto" : "100%"};
|
|
8
|
+
height: ${(p) => (p.noMargins || p.isInAppBar ? "auto" : "100%")};
|
|
9
9
|
`;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
const TabItem = styled.button<{ active: boolean; isInAppBar?: boolean; inversed?: boolean }>`
|
|
12
12
|
flex-grow: 1;
|
|
13
13
|
border: none;
|
|
14
|
-
border-bottom: 4px solid
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
border-bottom: 4px solid
|
|
15
|
+
${(p) =>
|
|
16
|
+
!p.active ? "transparent" : p.inversed ? p.theme.color.iconHighEmphasisInverse : p.theme.color.interactive01};
|
|
17
|
+
${(p) => p.theme.textStyle.headingXS};
|
|
18
|
+
color: ${(p) => (p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis)};
|
|
19
|
+
cursor: ${(p) => (p.active ? "initial" : "pointer")};
|
|
18
20
|
background: transparent;
|
|
19
|
-
height: ${p => (p.isInAppBar ? "100%" : "48px")};
|
|
21
|
+
height: ${(p) => (p.isInAppBar ? "100%" : "48px")};
|
|
20
22
|
|
|
21
23
|
&:hover {
|
|
22
|
-
color: ${p => (p.active ? p.theme.color.textHighEmphasis : p.theme.color.interactive01)};
|
|
24
|
+
color: ${(p) => (p.active ? p.theme.color.textHighEmphasis : p.theme.color.interactive01)};
|
|
23
25
|
svg {
|
|
24
26
|
path {
|
|
25
|
-
fill: ${p => p.theme.color.interactive01};
|
|
27
|
+
fill: ${(p) => (p.inversed ? p.theme.color.iconHighEmphasisInverse : p.theme.color.interactive01)};
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
}
|
|
@@ -33,12 +35,23 @@ export const TabItem = styled.button<{ active: boolean, isInAppBar?: boolean }>`
|
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
svg {
|
|
36
|
-
width: ${p => p.theme.spacing.m};
|
|
37
|
-
height: ${p => p.theme.spacing.m};
|
|
38
|
+
width: ${(p) => p.theme.spacing.m};
|
|
39
|
+
height: ${(p) => p.theme.spacing.m};
|
|
38
40
|
path {
|
|
39
|
-
fill: ${p =>
|
|
41
|
+
fill: ${(p) =>
|
|
42
|
+
!p.active
|
|
43
|
+
? p.theme.color.interactiveDisabled
|
|
44
|
+
: p.inversed
|
|
45
|
+
? p.theme.color.iconHighEmphasisInverse
|
|
46
|
+
: p.theme.color.interactive01};
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
`;
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
const TabIcon = styled.div`
|
|
52
|
+
text-transform: none;
|
|
53
|
+
padding-left: ${(p) => p.theme.spacing.xxs};
|
|
54
|
+
padding-right: ${(p) => p.theme.spacing.xxs};
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
export { TabsRow, TabItem, TabIcon };
|
|
@@ -4,7 +4,7 @@ import { useHandleClickOutside } from "@ax/hooks";
|
|
|
4
4
|
import * as S from "./style";
|
|
5
5
|
|
|
6
6
|
const Tooltip = (props: IProps): JSX.Element => {
|
|
7
|
-
const { content, children, hideOnClick, bottom, left } = props;
|
|
7
|
+
const { content, children, hideOnClick = true, bottom, left } = props;
|
|
8
8
|
|
|
9
9
|
const initialState: IState = {
|
|
10
10
|
active: false,
|
package/src/components/index.tsx
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
StatusFilter,
|
|
40
40
|
TranslationsFilter,
|
|
41
41
|
TypeFilter,
|
|
42
|
+
DateFilter,
|
|
42
43
|
} from "./TableFilters";
|
|
43
44
|
|
|
44
45
|
import ActionMenu from "./ActionMenu";
|
|
@@ -121,6 +122,7 @@ export {
|
|
|
121
122
|
ListTitle,
|
|
122
123
|
ListItem,
|
|
123
124
|
//Filters
|
|
125
|
+
DateFilter,
|
|
124
126
|
CategoryFilter,
|
|
125
127
|
CustomizeFilters,
|
|
126
128
|
LiveFilter,
|
|
@@ -37,7 +37,8 @@ export interface IUser {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export interface IGlobalSettings {
|
|
40
|
-
cloudinaryName: string;
|
|
40
|
+
cloudinaryName: string | null;
|
|
41
|
+
damDomain: string | null;
|
|
41
42
|
globalLogoBig: string;
|
|
42
43
|
globalLogoMini: string;
|
|
43
44
|
siteLogoBig: string;
|
|
@@ -66,6 +67,7 @@ export const initialState = {
|
|
|
66
67
|
globalLangs: [],
|
|
67
68
|
globalSettings: {
|
|
68
69
|
cloudinaryName: "",
|
|
70
|
+
damDomain: "",
|
|
69
71
|
globalLogoBig: "",
|
|
70
72
|
globalLogoMini: "",
|
|
71
73
|
siteLogoBig: "",
|
|
@@ -230,7 +230,8 @@ function createNavigation(): (dispatch: Dispatch, getState: any) => Promise<bool
|
|
|
230
230
|
const cleanValues = removeEditorIds(navigationValues);
|
|
231
231
|
|
|
232
232
|
const successAction = async (response: any) => {
|
|
233
|
-
|
|
233
|
+
const updatedContent = { ...editorContent, ...response };
|
|
234
|
+
generateContent(updatedContent, dispatch, getState);
|
|
234
235
|
dispatch(setIsNewTranslation(false));
|
|
235
236
|
};
|
|
236
237
|
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
} from "./interfaces";
|
|
78
78
|
|
|
79
79
|
const { setIsLoading, setIsSaving } = appActions;
|
|
80
|
-
const { getSiteDefaults } = navigationActions;
|
|
80
|
+
const { getSiteDefaults, getDefaults } = navigationActions;
|
|
81
81
|
|
|
82
82
|
// AUDIT: THIS FILE IS WAY TOO LONG - LOOK FOR A REFACTOR SOLUTION
|
|
83
83
|
// FIXME: CHECK EDITOR CONTENT STRUCTURE (editorContent.editorContent)
|
|
@@ -154,6 +154,40 @@ function setUserEditing(userEditing: IUserEditing | null): ISetUserEditing {
|
|
|
154
154
|
return { type: SET_USER_EDITING, payload: { userEditing } };
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
function setTranslatedParent(): (dispatch: Dispatch, getState: any) => void {
|
|
158
|
+
return async (dispatch, getState) => {
|
|
159
|
+
try {
|
|
160
|
+
const {
|
|
161
|
+
app: { lang },
|
|
162
|
+
pageEditor: {
|
|
163
|
+
selectedEditorID,
|
|
164
|
+
editorContent: {
|
|
165
|
+
editorContent: { parent, site, entity, language },
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
} = getState();
|
|
169
|
+
|
|
170
|
+
const responseActions = {
|
|
171
|
+
handleSuccess: (data: any) => {
|
|
172
|
+
const { items } = data;
|
|
173
|
+
const translatedParent = items.filter(
|
|
174
|
+
(item: any) => (item.languageId === lang.id && language !== lang.id && item.pageId) || null
|
|
175
|
+
);
|
|
176
|
+
const translatedParentId = translatedParent && translatedParent[0] ? translatedParent[0].pageId : null;
|
|
177
|
+
updateEditorContent(selectedEditorID, "parent", translatedParentId)(dispatch, getState);
|
|
178
|
+
},
|
|
179
|
+
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const callback = async () => pages.getPageLanguages(parent, site, entity);
|
|
183
|
+
|
|
184
|
+
await handleRequest(callback, responseActions, [])(dispatch);
|
|
185
|
+
} catch (e) {
|
|
186
|
+
console.log(e); // TODO: capturar error bien
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
157
191
|
function createNewTranslation(isNewTranslation: boolean): (dispatch: Dispatch, getState: any) => void {
|
|
158
192
|
return async (dispatch, getState) => {
|
|
159
193
|
try {
|
|
@@ -258,10 +292,11 @@ function getPage(pageID?: number, global?: boolean): (dispatch: Dispatch, getSta
|
|
|
258
292
|
const pageLiveStatus = page.draftFromPage
|
|
259
293
|
? pageStatus.MODIFIED
|
|
260
294
|
: isNewTranslation
|
|
261
|
-
|
|
262
|
-
|
|
295
|
+
? pageStatus.OFFLINE
|
|
296
|
+
: page.liveStatus.status;
|
|
263
297
|
|
|
264
298
|
if (isReqOk(response.status)) {
|
|
299
|
+
addTemplate(page.templateId)(dispatch);
|
|
265
300
|
setRootEditorID(dispatch, getState);
|
|
266
301
|
generatePageContent(page, dispatch, getState);
|
|
267
302
|
dispatch(setCurrentPageName(page.title));
|
|
@@ -269,7 +304,6 @@ function getPage(pageID?: number, global?: boolean): (dispatch: Dispatch, getSta
|
|
|
269
304
|
dispatch(setTemplateConfig(page.templateConfig));
|
|
270
305
|
dispatch(setUserEditing(page.editing));
|
|
271
306
|
dispatch(setCurrentPageStatus(pageLiveStatus));
|
|
272
|
-
addTemplate(page.templateId)(dispatch);
|
|
273
307
|
}
|
|
274
308
|
} else {
|
|
275
309
|
if (!isNewTranslation) {
|
|
@@ -285,6 +319,24 @@ function getPage(pageID?: number, global?: boolean): (dispatch: Dispatch, getSta
|
|
|
285
319
|
};
|
|
286
320
|
}
|
|
287
321
|
|
|
322
|
+
function getTemplatePage(template: string): (dispatch: Dispatch, getState: any) => Promise<void> {
|
|
323
|
+
return async (dispatch, getState) => {
|
|
324
|
+
try {
|
|
325
|
+
dispatch(setIsLoading(true));
|
|
326
|
+
|
|
327
|
+
const baseSchema = "Page";
|
|
328
|
+
|
|
329
|
+
await addTemplate(template)(dispatch);
|
|
330
|
+
await getTemplateConfig(template)(dispatch, getState);
|
|
331
|
+
await getDefaults()(dispatch, getState);
|
|
332
|
+
generateNewPage(dispatch, getState, baseSchema);
|
|
333
|
+
} catch (e) {
|
|
334
|
+
dispatch(setIsLoading(false));
|
|
335
|
+
console.log(e); // TODO: capturar error bien
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
288
340
|
function savePage(
|
|
289
341
|
createDraft: boolean,
|
|
290
342
|
publishPage?: any,
|
|
@@ -682,15 +734,17 @@ function overwriteHeaderConfig(params: IFieldProps): (dispatch: Dispatch, getSta
|
|
|
682
734
|
};
|
|
683
735
|
}
|
|
684
736
|
|
|
685
|
-
function generatePageContent(editorContent: IPage, dispatch: Dispatch, getState: any) {
|
|
737
|
+
function generatePageContent(editorContent: IPage, dispatch: Dispatch, getState: any): void {
|
|
686
738
|
const {
|
|
687
|
-
pageEditor: { selectedEditorID },
|
|
739
|
+
pageEditor: { selectedEditorID, isNewTranslation, template },
|
|
688
740
|
navigation: { currentDefaultsContent },
|
|
741
|
+
dataPacks: { configFormData },
|
|
689
742
|
} = getState();
|
|
690
743
|
const { header, footer, isGlobal } = editorContent;
|
|
744
|
+
const { defaultHeader, defaultFooter } = configFormData.templates && configFormData.templates[template] || {};
|
|
691
745
|
const { header: pageHeader, footer: pageFooter } = getPageNavigation(
|
|
692
|
-
header,
|
|
693
|
-
footer,
|
|
746
|
+
header || defaultHeader,
|
|
747
|
+
footer || defaultFooter,
|
|
694
748
|
currentDefaultsContent,
|
|
695
749
|
isGlobal
|
|
696
750
|
);
|
|
@@ -701,12 +755,12 @@ function generatePageContent(editorContent: IPage, dispatch: Dispatch, getState:
|
|
|
701
755
|
const schema = getSchema(component);
|
|
702
756
|
|
|
703
757
|
dispatch(setSchema(schema));
|
|
704
|
-
|
|
705
758
|
dispatch(setEditorContent(pageContent));
|
|
706
759
|
dispatch(updateBreadcrumb(selectedEditorID));
|
|
707
760
|
dispatch(setSelectedPageContent(selectedContent));
|
|
708
761
|
dispatch(setSelectedParent(selectedParent));
|
|
709
762
|
dispatch(setIsLoading(false));
|
|
763
|
+
if (isNewTranslation) setTranslatedParent()(dispatch, getState);
|
|
710
764
|
}
|
|
711
765
|
|
|
712
766
|
function updateEditorContent(
|
|
@@ -783,7 +837,7 @@ function updateBreadcrumb(editorID: number): any {
|
|
|
783
837
|
const { header, footer } = editorContent;
|
|
784
838
|
const navigationIds = [header?.editorID, footer?.editorID];
|
|
785
839
|
if (navigationIds.includes(editorID)) {
|
|
786
|
-
const rootBreadcrumb = { editorID: 0, displayName:
|
|
840
|
+
const rootBreadcrumb = { editorID: 0, displayName: "Page", component: "Page" };
|
|
787
841
|
newBreadcrumb.unshift(rootBreadcrumb);
|
|
788
842
|
}
|
|
789
843
|
|
|
@@ -1019,4 +1073,5 @@ export {
|
|
|
1019
1073
|
setSitePageID,
|
|
1020
1074
|
sendPagePing,
|
|
1021
1075
|
discardDraft,
|
|
1076
|
+
getTemplatePage,
|
|
1022
1077
|
};
|
|
@@ -132,7 +132,7 @@ function getSiteDataPack(packID: string): (dispatch: Dispatch, getState: any) =>
|
|
|
132
132
|
handleError: () => console.log("Error en getDataPack"),
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
-
const callback = async () => dataPack.getSiteDataPack(currentSiteID, packID);
|
|
135
|
+
const callback = async () => await dataPack.getSiteDataPack(currentSiteID, packID);
|
|
136
136
|
|
|
137
137
|
await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
|
|
138
138
|
} catch (e) {
|
|
@@ -226,6 +226,9 @@ function updateDataPack(dataPackID: string): (dispatch: Dispatch, getState: any)
|
|
|
226
226
|
handleError: (response: any) => appActions.handleError(response)(dispatch),
|
|
227
227
|
};
|
|
228
228
|
|
|
229
|
+
delete configFormData.defaultHeader;
|
|
230
|
+
delete configFormData.defaultFooter;
|
|
231
|
+
|
|
229
232
|
const callback = async () => dataPack.updateDataPack(currentSiteID, dataPackID, configFormData);
|
|
230
233
|
|
|
231
234
|
await handleRequest(callback, responseActions, [appActions.setIsSaving])(dispatch);
|
|
@@ -141,6 +141,7 @@ function setSiteInfo(currentSiteInfo: ISite): (dispatch: any, getState: any) =>
|
|
|
141
141
|
try {
|
|
142
142
|
const {
|
|
143
143
|
structuredData: { structuredData: currentStructuredData },
|
|
144
|
+
structuredData: { categories: currentCategories },
|
|
144
145
|
} = getState();
|
|
145
146
|
|
|
146
147
|
dispatch(setIsLoading(true));
|
|
@@ -192,8 +193,9 @@ function setSiteInfo(currentSiteInfo: ISite): (dispatch: any, getState: any) =>
|
|
|
192
193
|
const data = structuredDataResponse.data.items;
|
|
193
194
|
|
|
194
195
|
const categories = structuredDataActions.filterStructuredData(data, true, currentSiteInfo.id);
|
|
196
|
+
|
|
195
197
|
const structuredDataValues = structuredDataActions.filterStructuredData(data, false, currentSiteInfo.id);
|
|
196
|
-
dispatch(structuredDataActions.setCategories(categories));
|
|
198
|
+
dispatch(structuredDataActions.setCategories({ global: currentCategories.global, site: categories.site }));
|
|
197
199
|
|
|
198
200
|
dispatch(
|
|
199
201
|
structuredDataActions.setStructuredData({ ...currentStructuredData, site: structuredDataValues.site })
|
package/src/helpers/dates.tsx
CHANGED
|
@@ -60,14 +60,13 @@ const getStringifyDateRange = (start: Date, end: Date, formatDate?: string): str
|
|
|
60
60
|
const getHumanLastModifiedDate = (modified: Date): string => {
|
|
61
61
|
const now = new Date();
|
|
62
62
|
const date = new Date(modified);
|
|
63
|
-
const dateWithTimezone = addMinutes(date, date.getTimezoneOffset());
|
|
64
63
|
|
|
65
64
|
const oneDay = 60 * 60 * 24 * 1000;
|
|
66
|
-
const isMoreThan24Hours = now.getTime() -
|
|
65
|
+
const isMoreThan24Hours = now.getTime() - date.getTime() > oneDay;
|
|
67
66
|
|
|
68
67
|
return isMoreThan24Hours
|
|
69
|
-
? format(
|
|
70
|
-
: formatDistanceToNowStrict(
|
|
68
|
+
? format(date, "d MMM HH:mm")
|
|
69
|
+
: formatDistanceToNowStrict(date, { addSuffix: true });
|
|
71
70
|
};
|
|
72
71
|
|
|
73
72
|
const getFormattedDateWithTimezone = (date: Date, formatString: string): string => {
|
package/src/helpers/index.tsx
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
getFileExtension,
|
|
20
20
|
splitAndJoin,
|
|
21
21
|
splitAndTrim,
|
|
22
|
+
copyTextToClipboard,
|
|
22
23
|
} from "./strings";
|
|
23
24
|
|
|
24
25
|
import {
|
|
@@ -164,4 +165,5 @@ export {
|
|
|
164
165
|
getDataPackSchema,
|
|
165
166
|
splitAndJoin,
|
|
166
167
|
splitAndTrim,
|
|
168
|
+
copyTextToClipboard,
|
|
167
169
|
};
|
package/src/helpers/strings.tsx
CHANGED
|
@@ -82,15 +82,45 @@ const getFileExtension = (fileName: string): string | null => {
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
const splitAndJoin = (str = "", splitterIn = ",", splitterOut = ", "): string => {
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
return (
|
|
86
|
+
str
|
|
87
|
+
?.split(splitterIn)
|
|
88
|
+
.map((str: string) => str.trim())
|
|
89
|
+
.filter((str: string) => str.length)
|
|
90
|
+
.join(splitterOut) || ""
|
|
91
|
+
);
|
|
92
|
+
};
|
|
90
93
|
|
|
91
94
|
const splitAndTrim = (str?: string, splitter = ","): (string | never)[] => {
|
|
92
|
-
return
|
|
93
|
-
|
|
95
|
+
return (
|
|
96
|
+
str
|
|
97
|
+
?.split(splitter)
|
|
98
|
+
.map((str: string) => str.trim())
|
|
99
|
+
.filter((str: string) => str.length) || []
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const copyTextToClipboard = (text: string): Promise<void> => {
|
|
104
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
105
|
+
return navigator.clipboard.writeText(text);
|
|
106
|
+
} else {
|
|
107
|
+
const textArea = document.createElement("textarea");
|
|
108
|
+
textArea.value = text;
|
|
109
|
+
|
|
110
|
+
textArea.style.top = "-999999px";
|
|
111
|
+
textArea.style.left = "-999999px";
|
|
112
|
+
textArea.style.position = "fixed";
|
|
113
|
+
|
|
114
|
+
document.body.appendChild(textArea);
|
|
115
|
+
textArea.focus();
|
|
116
|
+
textArea.select();
|
|
117
|
+
|
|
118
|
+
return new Promise<void>((res, rej) => {
|
|
119
|
+
document.execCommand("copy") ? res() : rej();
|
|
120
|
+
textArea.remove();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
};
|
|
94
124
|
|
|
95
125
|
export {
|
|
96
126
|
filterImageText,
|
|
@@ -106,4 +136,5 @@ export {
|
|
|
106
136
|
getFileExtension,
|
|
107
137
|
splitAndJoin,
|
|
108
138
|
splitAndTrim,
|
|
139
|
+
copyTextToClipboard,
|
|
109
140
|
};
|
package/src/hooks/forms.tsx
CHANGED
|
@@ -89,7 +89,6 @@ const useIsDirty = (
|
|
|
89
89
|
const [isResetting, setIsResetting] = useState(false);
|
|
90
90
|
|
|
91
91
|
const prevContent = usePrevious(updatedValues, isSaved);
|
|
92
|
-
const isTranslatedVersion: boolean = prevContent?.language !== updatedValues?.language;
|
|
93
92
|
|
|
94
93
|
const hasChanged = () => {
|
|
95
94
|
if (prevContent && updatedValues) {
|
|
@@ -98,7 +97,7 @@ const useIsDirty = (
|
|
|
98
97
|
|
|
99
98
|
const { cleanUpdatedValues, cleanOriginalValues } = cleanPageValues(updatedValuesCloned, originalValuesCloned);
|
|
100
99
|
|
|
101
|
-
const hasChanged = !
|
|
100
|
+
const hasChanged = !isEqual(cleanUpdatedValues, cleanOriginalValues);
|
|
102
101
|
|
|
103
102
|
return hasChanged;
|
|
104
103
|
}
|
package/src/index.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import ReactDOM from "react-dom";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
3
|
import { Provider } from "react-redux";
|
|
4
4
|
import { PersistGate } from "redux-persist/integration/react";
|
|
5
5
|
import history from "./routes/history";
|
|
@@ -14,7 +14,7 @@ export class Main {
|
|
|
14
14
|
const configStore = globalStore.configureStore(history);
|
|
15
15
|
|
|
16
16
|
const container = document.getElementById("root");
|
|
17
|
-
if (!container) throw new Error(
|
|
17
|
+
if (!container) throw new Error("Failed to find the root element");
|
|
18
18
|
// @ts-ignore
|
|
19
19
|
const root = ReactDOM.createRoot(container);
|
|
20
20
|
|