@pushwoosh/smart-components-kit 1.1.5 → 1.1.7

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.
Files changed (39) hide show
  1. package/LanguagesSelector/LanguagesSelectFormLoader.js +4 -4
  2. package/LanguagesSelector/utils.d.ts +7 -0
  3. package/LanguagesSelector/utils.js +24 -4
  4. package/{MediaStore → MediaStorage}/CreateCropDrawer.js +16 -16
  5. package/{MediaStore/MediaStore.d.ts → MediaStorage/MediaStorage.d.ts} +3 -3
  6. package/{MediaStore/MediaStore.js → MediaStorage/MediaStorage.js} +20 -20
  7. package/MediaStorage/MediaStoragePaginated.d.ts +8 -0
  8. package/{MediaStore/MediaStorePaginated.js → MediaStorage/MediaStoragePaginated.js} +5 -5
  9. package/{MediaStore → MediaStorage}/hooks.d.ts +1 -1
  10. package/{MediaStore → MediaStorage}/hooks.js +3 -3
  11. package/MediaStorage/index.d.ts +3 -0
  12. package/MediaStorage/index.js +2 -0
  13. package/MediaStorage/polyglot/index.d.ts +2 -0
  14. package/MediaStorage/polyglot/messages_en.d.ts +3 -0
  15. package/MediaStorage/polyglot/messages_en.js +38 -0
  16. package/MediaStorage/polyglot/messages_ru.d.ts +3 -0
  17. package/MediaStorage/polyglot/messages_ru.js +38 -0
  18. package/MediaStorage/polyglot/types.d.ts +44 -0
  19. package/{MediaStore → MediaStorage}/styled.js +21 -21
  20. package/{MediaStore → MediaStorage}/types.d.ts +2 -2
  21. package/index.d.ts +1 -1
  22. package/index.js +1 -1
  23. package/package.json +1 -1
  24. package/MediaStore/MediaStorePaginated.d.ts +0 -8
  25. package/MediaStore/index.d.ts +0 -3
  26. package/MediaStore/index.js +0 -2
  27. package/MediaStore/polyglot/index.d.ts +0 -2
  28. package/MediaStore/polyglot/messages_en.d.ts +0 -3
  29. package/MediaStore/polyglot/messages_en.js +0 -38
  30. package/MediaStore/polyglot/messages_ru.d.ts +0 -3
  31. package/MediaStore/polyglot/messages_ru.js +0 -38
  32. package/MediaStore/polyglot/types.d.ts +0 -44
  33. /package/{MediaStore → MediaStorage}/CreateCropDrawer.d.ts +0 -0
  34. /package/{MediaStore → MediaStorage}/mediaFile.utils.d.ts +0 -0
  35. /package/{MediaStore → MediaStorage}/mediaFile.utils.js +0 -0
  36. /package/{MediaStore → MediaStorage}/polyglot/index.js +0 -0
  37. /package/{MediaStore → MediaStorage}/polyglot/types.js +0 -0
  38. /package/{MediaStore → MediaStorage}/styled.d.ts +0 -0
  39. /package/{MediaStore → MediaStorage}/types.js +0 -0
@@ -4,7 +4,7 @@ import { Horizontal, useAsync } from '@pushwoosh/kit-helpers';
4
4
  import { useSPAContext } from '@pushwoosh/spa-context';
5
5
  import { langCodes } from './constants';
6
6
  import { LanguagesSelectForm } from './LanguagesSelectForm';
7
- import { useGetLangName } from './utils';
7
+ import { canonicalizeLangCode, useGetLangName } from './utils';
8
8
  export const LanguagesSelectFormLoader = ({
9
9
  application,
10
10
  value,
@@ -22,8 +22,8 @@ export const LanguagesSelectFormLoader = ({
22
22
  application,
23
23
  name: 'Language'
24
24
  });
25
- const valuesLangCodes = values.map(v => v.value);
26
- const allLangCodes = Array.from(new Set([...valuesLangCodes, ...langCodes]).values());
25
+ const valuesLangCodes = values.map(v => canonicalizeLangCode(v.value));
26
+ const allLangCodes = Array.from(new Set([...valuesLangCodes, ...langCodes.map(canonicalizeLangCode)]).values());
27
27
  return allLangCodes.toSorted((a, b) => {
28
28
  return a.localeCompare(b, systemLanguage, {
29
29
  sensitivity: 'base'
@@ -33,7 +33,7 @@ export const LanguagesSelectFormLoader = ({
33
33
  return {
34
34
  code,
35
35
  name: getLangName(code),
36
- subscribers: ((_values$find = values.find(val => val.value === code)) === null || _values$find === void 0 ? void 0 : _values$find.count) || 0
36
+ subscribers: ((_values$find = values.find(val => canonicalizeLangCode(val.value) === code)) === null || _values$find === void 0 ? void 0 : _values$find.count) || 0
37
37
  };
38
38
  });
39
39
  }, [application, getLangName, systemLanguage]);
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Normalizes a language code to its canonical form (e.g. `zh-hant` -> `zh-Hant`).
3
+ * Canonicalization (rather than lowercasing) keeps codes in the same form that
4
+ * devices are tagged with on the backend, so subscriber counts match and
5
+ * targeting hits real devices. Falls back to the raw code on invalid input.
6
+ */
7
+ export declare function canonicalizeLangCode(code: string): string;
1
8
  export declare function fetchLastSelection(): string[];
2
9
  export declare function saveLastSelection(languages: string[]): void;
3
10
  export declare function useGetLangName(displayLang: string): (l: string) => string;
@@ -1,5 +1,19 @@
1
1
  import { useState } from 'react';
2
+ import { languages } from '@pushwoosh/kit-constants';
2
3
  import { LAST_SELECTION_KEY } from './constants';
4
+ /**
5
+ * Normalizes a language code to its canonical form (e.g. `zh-hant` -> `zh-Hant`).
6
+ * Canonicalization (rather than lowercasing) keeps codes in the same form that
7
+ * devices are tagged with on the backend, so subscriber counts match and
8
+ * targeting hits real devices. Falls back to the raw code on invalid input.
9
+ */
10
+ export function canonicalizeLangCode(code) {
11
+ try {
12
+ return Intl.getCanonicalLocales(code)[0] ?? code;
13
+ } catch {
14
+ return code;
15
+ }
16
+ }
3
17
  export function fetchLastSelection() {
4
18
  var _localStorage$getItem;
5
19
  return ((_localStorage$getItem = localStorage.getItem(LAST_SELECTION_KEY)) === null || _localStorage$getItem === void 0 ? void 0 : _localStorage$getItem.split(',')) || [];
@@ -18,11 +32,17 @@ export function useGetLangName(displayLang) {
18
32
  return 'Default language';
19
33
  }
20
34
  try {
21
- return idn.of(lang) || lang;
22
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
23
- } catch (_error) {
24
- return lang;
35
+ const name = idn.of(lang);
36
+ // Browser ICU is often trimmed and returns the code itself for rare
37
+ // languages (ve/vo/za, ...). Treat that as "no name" and fall through.
38
+ if (name && name !== lang) {
39
+ return name;
40
+ }
41
+ } catch {
42
+ // ignore — fall back to the static dictionary below
25
43
  }
44
+ // Static ISO-639 dictionary is complete, so rare codes still get a name.
45
+ return languages[lang.toLowerCase()] ?? lang;
26
46
  };
27
47
  });
28
48
  return getLangName;
@@ -116,7 +116,7 @@ export const CreateCropDrawer = ({
116
116
  });
117
117
  openToast({
118
118
  title: lang({
119
- message: 'SMART.MEDIA_STORE.CREATE_CROP.SUCCESS'
119
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.SUCCESS'
120
120
  }),
121
121
  type: 'success'
122
122
  });
@@ -124,7 +124,7 @@ export const CreateCropDrawer = ({
124
124
  } catch (error) {
125
125
  openToast({
126
126
  title: error.message || lang({
127
- message: 'SMART.MEDIA_STORE.CREATE_CROP.ERROR'
127
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.ERROR'
128
128
  }),
129
129
  type: 'error'
130
130
  });
@@ -151,7 +151,7 @@ export const CreateCropDrawer = ({
151
151
  children: _jsxs(DrawerTitle, {
152
152
  children: [_jsx("span", {
153
153
  children: lang({
154
- message: 'SMART.MEDIA_STORE.CREATE_CROP.TITLE'
154
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.TITLE'
155
155
  })
156
156
  }), _jsx(Button, {
157
157
  view: "ghost",
@@ -161,7 +161,7 @@ export const CreateCropDrawer = ({
161
161
  size: "small"
162
162
  }),
163
163
  "aria-label": lang({
164
- message: 'SMART.MEDIA_STORE.CREATE_CROP.CLOSE'
164
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.CLOSE'
165
165
  }),
166
166
  onClick: onClose
167
167
  })]
@@ -172,7 +172,7 @@ export const CreateCropDrawer = ({
172
172
  children: [_jsxs("div", {
173
173
  children: [_jsx(FieldLabel, {
174
174
  children: lang({
175
- message: 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_LABEL'
175
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_LABEL'
176
176
  })
177
177
  }), _jsx(Chips, {
178
178
  children: RATIOS.map(item => _jsx(Chip, {
@@ -185,7 +185,7 @@ export const CreateCropDrawer = ({
185
185
  }), _jsxs("div", {
186
186
  children: [_jsx(FieldLabel, {
187
187
  children: lang({
188
- message: 'SMART.MEDIA_STORE.CREATE_CROP.SIZE_LABEL'
188
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.SIZE_LABEL'
189
189
  })
190
190
  }), _jsxs(Columns, {
191
191
  "$sizes": "auto 1fr",
@@ -197,14 +197,14 @@ export const CreateCropDrawer = ({
197
197
  "$active": dimension === 'width',
198
198
  onClick: () => setDimension('width'),
199
199
  children: lang({
200
- message: 'SMART.MEDIA_STORE.CREATE_CROP.WIDTH'
200
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.WIDTH'
201
201
  })
202
202
  }), _jsx(SegmentItem, {
203
203
  type: "button",
204
204
  "$active": dimension === 'height',
205
205
  onClick: () => setDimension('height'),
206
206
  children: lang({
207
- message: 'SMART.MEDIA_STORE.CREATE_CROP.HEIGHT'
207
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.HEIGHT'
208
208
  })
209
209
  })]
210
210
  }), _jsx(NativeInput, {
@@ -231,7 +231,7 @@ export const CreateCropDrawer = ({
231
231
  }), isJpeg && _jsxs("div", {
232
232
  children: [_jsx(FieldLabel, {
233
233
  children: lang({
234
- message: 'SMART.MEDIA_STORE.CREATE_CROP.QUALITY_LABEL'
234
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.QUALITY_LABEL'
235
235
  })
236
236
  }), _jsx(NativeInput, {
237
237
  type: "number",
@@ -243,7 +243,7 @@ export const CreateCropDrawer = ({
243
243
  })]
244
244
  }), ratioExists && _jsx(Text, {
245
245
  children: lang({
246
- message: 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_EXISTS'
246
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_EXISTS'
247
247
  })
248
248
  }), _jsx(Button, {
249
249
  color: "primary",
@@ -252,16 +252,16 @@ export const CreateCropDrawer = ({
252
252
  isLoading: isCreating,
253
253
  onClick: () => void handleCreate(),
254
254
  children: lang({
255
- message: 'SMART.MEDIA_STORE.CREATE_CROP.CREATE_BUTTON'
255
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.CREATE_BUTTON'
256
256
  })
257
257
  }), _jsxs("div", {
258
258
  children: [_jsx(FieldLabel, {
259
259
  children: lang({
260
- message: 'SMART.MEDIA_STORE.CREATE_CROP.EXISTING_LABEL'
260
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.EXISTING_LABEL'
261
261
  })
262
262
  }), existingCrops.length === 0 ? _jsx(Text, {
263
263
  children: lang({
264
- message: 'SMART.MEDIA_STORE.CREATE_CROP.NO_CROPS'
264
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.NO_CROPS'
265
265
  })
266
266
  }) : _jsx(CropStrip, {
267
267
  children: existingCrops.map(crop => _jsxs(CropThumb, {
@@ -277,7 +277,7 @@ export const CreateCropDrawer = ({
277
277
  view: "lined"
278
278
  }),
279
279
  "aria-label": lang({
280
- message: 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_HINT'
280
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_HINT'
281
281
  }),
282
282
  onClick: () => setPendingDeleteCrop(crop)
283
283
  })
@@ -291,10 +291,10 @@ export const CreateCropDrawer = ({
291
291
  }), _jsx(ModalConfirm, {
292
292
  isOpen: pendingDeleteCrop !== null,
293
293
  title: lang({
294
- message: 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.TITLE'
294
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.TITLE'
295
295
  }),
296
296
  confirmButtonText: lang({
297
- message: 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.BUTTON'
297
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.BUTTON'
298
298
  }),
299
299
  confirmButtonColor: "danger",
300
300
  onAccept: () => void handleDeleteCrop(),
@@ -1,8 +1,8 @@
1
1
  import { type FC } from 'react';
2
- import type { MediaStoreProps } from './types';
2
+ import type { MediaStorageProps } from './types';
3
3
  /**
4
4
  * Controlled media gallery: the parent owns the current page (and page size)
5
5
  * and is notified of navigation via `onPageChange`. For a self-contained
6
- * version that keeps the page in internal state, use `MediaStorePaginated`.
6
+ * version that keeps the page in internal state, use `MediaStoragePaginated`.
7
7
  */
8
- export declare const MediaStore: FC<MediaStoreProps>;
8
+ export declare const MediaStorage: FC<MediaStorageProps>;
@@ -14,9 +14,9 @@ const UPLOAD_PATH = '/api/media/upload';
14
14
  /**
15
15
  * Controlled media gallery: the parent owns the current page (and page size)
16
16
  * and is notified of navigation via `onPageChange`. For a self-contained
17
- * version that keeps the page in internal state, use `MediaStorePaginated`.
17
+ * version that keeps the page in internal state, use `MediaStoragePaginated`.
18
18
  */
19
- export const MediaStore = ({
19
+ export const MediaStorage = ({
20
20
  application,
21
21
  page,
22
22
  perPage,
@@ -79,7 +79,7 @@ export const MediaStore = ({
79
79
  if (listAsync.error) {
80
80
  openToast({
81
81
  title: listAsync.error.message || lang({
82
- message: 'SMART.MEDIA_STORE.LOAD_ERROR'
82
+ message: 'SMART.MEDIA_STORAGE.LOAD_ERROR'
83
83
  }),
84
84
  type: 'error'
85
85
  });
@@ -137,7 +137,7 @@ export const MediaStore = ({
137
137
  if (failed < images.length) {
138
138
  openToast({
139
139
  title: lang({
140
- message: 'SMART.MEDIA_STORE.UPLOAD_SUCCESS'
140
+ message: 'SMART.MEDIA_STORAGE.UPLOAD_SUCCESS'
141
141
  }),
142
142
  type: 'success'
143
143
  });
@@ -152,7 +152,7 @@ export const MediaStore = ({
152
152
  if (failed > 0) {
153
153
  openToast({
154
154
  title: lang({
155
- message: 'SMART.MEDIA_STORE.UPLOAD_ERROR'
155
+ message: 'SMART.MEDIA_STORAGE.UPLOAD_ERROR'
156
156
  }),
157
157
  type: 'error'
158
158
  });
@@ -216,9 +216,9 @@ export const MediaStore = ({
216
216
  size: "medium",
217
217
  view: "lined"
218
218
  }), isUploading ? lang({
219
- message: 'SMART.MEDIA_STORE.UPLOADING'
219
+ message: 'SMART.MEDIA_STORAGE.UPLOADING'
220
220
  }) : lang({
221
- message: 'SMART.MEDIA_STORE.DROPZONE_HINT'
221
+ message: 'SMART.MEDIA_STORAGE.DROPZONE_HINT'
222
222
  })]
223
223
  }), _jsx(HiddenInput, {
224
224
  ref: uploadInputRef,
@@ -228,11 +228,11 @@ export const MediaStore = ({
228
228
  onChange: event => void uploadFiles(Array.from(event.target.files ?? []))
229
229
  }), loading && _jsx(EmptyState, {
230
230
  children: lang({
231
- message: 'SMART.MEDIA_STORE.LOADING'
231
+ message: 'SMART.MEDIA_STORAGE.LOADING'
232
232
  })
233
233
  }), !loading && files.length === 0 && _jsx(EmptyState, {
234
234
  children: lang({
235
- message: 'SMART.MEDIA_STORE.EMPTY'
235
+ message: 'SMART.MEDIA_STORAGE.EMPTY'
236
236
  })
237
237
  }), !loading && files.length > 0 && _jsx(Grid, {
238
238
  children: files.map(file => {
@@ -243,7 +243,7 @@ export const MediaStore = ({
243
243
  alt: file.filename
244
244
  }), crops.length > 0 && _jsx(CropBadge, {
245
245
  children: lang({
246
- message: 'SMART.MEDIA_STORE.CROPS_BADGE',
246
+ message: 'SMART.MEDIA_STORAGE.CROPS_BADGE',
247
247
  count: crops.length
248
248
  })
249
249
  }), _jsxs(TileActions, {
@@ -258,7 +258,7 @@ export const MediaStore = ({
258
258
  children: [_jsx(DropdownMenuItem, {
259
259
  onClick: () => onSelect(file.url),
260
260
  children: lang({
261
- message: 'SMART.MEDIA_STORE.SELECT_ORIGINAL'
261
+ message: 'SMART.MEDIA_STORAGE.SELECT_ORIGINAL'
262
262
  })
263
263
  }), crops.map(crop => _jsx(DropdownMenuItem, {
264
264
  onClick: () => onSelect(crop.url),
@@ -272,7 +272,7 @@ export const MediaStore = ({
272
272
  size: "small"
273
273
  }),
274
274
  "aria-label": lang({
275
- message: 'SMART.MEDIA_STORE.SELECT_HINT'
275
+ message: 'SMART.MEDIA_STORAGE.SELECT_HINT'
276
276
  }),
277
277
  onClick: () => onSelect(file.url)
278
278
  }), _jsx(Button, {
@@ -283,7 +283,7 @@ export const MediaStore = ({
283
283
  view: "lined"
284
284
  }),
285
285
  "aria-label": lang({
286
- message: 'SMART.MEDIA_STORE.CREATE_CROP_HINT'
286
+ message: 'SMART.MEDIA_STORAGE.CREATE_CROP_HINT'
287
287
  }),
288
288
  onClick: () => setCreateCropFor(file)
289
289
  }), _jsx(Button, {
@@ -294,7 +294,7 @@ export const MediaStore = ({
294
294
  view: "lined"
295
295
  }),
296
296
  "aria-label": lang({
297
- message: 'SMART.MEDIA_STORE.DELETE_HINT'
297
+ message: 'SMART.MEDIA_STORAGE.DELETE_HINT'
298
298
  }),
299
299
  onClick: () => setPendingDelete(file)
300
300
  })]
@@ -316,7 +316,7 @@ export const MediaStore = ({
316
316
  isDisabled: page <= 0,
317
317
  onClick: () => onPageChange(page - 1),
318
318
  children: lang({
319
- message: 'SMART.MEDIA_STORE.PREV_BUTTON'
319
+ message: 'SMART.MEDIA_STORAGE.PREV_BUTTON'
320
320
  })
321
321
  }), _jsx(Text, {
322
322
  children: `${page + 1} / ${totalPages}`
@@ -327,12 +327,12 @@ export const MediaStore = ({
327
327
  isDisabled: page + 1 >= totalPages,
328
328
  onClick: () => onPageChange(page + 1),
329
329
  children: lang({
330
- message: 'SMART.MEDIA_STORE.NEXT_BUTTON'
330
+ message: 'SMART.MEDIA_STORAGE.NEXT_BUTTON'
331
331
  })
332
332
  })]
333
333
  }), usageAsync.value && _jsx(UsageLine, {
334
334
  children: lang({
335
- message: 'SMART.MEDIA_STORE.USAGE',
335
+ message: 'SMART.MEDIA_STORAGE.USAGE',
336
336
  count: usageAsync.value.totalCount,
337
337
  size: formatBytes(usageAsync.value.totalSize)
338
338
  })
@@ -348,13 +348,13 @@ export const MediaStore = ({
348
348
  }), _jsx(ModalConfirm, {
349
349
  isOpen: pendingDelete !== null,
350
350
  title: lang({
351
- message: 'SMART.MEDIA_STORE.DELETE_CONFIRM.TITLE'
351
+ message: 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.TITLE'
352
352
  }),
353
353
  description: lang({
354
- message: 'SMART.MEDIA_STORE.DELETE_CONFIRM.DESCRIPTION'
354
+ message: 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.DESCRIPTION'
355
355
  }),
356
356
  confirmButtonText: lang({
357
- message: 'SMART.MEDIA_STORE.DELETE_CONFIRM.BUTTON'
357
+ message: 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.BUTTON'
358
358
  }),
359
359
  confirmButtonColor: "danger",
360
360
  onAccept: () => void handleDeleteConfirmed(),
@@ -0,0 +1,8 @@
1
+ import { type FC } from 'react';
2
+ import type { MediaStoragePaginatedProps } from './types';
3
+ /**
4
+ * Self-contained {@link MediaStorage} that owns the current page in internal
5
+ * state. Use this when the host has no opinion on pagination state; reach for
6
+ * `MediaStorage` directly to drive the page from the URL or another store.
7
+ */
8
+ export declare const MediaStoragePaginated: FC<MediaStoragePaginatedProps>;
@@ -1,20 +1,20 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
- import { MediaStore } from './MediaStore';
3
+ import { MediaStorage } from './MediaStorage';
4
4
  const DEFAULT_PER_PAGE = 30;
5
5
  /**
6
- * Self-contained {@link MediaStore} that owns the current page in internal
6
+ * Self-contained {@link MediaStorage} that owns the current page in internal
7
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.
8
+ * `MediaStorage` directly to drive the page from the URL or another store.
9
9
  */
10
- export const MediaStorePaginated = ({
10
+ export const MediaStoragePaginated = ({
11
11
  application,
12
12
  initialPage = 0,
13
13
  perPage = DEFAULT_PER_PAGE,
14
14
  onSelect
15
15
  }) => {
16
16
  const [page, setPage] = useState(initialPage);
17
- return _jsx(MediaStore, {
17
+ return _jsx(MediaStorage, {
18
18
  application: application,
19
19
  page: page,
20
20
  perPage: perPage,
@@ -2,6 +2,6 @@
2
2
  * Returns a function that deletes a media file (original or crop) and shows the
3
3
  * success/error toast. Resolves to `true` on success so the caller can run its
4
4
  * own post-delete routing (refetch, state update, pagination), `false` on
5
- * failure. Both `MediaStore` and `CreateCropDrawer` share this.
5
+ * failure. Both `MediaStorage` and `CreateCropDrawer` share this.
6
6
  */
7
7
  export declare function useDeleteMediaFile(application: string): (uuid: string) => Promise<boolean>;
@@ -6,7 +6,7 @@ import { useLang } from './polyglot';
6
6
  * Returns a function that deletes a media file (original or crop) and shows the
7
7
  * success/error toast. Resolves to `true` on success so the caller can run its
8
8
  * own post-delete routing (refetch, state update, pagination), `false` on
9
- * failure. Both `MediaStore` and `CreateCropDrawer` share this.
9
+ * failure. Both `MediaStorage` and `CreateCropDrawer` share this.
10
10
  */
11
11
  export function useDeleteMediaFile(application) {
12
12
  const {
@@ -24,7 +24,7 @@ export function useDeleteMediaFile(application) {
24
24
  });
25
25
  openToast({
26
26
  title: lang({
27
- message: 'SMART.MEDIA_STORE.DELETE_SUCCESS'
27
+ message: 'SMART.MEDIA_STORAGE.DELETE_SUCCESS'
28
28
  }),
29
29
  type: 'success'
30
30
  });
@@ -32,7 +32,7 @@ export function useDeleteMediaFile(application) {
32
32
  } catch (error) {
33
33
  openToast({
34
34
  title: error.message || lang({
35
- message: 'SMART.MEDIA_STORE.DELETE_ERROR'
35
+ message: 'SMART.MEDIA_STORAGE.DELETE_ERROR'
36
36
  }),
37
37
  type: 'error'
38
38
  });
@@ -0,0 +1,3 @@
1
+ export { MediaStorage } from './MediaStorage';
2
+ export { MediaStoragePaginated } from './MediaStoragePaginated';
3
+ export type { MediaStorageProps, MediaStoragePaginatedProps } from './types';
@@ -0,0 +1,2 @@
1
+ export { MediaStorage } from './MediaStorage';
2
+ export { MediaStoragePaginated } from './MediaStoragePaginated';
@@ -0,0 +1,2 @@
1
+ import { type MediaStorageMessages } from './types';
2
+ export declare const Lang: import("react").FC<import("@pushwoosh/dumb-components/polyglot").LangProps<MediaStorageMessages>>, useLang: () => (props: import("@pushwoosh/dumb-components/polyglot").LangProps<MediaStorageMessages>) => string;
@@ -0,0 +1,3 @@
1
+ import type { LangMessages } from '@pushwoosh/dumb-components/polyglot';
2
+ import { type MediaStorageMessages } from './types';
3
+ export declare const messages: LangMessages<MediaStorageMessages>;
@@ -0,0 +1,38 @@
1
+ export const messages = {
2
+ 'SMART.MEDIA_STORAGE.UPLOADING': 'Uploading...',
3
+ 'SMART.MEDIA_STORAGE.DROPZONE_HINT': 'Drag & drop images here or click to upload',
4
+ 'SMART.MEDIA_STORAGE.LOADING': 'Loading...',
5
+ 'SMART.MEDIA_STORAGE.EMPTY': 'No media files found',
6
+ 'SMART.MEDIA_STORAGE.SELECT_HINT': 'Click to select',
7
+ 'SMART.MEDIA_STORAGE.PREV_BUTTON': 'Previous',
8
+ 'SMART.MEDIA_STORAGE.NEXT_BUTTON': 'Next',
9
+ 'SMART.MEDIA_STORAGE.LOAD_ERROR': 'Failed to load media files',
10
+ 'SMART.MEDIA_STORAGE.UPLOAD_ERROR': 'Failed to upload image',
11
+ 'SMART.MEDIA_STORAGE.UPLOAD_SUCCESS': 'Image uploaded',
12
+ 'SMART.MEDIA_STORAGE.USAGE': '{{count}} files · {{size}}',
13
+ 'SMART.MEDIA_STORAGE.CROPS_BADGE': '{{count}} cr.',
14
+ 'SMART.MEDIA_STORAGE.SELECT_ORIGINAL': 'Original',
15
+ 'SMART.MEDIA_STORAGE.CREATE_CROP_HINT': 'Create crops',
16
+ 'SMART.MEDIA_STORAGE.DELETE_HINT': 'Delete',
17
+ 'SMART.MEDIA_STORAGE.DELETE_SUCCESS': 'Deleted',
18
+ 'SMART.MEDIA_STORAGE.DELETE_ERROR': 'Failed to delete',
19
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.TITLE': 'Delete this file?',
20
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.DESCRIPTION': 'Deleting the original also removes all of its crops. This can’t be undone.',
21
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.BUTTON': 'Delete',
22
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.TITLE': 'Create crop',
23
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.CLOSE': 'Close',
24
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_LABEL': 'Aspect ratio',
25
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.SIZE_LABEL': 'Size',
26
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.WIDTH': 'Width',
27
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.HEIGHT': 'Height',
28
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.QUALITY_LABEL': 'JPEG quality (1–100)',
29
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.CREATE_BUTTON': 'Create crop',
30
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_EXISTS': 'A crop with this aspect ratio already exists',
31
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.EXISTING_LABEL': 'Existing crops',
32
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.NO_CROPS': 'No crops yet',
33
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.SUCCESS': 'Crop created',
34
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.ERROR': 'Failed to create crop',
35
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_HINT': 'Delete crop',
36
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.TITLE': 'Delete this crop?',
37
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.BUTTON': 'Delete'
38
+ };
@@ -0,0 +1,3 @@
1
+ import type { LangMessages } from '@pushwoosh/dumb-components/polyglot';
2
+ import { type MediaStorageMessages } from './types';
3
+ export declare const messages: LangMessages<MediaStorageMessages>;
@@ -0,0 +1,38 @@
1
+ export const messages = {
2
+ 'SMART.MEDIA_STORAGE.UPLOADING': 'Загрузка...',
3
+ 'SMART.MEDIA_STORAGE.DROPZONE_HINT': 'Перетащите изображения сюда или нажмите для загрузки',
4
+ 'SMART.MEDIA_STORAGE.LOADING': 'Загрузка...',
5
+ 'SMART.MEDIA_STORAGE.EMPTY': 'Медиафайлы не найдены',
6
+ 'SMART.MEDIA_STORAGE.SELECT_HINT': 'Нажмите, чтобы выбрать',
7
+ 'SMART.MEDIA_STORAGE.PREV_BUTTON': 'Назад',
8
+ 'SMART.MEDIA_STORAGE.NEXT_BUTTON': 'Вперёд',
9
+ 'SMART.MEDIA_STORAGE.LOAD_ERROR': 'Не удалось загрузить медиафайлы',
10
+ 'SMART.MEDIA_STORAGE.UPLOAD_ERROR': 'Не удалось загрузить изображение',
11
+ 'SMART.MEDIA_STORAGE.UPLOAD_SUCCESS': 'Изображение загружено',
12
+ 'SMART.MEDIA_STORAGE.USAGE': '{{count}} файлов · {{size}}',
13
+ 'SMART.MEDIA_STORAGE.CROPS_BADGE': '{{count}} кр.',
14
+ 'SMART.MEDIA_STORAGE.SELECT_ORIGINAL': 'Оригинал',
15
+ 'SMART.MEDIA_STORAGE.CREATE_CROP_HINT': 'Создать кропы',
16
+ 'SMART.MEDIA_STORAGE.DELETE_HINT': 'Удалить',
17
+ 'SMART.MEDIA_STORAGE.DELETE_SUCCESS': 'Удалено',
18
+ 'SMART.MEDIA_STORAGE.DELETE_ERROR': 'Не удалось удалить',
19
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.TITLE': 'Удалить файл?',
20
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.DESCRIPTION': 'Удаление оригинала также удалит все его кропы. Действие необратимо.',
21
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.BUTTON': 'Удалить',
22
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.TITLE': 'Создание кропа',
23
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.CLOSE': 'Закрыть',
24
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_LABEL': 'Соотношение сторон',
25
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.SIZE_LABEL': 'Размер',
26
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.WIDTH': 'Ширина',
27
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.HEIGHT': 'Высота',
28
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.QUALITY_LABEL': 'Качество JPEG (1–100)',
29
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.CREATE_BUTTON': 'Создать кроп',
30
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_EXISTS': 'Кроп с таким соотношением сторон уже существует',
31
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.EXISTING_LABEL': 'Созданные кропы',
32
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.NO_CROPS': 'Кропов пока нет',
33
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.SUCCESS': 'Кроп создан',
34
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.ERROR': 'Не удалось создать кроп',
35
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_HINT': 'Удалить кроп',
36
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.TITLE': 'Удалить кроп?',
37
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.BUTTON': 'Удалить'
38
+ };
@@ -0,0 +1,44 @@
1
+ import type { NoParams } from '@pushwoosh/dumb-components/polyglot';
2
+ export type MediaStorageMessages = {
3
+ 'SMART.MEDIA_STORAGE.UPLOADING': NoParams;
4
+ 'SMART.MEDIA_STORAGE.DROPZONE_HINT': NoParams;
5
+ 'SMART.MEDIA_STORAGE.LOADING': NoParams;
6
+ 'SMART.MEDIA_STORAGE.EMPTY': NoParams;
7
+ 'SMART.MEDIA_STORAGE.SELECT_HINT': NoParams;
8
+ 'SMART.MEDIA_STORAGE.PREV_BUTTON': NoParams;
9
+ 'SMART.MEDIA_STORAGE.NEXT_BUTTON': NoParams;
10
+ 'SMART.MEDIA_STORAGE.LOAD_ERROR': NoParams;
11
+ 'SMART.MEDIA_STORAGE.UPLOAD_ERROR': NoParams;
12
+ 'SMART.MEDIA_STORAGE.UPLOAD_SUCCESS': NoParams;
13
+ 'SMART.MEDIA_STORAGE.USAGE': {
14
+ count: number;
15
+ size: string;
16
+ };
17
+ 'SMART.MEDIA_STORAGE.CROPS_BADGE': {
18
+ count: number;
19
+ };
20
+ 'SMART.MEDIA_STORAGE.SELECT_ORIGINAL': NoParams;
21
+ 'SMART.MEDIA_STORAGE.CREATE_CROP_HINT': NoParams;
22
+ 'SMART.MEDIA_STORAGE.DELETE_HINT': NoParams;
23
+ 'SMART.MEDIA_STORAGE.DELETE_SUCCESS': NoParams;
24
+ 'SMART.MEDIA_STORAGE.DELETE_ERROR': NoParams;
25
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.TITLE': NoParams;
26
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.DESCRIPTION': NoParams;
27
+ 'SMART.MEDIA_STORAGE.DELETE_CONFIRM.BUTTON': NoParams;
28
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.TITLE': NoParams;
29
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.CLOSE': NoParams;
30
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_LABEL': NoParams;
31
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.SIZE_LABEL': NoParams;
32
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.WIDTH': NoParams;
33
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.HEIGHT': NoParams;
34
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.QUALITY_LABEL': NoParams;
35
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.CREATE_BUTTON': NoParams;
36
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.RATIO_EXISTS': NoParams;
37
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.EXISTING_LABEL': NoParams;
38
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.NO_CROPS': NoParams;
39
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.SUCCESS': NoParams;
40
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.ERROR': NoParams;
41
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_HINT': NoParams;
42
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.TITLE': NoParams;
43
+ 'SMART.MEDIA_STORAGE.CREATE_CROP.DELETE_CONFIRM.BUTTON': NoParams;
44
+ };
@@ -2,31 +2,31 @@ import styled from 'styled-components';
2
2
  import { Color, FontSize, FontWeight } from '@pushwoosh/kit-constants';
3
3
  export const Grid = styled.div.withConfig({
4
4
  displayName: "Grid",
5
- componentId: "sc-1d9kmgw-0"
5
+ componentId: "sc-14317rj-0"
6
6
  })(["display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px;"]);
7
7
  export const Tile = styled.div.withConfig({
8
8
  displayName: "Tile",
9
- componentId: "sc-1d9kmgw-1"
9
+ componentId: "sc-14317rj-1"
10
10
  })(["position:relative;border-radius:6px;overflow:hidden;border:1px solid ", ";transition:border-color 0.15s;&:hover{border-color:", ";}"], Color.DIVIDER, Color.PRIMARY);
11
11
  export const TileImage = styled.img.withConfig({
12
12
  displayName: "TileImage",
13
- componentId: "sc-1d9kmgw-2"
13
+ componentId: "sc-14317rj-2"
14
14
  })(["width:100%;aspect-ratio:1;object-fit:cover;display:block;"]);
15
15
  export const CropBadge = styled.span.withConfig({
16
16
  displayName: "CropBadge",
17
- componentId: "sc-1d9kmgw-3"
17
+ componentId: "sc-14317rj-3"
18
18
  })(["position:absolute;top:6px;right:6px;font-size:10px;font-weight:", ";line-height:1;color:", ";background:", ";border-radius:20px;padding:3px 7px;pointer-events:none;"], FontWeight.BOLD, Color.CLEAR, Color.PRIMARY);
19
19
  export const TileActions = styled.div.withConfig({
20
20
  displayName: "TileActions",
21
- componentId: "sc-1d9kmgw-4"
21
+ componentId: "sc-14317rj-4"
22
22
  })(["position:absolute;top:6px;left:6px;display:flex;gap:6px;padding:4px;border-radius:8px;background:rgba(0,0,0,0.45);backdrop-filter:blur(2px);opacity:0;transition:opacity 0.15s;", ":hover &{opacity:1;}@media (hover:none){opacity:1;}"], Tile);
23
23
  export const EmptyState = styled.div.withConfig({
24
24
  displayName: "EmptyState",
25
- componentId: "sc-1d9kmgw-5"
25
+ componentId: "sc-14317rj-5"
26
26
  })(["text-align:center;padding:48px 16px;color:", ";"], Color.LOCKED);
27
27
  export const Dropzone = styled.button.withConfig({
28
28
  displayName: "Dropzone",
29
- componentId: "sc-1d9kmgw-6"
29
+ componentId: "sc-14317rj-6"
30
30
  })(["width:100%;min-height:96px;margin-bottom:16px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:16px;font:inherit;font-size:13px;color:", ";cursor:pointer;border:2px dashed ", ";border-radius:8px;background:", ";transition:border-color 0.15s,background 0.15s;&:hover{border-color:", ";}&:disabled{cursor:default;opacity:0.7;}"], Color.LOCKED, ({
31
31
  $dragOver
32
32
  }) => $dragOver ? Color.PRIMARY : Color.DIVIDER, ({
@@ -34,38 +34,38 @@ export const Dropzone = styled.button.withConfig({
34
34
  }) => $dragOver ? Color.SOFT_LIGHT : Color.CLEAR, Color.PRIMARY);
35
35
  export const HiddenInput = styled.input.withConfig({
36
36
  displayName: "HiddenInput",
37
- componentId: "sc-1d9kmgw-7"
37
+ componentId: "sc-14317rj-7"
38
38
  })(["display:none;"]);
39
39
  export const UsageLine = styled.div.withConfig({
40
40
  displayName: "UsageLine",
41
- componentId: "sc-1d9kmgw-8"
41
+ componentId: "sc-14317rj-8"
42
42
  })(["margin-left:auto;font-size:", ";color:", ";"], FontSize.SMALL, Color.LOCKED);
43
43
  /* ---------- CreateCropDrawer ---------- */
44
44
  export const PreviewStage = styled.div.withConfig({
45
45
  displayName: "PreviewStage",
46
- componentId: "sc-1d9kmgw-9"
46
+ componentId: "sc-14317rj-9"
47
47
  })(["display:flex;align-items:center;justify-content:center;min-height:200px;max-height:360px;padding:12px;border:1px solid ", ";border-radius:6px;overflow:hidden;background:", ";"], Color.DIVIDER, Color.SOFT_LIGHT);
48
48
  export const PreviewFrame = styled.div.withConfig({
49
49
  displayName: "PreviewFrame",
50
- componentId: "sc-1d9kmgw-10"
50
+ componentId: "sc-14317rj-10"
51
51
  })(["aspect-ratio:", ";max-width:100%;max-height:336px;overflow:hidden;border-radius:4px;"], ({
52
52
  $ratio
53
53
  }) => $ratio);
54
54
  export const PreviewImage = styled.img.withConfig({
55
55
  displayName: "PreviewImage",
56
- componentId: "sc-1d9kmgw-11"
56
+ componentId: "sc-14317rj-11"
57
57
  })(["width:100%;height:100%;object-fit:cover;display:block;"]);
58
58
  export const FieldLabel = styled.div.withConfig({
59
59
  displayName: "FieldLabel",
60
- componentId: "sc-1d9kmgw-12"
60
+ componentId: "sc-14317rj-12"
61
61
  })(["font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.4px;color:", ";margin-bottom:6px;"], Color.LOCKED);
62
62
  export const Chips = styled.div.withConfig({
63
63
  displayName: "Chips",
64
- componentId: "sc-1d9kmgw-13"
64
+ componentId: "sc-14317rj-13"
65
65
  })(["display:flex;flex-wrap:wrap;gap:7px;"]);
66
66
  export const Chip = styled.button.withConfig({
67
67
  displayName: "Chip",
68
- componentId: "sc-1d9kmgw-14"
68
+ componentId: "sc-14317rj-14"
69
69
  })(["font:inherit;font-size:13px;cursor:pointer;padding:6px 12px;border-radius:20px;border:1px solid ", ";background:", ";color:", ";transition:background 0.12s,border-color 0.12s;"], ({
70
70
  $active
71
71
  }) => $active ? Color.PRIMARY : Color.DIVIDER, ({
@@ -75,11 +75,11 @@ export const Chip = styled.button.withConfig({
75
75
  }) => $active ? Color.CLEAR : Color.MAIN);
76
76
  export const Segment = styled.div.withConfig({
77
77
  displayName: "Segment",
78
- componentId: "sc-1d9kmgw-15"
78
+ componentId: "sc-14317rj-15"
79
79
  })(["display:inline-flex;border:1px solid ", ";border-radius:6px;overflow:hidden;"], Color.DIVIDER);
80
80
  export const SegmentItem = styled.button.withConfig({
81
81
  displayName: "SegmentItem",
82
- componentId: "sc-1d9kmgw-16"
82
+ componentId: "sc-14317rj-16"
83
83
  })(["font:inherit;font-size:13px;cursor:pointer;padding:7px 14px;border:none;background:", ";color:", ";& + &{border-left:1px solid ", ";}"], ({
84
84
  $active
85
85
  }) => $active ? Color.PRIMARY : Color.CLEAR, ({
@@ -87,17 +87,17 @@ export const SegmentItem = styled.button.withConfig({
87
87
  }) => $active ? Color.CLEAR : Color.MAIN, Color.DIVIDER);
88
88
  export const CropStrip = styled.div.withConfig({
89
89
  displayName: "CropStrip",
90
- componentId: "sc-1d9kmgw-17"
90
+ componentId: "sc-14317rj-17"
91
91
  })(["display:flex;gap:10px;flex-wrap:wrap;align-items:flex-start;"]);
92
92
  export const CropThumb = styled.div.withConfig({
93
93
  displayName: "CropThumb",
94
- componentId: "sc-1d9kmgw-18"
94
+ componentId: "sc-14317rj-18"
95
95
  })(["position:relative;width:88px;border:1px solid ", ";border-radius:6px;overflow:hidden;background:", ";"], Color.DIVIDER, Color.SOFT_LIGHT);
96
96
  export const CropThumbDelete = styled.div.withConfig({
97
97
  displayName: "CropThumbDelete",
98
- componentId: "sc-1d9kmgw-19"
98
+ componentId: "sc-14317rj-19"
99
99
  })(["position:absolute;top:4px;right:4px;opacity:0;transition:opacity 0.15s;", ":hover &{opacity:1;}@media (hover:none){opacity:1;}"], CropThumb);
100
100
  export const CropThumbCaption = styled.div.withConfig({
101
101
  displayName: "CropThumbCaption",
102
- componentId: "sc-1d9kmgw-20"
102
+ componentId: "sc-14317rj-20"
103
103
  })(["font-size:10px;text-align:center;padding:3px 2px;color:", ";"], Color.LOCKED);
@@ -1,4 +1,4 @@
1
- export type MediaStoreProps = {
1
+ export type MediaStorageProps = {
2
2
  /** Application code whose media files are listed. */
3
3
  application: string;
4
4
  /** Current page (zero-based). Controlled by the parent. */
@@ -10,7 +10,7 @@ export type MediaStoreProps = {
10
10
  /** Called with the chosen file URL (original or crop). */
11
11
  onSelect: (url: string) => void;
12
12
  };
13
- export type MediaStorePaginatedProps = {
13
+ export type MediaStoragePaginatedProps = {
14
14
  /** Application code whose media files are listed. */
15
15
  application: string;
16
16
  /** Initial page to load (zero-based). Defaults to 0. */
package/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export * from './EmailTemplatePreview';
7
7
  export * from './ExportCSV';
8
8
  export * from './PlatformsConfigurationDrawer';
9
9
  export * from './LanguagesSelector';
10
- export * from './MediaStore';
10
+ export * from './MediaStorage';
11
11
  export * from './ResendModal';
12
12
  export * from './RichMessageEditorSmart';
13
13
  export * from './Table';
package/index.js CHANGED
@@ -7,7 +7,7 @@ export * from './EmailTemplatePreview';
7
7
  export * from './ExportCSV';
8
8
  export * from './PlatformsConfigurationDrawer';
9
9
  export * from './LanguagesSelector';
10
- export * from './MediaStore';
10
+ export * from './MediaStorage';
11
11
  export * from './ResendModal';
12
12
  export * from './RichMessageEditorSmart';
13
13
  export * from './Table';
package/package.json CHANGED
@@ -48,5 +48,5 @@
48
48
  "react": "^16.14.0 || ^18.0.0",
49
49
  "react-dom": "^16.14.0 || ^18.0.0"
50
50
  },
51
- "version": "1.1.5"
51
+ "version": "1.1.7"
52
52
  }
@@ -1,8 +0,0 @@
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>;
@@ -1,3 +0,0 @@
1
- export { MediaStore } from './MediaStore';
2
- export { MediaStorePaginated } from './MediaStorePaginated';
3
- export type { MediaStoreProps, MediaStorePaginatedProps } from './types';
@@ -1,2 +0,0 @@
1
- export { MediaStore } from './MediaStore';
2
- export { MediaStorePaginated } from './MediaStorePaginated';
@@ -1,2 +0,0 @@
1
- import { type MediaStoreMessages } from './types';
2
- export declare const Lang: import("react").FC<import("@pushwoosh/dumb-components/polyglot").LangProps<MediaStoreMessages>>, useLang: () => (props: import("@pushwoosh/dumb-components/polyglot").LangProps<MediaStoreMessages>) => string;
@@ -1,3 +0,0 @@
1
- import type { LangMessages } from '@pushwoosh/dumb-components/polyglot';
2
- import { type MediaStoreMessages } from './types';
3
- export declare const messages: LangMessages<MediaStoreMessages>;
@@ -1,38 +0,0 @@
1
- export const messages = {
2
- 'SMART.MEDIA_STORE.UPLOADING': 'Uploading...',
3
- 'SMART.MEDIA_STORE.DROPZONE_HINT': 'Drag & drop images here or click to upload',
4
- 'SMART.MEDIA_STORE.LOADING': 'Loading...',
5
- 'SMART.MEDIA_STORE.EMPTY': 'No media files found',
6
- 'SMART.MEDIA_STORE.SELECT_HINT': 'Click to select',
7
- 'SMART.MEDIA_STORE.PREV_BUTTON': 'Previous',
8
- 'SMART.MEDIA_STORE.NEXT_BUTTON': 'Next',
9
- 'SMART.MEDIA_STORE.LOAD_ERROR': 'Failed to load media files',
10
- 'SMART.MEDIA_STORE.UPLOAD_ERROR': 'Failed to upload image',
11
- 'SMART.MEDIA_STORE.UPLOAD_SUCCESS': 'Image uploaded',
12
- 'SMART.MEDIA_STORE.USAGE': '{{count}} files · {{size}}',
13
- 'SMART.MEDIA_STORE.CROPS_BADGE': '{{count}} cr.',
14
- 'SMART.MEDIA_STORE.SELECT_ORIGINAL': 'Original',
15
- 'SMART.MEDIA_STORE.CREATE_CROP_HINT': 'Create crops',
16
- 'SMART.MEDIA_STORE.DELETE_HINT': 'Delete',
17
- 'SMART.MEDIA_STORE.DELETE_SUCCESS': 'Deleted',
18
- 'SMART.MEDIA_STORE.DELETE_ERROR': 'Failed to delete',
19
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.TITLE': 'Delete this file?',
20
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.DESCRIPTION': 'Deleting the original also removes all of its crops. This can’t be undone.',
21
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.BUTTON': 'Delete',
22
- 'SMART.MEDIA_STORE.CREATE_CROP.TITLE': 'Create crop',
23
- 'SMART.MEDIA_STORE.CREATE_CROP.CLOSE': 'Close',
24
- 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_LABEL': 'Aspect ratio',
25
- 'SMART.MEDIA_STORE.CREATE_CROP.SIZE_LABEL': 'Size',
26
- 'SMART.MEDIA_STORE.CREATE_CROP.WIDTH': 'Width',
27
- 'SMART.MEDIA_STORE.CREATE_CROP.HEIGHT': 'Height',
28
- 'SMART.MEDIA_STORE.CREATE_CROP.QUALITY_LABEL': 'JPEG quality (1–100)',
29
- 'SMART.MEDIA_STORE.CREATE_CROP.CREATE_BUTTON': 'Create crop',
30
- 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_EXISTS': 'A crop with this aspect ratio already exists',
31
- 'SMART.MEDIA_STORE.CREATE_CROP.EXISTING_LABEL': 'Existing crops',
32
- 'SMART.MEDIA_STORE.CREATE_CROP.NO_CROPS': 'No crops yet',
33
- 'SMART.MEDIA_STORE.CREATE_CROP.SUCCESS': 'Crop created',
34
- 'SMART.MEDIA_STORE.CREATE_CROP.ERROR': 'Failed to create crop',
35
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_HINT': 'Delete crop',
36
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.TITLE': 'Delete this crop?',
37
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.BUTTON': 'Delete'
38
- };
@@ -1,3 +0,0 @@
1
- import type { LangMessages } from '@pushwoosh/dumb-components/polyglot';
2
- import { type MediaStoreMessages } from './types';
3
- export declare const messages: LangMessages<MediaStoreMessages>;
@@ -1,38 +0,0 @@
1
- export const messages = {
2
- 'SMART.MEDIA_STORE.UPLOADING': 'Загрузка...',
3
- 'SMART.MEDIA_STORE.DROPZONE_HINT': 'Перетащите изображения сюда или нажмите для загрузки',
4
- 'SMART.MEDIA_STORE.LOADING': 'Загрузка...',
5
- 'SMART.MEDIA_STORE.EMPTY': 'Медиафайлы не найдены',
6
- 'SMART.MEDIA_STORE.SELECT_HINT': 'Нажмите, чтобы выбрать',
7
- 'SMART.MEDIA_STORE.PREV_BUTTON': 'Назад',
8
- 'SMART.MEDIA_STORE.NEXT_BUTTON': 'Вперёд',
9
- 'SMART.MEDIA_STORE.LOAD_ERROR': 'Не удалось загрузить медиафайлы',
10
- 'SMART.MEDIA_STORE.UPLOAD_ERROR': 'Не удалось загрузить изображение',
11
- 'SMART.MEDIA_STORE.UPLOAD_SUCCESS': 'Изображение загружено',
12
- 'SMART.MEDIA_STORE.USAGE': '{{count}} файлов · {{size}}',
13
- 'SMART.MEDIA_STORE.CROPS_BADGE': '{{count}} кр.',
14
- 'SMART.MEDIA_STORE.SELECT_ORIGINAL': 'Оригинал',
15
- 'SMART.MEDIA_STORE.CREATE_CROP_HINT': 'Создать кропы',
16
- 'SMART.MEDIA_STORE.DELETE_HINT': 'Удалить',
17
- 'SMART.MEDIA_STORE.DELETE_SUCCESS': 'Удалено',
18
- 'SMART.MEDIA_STORE.DELETE_ERROR': 'Не удалось удалить',
19
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.TITLE': 'Удалить файл?',
20
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.DESCRIPTION': 'Удаление оригинала также удалит все его кропы. Действие необратимо.',
21
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.BUTTON': 'Удалить',
22
- 'SMART.MEDIA_STORE.CREATE_CROP.TITLE': 'Создание кропа',
23
- 'SMART.MEDIA_STORE.CREATE_CROP.CLOSE': 'Закрыть',
24
- 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_LABEL': 'Соотношение сторон',
25
- 'SMART.MEDIA_STORE.CREATE_CROP.SIZE_LABEL': 'Размер',
26
- 'SMART.MEDIA_STORE.CREATE_CROP.WIDTH': 'Ширина',
27
- 'SMART.MEDIA_STORE.CREATE_CROP.HEIGHT': 'Высота',
28
- 'SMART.MEDIA_STORE.CREATE_CROP.QUALITY_LABEL': 'Качество JPEG (1–100)',
29
- 'SMART.MEDIA_STORE.CREATE_CROP.CREATE_BUTTON': 'Создать кроп',
30
- 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_EXISTS': 'Кроп с таким соотношением сторон уже существует',
31
- 'SMART.MEDIA_STORE.CREATE_CROP.EXISTING_LABEL': 'Созданные кропы',
32
- 'SMART.MEDIA_STORE.CREATE_CROP.NO_CROPS': 'Кропов пока нет',
33
- 'SMART.MEDIA_STORE.CREATE_CROP.SUCCESS': 'Кроп создан',
34
- 'SMART.MEDIA_STORE.CREATE_CROP.ERROR': 'Не удалось создать кроп',
35
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_HINT': 'Удалить кроп',
36
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.TITLE': 'Удалить кроп?',
37
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.BUTTON': 'Удалить'
38
- };
@@ -1,44 +0,0 @@
1
- import type { NoParams } from '@pushwoosh/dumb-components/polyglot';
2
- export type MediaStoreMessages = {
3
- 'SMART.MEDIA_STORE.UPLOADING': NoParams;
4
- 'SMART.MEDIA_STORE.DROPZONE_HINT': NoParams;
5
- 'SMART.MEDIA_STORE.LOADING': NoParams;
6
- 'SMART.MEDIA_STORE.EMPTY': NoParams;
7
- 'SMART.MEDIA_STORE.SELECT_HINT': NoParams;
8
- 'SMART.MEDIA_STORE.PREV_BUTTON': NoParams;
9
- 'SMART.MEDIA_STORE.NEXT_BUTTON': NoParams;
10
- 'SMART.MEDIA_STORE.LOAD_ERROR': NoParams;
11
- 'SMART.MEDIA_STORE.UPLOAD_ERROR': NoParams;
12
- 'SMART.MEDIA_STORE.UPLOAD_SUCCESS': NoParams;
13
- 'SMART.MEDIA_STORE.USAGE': {
14
- count: number;
15
- size: string;
16
- };
17
- 'SMART.MEDIA_STORE.CROPS_BADGE': {
18
- count: number;
19
- };
20
- 'SMART.MEDIA_STORE.SELECT_ORIGINAL': NoParams;
21
- 'SMART.MEDIA_STORE.CREATE_CROP_HINT': NoParams;
22
- 'SMART.MEDIA_STORE.DELETE_HINT': NoParams;
23
- 'SMART.MEDIA_STORE.DELETE_SUCCESS': NoParams;
24
- 'SMART.MEDIA_STORE.DELETE_ERROR': NoParams;
25
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.TITLE': NoParams;
26
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.DESCRIPTION': NoParams;
27
- 'SMART.MEDIA_STORE.DELETE_CONFIRM.BUTTON': NoParams;
28
- 'SMART.MEDIA_STORE.CREATE_CROP.TITLE': NoParams;
29
- 'SMART.MEDIA_STORE.CREATE_CROP.CLOSE': NoParams;
30
- 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_LABEL': NoParams;
31
- 'SMART.MEDIA_STORE.CREATE_CROP.SIZE_LABEL': NoParams;
32
- 'SMART.MEDIA_STORE.CREATE_CROP.WIDTH': NoParams;
33
- 'SMART.MEDIA_STORE.CREATE_CROP.HEIGHT': NoParams;
34
- 'SMART.MEDIA_STORE.CREATE_CROP.QUALITY_LABEL': NoParams;
35
- 'SMART.MEDIA_STORE.CREATE_CROP.CREATE_BUTTON': NoParams;
36
- 'SMART.MEDIA_STORE.CREATE_CROP.RATIO_EXISTS': NoParams;
37
- 'SMART.MEDIA_STORE.CREATE_CROP.EXISTING_LABEL': NoParams;
38
- 'SMART.MEDIA_STORE.CREATE_CROP.NO_CROPS': NoParams;
39
- 'SMART.MEDIA_STORE.CREATE_CROP.SUCCESS': NoParams;
40
- 'SMART.MEDIA_STORE.CREATE_CROP.ERROR': NoParams;
41
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_HINT': NoParams;
42
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.TITLE': NoParams;
43
- 'SMART.MEDIA_STORE.CREATE_CROP.DELETE_CONFIRM.BUTTON': NoParams;
44
- };
File without changes
File without changes
File without changes
File without changes
File without changes