@pushwoosh/smart-components-kit 1.0.90 → 1.1.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/CampaignsConfigurationDrawer/CampaignsConfigurationDrawer.d.ts +1 -2
- package/CampaignsConfigurationDrawer/CampaignsConfigurationDrawer.js +103 -88
- package/CampaignsConfigurationDrawer/components/Card/Card.d.ts +1 -2
- package/CampaignsConfigurationDrawer/components/Card/Card.js +19 -13
- package/DocsButton/DocsButton.d.ts +1 -2
- package/DocsButton/DocsButton.js +21 -18
- package/DynamicContentPicker/DynamicContentPicker.js +76 -63
- package/DynamicContentPicker/Line.js +24 -22
- package/DynamicContentPickerForm/DynamicContentCustomPickerForm.js +18 -17
- package/DynamicContentPickerForm/DynamicContentEventPickerForm.js +60 -57
- package/DynamicContentPickerForm/DynamicContentTagPickerForm.js +60 -57
- package/DynamicContentPickerForm/SimpleDynamicContentPickerFormSmart.js +72 -63
- package/DynamicContentPickerForm/VariedDynamicContentPickerFormSmart.js +86 -74
- package/EmailTemplatePreview/EmailTemplatePreview.js +8 -6
- package/ExportCSV/ExportCsvBanner/ExportCsvBanner.d.ts +1 -2
- package/ExportCSV/ExportCsvBanner/ExportCsvBanner.js +54 -49
- package/ExportCSV/useExportService/useExportService.js +1 -0
- package/LanguagesSelector/LanguagesModal.js +38 -24
- package/LanguagesSelector/LanguagesSelectForm.js +73 -62
- package/LanguagesSelector/LanguagesSelectFormLoader.js +8 -7
- package/LanguagesSelector/LanguagesSelector.js +92 -78
- package/MediaStore/CreateVariantDrawer.js +134 -85
- package/MediaStore/MediaStore.d.ts +6 -10
- package/MediaStore/MediaStore.js +201 -161
- package/MediaStore/MediaStorePaginated.d.ts +8 -0
- package/MediaStore/MediaStorePaginated.js +24 -0
- package/MediaStore/index.d.ts +3 -1
- package/MediaStore/index.js +2 -1
- package/MediaStore/types.d.ts +22 -0
- package/MediaStore/types.js +1 -0
- package/ModalCloningJourney/ModalCloningJourney.d.ts +1 -2
- package/ModalCloningJourney/ModalCloningJourney.js +113 -91
- package/OpenActions/components/OpenActionsSummary/OpenActionsSummary.d.ts +1 -2
- package/OpenActions/components/OpenActionsSummary/OpenActionsSummary.js +98 -78
- package/OpenActions/components/OpenActionsSummaryByPreset.d.ts +1 -2
- package/OpenActions/components/OpenActionsSummaryByPreset.js +2 -2
- package/PlatformsConfigurationDrawer/PlatformsConfigurationDrawer.js +21 -17
- package/PlatformsConfigurationDrawer/components/DesktopPage/DesktopPage.js +112 -75
- package/PlatformsConfigurationDrawer/components/MainPage/MainPage.js +155 -101
- package/PlatformsConfigurationDrawer/components/MobilePage/MobilePage.js +138 -91
- package/ResendModal/ResendModal.d.ts +1 -2
- package/ResendModal/ResendModal.js +92 -72
- package/RichMessageEditorSmart/NewDynamicContentForm.js +16 -12
- package/RichMessageEditorSmart/RichMessageEditorSmart.js +4 -4
- package/SystemParcel/SystemParcel.d.ts +3 -3
- package/SystemParcel/SystemParcel.js +3 -2
- package/Table/components/DataTable/DataTable.js +80 -61
- package/Table/components/DataTableGetContext/DataTableGetContext.d.ts +1 -2
- package/Table/components/DataTableGetContext/DataTableGetContext.js +5 -2
- package/Table/components/DataTableList/DataTableList.d.ts +1 -2
- package/Table/components/DataTableList/DataTableList.js +86 -68
- package/Table/components/DataTablePagination/DataTablePagination.js +6 -4
- package/Table/components/DataTableSearchInput/DataTableSearchInput.js +3 -2
- package/Table/components/DataTableSortableCell/DataTableSortableCell.js +6 -4
- package/Table/components/Loading/Loading.d.ts +1 -2
- package/Table/components/Loading/Loading.js +16 -14
- package/Table/components/TablePagination/TablePagination.js +31 -25
- package/_devel/index.js +36 -24
- package/_devel/lib/dynamic-content-picker.d.ts +1 -2
- package/_devel/lib/dynamic-content-picker.js +16 -10
- package/_devel/lib/index.d.ts +2 -2
- package/_devel/lib/index.js +38 -19
- package/_devel/test-place.d.ts +1 -2
- package/_devel/test-place.js +4 -2
- package/package.json +2 -2
package/MediaStore/MediaStore.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
3
|
import { Button, DropdownMenuButton, DropdownMenuItem, DropdownMenuSection, useToast } from '@pushwoosh/dumb-components';
|
|
3
|
-
import { Horizontal } from '@pushwoosh/kit-helpers';
|
|
4
|
+
import { Horizontal, useAsync } from '@pushwoosh/kit-helpers';
|
|
4
5
|
import { CheckIcon, EditIcon, UploadIcon } from '@pushwoosh/kit-icons';
|
|
5
6
|
import { Text } from '@pushwoosh/kit-typography';
|
|
6
7
|
import { useSPAContext } from '@pushwoosh/spa-context';
|
|
@@ -8,14 +9,20 @@ import { CreateVariantDrawer } from './CreateVariantDrawer';
|
|
|
8
9
|
import { getRatioLabel, getThumbUrl } from './mediaFile.utils';
|
|
9
10
|
import { useLang } from './polyglot';
|
|
10
11
|
import { Dropzone, EmptyState, Grid, HiddenInput, Tile, TileActions, TileImage, VariantBadge } from './styled';
|
|
11
|
-
const DEFAULT_PER_PAGE = 30;
|
|
12
12
|
const UPLOAD_PATH = '/api/media/upload';
|
|
13
|
+
/**
|
|
14
|
+
* Controlled media gallery: the parent owns the current page (and page size)
|
|
15
|
+
* and is notified of navigation via `onPageChange`. For a self-contained
|
|
16
|
+
* variant that keeps the page in internal state, use `MediaStorePaginated`.
|
|
17
|
+
*/
|
|
13
18
|
export const MediaStore = ({
|
|
14
19
|
application,
|
|
15
|
-
page
|
|
16
|
-
perPage
|
|
20
|
+
page,
|
|
21
|
+
perPage,
|
|
22
|
+
onPageChange,
|
|
17
23
|
onSelect
|
|
18
24
|
}) => {
|
|
25
|
+
var _listAsync$value, _listAsync$value2;
|
|
19
26
|
const lang = useLang();
|
|
20
27
|
const {
|
|
21
28
|
rpcGateway,
|
|
@@ -28,51 +35,54 @@ export const MediaStore = ({
|
|
|
28
35
|
openToast
|
|
29
36
|
} = useToast();
|
|
30
37
|
const uploadInputRef = useRef(null);
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
// `uploadFiles` resolves asynchronously; read the latest page from the ref so
|
|
39
|
+
// the post-upload decision isn't made on a value captured at click time.
|
|
40
|
+
const pageRef = useRef(page);
|
|
41
|
+
pageRef.current = page;
|
|
33
42
|
const [variantsByUuid, setVariantsByUuid] = useState({});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const [
|
|
43
|
+
// Bumped to force a reload of the current page (e.g. after an upload) when
|
|
44
|
+
// the page prop itself does not change.
|
|
45
|
+
const [reloadToken, setReloadToken] = useState(0);
|
|
37
46
|
const [isUploading, setIsUploading] = useState(false);
|
|
38
47
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
39
48
|
const [createVariantFor, setCreateVariantFor] = useState(null);
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
const listAsync = useAsync(async () => {
|
|
50
|
+
const response = await rpcGateway.mediaFiles.List({
|
|
51
|
+
application,
|
|
52
|
+
page,
|
|
53
|
+
perPage
|
|
54
|
+
});
|
|
55
|
+
// protobuf JSON omits empty `repeated` fields, so `files` can be undefined.
|
|
56
|
+
return {
|
|
57
|
+
files: response.files ?? [],
|
|
58
|
+
total: response.total
|
|
59
|
+
};
|
|
60
|
+
}, [rpcGateway, application, page, perPage, reloadToken]);
|
|
61
|
+
const {
|
|
62
|
+
loading
|
|
63
|
+
} = listAsync;
|
|
64
|
+
const files = ((_listAsync$value = listAsync.value) === null || _listAsync$value === void 0 ? void 0 : _listAsync$value.files) ?? [];
|
|
65
|
+
const total = ((_listAsync$value2 = listAsync.value) === null || _listAsync$value2 === void 0 ? void 0 : _listAsync$value2.total) ?? 0;
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (listAsync.error) {
|
|
68
|
+
openToast({
|
|
69
|
+
title: listAsync.error.message || lang({
|
|
70
|
+
message: 'SMART.MEDIA_STORE.LOAD_ERROR'
|
|
71
|
+
}),
|
|
72
|
+
type: 'error'
|
|
51
73
|
});
|
|
52
|
-
if (token !== loadTokenRef.current) return;
|
|
53
|
-
// protobuf JSON omits empty `repeated` fields, so `files` can be undefined.
|
|
54
|
-
originals = response.files ?? [];
|
|
55
|
-
setFiles(originals);
|
|
56
|
-
setTotal(response.total);
|
|
57
|
-
setPage(response.page);
|
|
58
|
-
} catch (error) {
|
|
59
|
-
if (token === loadTokenRef.current) {
|
|
60
|
-
openToast({
|
|
61
|
-
title: error.message || lang({
|
|
62
|
-
message: 'SMART.MEDIA_STORE.LOAD_ERROR'
|
|
63
|
-
}),
|
|
64
|
-
type: 'error'
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return;
|
|
68
|
-
} finally {
|
|
69
|
-
if (token === loadTokenRef.current) {
|
|
70
|
-
setLoading(false);
|
|
71
|
-
}
|
|
72
74
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
}, [listAsync.error, openToast, lang]);
|
|
76
|
+
// The List of originals carries no variant count, so once a page of originals
|
|
77
|
+
// resolves, fetch each one's variants in the background and let the
|
|
78
|
+
// "N variants" badge appear per file as soon as its request resolves. The
|
|
79
|
+
// cleanup flag drops results of a page that has since been replaced.
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
var _listAsync$value3;
|
|
82
|
+
const originals = (_listAsync$value3 = listAsync.value) === null || _listAsync$value3 === void 0 ? void 0 : _listAsync$value3.files;
|
|
83
|
+
if (!originals) return undefined;
|
|
84
|
+
setVariantsByUuid({});
|
|
85
|
+
let cancelled = false;
|
|
76
86
|
originals.forEach(file => {
|
|
77
87
|
void (async () => {
|
|
78
88
|
try {
|
|
@@ -80,7 +90,7 @@ export const MediaStore = ({
|
|
|
80
90
|
application,
|
|
81
91
|
parentUuid: file.uuid
|
|
82
92
|
});
|
|
83
|
-
if (
|
|
93
|
+
if (cancelled) return;
|
|
84
94
|
setVariantsByUuid(prev => ({
|
|
85
95
|
...prev,
|
|
86
96
|
[file.uuid]: response.files ?? []
|
|
@@ -90,10 +100,10 @@ export const MediaStore = ({
|
|
|
90
100
|
}
|
|
91
101
|
})();
|
|
92
102
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}, [
|
|
103
|
+
return () => {
|
|
104
|
+
cancelled = true;
|
|
105
|
+
};
|
|
106
|
+
}, [listAsync.value, rpcGateway, application]);
|
|
97
107
|
const uploadFiles = async selected => {
|
|
98
108
|
const images = selected.filter(file => file.type.startsWith('image/'));
|
|
99
109
|
if (images.length === 0) return;
|
|
@@ -119,7 +129,13 @@ export const MediaStore = ({
|
|
|
119
129
|
}),
|
|
120
130
|
type: 'success'
|
|
121
131
|
});
|
|
122
|
-
|
|
132
|
+
// Jump back to the first page to surface the freshly uploaded files. If
|
|
133
|
+
// already there, the prop won't change, so bump the reload token too.
|
|
134
|
+
if (pageRef.current === 0) {
|
|
135
|
+
setReloadToken(token => token + 1);
|
|
136
|
+
} else {
|
|
137
|
+
onPageChange(0);
|
|
138
|
+
}
|
|
123
139
|
}
|
|
124
140
|
if (failed > 0) {
|
|
125
141
|
openToast({
|
|
@@ -143,116 +159,140 @@ export const MediaStore = ({
|
|
|
143
159
|
}));
|
|
144
160
|
};
|
|
145
161
|
const totalPages = Math.ceil(total / perPage);
|
|
146
|
-
return
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
event
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
event
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}), isUploading ? lang({
|
|
168
|
-
message: 'SMART.MEDIA_STORE.UPLOADING'
|
|
169
|
-
}) : lang({
|
|
170
|
-
message: 'SMART.MEDIA_STORE.DROPZONE_HINT'
|
|
171
|
-
})), React.createElement(HiddenInput, {
|
|
172
|
-
ref: uploadInputRef,
|
|
173
|
-
type: "file",
|
|
174
|
-
accept: "image/*",
|
|
175
|
-
multiple: true,
|
|
176
|
-
onChange: event => void uploadFiles(Array.from(event.target.files ?? []))
|
|
177
|
-
}), loading && React.createElement(EmptyState, null, lang({
|
|
178
|
-
message: 'SMART.MEDIA_STORE.LOADING'
|
|
179
|
-
})), !loading && files.length === 0 && React.createElement(EmptyState, null, lang({
|
|
180
|
-
message: 'SMART.MEDIA_STORE.EMPTY'
|
|
181
|
-
})), !loading && files.length > 0 && React.createElement(React.Fragment, null, React.createElement(Grid, null, files.map(file => {
|
|
182
|
-
const variants = variantsByUuid[file.uuid] ?? [];
|
|
183
|
-
return React.createElement(Tile, {
|
|
184
|
-
key: file.uuid
|
|
185
|
-
}, React.createElement(TileImage, {
|
|
186
|
-
src: getThumbUrl(file),
|
|
187
|
-
alt: file.filename
|
|
188
|
-
}), variants.length > 0 && React.createElement(VariantBadge, null, lang({
|
|
189
|
-
message: 'SMART.MEDIA_STORE.VARIANTS_BADGE',
|
|
190
|
-
count: variants.length
|
|
191
|
-
})), React.createElement(TileActions, null, variants.length > 0 ? React.createElement(DropdownMenuButton, {
|
|
192
|
-
color: "secondary",
|
|
193
|
-
size: "compact",
|
|
194
|
-
icon: React.createElement(CheckIcon, {
|
|
195
|
-
size: "small"
|
|
196
|
-
}),
|
|
197
|
-
menuPlacement: "bottom-start"
|
|
198
|
-
}, React.createElement(DropdownMenuSection, null, React.createElement(DropdownMenuItem, {
|
|
199
|
-
onClick: () => onSelect(file.url)
|
|
200
|
-
}, lang({
|
|
201
|
-
message: 'SMART.MEDIA_STORE.SELECT_ORIGINAL'
|
|
202
|
-
})), variants.map(variant => React.createElement(DropdownMenuItem, {
|
|
203
|
-
key: variant.uuid,
|
|
204
|
-
onClick: () => onSelect(variant.url)
|
|
205
|
-
}, getRatioLabel(variant) || variant.filename)))) : React.createElement(Button, {
|
|
206
|
-
color: "secondary",
|
|
207
|
-
size: "compact",
|
|
208
|
-
icon: React.createElement(CheckIcon, {
|
|
209
|
-
size: "small"
|
|
210
|
-
}),
|
|
211
|
-
"aria-label": lang({
|
|
212
|
-
message: 'SMART.MEDIA_STORE.SELECT_HINT'
|
|
213
|
-
}),
|
|
214
|
-
onClick: () => onSelect(file.url)
|
|
215
|
-
}), React.createElement(Button, {
|
|
216
|
-
color: "secondary",
|
|
217
|
-
size: "compact",
|
|
218
|
-
icon: React.createElement(EditIcon, {
|
|
219
|
-
size: "small",
|
|
162
|
+
return _jsxs(_Fragment, {
|
|
163
|
+
children: [_jsxs(Dropzone, {
|
|
164
|
+
type: "button",
|
|
165
|
+
"$dragOver": isDragOver,
|
|
166
|
+
disabled: isUploading,
|
|
167
|
+
onClick: () => {
|
|
168
|
+
var _uploadInputRef$curre;
|
|
169
|
+
return (_uploadInputRef$curre = uploadInputRef.current) === null || _uploadInputRef$curre === void 0 ? void 0 : _uploadInputRef$curre.click();
|
|
170
|
+
},
|
|
171
|
+
onDragOver: event => {
|
|
172
|
+
event.preventDefault();
|
|
173
|
+
setIsDragOver(true);
|
|
174
|
+
},
|
|
175
|
+
onDragLeave: () => setIsDragOver(false),
|
|
176
|
+
onDrop: event => {
|
|
177
|
+
event.preventDefault();
|
|
178
|
+
setIsDragOver(false);
|
|
179
|
+
void uploadFiles(Array.from(event.dataTransfer.files));
|
|
180
|
+
},
|
|
181
|
+
children: [_jsx(UploadIcon, {
|
|
182
|
+
size: "medium",
|
|
220
183
|
view: "lined"
|
|
221
|
-
}),
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
184
|
+
}), isUploading ? lang({
|
|
185
|
+
message: 'SMART.MEDIA_STORE.UPLOADING'
|
|
186
|
+
}) : lang({
|
|
187
|
+
message: 'SMART.MEDIA_STORE.DROPZONE_HINT'
|
|
188
|
+
})]
|
|
189
|
+
}), _jsx(HiddenInput, {
|
|
190
|
+
ref: uploadInputRef,
|
|
191
|
+
type: "file",
|
|
192
|
+
accept: "image/*",
|
|
193
|
+
multiple: true,
|
|
194
|
+
onChange: event => void uploadFiles(Array.from(event.target.files ?? []))
|
|
195
|
+
}), loading && _jsx(EmptyState, {
|
|
196
|
+
children: lang({
|
|
197
|
+
message: 'SMART.MEDIA_STORE.LOADING'
|
|
198
|
+
})
|
|
199
|
+
}), !loading && files.length === 0 && _jsx(EmptyState, {
|
|
200
|
+
children: lang({
|
|
201
|
+
message: 'SMART.MEDIA_STORE.EMPTY'
|
|
202
|
+
})
|
|
203
|
+
}), !loading && files.length > 0 && _jsxs(_Fragment, {
|
|
204
|
+
children: [_jsx(Grid, {
|
|
205
|
+
children: files.map(file => {
|
|
206
|
+
const variants = variantsByUuid[file.uuid] ?? [];
|
|
207
|
+
return _jsxs(Tile, {
|
|
208
|
+
children: [_jsx(TileImage, {
|
|
209
|
+
src: getThumbUrl(file),
|
|
210
|
+
alt: file.filename
|
|
211
|
+
}), variants.length > 0 && _jsx(VariantBadge, {
|
|
212
|
+
children: lang({
|
|
213
|
+
message: 'SMART.MEDIA_STORE.VARIANTS_BADGE',
|
|
214
|
+
count: variants.length
|
|
215
|
+
})
|
|
216
|
+
}), _jsxs(TileActions, {
|
|
217
|
+
children: [variants.length > 0 ? _jsx(DropdownMenuButton, {
|
|
218
|
+
color: "secondary",
|
|
219
|
+
size: "compact",
|
|
220
|
+
icon: _jsx(CheckIcon, {
|
|
221
|
+
size: "small"
|
|
222
|
+
}),
|
|
223
|
+
menuPlacement: "bottom-start",
|
|
224
|
+
children: _jsxs(DropdownMenuSection, {
|
|
225
|
+
children: [_jsx(DropdownMenuItem, {
|
|
226
|
+
onClick: () => onSelect(file.url),
|
|
227
|
+
children: lang({
|
|
228
|
+
message: 'SMART.MEDIA_STORE.SELECT_ORIGINAL'
|
|
229
|
+
})
|
|
230
|
+
}), variants.map(variant => _jsx(DropdownMenuItem, {
|
|
231
|
+
onClick: () => onSelect(variant.url),
|
|
232
|
+
children: getRatioLabel(variant) || variant.filename
|
|
233
|
+
}, variant.uuid))]
|
|
234
|
+
})
|
|
235
|
+
}) : _jsx(Button, {
|
|
236
|
+
color: "secondary",
|
|
237
|
+
size: "compact",
|
|
238
|
+
icon: _jsx(CheckIcon, {
|
|
239
|
+
size: "small"
|
|
240
|
+
}),
|
|
241
|
+
"aria-label": lang({
|
|
242
|
+
message: 'SMART.MEDIA_STORE.SELECT_HINT'
|
|
243
|
+
}),
|
|
244
|
+
onClick: () => onSelect(file.url)
|
|
245
|
+
}), _jsx(Button, {
|
|
246
|
+
color: "secondary",
|
|
247
|
+
size: "compact",
|
|
248
|
+
icon: _jsx(EditIcon, {
|
|
249
|
+
size: "small",
|
|
250
|
+
view: "lined"
|
|
251
|
+
}),
|
|
252
|
+
"aria-label": lang({
|
|
253
|
+
message: 'SMART.MEDIA_STORE.CREATE_VARIANT_HINT'
|
|
254
|
+
}),
|
|
255
|
+
onClick: () => setCreateVariantFor(file)
|
|
256
|
+
})]
|
|
257
|
+
})]
|
|
258
|
+
}, file.uuid);
|
|
259
|
+
})
|
|
260
|
+
}), totalPages > 1 && _jsxs(Horizontal, {
|
|
261
|
+
"$justifyContent": "center",
|
|
262
|
+
"$alignItems": "center",
|
|
263
|
+
"$gap": 8,
|
|
264
|
+
"$margin": {
|
|
265
|
+
top: 16
|
|
266
|
+
},
|
|
267
|
+
children: [_jsx(Button, {
|
|
268
|
+
view: "ghost",
|
|
269
|
+
color: "secondary",
|
|
270
|
+
size: "field",
|
|
271
|
+
isDisabled: page <= 0,
|
|
272
|
+
onClick: () => onPageChange(page - 1),
|
|
273
|
+
children: lang({
|
|
274
|
+
message: 'SMART.MEDIA_STORE.PREV_BUTTON'
|
|
275
|
+
})
|
|
276
|
+
}), _jsx(Text, {
|
|
277
|
+
children: `${page + 1} / ${totalPages}`
|
|
278
|
+
}), _jsx(Button, {
|
|
279
|
+
view: "ghost",
|
|
280
|
+
color: "secondary",
|
|
281
|
+
size: "field",
|
|
282
|
+
isDisabled: page + 1 >= totalPages,
|
|
283
|
+
onClick: () => onPageChange(page + 1),
|
|
284
|
+
children: lang({
|
|
285
|
+
message: 'SMART.MEDIA_STORE.NEXT_BUTTON'
|
|
286
|
+
})
|
|
287
|
+
})]
|
|
288
|
+
})]
|
|
289
|
+
}), _jsx(CreateVariantDrawer, {
|
|
290
|
+
application: application,
|
|
291
|
+
original: createVariantFor,
|
|
292
|
+
isOpen: createVariantFor !== null,
|
|
293
|
+
existingVariants: createVariantFor ? variantsByUuid[createVariantFor.uuid] ?? [] : [],
|
|
294
|
+
onClose: () => setCreateVariantFor(null),
|
|
295
|
+
onCreated: handleVariantCreated
|
|
296
|
+
})]
|
|
297
|
+
});
|
|
258
298
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type FC } from 'react';
|
|
2
|
+
import type { MediaStorePaginatedProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Self-contained {@link MediaStore} that owns the current page in internal
|
|
5
|
+
* state. Use this when the host has no opinion on pagination state; reach for
|
|
6
|
+
* `MediaStore` directly to drive the page from the URL or another store.
|
|
7
|
+
*/
|
|
8
|
+
export declare const MediaStorePaginated: FC<MediaStorePaginatedProps>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { MediaStore } from './MediaStore';
|
|
4
|
+
const DEFAULT_PER_PAGE = 30;
|
|
5
|
+
/**
|
|
6
|
+
* Self-contained {@link MediaStore} that owns the current page in internal
|
|
7
|
+
* state. Use this when the host has no opinion on pagination state; reach for
|
|
8
|
+
* `MediaStore` directly to drive the page from the URL or another store.
|
|
9
|
+
*/
|
|
10
|
+
export const MediaStorePaginated = ({
|
|
11
|
+
application,
|
|
12
|
+
initialPage = 0,
|
|
13
|
+
perPage = DEFAULT_PER_PAGE,
|
|
14
|
+
onSelect
|
|
15
|
+
}) => {
|
|
16
|
+
const [page, setPage] = useState(initialPage);
|
|
17
|
+
return _jsx(MediaStore, {
|
|
18
|
+
application: application,
|
|
19
|
+
page: page,
|
|
20
|
+
perPage: perPage,
|
|
21
|
+
onPageChange: setPage,
|
|
22
|
+
onSelect: onSelect
|
|
23
|
+
});
|
|
24
|
+
};
|
package/MediaStore/index.d.ts
CHANGED
package/MediaStore/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { MediaStore } from './MediaStore';
|
|
1
|
+
export { MediaStore } from './MediaStore';
|
|
2
|
+
export { MediaStorePaginated } from './MediaStorePaginated';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type MediaStoreProps = {
|
|
2
|
+
/** Application code whose media files are listed. */
|
|
3
|
+
application: string;
|
|
4
|
+
/** Current page (zero-based). Controlled by the parent. */
|
|
5
|
+
page: number;
|
|
6
|
+
/** Page size. */
|
|
7
|
+
perPage: number;
|
|
8
|
+
/** Called when the user requests a different page. */
|
|
9
|
+
onPageChange: (page: number) => void;
|
|
10
|
+
/** Called with the chosen file URL (original or variant). */
|
|
11
|
+
onSelect: (url: string) => void;
|
|
12
|
+
};
|
|
13
|
+
export type MediaStorePaginatedProps = {
|
|
14
|
+
/** Application code whose media files are listed. */
|
|
15
|
+
application: string;
|
|
16
|
+
/** Initial page to load (zero-based). Defaults to 0. */
|
|
17
|
+
initialPage?: number;
|
|
18
|
+
/** Page size. Defaults to 30. */
|
|
19
|
+
perPage?: number;
|
|
20
|
+
/** Called with the chosen file URL (original or variant). */
|
|
21
|
+
onSelect: (url: string) => void;
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { type ModalCloningJourneyProps } from './types';
|
|
3
|
-
export declare function ModalCloningJourney({ journeyId, journeyTitle, onAfterClone, onCancel, isOpen }: ModalCloningJourneyProps):
|
|
2
|
+
export declare function ModalCloningJourney({ journeyId, journeyTitle, onAfterClone, onCancel, isOpen }: ModalCloningJourneyProps): import("react").JSX.Element;
|