@nyaruka/temba-components 0.120.7 → 0.121.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/CHANGELOG.md +9 -1
- package/dist/temba-components.js +140 -140
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/completion/Completion.js +1 -2
- package/out-tsc/src/completion/Completion.js.map +1 -1
- package/out-tsc/src/completion/helpers.js +9 -5
- package/out-tsc/src/completion/helpers.js.map +1 -1
- package/out-tsc/src/select/Select.js +1 -1
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/store/AppState.js +91 -0
- package/out-tsc/src/store/AppState.js.map +1 -0
- package/out-tsc/src/store/Store.js +19 -14
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/test/utils.test.js +2 -1
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +5 -2
- package/rollup.components.mjs +7 -0
- package/src/completion/Completion.ts +1 -7
- package/src/completion/helpers.ts +14 -10
- package/src/select/Select.ts +0 -1
- package/src/store/AppState.ts +188 -0
- package/src/store/Store.ts +20 -55
- package/src/store/flow-definition.d.ts +139 -0
- package/test/utils.test.ts +2 -2
- package/test-assets/store/workspace.json +14 -0
- package/tsconfig.json +1 -1
- package/web-dev-server.config.mjs +14 -0
- package/web-test-runner.config.mjs +10 -1
package/src/store/Store.ts
CHANGED
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
KeyedAssets,
|
|
19
19
|
CustomEventType,
|
|
20
20
|
Workspace,
|
|
21
|
-
User,
|
|
22
21
|
Shortcut
|
|
23
22
|
} from '../interfaces';
|
|
24
23
|
import { RapidElement } from '../RapidElement';
|
|
@@ -29,6 +28,8 @@ import { configureLocalization } from '@lit/localize';
|
|
|
29
28
|
import { sourceLocale, targetLocales } from '../locales/locale-codes';
|
|
30
29
|
import { StoreMonitorElement } from './StoreMonitorElement';
|
|
31
30
|
import { getFullName } from '../user/TembaUser';
|
|
31
|
+
import app, { AppState } from './AppState';
|
|
32
|
+
import { StoreApi } from 'zustand/vanilla';
|
|
32
33
|
|
|
33
34
|
const { setLocale } = configureLocalization({
|
|
34
35
|
sourceLocale,
|
|
@@ -36,6 +37,10 @@ const { setLocale } = configureLocalization({
|
|
|
36
37
|
loadLocale: (locale) => import(`./locales/${locale}.js`)
|
|
37
38
|
});
|
|
38
39
|
|
|
40
|
+
export const getStore = () => {
|
|
41
|
+
return document.querySelector('temba-store') as Store;
|
|
42
|
+
};
|
|
43
|
+
|
|
39
44
|
export class Store extends RapidElement {
|
|
40
45
|
public static get styles() {
|
|
41
46
|
return css`
|
|
@@ -102,10 +107,8 @@ export class Store extends RapidElement {
|
|
|
102
107
|
private groups: { [uuid: string]: ContactGroup } = {};
|
|
103
108
|
private shortcuts: Shortcut[] = [];
|
|
104
109
|
private languages: any = {};
|
|
105
|
-
private users: User[] = [];
|
|
106
110
|
private workspace: Workspace;
|
|
107
111
|
private featuredFields: ContactField[] = [];
|
|
108
|
-
private flowContents: FlowContents;
|
|
109
112
|
|
|
110
113
|
// http promise to monitor for completeness
|
|
111
114
|
public initialHttpComplete: Promise<void | WebResponse[]>;
|
|
@@ -146,6 +149,7 @@ export class Store extends RapidElement {
|
|
|
146
149
|
}
|
|
147
150
|
|
|
148
151
|
public reset() {
|
|
152
|
+
const appState = this.getState();
|
|
149
153
|
this.ready = false;
|
|
150
154
|
this.clearCache();
|
|
151
155
|
this.settings = JSON.parse(getCookie('settings') || '{}');
|
|
@@ -188,6 +192,7 @@ export class Store extends RapidElement {
|
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
if (this.languagesEndpoint) {
|
|
195
|
+
appState.fetchAllLanguages(this.languagesEndpoint);
|
|
191
196
|
fetches.push(
|
|
192
197
|
getAssets(this.languagesEndpoint).then((results: any[]) => {
|
|
193
198
|
// convert array of objects to lookup
|
|
@@ -214,6 +219,7 @@ export class Store extends RapidElement {
|
|
|
214
219
|
}
|
|
215
220
|
|
|
216
221
|
if (this.workspaceEndpoint) {
|
|
222
|
+
appState.fetchWorkspace(this.workspaceEndpoint);
|
|
217
223
|
fetches.push(
|
|
218
224
|
getUrl(this.workspaceEndpoint).then((response: WebResponse) => {
|
|
219
225
|
this.workspace = response.json;
|
|
@@ -617,61 +623,20 @@ export class Store extends RapidElement {
|
|
|
617
623
|
}
|
|
618
624
|
}
|
|
619
625
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
this.flowContents.info = info;
|
|
626
|
+
public getCompletions(type: string) {
|
|
627
|
+
const info = this.getState().flow.info;
|
|
628
|
+
if (type === 'results') {
|
|
629
|
+
return info.results.map((result) => result.key);
|
|
630
|
+
} else if (type === 'locals') {
|
|
631
|
+
return info.locals;
|
|
632
|
+
}
|
|
628
633
|
}
|
|
629
634
|
|
|
630
|
-
public
|
|
631
|
-
|
|
632
|
-
revision = 'latest'
|
|
633
|
-
): Promise<FlowContents> {
|
|
634
|
-
const response = await getUrl(
|
|
635
|
-
`/flow/revisions/${flowUUID}/${revision}/?version=14.3`
|
|
636
|
-
);
|
|
637
|
-
this.flowContents = response.json;
|
|
638
|
-
return this.flowContents;
|
|
635
|
+
public getApp(): StoreApi<AppState> {
|
|
636
|
+
return app;
|
|
639
637
|
}
|
|
640
638
|
|
|
641
|
-
public
|
|
642
|
-
return
|
|
639
|
+
public getState(): AppState {
|
|
640
|
+
return app.getState();
|
|
643
641
|
}
|
|
644
642
|
}
|
|
645
|
-
|
|
646
|
-
export interface InfoResult {
|
|
647
|
-
key: string;
|
|
648
|
-
name: string;
|
|
649
|
-
categories: string[];
|
|
650
|
-
node_uuids: string[];
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
export interface ObjectRef {
|
|
654
|
-
uuid: string;
|
|
655
|
-
name: string;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
export interface TypedObjectRef extends ObjectRef {
|
|
659
|
-
type: string;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
export interface Language {
|
|
663
|
-
code: string;
|
|
664
|
-
name: string;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
export interface FlowInfo {
|
|
668
|
-
results: InfoResult[];
|
|
669
|
-
dependencies: TypedObjectRef[];
|
|
670
|
-
counts: { nodes: number; languages: number };
|
|
671
|
-
locals: string[];
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
export interface FlowContents {
|
|
675
|
-
definition: any;
|
|
676
|
-
info: FlowInfo;
|
|
677
|
-
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export type LocalizationMap = Record<string, Record<string, any>>;
|
|
2
|
+
|
|
3
|
+
export type FlowTypes =
|
|
4
|
+
| 'messaging'
|
|
5
|
+
| 'messaging_background'
|
|
6
|
+
| 'messaging_offline'
|
|
7
|
+
| 'voice'
|
|
8
|
+
| '-';
|
|
9
|
+
|
|
10
|
+
export type ActionType =
|
|
11
|
+
| 'execute_actions'
|
|
12
|
+
| 'add_contact_urn'
|
|
13
|
+
| 'add_contact_groups'
|
|
14
|
+
| 'add_input_labels'
|
|
15
|
+
| 'remove_contact_groups'
|
|
16
|
+
| 'set_contact_channel'
|
|
17
|
+
| 'set_contact_field'
|
|
18
|
+
| 'set_contact_name'
|
|
19
|
+
| 'set_contact_language'
|
|
20
|
+
| 'set_contact_status'
|
|
21
|
+
| 'set_run_result'
|
|
22
|
+
| 'call_classifier'
|
|
23
|
+
| 'call_resthook'
|
|
24
|
+
| 'call_webhook'
|
|
25
|
+
| 'call_llm'
|
|
26
|
+
| 'open_ticket'
|
|
27
|
+
| 'send_msg'
|
|
28
|
+
| 'send_email'
|
|
29
|
+
| 'send_broadcast'
|
|
30
|
+
| 'enter_flow'
|
|
31
|
+
| 'start_session'
|
|
32
|
+
| 'transfer_airtime'
|
|
33
|
+
| 'split_by_airtime'
|
|
34
|
+
| 'split_by_expression'
|
|
35
|
+
| 'split_by_contact_field'
|
|
36
|
+
| 'split_by_run_result'
|
|
37
|
+
| 'split_by_run_result_delimited'
|
|
38
|
+
| 'split_by_groups'
|
|
39
|
+
| 'split_by_intent'
|
|
40
|
+
| 'split_by_random'
|
|
41
|
+
| 'split_by_resthook'
|
|
42
|
+
| 'split_by_ticket'
|
|
43
|
+
| 'split_by_scheme'
|
|
44
|
+
| 'split_by_subflow'
|
|
45
|
+
| 'split_by_webhook'
|
|
46
|
+
| 'split_by_llm'
|
|
47
|
+
| 'wait_for_response'
|
|
48
|
+
| 'wait_for_menu'
|
|
49
|
+
| 'wait_for_dial'
|
|
50
|
+
| 'wait_for_digits'
|
|
51
|
+
| 'wait_for_audio'
|
|
52
|
+
| 'wait_for_video'
|
|
53
|
+
| 'wait_for_location'
|
|
54
|
+
| 'wait_for_image'
|
|
55
|
+
| 'request_optin'
|
|
56
|
+
| 'missing'
|
|
57
|
+
| 'say_msg'
|
|
58
|
+
| 'play_audio';
|
|
59
|
+
|
|
60
|
+
export interface Action {
|
|
61
|
+
type: ActionType;
|
|
62
|
+
uuid: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface Exit {
|
|
66
|
+
uuid: string;
|
|
67
|
+
destination_uuid?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type Hint = {
|
|
71
|
+
type: 'digits' | 'audio' | 'image' | 'video' | 'location';
|
|
72
|
+
count?: number;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export interface Timeout {
|
|
76
|
+
category_uuid: string;
|
|
77
|
+
seconds: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface Wait {
|
|
81
|
+
type: 'msg' | 'dial';
|
|
82
|
+
timeout?: Timeout;
|
|
83
|
+
hint?: Hint;
|
|
84
|
+
phone?: string;
|
|
85
|
+
dial_limit_seconds?: number;
|
|
86
|
+
call_limit_seconds?: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface Category {
|
|
90
|
+
uuid: string;
|
|
91
|
+
name: string;
|
|
92
|
+
exit_uuid: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface Router {
|
|
96
|
+
type: 'switch' | 'random';
|
|
97
|
+
result_name?: string;
|
|
98
|
+
categories: Category[];
|
|
99
|
+
wait?: Wait;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface FlowNode {
|
|
103
|
+
uuid: string;
|
|
104
|
+
actions: Action[];
|
|
105
|
+
exits: Exit[];
|
|
106
|
+
router?: Router;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface FlowPosition {
|
|
110
|
+
left: number;
|
|
111
|
+
top: number;
|
|
112
|
+
right?: number;
|
|
113
|
+
bottom?: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface UINode {
|
|
117
|
+
position: FlowPosition;
|
|
118
|
+
type?: ActionType;
|
|
119
|
+
config?: Record<string, any>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface UIMetaData {
|
|
123
|
+
nodes: Record<string, UINode>;
|
|
124
|
+
languages: Record<string, string>[];
|
|
125
|
+
translation_filters?: { categories: boolean };
|
|
126
|
+
auto_translations?: Record<string, Record<string, string[]>>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface FlowDefinition {
|
|
130
|
+
localization: LocalizationMap;
|
|
131
|
+
language: string;
|
|
132
|
+
name: string;
|
|
133
|
+
nodes: FlowNode[];
|
|
134
|
+
uuid: string;
|
|
135
|
+
type: FlowTypes;
|
|
136
|
+
revision: number;
|
|
137
|
+
spec_version: string;
|
|
138
|
+
_ui: UIMetaData;
|
|
139
|
+
}
|
package/test/utils.test.ts
CHANGED
|
@@ -82,7 +82,7 @@ const createJSONResponse = (mocked) => {
|
|
|
82
82
|
return Promise.resolve(mockResponse);
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
const getResponse = (endpoint: string, options) => {
|
|
85
|
+
const getResponse = (endpoint: string, options = { method: 'GET' }) => {
|
|
86
86
|
// check if our path has been mocked in code
|
|
87
87
|
const mocks = options.method === 'GET' ? gets : posts;
|
|
88
88
|
const codeMock = mocks.find((mock) => mock.endpoint.test(endpoint));
|
|
@@ -99,7 +99,6 @@ const getResponse = (endpoint: string, options) => {
|
|
|
99
99
|
return createJSONResponse(codeMock);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
|
|
103
102
|
// otherwise fetch over http
|
|
104
103
|
return normalFetch(endpoint, options);
|
|
105
104
|
};
|
|
@@ -262,6 +261,7 @@ export const loadStore = async () => {
|
|
|
262
261
|
languages='/test-assets/store/languages.json'
|
|
263
262
|
fields='/test-assets/store/fields.json'
|
|
264
263
|
users='/test-assets/store/users.json'
|
|
264
|
+
workspace='/test-assets/store/workspace.json'
|
|
265
265
|
/>`
|
|
266
266
|
);
|
|
267
267
|
await store.initialHttpComplete;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"uuid": "3e8e7154-0233-4d53-b564-c258ee8390f9",
|
|
3
|
+
"name": "WHO Chile",
|
|
4
|
+
"country": "NG",
|
|
5
|
+
"languages": ["eng", "spa", "afr"],
|
|
6
|
+
"timezone": "PST8PDT",
|
|
7
|
+
"date_style": "day_first",
|
|
8
|
+
"anon": false,
|
|
9
|
+
"credits": {
|
|
10
|
+
"used": -1,
|
|
11
|
+
"remaining": -1
|
|
12
|
+
},
|
|
13
|
+
"primary_language": "eng"
|
|
14
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import replace from '@rollup/plugin-replace';
|
|
2
|
+
import { fromRollup } from '@web/dev-server-rollup';
|
|
3
|
+
|
|
4
|
+
const replacePlugin = fromRollup(replace);
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
nodeResolve: true,
|
|
8
|
+
plugins: [
|
|
9
|
+
replacePlugin({
|
|
10
|
+
preventAssignment: true,
|
|
11
|
+
'process.env.NODE_ENV': JSON.stringify('development'),
|
|
12
|
+
}),
|
|
13
|
+
],
|
|
14
|
+
};
|
|
@@ -11,6 +11,10 @@ import sizeOf from 'image-size';
|
|
|
11
11
|
|
|
12
12
|
import rimraf from 'rimraf';
|
|
13
13
|
|
|
14
|
+
import replace from '@rollup/plugin-replace';
|
|
15
|
+
import { fromRollup } from '@web/dev-server-rollup';
|
|
16
|
+
const replacePlugin = fromRollup(replace);
|
|
17
|
+
|
|
14
18
|
const SCREENSHOTS = 'screenshots';
|
|
15
19
|
const DIFF = 'diff';
|
|
16
20
|
const TEST = 'test';
|
|
@@ -297,7 +301,7 @@ export default {
|
|
|
297
301
|
rootDir: './',
|
|
298
302
|
files: '**/test/**/*.test.ts',
|
|
299
303
|
nodeResolve: true,
|
|
300
|
-
|
|
304
|
+
setupFiles: ['./test-setup.js'],
|
|
301
305
|
testFramework: {
|
|
302
306
|
config: {
|
|
303
307
|
timeout: '10000',
|
|
@@ -305,6 +309,10 @@ export default {
|
|
|
305
309
|
},
|
|
306
310
|
|
|
307
311
|
plugins: [
|
|
312
|
+
replacePlugin({
|
|
313
|
+
preventAssignment: true,
|
|
314
|
+
'process.env.NODE_ENV': JSON.stringify('test'),
|
|
315
|
+
}),
|
|
308
316
|
{
|
|
309
317
|
name: 'add-style',
|
|
310
318
|
transform(context) {
|
|
@@ -372,3 +380,4 @@ export default {
|
|
|
372
380
|
}),
|
|
373
381
|
],
|
|
374
382
|
};
|
|
383
|
+
|