@pushwoosh/smart-components-kit 1.1.6 → 1.1.8
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/DynamicContentPickerForm/SimpleDynamicContentPickerFormSmart.d.ts +2 -0
- package/DynamicContentPickerForm/SimpleDynamicContentPickerFormSmart.js +14 -10
- package/DynamicContentPickerForm/index.d.ts +1 -1
- package/DynamicContentPickerForm/types.d.ts +10 -0
- package/DynamicContentPickerForm/utils.d.ts +2 -1
- package/DynamicContentPickerForm/utils.js +14 -0
- package/LanguagesSelector/LanguagesSelectFormLoader.js +4 -4
- package/LanguagesSelector/utils.d.ts +7 -0
- package/LanguagesSelector/utils.js +24 -4
- package/RichMessageEditorSmart/NewDynamicContentForm.d.ts +2 -0
- package/RichMessageEditorSmart/NewDynamicContentForm.js +4 -2
- package/RichMessageEditorSmart/RichMessageEditorSmart.d.ts +4 -1
- package/RichMessageEditorSmart/RichMessageEditorSmart.js +9 -4
- package/package.json +1 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type FC, type PropsWithChildren } from 'react';
|
|
2
2
|
import { type DynamicContent } from '@pushwoosh/dumb-components/RichMessageEditor/slate/types';
|
|
3
|
+
import type { SystemVariable } from './types';
|
|
3
4
|
type SimpleDynamicContentPickerFormSmartProps = {
|
|
4
5
|
dc?: DynamicContent;
|
|
5
6
|
onChange: (dc: DynamicContent) => void;
|
|
6
7
|
update?: () => void;
|
|
8
|
+
systemVariables?: SystemVariable[];
|
|
7
9
|
};
|
|
8
10
|
export declare const SimpleDynamicContentPickerFormSmart: FC<PropsWithChildren<SimpleDynamicContentPickerFormSmartProps>>;
|
|
9
11
|
export {};
|
|
@@ -5,6 +5,7 @@ import { Horizontal, Vertical } from '@pushwoosh/kit-helpers';
|
|
|
5
5
|
import { useDynamicContentTags } from './hooks';
|
|
6
6
|
import { useLang } from './polyglot';
|
|
7
7
|
import { SimpleTagPickerDiv } from './styled';
|
|
8
|
+
import { buildOptions } from './utils';
|
|
8
9
|
const defaultDynamicContent = {
|
|
9
10
|
tagName: '',
|
|
10
11
|
modifier: 'regular',
|
|
@@ -14,6 +15,7 @@ export const SimpleDynamicContentPickerFormSmart = ({
|
|
|
14
15
|
dc = defaultDynamicContent,
|
|
15
16
|
onChange,
|
|
16
17
|
update,
|
|
18
|
+
systemVariables,
|
|
17
19
|
children
|
|
18
20
|
}) => {
|
|
19
21
|
const lang = useLang();
|
|
@@ -34,9 +36,10 @@ export const SimpleDynamicContentPickerFormSmart = ({
|
|
|
34
36
|
})
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
+
const options = buildOptions(systemVariables ?? [], asyncResult.value || []);
|
|
40
|
+
const selectedTag = options.find(option => option.name === dc.tagName) || {
|
|
39
41
|
name: '',
|
|
42
|
+
label: '',
|
|
40
43
|
modifiers: ['regular']
|
|
41
44
|
};
|
|
42
45
|
return _jsxs(SimpleTagPickerDiv, {
|
|
@@ -51,18 +54,19 @@ export const SimpleDynamicContentPickerFormSmart = ({
|
|
|
51
54
|
menuPlacement: "auto",
|
|
52
55
|
value: {
|
|
53
56
|
value: dc.tagName,
|
|
54
|
-
label: dc.tagName
|
|
57
|
+
label: selectedTag.name ? selectedTag.label : dc.tagName
|
|
55
58
|
},
|
|
56
59
|
onChange: option => {
|
|
60
|
+
const picked = options.find(item => item.name === option.value);
|
|
57
61
|
onChange({
|
|
58
62
|
tagName: option.value,
|
|
59
|
-
modifier:
|
|
63
|
+
modifier: (picked === null || picked === void 0 ? void 0 : picked.modifiers[0]) ?? 'regular',
|
|
60
64
|
defaultValue: ''
|
|
61
65
|
});
|
|
62
66
|
},
|
|
63
|
-
options:
|
|
64
|
-
value:
|
|
65
|
-
label:
|
|
67
|
+
options: options.map(option => ({
|
|
68
|
+
value: option.name,
|
|
69
|
+
label: option.label
|
|
66
70
|
}))
|
|
67
71
|
}), _jsx(Select, {
|
|
68
72
|
width: "auto",
|
|
@@ -77,11 +81,11 @@ export const SimpleDynamicContentPickerFormSmart = ({
|
|
|
77
81
|
modifier: option.value
|
|
78
82
|
});
|
|
79
83
|
},
|
|
80
|
-
options:
|
|
84
|
+
options: selectedTag.modifiers.map(modifier => ({
|
|
81
85
|
value: modifier,
|
|
82
86
|
label: modifier
|
|
83
87
|
})),
|
|
84
|
-
isDisabled: !
|
|
88
|
+
isDisabled: !selectedTag.name
|
|
85
89
|
})]
|
|
86
90
|
})
|
|
87
91
|
}), _jsx(FieldBox, {
|
|
@@ -96,7 +100,7 @@ export const SimpleDynamicContentPickerFormSmart = ({
|
|
|
96
100
|
defaultValue: e.target.value
|
|
97
101
|
});
|
|
98
102
|
},
|
|
99
|
-
disabled: !
|
|
103
|
+
disabled: !selectedTag.name
|
|
100
104
|
})
|
|
101
105
|
}), children]
|
|
102
106
|
});
|
|
@@ -2,6 +2,16 @@ import type { Tag } from '@pushwoosh/rpc-v2-http-api-data/tags';
|
|
|
2
2
|
export type FullTagData = Tag & {
|
|
3
3
|
modifiers: string[];
|
|
4
4
|
};
|
|
5
|
+
export type SystemVariable = {
|
|
6
|
+
name: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
modifiers?: string[];
|
|
9
|
+
};
|
|
10
|
+
export type PickerOption = {
|
|
11
|
+
name: string;
|
|
12
|
+
label: string;
|
|
13
|
+
modifiers: string[];
|
|
14
|
+
};
|
|
5
15
|
export type TagDynamicContent = {
|
|
6
16
|
kind: 'tag';
|
|
7
17
|
dc: {
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { type VariedDynamicContent } from './types';
|
|
1
|
+
import { type FullTagData, type PickerOption, type SystemVariable, type VariedDynamicContent } from './types';
|
|
2
|
+
export declare function buildOptions(systemVariables: SystemVariable[], tags: FullTagData[]): PickerOption[];
|
|
2
3
|
export declare function createDefaultDynamicContent(kind: 'tag' | 'event' | 'customText'): VariedDynamicContent;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
export function buildOptions(systemVariables, tags) {
|
|
2
|
+
const taken = new Set(systemVariables.map(v => v.name));
|
|
3
|
+
const system = systemVariables.map(v => ({
|
|
4
|
+
name: v.name,
|
|
5
|
+
label: v.label ?? v.name,
|
|
6
|
+
modifiers: v.modifiers ?? ['regular']
|
|
7
|
+
}));
|
|
8
|
+
const rest = tags.filter(tag => !taken.has(tag.name)).map(tag => ({
|
|
9
|
+
name: tag.name,
|
|
10
|
+
label: tag.name,
|
|
11
|
+
modifiers: tag.modifiers
|
|
12
|
+
}));
|
|
13
|
+
return [...system, ...rest];
|
|
14
|
+
}
|
|
1
15
|
export function createDefaultDynamicContent(kind) {
|
|
2
16
|
switch (kind) {
|
|
3
17
|
case 'tag':
|
|
@@ -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
|
-
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
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;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
2
|
import { type DynamicContent } from '@pushwoosh/dumb-components/RichMessageEditor/slate/types';
|
|
3
|
+
import { type SystemVariable } from '../DynamicContentPickerForm';
|
|
3
4
|
type NewDynamicContentFormProps = {
|
|
4
5
|
update?: () => void;
|
|
5
6
|
onSubmit: (dc: DynamicContent) => void;
|
|
7
|
+
systemVariables?: SystemVariable[];
|
|
6
8
|
};
|
|
7
9
|
export declare const NewDynamicContentForm: FC<NewDynamicContentFormProps>;
|
|
8
10
|
export {};
|
|
@@ -2,11 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Button } from '@pushwoosh/dumb-components';
|
|
4
4
|
import { Horizontal } from '@pushwoosh/kit-helpers';
|
|
5
|
-
import { SimpleDynamicContentPickerFormSmart } from '../DynamicContentPickerForm';
|
|
6
5
|
import { useLang } from './polyglot';
|
|
6
|
+
import { SimpleDynamicContentPickerFormSmart } from '../DynamicContentPickerForm';
|
|
7
7
|
export const NewDynamicContentForm = ({
|
|
8
8
|
update,
|
|
9
|
-
onSubmit
|
|
9
|
+
onSubmit,
|
|
10
|
+
systemVariables
|
|
10
11
|
}) => {
|
|
11
12
|
const [dc, setDc] = useState();
|
|
12
13
|
const lang = useLang();
|
|
@@ -14,6 +15,7 @@ export const NewDynamicContentForm = ({
|
|
|
14
15
|
dc: dc,
|
|
15
16
|
onChange: setDc,
|
|
16
17
|
update: update,
|
|
18
|
+
systemVariables: systemVariables,
|
|
17
19
|
children: _jsx(Horizontal, {
|
|
18
20
|
"$justifyContent": "end",
|
|
19
21
|
children: _jsx(Button, {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
2
|
import { type RichMessageEditorProps } from '@pushwoosh/dumb-components/RichMessageEditor/RichMessageEditor.types';
|
|
3
|
-
type
|
|
3
|
+
import { type SystemVariable } from '../DynamicContentPickerForm';
|
|
4
|
+
type RichMessageEditorSmartProps = Omit<RichMessageEditorProps, 'renderDynamicContent'> & {
|
|
5
|
+
systemVariables?: SystemVariable[];
|
|
6
|
+
};
|
|
4
7
|
export declare const RichMessageEditorSmart: FC<RichMessageEditorSmartProps>;
|
|
5
8
|
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { RichMessageEditor } from '@pushwoosh/dumb-components';
|
|
3
|
-
import { SimpleDynamicContentPickerFormSmart } from '../DynamicContentPickerForm';
|
|
4
3
|
import { NewDynamicContentForm } from './NewDynamicContentForm';
|
|
5
|
-
|
|
4
|
+
import { SimpleDynamicContentPickerFormSmart } from '../DynamicContentPickerForm';
|
|
5
|
+
export const RichMessageEditorSmart = ({
|
|
6
|
+
systemVariables,
|
|
7
|
+
...props
|
|
8
|
+
}) => {
|
|
6
9
|
return _jsx(RichMessageEditor, {
|
|
7
10
|
...props,
|
|
8
11
|
renderDynamicContent: ({
|
|
@@ -12,10 +15,12 @@ export const RichMessageEditorSmart = props => {
|
|
|
12
15
|
}) => dc ? _jsx(SimpleDynamicContentPickerFormSmart, {
|
|
13
16
|
dc: dc,
|
|
14
17
|
onChange: onChange,
|
|
15
|
-
update: update
|
|
18
|
+
update: update,
|
|
19
|
+
systemVariables: systemVariables
|
|
16
20
|
}) : _jsx(NewDynamicContentForm, {
|
|
17
21
|
update: update,
|
|
18
|
-
onSubmit: onChange
|
|
22
|
+
onSubmit: onChange,
|
|
23
|
+
systemVariables: systemVariables
|
|
19
24
|
})
|
|
20
25
|
});
|
|
21
26
|
};
|
package/package.json
CHANGED