@griddo/ax 1.55.13 → 1.56.1
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/GlobalStore.tsx +3 -0
- package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/index.tsx +6 -0
- package/src/components/Fields/Wysiwyg/config.tsx +0 -1
- package/src/components/Fields/Wysiwyg/index.tsx +16 -5
- package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +110 -99
- package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +75 -55
- package/src/components/Gallery/GalleryPanel/index.tsx +14 -8
- package/src/components/Gallery/index.tsx +113 -151
- package/src/components/Gallery/style.tsx +40 -10
- package/src/components/MainWrapper/AppBar/index.tsx +1 -0
- package/src/components/Toast/index.tsx +15 -9
- package/src/components/Toast/style.tsx +2 -2
- package/src/containers/Gallery/actions.tsx +171 -0
- package/src/containers/Gallery/constants.tsx +18 -0
- package/src/containers/Gallery/index.tsx +7 -0
- package/src/containers/Gallery/interfaces.tsx +41 -0
- package/src/containers/Gallery/reducer.tsx +78 -0
- package/src/containers/PageEditor/actions.tsx +15 -5
- package/src/containers/StructuredData/actions.tsx +4 -21
- package/src/forms/fields.tsx +19 -6
- package/src/guards/error/index.tsx +3 -1
- package/src/modules/Content/HeaderMenus/Live/index.tsx +6 -5
- package/src/modules/Sites/SitesList/index.tsx +1 -1
- package/src/modules/StructuredData/Form/ConnectedField/index.tsx +1 -1
- package/src/modules/StructuredData/Form/index.tsx +10 -4
- package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Live/index.tsx +1 -1
- package/src/types/index.tsx +20 -0
- package/src/components/Gallery/store.tsx +0 -186
|
@@ -1,36 +1,31 @@
|
|
|
1
1
|
import React, { useEffect, useState, memo, useRef } from "react";
|
|
2
|
+
import { connect } from "react-redux";
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { galleryActions } from "@ax/containers/Gallery";
|
|
5
|
+
import { IData, IIsLoading } from "@ax/containers/Gallery/reducer";
|
|
6
|
+
import { IGetSiteImages, IImage, IRootState, ISite } from "@ax/types";
|
|
7
|
+
import { Icon, Loader, Tabs, SearchField, EmptyState, ErrorToast, Notification } from "@ax/components";
|
|
6
8
|
|
|
7
|
-
import Orientation from "./GalleryFilters/Orientation"
|
|
8
|
-
import SortBy from "./GalleryFilters/SortBy"
|
|
9
|
+
import Orientation from "./GalleryFilters/Orientation";
|
|
10
|
+
import SortBy from "./GalleryFilters/SortBy";
|
|
9
11
|
import GalleryPanel from "./GalleryPanel";
|
|
10
12
|
import * as S from "./style";
|
|
11
13
|
import { useFilterQuery, useSortedListStatus } from "./hooks";
|
|
12
|
-
import { getSortedListStatus } from "./utils"
|
|
14
|
+
import { getSortedListStatus } from "./utils";
|
|
13
15
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
+
const itemsPerPage = 50;
|
|
17
|
+
const firstPage = 1;
|
|
18
|
+
|
|
19
|
+
const Gallery = (props: IProps): JSX.Element => {
|
|
20
|
+
const { data, isLoading, getSiteImages, selectImage, getImageSelected, toggleModal, site } = props;
|
|
16
21
|
|
|
17
22
|
const tabs = [];
|
|
18
23
|
if (site) tabs.unshift(...["Local", "Global"]);
|
|
19
24
|
const [selectedTab, setSelectedTab] = useState(tabs[0]);
|
|
20
25
|
const isLocalTab = selectedTab === "Local";
|
|
26
|
+
const isGlobalTab = selectedTab === "Global";
|
|
21
27
|
const galleryScope = isLocalTab ? site.id : "global";
|
|
22
28
|
|
|
23
|
-
const initialState: IGalleryState = {
|
|
24
|
-
items: [],
|
|
25
|
-
isImageSelected: false,
|
|
26
|
-
imageSelected: null,
|
|
27
|
-
page: 1,
|
|
28
|
-
isFinished: false,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const [data, setData] = useState(initialState);
|
|
32
|
-
const [isLoading, setIsLoading] = useState({ init: false, more: false });
|
|
33
|
-
|
|
34
29
|
const validFormats = ["jpeg", "jpg", "png", "svg"];
|
|
35
30
|
|
|
36
31
|
const galleryRef = useRef<HTMLDivElement>(null);
|
|
@@ -40,125 +35,67 @@ const Gallery = (props: IGalleryProps): JSX.Element => {
|
|
|
40
35
|
const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
|
|
41
36
|
const [searchQuery, setSearchQuery] = useState<string>("");
|
|
42
37
|
const isSearching = searchQuery.length > 0;
|
|
38
|
+
const pageRef = useRef(firstPage);
|
|
43
39
|
|
|
44
40
|
const getParams = () => ({
|
|
45
41
|
site: galleryScope,
|
|
46
|
-
page: data
|
|
47
|
-
items:
|
|
42
|
+
page: data?.page,
|
|
43
|
+
items: itemsPerPage,
|
|
48
44
|
query: currentFilterQuery,
|
|
49
|
-
search: searchQuery
|
|
45
|
+
search: searchQuery,
|
|
50
46
|
});
|
|
51
47
|
|
|
48
|
+
pageRef.current = getParams().page;
|
|
49
|
+
|
|
52
50
|
useEffect(() => {
|
|
53
51
|
const params = getParams();
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.then((result) => {
|
|
57
|
-
setData({ items: result, page: 1, isImageSelected: false, imageSelected: null, isFinished: false });
|
|
58
|
-
setIsLoading({ init: false, more: false });
|
|
59
|
-
})
|
|
60
|
-
.catch((error) => console.log(error));
|
|
61
|
-
};
|
|
62
|
-
setIsLoading({ init: true, more: false });
|
|
63
|
-
getAndSetImages();
|
|
64
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
getSiteImages({ ...params, page: firstPage });
|
|
53
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
65
54
|
}, [galleryScope]);
|
|
66
55
|
|
|
67
56
|
useEffect(() => {
|
|
68
57
|
const handleScroll = () => {
|
|
69
|
-
|
|
70
|
-
galleryRef.current &&
|
|
71
|
-
galleryRef.current.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
const loadMore =
|
|
59
|
+
galleryRef.current &&
|
|
60
|
+
galleryRef.current.scrollHeight -
|
|
61
|
+
(galleryRef.current.scrollTop + galleryRef.current.getBoundingClientRect().height) <
|
|
62
|
+
60 &&
|
|
63
|
+
galleryRef.current.scrollTop > 0;
|
|
64
|
+
if (!loadMore) return;
|
|
75
65
|
if (!data.isFinished) {
|
|
76
|
-
|
|
66
|
+
const params = getParams();
|
|
67
|
+
getSiteImages({ ...params, page: pageRef.current + 1, more: true });
|
|
77
68
|
}
|
|
78
69
|
};
|
|
79
70
|
window.addEventListener("scroll", handleScroll, true);
|
|
80
71
|
return () => window.removeEventListener("scroll", handleScroll, true);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const getAndSetMoreImages = async () => {
|
|
84
|
-
const params = getParams();
|
|
85
|
-
const result = await getSiteImages({ ...params, page: params.page + 1 });
|
|
86
|
-
try {
|
|
87
|
-
setData({
|
|
88
|
-
...data,
|
|
89
|
-
items: [...data.items, ...result],
|
|
90
|
-
page: data.page + 1,
|
|
91
|
-
isFinished: result.length < ITEMS_PER_PAGE,
|
|
92
|
-
});
|
|
93
|
-
setIsLoading({ init: false, more: false });
|
|
94
|
-
} catch (error) {
|
|
95
|
-
console.log(error);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
72
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
73
|
+
}, [data?.isFinished]);
|
|
98
74
|
|
|
99
|
-
const
|
|
75
|
+
const refreshImages = async (page = firstPage) => {
|
|
100
76
|
const params = getParams();
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
setIsLoading({ init: false, more: false });
|
|
105
|
-
galleryRef && galleryRef.current && galleryRef.current.scrollTo(0, 0);
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.log(error);
|
|
108
|
-
}
|
|
77
|
+
const more = page !== firstPage;
|
|
78
|
+
await getSiteImages({ ...params, page, more });
|
|
79
|
+
if (page < params.page) refreshImages(page + 1);
|
|
109
80
|
};
|
|
110
81
|
|
|
111
82
|
useEffect(() => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
getAndSetMoreImages();
|
|
115
|
-
}, 2000);
|
|
116
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
117
|
-
}, [isLoading.more]);
|
|
118
|
-
|
|
119
|
-
useEffect(() => {
|
|
120
|
-
setIsLoading({ init: true, more: false });
|
|
121
|
-
getAndSetImages();
|
|
83
|
+
const params = getParams();
|
|
84
|
+
getSiteImages({ ...params, page: firstPage });
|
|
122
85
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
123
86
|
}, [currentFilterQuery, searchQuery]);
|
|
124
87
|
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
setData({ ...data, imageSelected: null, isImageSelected: false });
|
|
128
|
-
} else {
|
|
129
|
-
setData({ ...data, imageSelected: item, isImageSelected: true });
|
|
130
|
-
}
|
|
88
|
+
const handleClick = (item: IImage) => (e: React.MouseEvent<HTMLDivElement>) => {
|
|
89
|
+
selectImage(item);
|
|
131
90
|
};
|
|
132
91
|
|
|
133
|
-
const setImage = () => {
|
|
134
|
-
|
|
92
|
+
const setImage = (imageData: any) => {
|
|
93
|
+
const updatedImage = { ...data.imageSelected, ...imageData };
|
|
94
|
+
getImageSelected(updatedImage);
|
|
135
95
|
toggleModal();
|
|
136
96
|
};
|
|
137
97
|
|
|
138
|
-
const updateItems = () => {
|
|
139
|
-
setIsLoading({ init: true, more: false });
|
|
140
|
-
const params = getParams();
|
|
141
|
-
getSiteImages({ ...params, page: 1 })
|
|
142
|
-
.then((result) => {
|
|
143
|
-
setData({ items: result, isImageSelected: false, imageSelected: null, page: 1, isFinished: false });
|
|
144
|
-
setIsLoading({ init: false, more: false });
|
|
145
|
-
})
|
|
146
|
-
.catch((error) => console.log(error));
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const addImage = (item: IImage) => {
|
|
150
|
-
setIsLoading({ init: true, more: false });
|
|
151
|
-
const params = getParams();
|
|
152
|
-
getSiteImages({ ...params, page: 1 })
|
|
153
|
-
.then((result) => {
|
|
154
|
-
setData({ items: result, isImageSelected: true, imageSelected: item, page: 1, isFinished: false });
|
|
155
|
-
setIsLoading({ init: false, more: false });
|
|
156
|
-
})
|
|
157
|
-
.catch((error) => console.log(error));
|
|
158
|
-
};
|
|
159
|
-
|
|
160
98
|
const sortItems = async (orderPointer: string, isAscending: boolean) => {
|
|
161
|
-
setData((data) => ({ ...data, page: 1 }));
|
|
162
99
|
const sortedState = getSortedListStatus(orderPointer, isAscending);
|
|
163
100
|
setSortedListStatus(sortedState);
|
|
164
101
|
|
|
@@ -168,7 +105,6 @@ const Gallery = (props: IGalleryProps): JSX.Element => {
|
|
|
168
105
|
};
|
|
169
106
|
|
|
170
107
|
const filterItems = async (filterPointer: string, filtersSelected: string) => {
|
|
171
|
-
setData((data) => ({ ...data, page: 1 }));
|
|
172
108
|
const filtersSelection = setFiltersSelection(filterPointer, filtersSelected);
|
|
173
109
|
const filterQuery = setFilterQuery(filtersSelection);
|
|
174
110
|
setCurrentFilterQuery(filterQuery);
|
|
@@ -178,9 +114,9 @@ const Gallery = (props: IGalleryProps): JSX.Element => {
|
|
|
178
114
|
icon: "search",
|
|
179
115
|
title: "Oh! No Results Found",
|
|
180
116
|
message: "We couldn’t find what you are looking for. Please, try another search.",
|
|
181
|
-
}
|
|
117
|
+
};
|
|
182
118
|
|
|
183
|
-
const noSearchResults = !data
|
|
119
|
+
const noSearchResults = !data?.items?.length && isSearching;
|
|
184
120
|
|
|
185
121
|
return (
|
|
186
122
|
<S.Wrapper>
|
|
@@ -195,76 +131,102 @@ const Gallery = (props: IGalleryProps): JSX.Element => {
|
|
|
195
131
|
<Orientation filterItems={filterItems} />
|
|
196
132
|
<SortBy sortItems={sortItems} sortedState={sortedListStatus} />
|
|
197
133
|
</S.Filters>
|
|
198
|
-
</
|
|
134
|
+
</S.Header>
|
|
199
135
|
<S.Search>
|
|
200
136
|
<SearchField onChange={setSearchQuery} placeholder="Type an image’s name, title, or #tag" />
|
|
201
|
-
</
|
|
137
|
+
</S.Search>
|
|
202
138
|
<S.GalleryWrapper ref={galleryRef}>
|
|
139
|
+
{isGlobalTab && (
|
|
140
|
+
<S.NotificationWrapper>
|
|
141
|
+
<Notification
|
|
142
|
+
type="info"
|
|
143
|
+
text="This is a global Library. All the changes you make will be applied to all the sites."
|
|
144
|
+
/>
|
|
145
|
+
</S.NotificationWrapper>
|
|
146
|
+
)}
|
|
147
|
+
<ErrorToast size="l" />
|
|
203
148
|
{isLoading.init ? (
|
|
204
149
|
<S.LoadingWrapper>
|
|
205
150
|
<Loader name="circle" />
|
|
206
151
|
</S.LoadingWrapper>
|
|
207
152
|
) : (
|
|
208
|
-
|
|
209
|
-
{
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
153
|
+
<>
|
|
154
|
+
{noSearchResults ? (
|
|
155
|
+
<S.EmptyWrapper>
|
|
156
|
+
<EmptyState {...emptyStateProps} />
|
|
157
|
+
</S.EmptyWrapper>
|
|
158
|
+
) : (
|
|
159
|
+
<S.Grid>
|
|
160
|
+
{data &&
|
|
161
|
+
data.items &&
|
|
162
|
+
data.items.map((item: IImage, index: number) => {
|
|
163
|
+
const isSelected = data.imageSelected ? item.id === data.imageSelected.id : false;
|
|
164
|
+
return (
|
|
165
|
+
<S.GridItem key={item.name + index} orientation={item.orientation}>
|
|
166
|
+
<S.ImageWrapper
|
|
167
|
+
onClick={handleClick(item)}
|
|
168
|
+
selected={isSelected}
|
|
169
|
+
orientation={item.orientation}
|
|
170
|
+
>
|
|
171
|
+
<img src={item.thumb} alt={item.alt} />
|
|
172
|
+
<S.IconUnchecked>
|
|
173
|
+
<Icon name="emptyCheck" size="24" />
|
|
174
|
+
</S.IconUnchecked>
|
|
175
|
+
<S.IconChecked>
|
|
176
|
+
<Icon name="success" size="24" />
|
|
177
|
+
</S.IconChecked>
|
|
178
|
+
</S.ImageWrapper>
|
|
179
|
+
</S.GridItem>
|
|
180
|
+
);
|
|
181
|
+
})}
|
|
182
|
+
</S.Grid>
|
|
183
|
+
)}
|
|
227
184
|
{isLoading.more && (
|
|
228
185
|
<S.LoaderWrapper>
|
|
229
186
|
<Loader name="dots" />
|
|
230
187
|
</S.LoaderWrapper>
|
|
231
188
|
)}
|
|
232
|
-
|
|
233
|
-
<S.EmptyWrapper>
|
|
234
|
-
<EmptyState {...emptyStateProps} />
|
|
235
|
-
</S.EmptyWrapper>)
|
|
236
|
-
}
|
|
237
|
-
</S.Grid>
|
|
189
|
+
</>
|
|
238
190
|
)}
|
|
239
191
|
</S.GalleryWrapper>
|
|
240
|
-
</
|
|
192
|
+
</S.GalleryTabs>
|
|
241
193
|
<GalleryPanel
|
|
242
|
-
isImageSelected={data
|
|
243
|
-
imageSelected={data
|
|
194
|
+
isImageSelected={data?.isImageSelected}
|
|
195
|
+
imageSelected={data?.imageSelected}
|
|
244
196
|
validFormats={validFormats}
|
|
245
|
-
addImage={addImage}
|
|
246
|
-
updateItems={updateItems}
|
|
247
197
|
setImage={setImage}
|
|
248
198
|
isGlobalTab={!isLocalTab}
|
|
249
199
|
site={galleryScope}
|
|
250
200
|
selectedTab={selectedTab}
|
|
201
|
+
refreshImages={refreshImages}
|
|
251
202
|
/>
|
|
252
203
|
</S.Wrapper>
|
|
253
204
|
);
|
|
254
205
|
};
|
|
255
206
|
|
|
256
|
-
interface IGalleryState {
|
|
257
|
-
items: IImage[];
|
|
258
|
-
isImageSelected: boolean;
|
|
259
|
-
imageSelected: IImage | null;
|
|
260
|
-
page: number;
|
|
261
|
-
isFinished: boolean;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
207
|
interface IGalleryProps {
|
|
265
208
|
getImageSelected: (img: IImage | null) => void;
|
|
266
209
|
toggleModal: () => void;
|
|
267
210
|
site: ISite;
|
|
211
|
+
data: IData;
|
|
212
|
+
isLoading: IIsLoading;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const mapStateToProps = (state: IRootState) => ({
|
|
216
|
+
data: state.gallery.data,
|
|
217
|
+
isLoading: state.gallery.isLoading,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
interface IDispatchProps {
|
|
221
|
+
getSiteImages(params: IGetSiteImages): Promise<void>;
|
|
222
|
+
selectImage(item: IImage): void;
|
|
268
223
|
}
|
|
269
224
|
|
|
270
|
-
|
|
225
|
+
const mapDispatchToProps = {
|
|
226
|
+
getSiteImages: galleryActions.getSiteImages,
|
|
227
|
+
selectImage: galleryActions.selectImage,
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
type IProps = IGalleryProps & IDispatchProps;
|
|
231
|
+
|
|
232
|
+
export default connect(mapStateToProps, mapDispatchToProps)(memo(Gallery));
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
2
|
|
|
3
|
-
const gutter = "
|
|
4
|
-
const
|
|
3
|
+
const gutter = "6px";
|
|
4
|
+
const imageSizes: Record<string, number> = {
|
|
5
|
+
"S": 2.5,
|
|
6
|
+
"L": 4,
|
|
7
|
+
"P": 1.75
|
|
8
|
+
}
|
|
5
9
|
|
|
6
10
|
export const Wrapper = styled.div`
|
|
7
11
|
display: flex;
|
|
@@ -53,6 +57,7 @@ export const GalleryWrapper = styled.div`
|
|
|
53
57
|
overflow: auto;
|
|
54
58
|
padding-right: ${gutter};
|
|
55
59
|
min-height: calc(100% - ${p => p.theme.spacing.xl} * 2);
|
|
60
|
+
position: relative;
|
|
56
61
|
`;
|
|
57
62
|
|
|
58
63
|
export const IconChecked = styled.div`
|
|
@@ -86,26 +91,37 @@ export const IconUnchecked = styled.div`
|
|
|
86
91
|
export const Grid = styled.div`
|
|
87
92
|
display: flex;
|
|
88
93
|
flex-flow: row wrap;
|
|
94
|
+
align-content: flex-start;
|
|
95
|
+
align-items: stretch;
|
|
89
96
|
padding: ${p => p.theme.spacing.m};
|
|
90
97
|
margin: 0 -${gutter};
|
|
91
98
|
margin-top: -${gutter};
|
|
92
99
|
border-right: 1px solid ${p => p.theme.color.uiLine};
|
|
93
100
|
min-height: calc(100% + ${gutter});
|
|
101
|
+
|
|
102
|
+
&::after {
|
|
103
|
+
content: "";
|
|
104
|
+
flex: auto;
|
|
105
|
+
}
|
|
94
106
|
`;
|
|
95
107
|
|
|
96
|
-
export const GridItem = styled.div
|
|
97
|
-
width: calc(100% / ${columns});
|
|
108
|
+
export const GridItem = styled.div<{ orientation: string }>`
|
|
98
109
|
padding-left: ${gutter};
|
|
99
110
|
padding-top: ${gutter};
|
|
111
|
+
flex: ${p => p.orientation === "P" ? 0 : 1};
|
|
112
|
+
|
|
113
|
+
&:last-child {
|
|
114
|
+
flex: 0;
|
|
115
|
+
}
|
|
100
116
|
`;
|
|
101
117
|
|
|
102
|
-
export const ImageWrapper = styled.div<{ selected: boolean }>`
|
|
118
|
+
export const ImageWrapper = styled.div<{ selected: boolean, orientation: string }>`
|
|
103
119
|
position: relative;
|
|
104
|
-
width: ${p => `calc(${p.theme.spacing.
|
|
105
|
-
|
|
120
|
+
min-width: ${p => `calc(${p.theme.spacing.l} * ${imageSizes[p.orientation]})`};
|
|
121
|
+
width: ${p => p.orientation === "P" ? `calc(${p.theme.spacing.l} * ${imageSizes["P"]})` : "auto"};
|
|
122
|
+
height: ${p => `calc(${p.theme.spacing.l} * ${imageSizes["S"]})`};
|
|
106
123
|
border: 1px solid;
|
|
107
124
|
border-color: ${p => (p.selected === true ? p.theme.color.interactive02 : p.theme.color.uiLine)};
|
|
108
|
-
border-radius: 4px;
|
|
109
125
|
:before {
|
|
110
126
|
content: "";
|
|
111
127
|
position: absolute;
|
|
@@ -116,7 +132,6 @@ export const ImageWrapper = styled.div<{ selected: boolean }>`
|
|
|
116
132
|
opacity: ${p => (p.selected === true ? 1 : 0)};
|
|
117
133
|
transition: opacity 0.1s;
|
|
118
134
|
background-color: ${p => (p.selected === true ? p.theme.color.overlay : `transparent`)};
|
|
119
|
-
border-radius: 4px;
|
|
120
135
|
}
|
|
121
136
|
:hover {
|
|
122
137
|
cursor: pointer;
|
|
@@ -133,7 +148,6 @@ export const ImageWrapper = styled.div<{ selected: boolean }>`
|
|
|
133
148
|
width: 100%;
|
|
134
149
|
height: 100%;
|
|
135
150
|
object-fit: cover;
|
|
136
|
-
border-radius: 4px;
|
|
137
151
|
}
|
|
138
152
|
${IconChecked} {
|
|
139
153
|
display: ${p => (p.selected === true ? `block` : 0)};
|
|
@@ -156,10 +170,26 @@ export const LoadingWrapper = styled.div`
|
|
|
156
170
|
export const LoaderWrapper = styled.div`
|
|
157
171
|
width: 100%;
|
|
158
172
|
text-align: center;
|
|
173
|
+
margin-bottom: ${p => p.theme.spacing.s};
|
|
159
174
|
`;
|
|
160
175
|
|
|
161
176
|
export const EmptyWrapper = styled.div`
|
|
162
177
|
display: flex;
|
|
163
178
|
align-items: center;
|
|
164
179
|
margin: auto;
|
|
180
|
+
align-content: center;
|
|
181
|
+
padding: ${p => p.theme.spacing.m};
|
|
182
|
+
margin: 0 -${gutter};
|
|
183
|
+
margin-top: -${gutter};
|
|
184
|
+
border-right: 1px solid ${p => p.theme.color.uiLine};
|
|
185
|
+
min-height: calc(100% + ${gutter});
|
|
186
|
+
`;
|
|
187
|
+
|
|
188
|
+
export const NotificationWrapper = styled.div`
|
|
189
|
+
width: 100%;
|
|
190
|
+
position: absolute;
|
|
191
|
+
top: 0;
|
|
192
|
+
left: 0;
|
|
193
|
+
right: 0;
|
|
194
|
+
z-index: 2;
|
|
165
195
|
`;
|
|
@@ -84,6 +84,7 @@ const AppBar = (props: IProps): JSX.Element => {
|
|
|
84
84
|
if (pageLanguages && !getCurrentLanguage(item.locale)) {
|
|
85
85
|
setNewTranslation(true);
|
|
86
86
|
languageActions.getContent && currentPageID && languageActions.getContent(currentPageID);
|
|
87
|
+
languageActions.getDataContent && currentPageID && languageActions.getDataContent(currentPageID);
|
|
87
88
|
}
|
|
88
89
|
};
|
|
89
90
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef } from "react";
|
|
1
|
+
import React, { useRef, useEffect } from "react";
|
|
2
2
|
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { Button, IconAction } from "@ax/components";
|
|
@@ -10,22 +10,28 @@ const Toast = (props: IProps) => {
|
|
|
10
10
|
const toast = useRef<any>(null);
|
|
11
11
|
|
|
12
12
|
let temp: any;
|
|
13
|
-
const setTemp = () => (temp = setTimeout(() => setIsVisible(false),
|
|
14
|
-
const stopTemp = () => clearTimeout(temp);
|
|
13
|
+
const setTemp = (time: number) => (temp = setTimeout(() => setIsVisible(false), time));
|
|
15
14
|
|
|
16
15
|
const close = () => {
|
|
17
16
|
toast.current.classList.add("close-animation");
|
|
18
|
-
setTemp();
|
|
19
|
-
stopTemp();
|
|
17
|
+
setTemp(1000);
|
|
20
18
|
};
|
|
21
19
|
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
setTemp(5000);
|
|
22
|
+
return () => clearTimeout(temp);
|
|
23
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
22
26
|
return createPortal(
|
|
23
27
|
<S.Wrapper ref={toast}>
|
|
24
28
|
<S.Text>{message}</S.Text>
|
|
25
29
|
<S.Buttons>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
{action &&
|
|
31
|
+
<Button type="button" buttonStyle="lineInverse" onClick={action}>
|
|
32
|
+
Undo
|
|
33
|
+
</Button>
|
|
34
|
+
}
|
|
29
35
|
<IconAction icon="close" onClick={close} inversed={true} />
|
|
30
36
|
</S.Buttons>
|
|
31
37
|
</S.Wrapper>,
|
|
@@ -34,7 +40,7 @@ const Toast = (props: IProps) => {
|
|
|
34
40
|
};
|
|
35
41
|
|
|
36
42
|
interface IProps {
|
|
37
|
-
action
|
|
43
|
+
action?: () => void;
|
|
38
44
|
message: string;
|
|
39
45
|
setIsVisible: (visibility: boolean) => void;
|
|
40
46
|
}
|
|
@@ -8,8 +8,8 @@ const Wrapper = styled.div`
|
|
|
8
8
|
justify-content: space-between;
|
|
9
9
|
align-items: center;
|
|
10
10
|
border-radius: 4px;
|
|
11
|
-
position:
|
|
12
|
-
z-index:
|
|
11
|
+
position: fixed;
|
|
12
|
+
z-index: 1100;
|
|
13
13
|
bottom: ${p => p.theme.spacing.m};
|
|
14
14
|
left: ${p => `calc(${p.theme.spacing.m} * 4)`};
|
|
15
15
|
padding-left: ${p => p.theme.spacing.m};
|