@pushwoosh/smart-components-kit 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ExportCSV/ExportCsvBanner/ExportCsvBanner.js +1 -1
- package/OpenActions/components/OpenActionsSummary/OpenActionsSummary.js +1 -1
- package/PickerSort/components/PickerSortMenu/PickerSortMenu.d.ts +4 -0
- package/PickerSort/components/PickerSortMenu/PickerSortMenu.js +44 -0
- package/PickerSort/components/PickerSortMenu/index.d.ts +1 -0
- package/PickerSort/components/PickerSortMenu/index.js +1 -0
- package/PickerSort/components/PickerSortMenu/types.d.ts +12 -0
- package/PickerSort/components/PickerSortMenu/types.js +1 -0
- package/PickerSort/constants.d.ts +4 -0
- package/PickerSort/constants.js +3 -0
- package/PickerSort/helpers.d.ts +6 -0
- package/PickerSort/helpers.js +36 -0
- package/PickerSort/index.d.ts +7 -0
- package/PickerSort/index.js +5 -0
- package/PickerSort/polyglot/index.d.ts +4 -0
- package/PickerSort/polyglot/index.js +41 -0
- package/PickerSort/polyglot/messages_ar.d.ts +3 -0
- package/PickerSort/polyglot/messages_ar.js +8 -0
- package/PickerSort/polyglot/messages_bn.d.ts +3 -0
- package/PickerSort/polyglot/messages_bn.js +8 -0
- package/PickerSort/polyglot/messages_de.d.ts +3 -0
- package/PickerSort/polyglot/messages_de.js +8 -0
- package/PickerSort/polyglot/messages_en.d.ts +3 -0
- package/PickerSort/polyglot/messages_en.js +8 -0
- package/PickerSort/polyglot/messages_es.d.ts +3 -0
- package/PickerSort/polyglot/messages_es.js +8 -0
- package/PickerSort/polyglot/messages_fr.d.ts +3 -0
- package/PickerSort/polyglot/messages_fr.js +8 -0
- package/PickerSort/polyglot/messages_he.d.ts +3 -0
- package/PickerSort/polyglot/messages_he.js +8 -0
- package/PickerSort/polyglot/messages_hi.d.ts +3 -0
- package/PickerSort/polyglot/messages_hi.js +8 -0
- package/PickerSort/polyglot/messages_ja.d.ts +3 -0
- package/PickerSort/polyglot/messages_ja.js +8 -0
- package/PickerSort/polyglot/messages_ko.d.ts +3 -0
- package/PickerSort/polyglot/messages_ko.js +8 -0
- package/PickerSort/polyglot/messages_pt.d.ts +3 -0
- package/PickerSort/polyglot/messages_pt.js +8 -0
- package/PickerSort/polyglot/messages_ru.d.ts +3 -0
- package/PickerSort/polyglot/messages_ru.js +8 -0
- package/PickerSort/polyglot/messages_th.d.ts +3 -0
- package/PickerSort/polyglot/messages_th.js +8 -0
- package/PickerSort/polyglot/messages_zh.d.ts +3 -0
- package/PickerSort/polyglot/messages_zh.js +8 -0
- package/PickerSort/polyglot/types.d.ts +9 -0
- package/PickerSort/polyglot/types.js +1 -0
- package/PickerSort/types.d.ts +50 -0
- package/PickerSort/types.js +1 -0
- package/PickerSort/usePagedItems.d.ts +3 -0
- package/PickerSort/usePagedItems.js +91 -0
- package/PickerSort/usePickerSortOrder.d.ts +3 -0
- package/PickerSort/usePickerSortOrder.js +51 -0
- package/ProductUpdates/ProductUpdateCard.js +1 -1
- package/ProductUpdates/styles.d.ts +4 -2
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DropdownMenuButton, DropdownMenuItem, DropdownMenuSection } from '@pushwoosh/dumb-components';
|
|
3
|
+
import { DropdownIcon, SortIcon } from '@pushwoosh/kit-icons';
|
|
4
|
+
import { PICKER_SORT_ORDERS } from '../../constants';
|
|
5
|
+
import { ORDER_MESSAGES, useLang } from '../../polyglot';
|
|
6
|
+
/** Compact "⇅ <order> ▾" button that lets the user pick the order of a picker list. */
|
|
7
|
+
export const PickerSortMenu = ({
|
|
8
|
+
value,
|
|
9
|
+
onChange,
|
|
10
|
+
orders = PICKER_SORT_ORDERS,
|
|
11
|
+
isDisabled
|
|
12
|
+
}) => {
|
|
13
|
+
const lang = useLang();
|
|
14
|
+
return _jsx(DropdownMenuButton, {
|
|
15
|
+
color: "secondary",
|
|
16
|
+
view: "ghost",
|
|
17
|
+
size: "compact",
|
|
18
|
+
icon: _jsx(SortIcon, {
|
|
19
|
+
size: "small",
|
|
20
|
+
type: "not-sorted"
|
|
21
|
+
}),
|
|
22
|
+
rightIcon: _jsx(DropdownIcon, {
|
|
23
|
+
direction: "down",
|
|
24
|
+
size: "small"
|
|
25
|
+
}),
|
|
26
|
+
label: lang({
|
|
27
|
+
message: ORDER_MESSAGES[value]
|
|
28
|
+
}),
|
|
29
|
+
isDisabled: isDisabled,
|
|
30
|
+
menuPlacement: "bottom-end",
|
|
31
|
+
children: _jsx(DropdownMenuSection, {
|
|
32
|
+
title: lang({
|
|
33
|
+
message: 'SMART.PICKER_SORT.TITLE'
|
|
34
|
+
}),
|
|
35
|
+
children: orders.map(order => _jsx(DropdownMenuItem, {
|
|
36
|
+
isActive: order === value,
|
|
37
|
+
onClick: () => onChange(order),
|
|
38
|
+
children: lang({
|
|
39
|
+
message: ORDER_MESSAGES[order]
|
|
40
|
+
})
|
|
41
|
+
}, order))
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PickerSortMenu } from './PickerSortMenu';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PickerSortMenu } from './PickerSortMenu';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type PickerSortOrder } from '../../types';
|
|
2
|
+
/** Props of {@link PickerSortMenu}. */
|
|
3
|
+
export type PickerSortMenuProps = {
|
|
4
|
+
/** Current order. */
|
|
5
|
+
readonly value: PickerSortOrder;
|
|
6
|
+
/** Fires with the order the user picked. */
|
|
7
|
+
readonly onChange: (order: PickerSortOrder) => void;
|
|
8
|
+
/** Orders to offer; defaults to all of them. */
|
|
9
|
+
readonly orders?: readonly PickerSortOrder[];
|
|
10
|
+
/** Disable the trigger. */
|
|
11
|
+
readonly isDisabled?: boolean;
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type PickerContentType, type PickerSortOrder, type PresetListOrder } from './types';
|
|
2
|
+
/** Map a picker order to the `orderBy` / `orderDirection` of the preset `List` RPCs. */
|
|
3
|
+
export declare function toPresetListOrder(order: PickerSortOrder): PresetListOrder;
|
|
4
|
+
export declare function isPickerSortOrder(value: unknown): value is PickerSortOrder;
|
|
5
|
+
export declare function resolvePickerSortOrder(stored: unknown, defaultOrder: PickerSortOrder, supportedOrders: readonly PickerSortOrder[]): PickerSortOrder;
|
|
6
|
+
export declare function pickerSortStorageKey(userEmail: string, contentType: PickerContentType): string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { PICKER_SORT_ORDERS, PICKER_SORT_STORAGE_PREFIX } from './constants';
|
|
2
|
+
const PRESET_LIST_ORDERS = {
|
|
3
|
+
'created-desc': {
|
|
4
|
+
orderBy: 'CREATED',
|
|
5
|
+
orderDirection: 'DESC'
|
|
6
|
+
},
|
|
7
|
+
'created-asc': {
|
|
8
|
+
orderBy: 'CREATED',
|
|
9
|
+
orderDirection: 'ASC'
|
|
10
|
+
},
|
|
11
|
+
'updated-desc': {
|
|
12
|
+
orderBy: 'UPDATED',
|
|
13
|
+
orderDirection: 'DESC'
|
|
14
|
+
},
|
|
15
|
+
'name-asc': {
|
|
16
|
+
orderBy: 'NAME',
|
|
17
|
+
orderDirection: 'ASC'
|
|
18
|
+
},
|
|
19
|
+
'name-desc': {
|
|
20
|
+
orderBy: 'NAME',
|
|
21
|
+
orderDirection: 'DESC'
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
/** Map a picker order to the `orderBy` / `orderDirection` of the preset `List` RPCs. */
|
|
25
|
+
export function toPresetListOrder(order) {
|
|
26
|
+
return PRESET_LIST_ORDERS[order];
|
|
27
|
+
}
|
|
28
|
+
export function isPickerSortOrder(value) {
|
|
29
|
+
return typeof value === 'string' && PICKER_SORT_ORDERS.includes(value);
|
|
30
|
+
}
|
|
31
|
+
export function resolvePickerSortOrder(stored, defaultOrder, supportedOrders) {
|
|
32
|
+
return isPickerSortOrder(stored) && supportedOrders.includes(stored) ? stored : defaultOrder;
|
|
33
|
+
}
|
|
34
|
+
export function pickerSortStorageKey(userEmail, contentType) {
|
|
35
|
+
return `${PICKER_SORT_STORAGE_PREFIX}:${userEmail}:${contentType}`;
|
|
36
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { PickerSortMenu } from './components/PickerSortMenu';
|
|
2
|
+
export { PICKER_SORT_ORDERS } from './constants';
|
|
3
|
+
export { toPresetListOrder } from './helpers';
|
|
4
|
+
export { usePagedItems } from './usePagedItems';
|
|
5
|
+
export { usePickerSortOrder } from './usePickerSortOrder';
|
|
6
|
+
export type { PickerSortMenuProps } from './components/PickerSortMenu/types';
|
|
7
|
+
export type { LoadPagedItems, PagedItemsPage, PagedItemsState, PickerContentType, PickerSortOrder, PickerSortOrderState, PresetListOrder, UsePickerSortOrderOptions, } from './types';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { PickerSortMenu } from './components/PickerSortMenu';
|
|
2
|
+
export { PICKER_SORT_ORDERS } from './constants';
|
|
3
|
+
export { toPresetListOrder } from './helpers';
|
|
4
|
+
export { usePagedItems } from './usePagedItems';
|
|
5
|
+
export { usePickerSortOrder } from './usePickerSortOrder';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type PickerSortOrder } from '../types';
|
|
2
|
+
import { type PickerSortMessages } from './types';
|
|
3
|
+
export declare const Lang: import("react").FC<import("@pushwoosh/dumb-components/polyglot").LangProps<PickerSortMessages>>, useLang: () => (props: import("@pushwoosh/dumb-components/polyglot").LangProps<PickerSortMessages>) => string;
|
|
4
|
+
export declare const ORDER_MESSAGES: Record<PickerSortOrder, keyof PickerSortMessages>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createLang } from '@pushwoosh/dumb-components/polyglot';
|
|
2
|
+
import { messages as ar } from './messages_ar';
|
|
3
|
+
import { messages as bn } from './messages_bn';
|
|
4
|
+
import { messages as de } from './messages_de';
|
|
5
|
+
import { messages as en } from './messages_en';
|
|
6
|
+
import { messages as es } from './messages_es';
|
|
7
|
+
import { messages as fr } from './messages_fr';
|
|
8
|
+
import { messages as he } from './messages_he';
|
|
9
|
+
import { messages as hi } from './messages_hi';
|
|
10
|
+
import { messages as ja } from './messages_ja';
|
|
11
|
+
import { messages as ko } from './messages_ko';
|
|
12
|
+
import { messages as pt } from './messages_pt';
|
|
13
|
+
import { messages as ru } from './messages_ru';
|
|
14
|
+
import { messages as th } from './messages_th';
|
|
15
|
+
import { messages as zh } from './messages_zh';
|
|
16
|
+
export const {
|
|
17
|
+
Lang,
|
|
18
|
+
useLang
|
|
19
|
+
} = createLang({
|
|
20
|
+
ar,
|
|
21
|
+
bn,
|
|
22
|
+
de,
|
|
23
|
+
en,
|
|
24
|
+
es,
|
|
25
|
+
fr,
|
|
26
|
+
he,
|
|
27
|
+
hi,
|
|
28
|
+
ja,
|
|
29
|
+
ko,
|
|
30
|
+
pt,
|
|
31
|
+
ru,
|
|
32
|
+
th,
|
|
33
|
+
zh
|
|
34
|
+
});
|
|
35
|
+
export const ORDER_MESSAGES = {
|
|
36
|
+
'created-desc': 'SMART.PICKER_SORT.ORDER.CREATED_DESC',
|
|
37
|
+
'created-asc': 'SMART.PICKER_SORT.ORDER.CREATED_ASC',
|
|
38
|
+
'updated-desc': 'SMART.PICKER_SORT.ORDER.UPDATED_DESC',
|
|
39
|
+
'name-asc': 'SMART.PICKER_SORT.ORDER.NAME_ASC',
|
|
40
|
+
'name-desc': 'SMART.PICKER_SORT.ORDER.NAME_DESC'
|
|
41
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'ترتيب حسب',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'الأحدث أولاً',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'الأقدم أولاً',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'المحدّثة مؤخرًا',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'الاسم أ→ي',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'الاسم ي→أ'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'সাজান',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'নতুন আগে',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'পুরনো আগে',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'সম্প্রতি আপডেট করা',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'নাম A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'নাম Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'Sortieren nach',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'Neueste zuerst',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'Älteste zuerst',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'Zuletzt aktualisiert',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'Name A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'Name Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'Sort by',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'Newest first',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'Oldest first',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'Recently updated',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'Name A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'Name Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'Ordenar por',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'Más recientes primero',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'Más antiguos primero',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'Actualizados recientemente',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'Nombre A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'Nombre Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'Trier par',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'Plus récents d’abord',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'Plus anciens d’abord',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'Modifiés récemment',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'Nom A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'Nom Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'מיון לפי',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'החדשים קודם',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'הישנים קודם',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'עודכנו לאחרונה',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'שם א→ת',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'שם ת→א'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'क्रमबद्ध करें',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'नए पहले',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'पुराने पहले',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'हाल ही में अपडेट किए गए',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'नाम A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'नाम Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': '並べ替え',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': '新しい順',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': '古い順',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': '最近更新した順',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': '名前 A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': '名前 Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': '정렬',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': '최신순',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': '오래된순',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': '최근 업데이트순',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': '이름 A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': '이름 Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'Ordenar por',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'Mais recentes primeiro',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'Mais antigos primeiro',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'Atualizados recentemente',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'Nome A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'Nome Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'Сортировка',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'Сначала новые',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'Сначала старые',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'Недавно изменённые',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'Название А→Я',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'Название Я→А'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': 'เรียงตาม',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': 'ใหม่สุดก่อน',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': 'เก่าสุดก่อน',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': 'อัปเดตล่าสุด',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': 'ชื่อ A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': 'ชื่อ Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const messages = {
|
|
2
|
+
'SMART.PICKER_SORT.TITLE': '排序方式',
|
|
3
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': '最新优先',
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': '最早优先',
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': '最近更新',
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': '名称 A→Z',
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': '名称 Z→A'
|
|
8
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NoParams } from '@pushwoosh/dumb-components/polyglot';
|
|
2
|
+
export type PickerSortMessages = {
|
|
3
|
+
'SMART.PICKER_SORT.TITLE': NoParams;
|
|
4
|
+
'SMART.PICKER_SORT.ORDER.CREATED_DESC': NoParams;
|
|
5
|
+
'SMART.PICKER_SORT.ORDER.CREATED_ASC': NoParams;
|
|
6
|
+
'SMART.PICKER_SORT.ORDER.UPDATED_DESC': NoParams;
|
|
7
|
+
'SMART.PICKER_SORT.ORDER.NAME_ASC': NoParams;
|
|
8
|
+
'SMART.PICKER_SORT.ORDER.NAME_DESC': NoParams;
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type ListPresetsRequest_OrderBy, type ListPresetsRequest_OrderDirection } from '@pushwoosh/rpc-v2-http-api-data/presets';
|
|
2
|
+
/** Order a picker can list its items in. */
|
|
3
|
+
export type PickerSortOrder = 'created-desc' | 'created-asc' | 'updated-desc' | 'name-asc' | 'name-desc';
|
|
4
|
+
/** Content kind a picker lists; the chosen order is remembered per user and per kind. */
|
|
5
|
+
export type PickerContentType = 'push' | 'sms' | 'email' | 'line' | 'kakao' | 'inbox' | 'whatsapp' | 'viber' | 'richmedia' | 'popup';
|
|
6
|
+
/** `orderBy` / `orderDirection` pair of `presets.List`; `smsPresets`, `linePresets`, `kakaoPresets` and `appInboxPresets` share the same enums. */
|
|
7
|
+
export type PresetListOrder = {
|
|
8
|
+
readonly orderBy: ListPresetsRequest_OrderBy;
|
|
9
|
+
readonly orderDirection: ListPresetsRequest_OrderDirection;
|
|
10
|
+
};
|
|
11
|
+
/** Options of {@link usePickerSortOrder}. */
|
|
12
|
+
export type UsePickerSortOrderOptions = {
|
|
13
|
+
/** Content kind the picker lists. */
|
|
14
|
+
readonly contentType: PickerContentType;
|
|
15
|
+
/** Order shown until the user picks one, and whenever the stored one is not supported here. */
|
|
16
|
+
readonly defaultOrder: PickerSortOrder;
|
|
17
|
+
/** Orders this picker can request; defaults to all of them. */
|
|
18
|
+
readonly supportedOrders?: readonly PickerSortOrder[];
|
|
19
|
+
};
|
|
20
|
+
/** Result of {@link usePickerSortOrder}. */
|
|
21
|
+
export type PickerSortOrderState = {
|
|
22
|
+
/** Order to request. */
|
|
23
|
+
readonly order: PickerSortOrder;
|
|
24
|
+
/** Remember a new order for this user and content kind. */
|
|
25
|
+
readonly setOrder: (order: PickerSortOrder) => void;
|
|
26
|
+
/** `false` until the stored choice is read; load the first page only after that to avoid a double request. */
|
|
27
|
+
readonly isReady: boolean;
|
|
28
|
+
};
|
|
29
|
+
/** One page returned by a {@link usePagedItems} loader. */
|
|
30
|
+
export type PagedItemsPage<T> = {
|
|
31
|
+
/** Items of the requested page. */
|
|
32
|
+
readonly items: T[];
|
|
33
|
+
/** Whether a next page exists. */
|
|
34
|
+
readonly hasMore: boolean;
|
|
35
|
+
};
|
|
36
|
+
/** Loads one zero-based page. */
|
|
37
|
+
export type LoadPagedItems<T> = (page: number) => Promise<PagedItemsPage<T>>;
|
|
38
|
+
/** Result of {@link usePagedItems}. */
|
|
39
|
+
export type PagedItemsState<T> = {
|
|
40
|
+
/** Items of all pages loaded so far. */
|
|
41
|
+
readonly items: T[];
|
|
42
|
+
/** A page is being loaded. */
|
|
43
|
+
readonly isLoading: boolean;
|
|
44
|
+
/** A next page exists. */
|
|
45
|
+
readonly hasMore: boolean;
|
|
46
|
+
/** The last page request failed; `loadMore` retries it. */
|
|
47
|
+
readonly isError: boolean;
|
|
48
|
+
/** Load the next page; no-op while loading or when there is nothing more. Wire it to `onMenuScrollToBottom`. */
|
|
49
|
+
readonly loadMore: () => void;
|
|
50
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type LoadPagedItems, type PagedItemsState } from './types';
|
|
2
|
+
/** Accumulates pages of a server-sorted list for infinite scroll; a new `resetKey` restarts from page 0. */
|
|
3
|
+
export declare function usePagedItems<T>(loadPage: LoadPagedItems<T>, resetKey: string, enabled?: boolean): PagedItemsState<T>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { usePersistentFunction } from '@pushwoosh/kit-helpers';
|
|
3
|
+
/** Accumulates pages of a server-sorted list for infinite scroll; a new `resetKey` restarts from page 0. */
|
|
4
|
+
export function usePagedItems(loadPage, resetKey, enabled = true) {
|
|
5
|
+
const [state, setState] = useState({
|
|
6
|
+
items: [],
|
|
7
|
+
hasMore: true,
|
|
8
|
+
isLoading: enabled,
|
|
9
|
+
isError: false
|
|
10
|
+
});
|
|
11
|
+
const load = usePersistentFunction(loadPage);
|
|
12
|
+
const runRef = useRef(0);
|
|
13
|
+
const cursorRef = useRef({
|
|
14
|
+
next: 0,
|
|
15
|
+
hasMore: true,
|
|
16
|
+
isFetching: false
|
|
17
|
+
});
|
|
18
|
+
const fetchPage = useCallback(page => {
|
|
19
|
+
const run = runRef.current;
|
|
20
|
+
cursorRef.current.isFetching = true;
|
|
21
|
+
setState(prev => ({
|
|
22
|
+
...prev,
|
|
23
|
+
isLoading: true,
|
|
24
|
+
isError: false
|
|
25
|
+
}));
|
|
26
|
+
load(page).then(({
|
|
27
|
+
items,
|
|
28
|
+
hasMore
|
|
29
|
+
}) => {
|
|
30
|
+
if (run !== runRef.current) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
cursorRef.current = {
|
|
34
|
+
next: page + 1,
|
|
35
|
+
hasMore,
|
|
36
|
+
isFetching: false
|
|
37
|
+
};
|
|
38
|
+
setState(prev => ({
|
|
39
|
+
items: page === 0 ? items : [...prev.items, ...items],
|
|
40
|
+
hasMore,
|
|
41
|
+
isLoading: false,
|
|
42
|
+
isError: false
|
|
43
|
+
}));
|
|
44
|
+
}).catch(() => {
|
|
45
|
+
if (run === runRef.current) {
|
|
46
|
+
cursorRef.current.isFetching = false;
|
|
47
|
+
setState(prev => ({
|
|
48
|
+
...prev,
|
|
49
|
+
isLoading: false,
|
|
50
|
+
isError: true
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}, [load]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
cursorRef.current = {
|
|
57
|
+
next: 0,
|
|
58
|
+
hasMore: true,
|
|
59
|
+
isFetching: false
|
|
60
|
+
};
|
|
61
|
+
setState({
|
|
62
|
+
items: [],
|
|
63
|
+
hasMore: true,
|
|
64
|
+
isLoading: enabled,
|
|
65
|
+
isError: false
|
|
66
|
+
});
|
|
67
|
+
if (enabled) {
|
|
68
|
+
fetchPage(0);
|
|
69
|
+
}
|
|
70
|
+
return () => {
|
|
71
|
+
runRef.current += 1;
|
|
72
|
+
};
|
|
73
|
+
}, [resetKey, enabled, fetchPage]);
|
|
74
|
+
const loadMore = useCallback(() => {
|
|
75
|
+
const {
|
|
76
|
+
next,
|
|
77
|
+
hasMore,
|
|
78
|
+
isFetching
|
|
79
|
+
} = cursorRef.current;
|
|
80
|
+
if (enabled && hasMore && !isFetching) {
|
|
81
|
+
fetchPage(next);
|
|
82
|
+
}
|
|
83
|
+
}, [enabled, fetchPage]);
|
|
84
|
+
return {
|
|
85
|
+
items: state.items,
|
|
86
|
+
isLoading: state.isLoading,
|
|
87
|
+
hasMore: state.hasMore,
|
|
88
|
+
isError: state.isError,
|
|
89
|
+
loadMore
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type PickerSortOrderState, type UsePickerSortOrderOptions } from './types';
|
|
2
|
+
/** Order the user chose for pickers of one content kind, kept in the shell key-value storage. */
|
|
3
|
+
export declare function usePickerSortOrder({ contentType, defaultOrder, supportedOrders, }: UsePickerSortOrderOptions): PickerSortOrderState;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { useSession, useSPAContext } from '@pushwoosh/spa-context';
|
|
3
|
+
import { PICKER_SORT_ORDERS } from './constants';
|
|
4
|
+
import { pickerSortStorageKey, resolvePickerSortOrder } from './helpers';
|
|
5
|
+
/** Order the user chose for pickers of one content kind, kept in the shell key-value storage. */
|
|
6
|
+
export function usePickerSortOrder({
|
|
7
|
+
contentType,
|
|
8
|
+
defaultOrder,
|
|
9
|
+
supportedOrders = PICKER_SORT_ORDERS
|
|
10
|
+
}) {
|
|
11
|
+
const {
|
|
12
|
+
keyValueStorage
|
|
13
|
+
} = useSPAContext();
|
|
14
|
+
const {
|
|
15
|
+
user
|
|
16
|
+
} = useSession();
|
|
17
|
+
const storageKey = pickerSortStorageKey(user.email, contentType);
|
|
18
|
+
const [stored, setStored] = useState(null);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
let isActive = true;
|
|
21
|
+
let isChanged = false;
|
|
22
|
+
const unsubscribe = keyValueStorage.subscribe(storageKey, change => {
|
|
23
|
+
isChanged = true;
|
|
24
|
+
setStored({
|
|
25
|
+
key: storageKey,
|
|
26
|
+
value: change.value
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
keyValueStorage.get(storageKey).catch(() => undefined).then(value => {
|
|
30
|
+
if (isActive && !isChanged) {
|
|
31
|
+
setStored({
|
|
32
|
+
key: storageKey,
|
|
33
|
+
value
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return () => {
|
|
38
|
+
isActive = false;
|
|
39
|
+
unsubscribe();
|
|
40
|
+
};
|
|
41
|
+
}, [keyValueStorage, storageKey]);
|
|
42
|
+
const setOrder = useCallback(order => {
|
|
43
|
+
keyValueStorage.set(storageKey, order).catch(() => undefined);
|
|
44
|
+
}, [keyValueStorage, storageKey]);
|
|
45
|
+
const isReady = stored?.key === storageKey;
|
|
46
|
+
return {
|
|
47
|
+
order: resolvePickerSortOrder(isReady ? stored.value : undefined, defaultOrder, supportedOrders),
|
|
48
|
+
setOrder,
|
|
49
|
+
isReady
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -46,7 +46,7 @@ export function ProductUpdateCard({
|
|
|
46
46
|
children: [_jsx(Text, {
|
|
47
47
|
"$variant": "footnote",
|
|
48
48
|
"$color": Color.LOCKED,
|
|
49
|
-
"$
|
|
49
|
+
"$textTransform": "uppercase",
|
|
50
50
|
children: formatUpdateDate(update.created, language)
|
|
51
51
|
}), update.status === ALERT_STATUS_UNREAD && _jsx(Badge, {
|
|
52
52
|
color: "sky",
|
|
@@ -8,7 +8,8 @@ export declare const List: import("styled-components/dist/types").IStyledCompone
|
|
|
8
8
|
style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
|
|
9
9
|
}, {
|
|
10
10
|
$color?: string;
|
|
11
|
-
$
|
|
11
|
+
$textAlign?: import("react").CSSProperties["textAlign"];
|
|
12
|
+
$textTransform?: import("react").CSSProperties["textTransform"];
|
|
12
13
|
$ellipsis?: boolean;
|
|
13
14
|
$variant?: import("@pushwoosh/kit-typography").TypographyVariant;
|
|
14
15
|
}>, "as" | "forwardedAs"> & {
|
|
@@ -26,7 +27,8 @@ export declare const List: import("styled-components/dist/types").IStyledCompone
|
|
|
26
27
|
style?: import("react").CSSProperties | import("styled-components/dist/types").CSSPropertiesWithVars | undefined;
|
|
27
28
|
}, {
|
|
28
29
|
$color?: string;
|
|
29
|
-
$
|
|
30
|
+
$textAlign?: import("react").CSSProperties["textAlign"];
|
|
31
|
+
$textTransform?: import("react").CSSProperties["textTransform"];
|
|
30
32
|
$ellipsis?: boolean;
|
|
31
33
|
$variant?: import("@pushwoosh/kit-typography").TypographyVariant;
|
|
32
34
|
}>, "as" | "forwardedAs"> & {
|
package/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export * from './ResendModal';
|
|
|
15
15
|
export * from './RichMessageEditorSmart';
|
|
16
16
|
export * from './Table';
|
|
17
17
|
export * from './OpenActions';
|
|
18
|
+
export * from './PickerSort';
|
|
18
19
|
export * from './SystemParcel';
|
|
19
20
|
export * from './ModalCloningJourney';
|
|
20
21
|
export * from './types';
|
package/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export * from './ResendModal';
|
|
|
15
15
|
export * from './RichMessageEditorSmart';
|
|
16
16
|
export * from './Table';
|
|
17
17
|
export * from './OpenActions';
|
|
18
|
+
export * from './PickerSort';
|
|
18
19
|
export * from './SystemParcel';
|
|
19
20
|
export * from './ModalCloningJourney';
|
|
20
21
|
export * from './types';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pushwoosh/smart-components-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Stateful, data-connected React components shared by Pushwoosh micro-frontends",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@floating-ui/react-dom": "^2.1.2",
|
|
20
|
-
"@pushwoosh/dumb-components": "^2.11.
|
|
20
|
+
"@pushwoosh/dumb-components": "^2.11.4",
|
|
21
21
|
"@pushwoosh/kit-constants": "^2.1.1",
|
|
22
22
|
"@pushwoosh/kit-helpers": "^4.14.0",
|
|
23
23
|
"@pushwoosh/kit-icons": "^2.3.10",
|
|
24
|
-
"@pushwoosh/kit-typography": "^1.
|
|
24
|
+
"@pushwoosh/kit-typography": "^1.11.0",
|
|
25
25
|
"@pushwoosh/rpc-v2-http-api-data": "^0.2.389",
|
|
26
26
|
"@pushwoosh/spa-context": "^3.0.0",
|
|
27
27
|
"idb-keyval": "^6.2.2",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"react-router-dom": "^5.3.4"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@pushwoosh/frontend-builder-engine": "^3.1.
|
|
33
|
+
"@pushwoosh/frontend-builder-engine": "^3.1.6",
|
|
34
34
|
"@svgr/webpack": "^8.1.0",
|
|
35
35
|
"@types/node": "^24.19.1",
|
|
36
36
|
"@types/react": "^18.3.31",
|