@griddo/ax 1.60.9 → 1.61.2
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 +4 -2
- package/public/fonts/fonts.css +48 -660
- package/public/index.html +19 -16
- package/public/templates/template-redirects.csv +2 -0
- package/src/GlobalStore.tsx +3 -0
- package/src/Style/fonts.tsx +98 -72
- package/src/api/analytics.tsx +78 -0
- package/src/api/index.tsx +2 -0
- package/src/api/redirects.tsx +30 -2
- package/src/components/Button/style.tsx +1 -0
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +1 -1
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/TemplateManager/index.tsx +4 -3
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +6 -1
- package/src/components/FieldContainer/index.tsx +2 -2
- package/src/components/Fields/AnalyticsField/PageAnalytics/atoms.tsx +75 -0
- package/src/components/Fields/AnalyticsField/PageAnalytics/index.tsx +139 -0
- package/src/components/Fields/AnalyticsField/StructuredDataAnalytics/atoms.tsx +77 -0
- package/src/components/Fields/AnalyticsField/StructuredDataAnalytics/index.tsx +89 -0
- package/src/components/Fields/AnalyticsField/index.tsx +38 -0
- package/src/components/Fields/AnalyticsField/style.tsx +13 -0
- package/src/components/Fields/AnalyticsField/utils.tsx +13 -0
- package/src/components/Fields/FieldGroup/style.tsx +1 -1
- package/src/components/Fields/ImageField/index.tsx +1 -1
- package/src/components/Fields/MultiCheckSelect/index.tsx +23 -6
- package/src/components/Fields/MultiCheckSelect/style.tsx +1 -0
- package/src/components/Fields/NoteField/index.tsx +1 -1
- package/src/components/Fields/RadioGroup/index.tsx +4 -3
- package/src/components/Fields/RadioGroup/style.tsx +8 -3
- package/src/components/Fields/RichText/index.tsx +13 -8
- package/src/components/Fields/TextArea/index.tsx +1 -3
- package/src/components/Fields/TextArea/style.tsx +3 -3
- package/src/components/Fields/UrlField/style.tsx +1 -0
- package/src/components/Fields/index.tsx +2 -0
- package/src/components/Modal/index.tsx +1 -1
- package/src/components/Modal/style.tsx +5 -1
- package/src/components/Notification/style.tsx +2 -5
- package/src/components/TableFilters/LiveFilter/index.tsx +4 -0
- package/src/components/TableFilters/NameFilter/style.tsx +1 -0
- package/src/components/TableFilters/TypeFilter/index.tsx +7 -2
- package/src/containers/Analytics/actions.tsx +58 -0
- package/src/containers/Analytics/constants.tsx +5 -0
- package/src/containers/Analytics/index.tsx +4 -0
- package/src/containers/Analytics/interfaces.tsx +9 -0
- package/src/containers/Analytics/reducer.tsx +26 -0
- package/src/containers/PageEditor/actions.tsx +1 -0
- package/src/containers/Redirects/actions.tsx +49 -3
- package/src/containers/Redirects/constants.tsx +12 -1
- package/src/containers/Redirects/interfaces.tsx +11 -1
- package/src/containers/Redirects/reducer.tsx +12 -1
- package/src/containers/Sites/actions.tsx +3 -0
- package/src/global.d.ts +2 -0
- package/src/helpers/index.tsx +4 -0
- package/src/helpers/requests.tsx +12 -7
- package/src/helpers/strings.tsx +13 -0
- package/src/hooks/forms.tsx +1 -1
- package/src/modules/Analytics/DimensionItem/index.tsx +71 -0
- package/src/modules/Analytics/DimensionItem/style.tsx +59 -0
- package/src/modules/Analytics/DimensionPanel/index.tsx +110 -0
- package/src/modules/Analytics/DimensionPanel/style.tsx +14 -0
- package/src/modules/Analytics/GroupItem/index.tsx +75 -0
- package/src/modules/Analytics/GroupItem/style.tsx +80 -0
- package/src/modules/Analytics/GroupPanel/index.tsx +178 -0
- package/src/modules/Analytics/GroupPanel/style.tsx +67 -0
- package/src/modules/Analytics/GroupPanel/utils.tsx +29 -0
- package/src/modules/Analytics/index.tsx +207 -0
- package/src/modules/Analytics/style.tsx +68 -0
- package/src/modules/Content/BulkHeader/TableHeader/index.tsx +1 -1
- package/src/modules/Content/PageItem/index.tsx +3 -3
- package/src/modules/Content/PageItem/style.tsx +1 -1
- package/src/modules/Content/hooks.tsx +2 -2
- package/src/modules/Content/index.tsx +22 -20
- package/src/modules/GlobalEditor/index.tsx +1 -1
- package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +2 -2
- package/src/modules/PageEditor/index.tsx +1 -1
- package/src/modules/Redirects/RedirectItem/index.tsx +6 -2
- package/src/modules/Redirects/RedirectPanel/index.tsx +2 -0
- package/src/modules/Redirects/atoms.tsx +212 -0
- package/src/modules/Redirects/index.tsx +85 -27
- package/src/modules/Redirects/style.tsx +124 -3
- package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +1 -1
- package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +12 -3
- package/src/modules/StructuredData/StructuredDataList/index.tsx +17 -2
- package/src/routes/multisite.tsx +20 -2
- package/src/schemas/pages/GlobalPage.tsx +75 -64
- package/src/schemas/pages/Page.tsx +79 -67
- package/src/types/index.tsx +25 -3
- package/public/fonts/Source_Sans_Pro-200-cyrillic-ext107.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-cyrillic-ext149.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-cyrillic108.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-cyrillic150.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-greek-ext109.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-greek-ext151.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-greek110.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-greek152.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-vietnamese111.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-200-vietnamese153.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-cyrillic-ext114.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-cyrillic-ext156.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-cyrillic115.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-cyrillic157.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-greek-ext116.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-greek-ext158.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-greek117.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-greek159.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-vietnamese118.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-300-vietnamese160.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-cyrillic-ext121.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-cyrillic-ext163.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-cyrillic122.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-cyrillic164.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-greek-ext123.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-greek-ext165.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-greek124.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-greek166.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-vietnamese125.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-400-vietnamese167.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-cyrillic-ext128.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-cyrillic-ext170.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-cyrillic129.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-cyrillic171.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-greek-ext130.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-greek-ext172.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-greek131.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-greek173.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-vietnamese132.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-600-vietnamese174.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-cyrillic-ext135.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-cyrillic-ext177.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-cyrillic136.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-cyrillic178.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-greek-ext137.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-greek-ext179.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-greek138.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-greek180.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-vietnamese139.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-700-vietnamese181.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-cyrillic-ext142.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-cyrillic-ext184.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-cyrillic143.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-cyrillic185.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-greek-ext144.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-greek-ext186.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-greek145.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-greek187.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-vietnamese146.woff2 +0 -0
- package/public/fonts/Source_Sans_Pro-900-vietnamese188.woff2 +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
|
|
3
|
+
const Footer = styled.div`
|
|
4
|
+
position: absolute;
|
|
5
|
+
bottom: ${(p) => p.theme.spacing.m};
|
|
6
|
+
right: ${(p) => p.theme.spacing.m};
|
|
7
|
+
`;
|
|
8
|
+
|
|
9
|
+
const Divider = styled.div`
|
|
10
|
+
position: relative;
|
|
11
|
+
height: 1px;
|
|
12
|
+
margin-top: ${(p) => p.theme.spacing.s};
|
|
13
|
+
margin-bottom: ${(p) => p.theme.spacing.s};
|
|
14
|
+
|
|
15
|
+
&:after {
|
|
16
|
+
content: "";
|
|
17
|
+
position: absolute;
|
|
18
|
+
height: 1px;
|
|
19
|
+
width: calc(100% + ${(p) => p.theme.spacing.m} * 2);
|
|
20
|
+
top: 0;
|
|
21
|
+
left: calc(-${(p) => p.theme.spacing.m});
|
|
22
|
+
border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
const Heading = styled.div<{ $spaceBetween?: boolean }>`
|
|
27
|
+
${(p) => p.theme.textStyle.headingXS};
|
|
28
|
+
display: flex;
|
|
29
|
+
justify-content: ${(p) => p.$spaceBetween ? "space-between" : "flex-start"};
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
const HeadingText = styled.div`
|
|
33
|
+
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const HeadingCounter = styled.div`
|
|
37
|
+
color: ${(p) => p.theme.color.textMediumEmphasis};
|
|
38
|
+
margin-left: ${(p) => p.theme.spacing.xs};
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
const Description = styled.div`
|
|
42
|
+
${(p) => p.theme.textStyle.uiXS};
|
|
43
|
+
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
44
|
+
padding-bottom: ${(p) => p.theme.spacing.s};
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
const RadioTemplate = styled.div``;
|
|
48
|
+
|
|
49
|
+
const ContentWrapper = styled.div`
|
|
50
|
+
height: calc(100% - ${(p) => p.theme.spacing.s} * 10);
|
|
51
|
+
overflow-y: scroll;
|
|
52
|
+
border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
|
|
53
|
+
position: absolute;
|
|
54
|
+
left: 0;
|
|
55
|
+
padding: 0 ${(p) => p.theme.spacing.m} ${(p) => p.theme.spacing.s} ${(p) => p.theme.spacing.m};
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
Footer,
|
|
60
|
+
Divider,
|
|
61
|
+
Heading,
|
|
62
|
+
HeadingText,
|
|
63
|
+
HeadingCounter,
|
|
64
|
+
Description,
|
|
65
|
+
RadioTemplate,
|
|
66
|
+
ContentWrapper
|
|
67
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { schemas } from "components";
|
|
2
|
+
|
|
3
|
+
const getTemplateOptions = (): ITemplateOption[] => {
|
|
4
|
+
const { templates } = schemas;
|
|
5
|
+
const templatesOptionsValues: ITemplateOption[] = [];
|
|
6
|
+
|
|
7
|
+
Object.keys(templates).forEach((schema: string) => {
|
|
8
|
+
const currSchema = templates[schema];
|
|
9
|
+
const { component, displayName } = currSchema;
|
|
10
|
+
|
|
11
|
+
!!currSchema.type &&
|
|
12
|
+
["list", "detail"].includes(currSchema.type.mode) &&
|
|
13
|
+
templatesOptionsValues.push({
|
|
14
|
+
name: component,
|
|
15
|
+
title: displayName,
|
|
16
|
+
value: component,
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return templatesOptionsValues;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
interface ITemplateOption {
|
|
24
|
+
name: string,
|
|
25
|
+
title: string,
|
|
26
|
+
value: string,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { getTemplateOptions };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { connect } from "react-redux";
|
|
3
|
+
|
|
4
|
+
import { IAnalytics, IDimension, IDimensionsGroup, IRootState } from "@ax/types";
|
|
5
|
+
import { appActions } from "@ax/containers/App";
|
|
6
|
+
import { analyticsActions } from "@ax/containers/Analytics";
|
|
7
|
+
import { MainWrapper, ErrorToast, Loading, FieldsBehavior } from "@ax/components";
|
|
8
|
+
import { RouteLeavingGuard } from "@ax/guards";
|
|
9
|
+
import { useIsDirty } from "@ax/hooks";
|
|
10
|
+
import { useModal } from "@ax/hooks";
|
|
11
|
+
|
|
12
|
+
import DimensionItem from "./DimensionItem";
|
|
13
|
+
import DimensionPanel from "./DimensionPanel";
|
|
14
|
+
import GroupItem from "./GroupItem";
|
|
15
|
+
import GroupPanel from "./GroupPanel";
|
|
16
|
+
import * as S from "./style";
|
|
17
|
+
|
|
18
|
+
const Analytics = (props: IProps): JSX.Element => {
|
|
19
|
+
const {
|
|
20
|
+
isSaving,
|
|
21
|
+
isLoading,
|
|
22
|
+
analytics,
|
|
23
|
+
getAnalytics,
|
|
24
|
+
setHistoryPush,
|
|
25
|
+
site,
|
|
26
|
+
updateAnalytics,
|
|
27
|
+
} = props;
|
|
28
|
+
|
|
29
|
+
const [analyticsState, setAnalyticsState] = useState(analytics);
|
|
30
|
+
const { isDirty, resetDirty } = useIsDirty(analyticsState);
|
|
31
|
+
const { isOpen: isDimensionOpen, toggleModal: toggleDimensionModal } = useModal();
|
|
32
|
+
const { isOpen: isGroupOpen, toggleModal: toggleGroupModal } = useModal();
|
|
33
|
+
|
|
34
|
+
const { scriptCode, dimensions, groups } = analyticsState;
|
|
35
|
+
|
|
36
|
+
const changeScriptCode = (scriptCode: string) => setAnalyticsState((state) => ({ ...state, scriptCode }));
|
|
37
|
+
const changeDimensions = (dimensions: IDimension[]) => setAnalyticsState((state) => ({ ...state, dimensions }));
|
|
38
|
+
const changeGroups = (groups: IDimensionsGroup[]) => setAnalyticsState((state) => ({ ...state, groups }));
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
getAnalytics(site?.id);
|
|
42
|
+
}, [getAnalytics, site?.id]);
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
setAnalyticsState(analytics);
|
|
46
|
+
}, [analytics]);
|
|
47
|
+
|
|
48
|
+
const handleSave = async () => {
|
|
49
|
+
const isSaved = await updateAnalytics(analyticsState, site?.id);
|
|
50
|
+
if (isSaved) resetDirty();
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const rightButtonProps = {
|
|
54
|
+
label: isSaving ? "Saving" : "Save",
|
|
55
|
+
disabled: isSaving,
|
|
56
|
+
action: () => handleSave(),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const mapDimensionList = (items: IDimension[]) =>
|
|
60
|
+
Array.isArray(items) &&
|
|
61
|
+
items.map((item: IDimension, i: number) => {
|
|
62
|
+
const handleSetItem = (newContent: IDimension) => {
|
|
63
|
+
const newItems = [...dimensions];
|
|
64
|
+
newItems[i] = newContent;
|
|
65
|
+
changeDimensions(newItems);
|
|
66
|
+
};
|
|
67
|
+
const handleRemoveDimension = () => {
|
|
68
|
+
const newItems = [...dimensions];
|
|
69
|
+
newItems.splice(i, 1);
|
|
70
|
+
changeDimensions(newItems);
|
|
71
|
+
};
|
|
72
|
+
return (
|
|
73
|
+
<DimensionItem
|
|
74
|
+
key={`${item.id}${item.name}${i}`}
|
|
75
|
+
item={item}
|
|
76
|
+
setDimensionItem={handleSetItem}
|
|
77
|
+
removeDimension={handleRemoveDimension}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const mapGroupList = (items: IDimensionsGroup[]) =>
|
|
83
|
+
Array.isArray(items) &&
|
|
84
|
+
items.map((item: IDimensionsGroup, i: number) => {
|
|
85
|
+
const handleSetItem = (newContent: IDimensionsGroup) => {
|
|
86
|
+
const newItems = [...groups];
|
|
87
|
+
newItems[i] = newContent;
|
|
88
|
+
changeGroups(newItems);
|
|
89
|
+
};
|
|
90
|
+
const handleRemoveGroup = () => {
|
|
91
|
+
const newItems = [...groups];
|
|
92
|
+
newItems.splice(i, 1);
|
|
93
|
+
changeGroups(newItems);
|
|
94
|
+
};
|
|
95
|
+
return (
|
|
96
|
+
<GroupItem
|
|
97
|
+
key={`${item.id}${item.name}${i}`}
|
|
98
|
+
item={item}
|
|
99
|
+
setGroupItem={handleSetItem}
|
|
100
|
+
dimensions={dimensions}
|
|
101
|
+
removeGroup={handleRemoveGroup}
|
|
102
|
+
/>
|
|
103
|
+
)
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const handleAddDimension = (item: IDimension) => {
|
|
107
|
+
const { dimensions } = analyticsState;
|
|
108
|
+
const updatedDimensions = dimensions ? [...dimensions, item] : [item];
|
|
109
|
+
changeDimensions(updatedDimensions);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const handleAddGroup = (item: IDimensionsGroup) => {
|
|
113
|
+
const { groups } = analyticsState;
|
|
114
|
+
const updatedGroups = groups ? [...groups, item] : [item];
|
|
115
|
+
changeGroups(updatedGroups);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const setRoute = (path: string) => setHistoryPush(path);
|
|
119
|
+
const modalText = (
|
|
120
|
+
<>
|
|
121
|
+
Some analytics <strong>are not saved</strong>.{" "}
|
|
122
|
+
</>
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const isGroupDisabled = dimensions?.length < 2;
|
|
126
|
+
|
|
127
|
+
if (isLoading) return <Loading />;
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<>
|
|
131
|
+
<RouteLeavingGuard when={isDirty} action={setRoute} text={modalText} />
|
|
132
|
+
<MainWrapper backLink={false} title="Analytics Settings" rightButton={rightButtonProps}>
|
|
133
|
+
<ErrorToast />
|
|
134
|
+
<S.Wrapper>
|
|
135
|
+
<S.FormWrapper>
|
|
136
|
+
<S.ScriptCodeWrapper>
|
|
137
|
+
<FieldsBehavior
|
|
138
|
+
title="Analytics Tracking ID or Script Code"
|
|
139
|
+
name="scriptCode"
|
|
140
|
+
fieldType="TextArea"
|
|
141
|
+
value={scriptCode || ""}
|
|
142
|
+
onChange={changeScriptCode}
|
|
143
|
+
placeholder="Type the Google Analytics or Google Tag Manager code."
|
|
144
|
+
/>
|
|
145
|
+
</S.ScriptCodeWrapper>
|
|
146
|
+
<S.SettingsWrapper>
|
|
147
|
+
<S.Heading>Data layer configuration</S.Heading>
|
|
148
|
+
<S.SettingContent>
|
|
149
|
+
<S.SettingText>
|
|
150
|
+
You can configure Data Layer to measure dimensions and data values when loading a page.
|
|
151
|
+
</S.SettingText>
|
|
152
|
+
<S.StyledButton type="button" buttonStyle="text" icon="addCircle" onClick={toggleDimensionModal}>
|
|
153
|
+
Add dimension
|
|
154
|
+
</S.StyledButton>
|
|
155
|
+
<S.Table>{dimensions && mapDimensionList(dimensions)}</S.Table>
|
|
156
|
+
</S.SettingContent>
|
|
157
|
+
</S.SettingsWrapper>
|
|
158
|
+
<S.SettingsWrapper>
|
|
159
|
+
<S.Heading>Dimensions group by content</S.Heading>
|
|
160
|
+
<S.SettingContent>
|
|
161
|
+
<S.SettingText>
|
|
162
|
+
You can create groups with the dimensions to measure on a page based on its content..
|
|
163
|
+
</S.SettingText>
|
|
164
|
+
<S.StyledButton type="button" buttonStyle="text" icon="addCircle" onClick={toggleGroupModal} disabled={isGroupDisabled}>
|
|
165
|
+
Define group
|
|
166
|
+
</S.StyledButton>
|
|
167
|
+
<S.Table>{groups && mapGroupList(groups)}</S.Table>
|
|
168
|
+
</S.SettingContent>
|
|
169
|
+
</S.SettingsWrapper>
|
|
170
|
+
</S.FormWrapper>
|
|
171
|
+
</S.Wrapper>
|
|
172
|
+
<DimensionPanel isOpen={isDimensionOpen} toggleModal={toggleDimensionModal} setDimensionItem={handleAddDimension} />
|
|
173
|
+
<GroupPanel isOpen={isGroupOpen} toggleModal={toggleGroupModal} setGroupItem={handleAddGroup} dimensions={dimensions} />
|
|
174
|
+
</MainWrapper>
|
|
175
|
+
</>
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const mapStateToProps = (state: IRootState) => ({
|
|
180
|
+
isSaving: state.app.isSaving,
|
|
181
|
+
isLoading: state.app.isLoading,
|
|
182
|
+
analytics: state.analytics,
|
|
183
|
+
site: state.sites.currentSiteInfo,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const mapDispatchToProps = {
|
|
187
|
+
setHistoryPush: appActions.setHistoryPush,
|
|
188
|
+
getAnalytics: analyticsActions.getAnalytics,
|
|
189
|
+
updateAnalytics: analyticsActions.updateAnalytics,
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
interface IAnalyticsProps {
|
|
193
|
+
isSaving: boolean;
|
|
194
|
+
isLoading: boolean;
|
|
195
|
+
analytics: IAnalytics;
|
|
196
|
+
site: any;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
interface IDispatchProps {
|
|
200
|
+
getAnalytics(siteId?: number): void;
|
|
201
|
+
setHistoryPush(path: string, isEditor?: boolean): void;
|
|
202
|
+
updateAnalytics(analyticsState: IAnalytics, siteId?: number): Promise<boolean>;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
type IProps = IAnalyticsProps & IDispatchProps;
|
|
206
|
+
|
|
207
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Analytics);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Button } from "@ax/components";
|
|
3
|
+
|
|
4
|
+
const Wrapper = styled.div`
|
|
5
|
+
display: flex;
|
|
6
|
+
height: 100%;
|
|
7
|
+
overflow: auto;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
width: 100%;
|
|
10
|
+
padding: ${(p) => p.theme.spacing.m};
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
const Table = styled.div`
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
width: 100%;
|
|
17
|
+
margin-top: ${(p) => p.theme.spacing.m};
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
const Heading = styled.div`
|
|
21
|
+
${(p) => p.theme.textStyle.headingXS};
|
|
22
|
+
color: ${(p) => p.theme.color.textHighEmphasis};
|
|
23
|
+
padding-bottom: ${(p) => p.theme.spacing.xs};
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
const SettingsWrapper = styled.div`
|
|
27
|
+
position: relative;
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
const ScriptCodeWrapper = styled.div`
|
|
31
|
+
border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
|
|
32
|
+
margin-bottom: ${(p) => p.theme.spacing.m};
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
const SettingContent = styled.div`
|
|
36
|
+
border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
|
|
37
|
+
margin-bottom: ${(p) => p.theme.spacing.m};
|
|
38
|
+
padding-bottom: ${(p) => p.theme.spacing.m};
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
const SettingText = styled.div`
|
|
42
|
+
${(p) => p.theme.textStyle.uiM};
|
|
43
|
+
color: ${(p) => p.theme.color.textMediumEmphasis};
|
|
44
|
+
width: calc(${(p) => p.theme.spacing.l} * 12);
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
const StyledButton = styled(Button)`
|
|
48
|
+
position: absolute;
|
|
49
|
+
top: 0;
|
|
50
|
+
right: 0;
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
const FormWrapper = styled.div`
|
|
54
|
+
width: 720px;
|
|
55
|
+
margin: ${(p) => `${p.theme.spacing.m} 0 0 ${p.theme.spacing.m}`};
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
Wrapper,
|
|
60
|
+
Table,
|
|
61
|
+
Heading,
|
|
62
|
+
SettingsWrapper,
|
|
63
|
+
SettingContent,
|
|
64
|
+
SettingText,
|
|
65
|
+
StyledButton,
|
|
66
|
+
FormWrapper,
|
|
67
|
+
ScriptCodeWrapper
|
|
68
|
+
};
|
|
@@ -94,7 +94,7 @@ const TableHeader = (props: IProps): JSX.Element => {
|
|
|
94
94
|
{CategoryColumns}
|
|
95
95
|
{activeColumns.includes("type") && (
|
|
96
96
|
<S.HeaderWrapper>
|
|
97
|
-
<TypeFilter filterItems={filterItems} filters={typeFilters} pointer="type" />
|
|
97
|
+
<TypeFilter filterItems={filterItems} filters={typeFilters} value={filterValues.types} pointer="type" />
|
|
98
98
|
</S.HeaderWrapper>
|
|
99
99
|
)}
|
|
100
100
|
{activeColumns.includes("live") && (
|
|
@@ -261,8 +261,8 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
261
261
|
isGlobal && !manuallyImported
|
|
262
262
|
? "This page has been provided by subscription. You cannot remove it."
|
|
263
263
|
: canBeUnpublished === false
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
? "This is the canonical site of the page. You cannot remove it."
|
|
265
|
+
: null;
|
|
266
266
|
|
|
267
267
|
let menuOptions: IPageOption[] = [
|
|
268
268
|
{
|
|
@@ -370,7 +370,7 @@ const PageItem = (props: IPageItemProps): JSX.Element => {
|
|
|
370
370
|
isGlobal &&
|
|
371
371
|
categoryColumns.map((col: any) => {
|
|
372
372
|
const type = structuredDataContent[col.from];
|
|
373
|
-
const categories = type && type.map((cat: any) => cat.label || cat.title);
|
|
373
|
+
const categories = Array.isArray(type) && type.map((cat: any) => cat.label || cat.title);
|
|
374
374
|
return (
|
|
375
375
|
activeColumns.includes(col.key) && (
|
|
376
376
|
<CategoryCell
|
|
@@ -90,6 +90,7 @@ const Wrapper = styled.div`
|
|
|
90
90
|
|
|
91
91
|
const ActionsCell = styled(Cell)`
|
|
92
92
|
flex: 0 0 100px;
|
|
93
|
+
text-align: center;
|
|
93
94
|
`;
|
|
94
95
|
|
|
95
96
|
const CategoryCell = styled(Cell)`
|
|
@@ -102,7 +103,6 @@ const StyledActionMenu = styled(ActionMenu)`
|
|
|
102
103
|
opacity: 0;
|
|
103
104
|
width: 32px;
|
|
104
105
|
display: flex;
|
|
105
|
-
margin-left: auto;
|
|
106
106
|
`;
|
|
107
107
|
|
|
108
108
|
const PageRow = styled(Row)<{ global?: boolean }>`
|
|
@@ -161,25 +161,26 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
161
161
|
|
|
162
162
|
const getParams = useCallback(() => {
|
|
163
163
|
const siteID = currentSiteInfo ? currentSiteInfo.id : null;
|
|
164
|
-
const params = isStructuredData
|
|
165
|
-
{
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
164
|
+
const params = isStructuredData
|
|
165
|
+
? {
|
|
166
|
+
siteID,
|
|
167
|
+
dataID: typeof filter === "object" ? filter.value : filter,
|
|
168
|
+
page,
|
|
169
|
+
itemsPerPage,
|
|
170
|
+
pagination: true,
|
|
171
|
+
deleted: false,
|
|
172
|
+
include_draft: true,
|
|
173
|
+
query: searchQuery,
|
|
174
|
+
format: "list",
|
|
175
|
+
}
|
|
176
|
+
: {
|
|
177
|
+
siteID,
|
|
178
|
+
deleted: false,
|
|
179
|
+
page,
|
|
180
|
+
itemsPerPage,
|
|
181
|
+
query: searchQuery,
|
|
182
|
+
format: "list",
|
|
183
|
+
};
|
|
183
184
|
|
|
184
185
|
return params;
|
|
185
186
|
}, [filter, currentSiteInfo, isStructuredData, page, searchQuery]);
|
|
@@ -237,7 +238,8 @@ const Content = (props: IProps): JSX.Element => {
|
|
|
237
238
|
if (!isLoading) {
|
|
238
239
|
const isContentType = filter !== "unique-pages";
|
|
239
240
|
const emptyState: IEmptyStateProps = {};
|
|
240
|
-
const
|
|
241
|
+
const { liveStatus, translated, type } = filterValues;
|
|
242
|
+
const isSearching = searchQuery.length > 0 || liveStatus !== "all" || translated !== "all" || type !== "all";
|
|
241
243
|
if (isSearching) {
|
|
242
244
|
emptyState.icon = "search";
|
|
243
245
|
emptyState.title = "Oh! No Results Found";
|
|
@@ -45,7 +45,7 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
45
45
|
useEffect(() => {
|
|
46
46
|
getValues();
|
|
47
47
|
if (isNew) {
|
|
48
|
-
setIsDirty(
|
|
48
|
+
setIsDirty(false);
|
|
49
49
|
}
|
|
50
50
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
51
51
|
}, []);
|
|
@@ -88,7 +88,7 @@ const DefaultsEditor = (props: IProps) => {
|
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
const createNewTranslation = (isNewTranslation: boolean) => {
|
|
91
|
-
setIsDirty(
|
|
91
|
+
setIsDirty(false);
|
|
92
92
|
createTranslation(isNewTranslation);
|
|
93
93
|
};
|
|
94
94
|
|
|
@@ -59,8 +59,12 @@ const RedirectItem = (props: IRedirectItemProps): JSX.Element => {
|
|
|
59
59
|
title: "Delete redirect",
|
|
60
60
|
onClick: removeItem,
|
|
61
61
|
};
|
|
62
|
+
|
|
62
63
|
const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleModalDelete };
|
|
63
64
|
|
|
65
|
+
const target = `(${redirect.domain || ""}|${redirect.site?.siteUrl || ""})`;
|
|
66
|
+
const regex = new RegExp(target, "g");
|
|
67
|
+
|
|
64
68
|
return (
|
|
65
69
|
<>
|
|
66
70
|
<S.ItemRow role="rowgroup" selected={isSelected}>
|
|
@@ -75,10 +79,10 @@ const RedirectItem = (props: IRedirectItemProps): JSX.Element => {
|
|
|
75
79
|
</S.SiteCell>
|
|
76
80
|
)}
|
|
77
81
|
<S.UrlCell role="cell" onClick={handleClick}>
|
|
78
|
-
{redirect.from}
|
|
82
|
+
{redirect.from.replace(regex, "")}
|
|
79
83
|
</S.UrlCell>
|
|
80
84
|
<S.UrlCell role="cell" onClick={handleClick}>
|
|
81
|
-
{redirect.to?.url}
|
|
85
|
+
{redirect.to?.url.replace(regex, "")}
|
|
82
86
|
</S.UrlCell>
|
|
83
87
|
<S.ActionsCell role="cell">
|
|
84
88
|
<S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />
|
|
@@ -67,6 +67,7 @@ const RedirectPanel = (props: IProps): JSX.Element => {
|
|
|
67
67
|
value={formValues.from}
|
|
68
68
|
onChange={handleOldUrl}
|
|
69
69
|
autoComplete="redirect-old"
|
|
70
|
+
helptext="Type the complete old page url you want to redirect."
|
|
70
71
|
/>
|
|
71
72
|
<FieldsBehavior
|
|
72
73
|
title="New URL"
|
|
@@ -77,6 +78,7 @@ const RedirectPanel = (props: IProps): JSX.Element => {
|
|
|
77
78
|
handlePanel={toggleSecondaryPanel}
|
|
78
79
|
inFloatingPanel={true}
|
|
79
80
|
autoComplete="redirect-new"
|
|
81
|
+
helptext="Select an internal page or paste an external url."
|
|
80
82
|
/>
|
|
81
83
|
<S.Footer>
|
|
82
84
|
{redirect ? (
|