Skip to content

Commit 0da29fa

Browse files
committed
Merge tag 'v1.14.3' into update/v1.14.3
v1.14.3
2 parents 69049d2 + 0725591 commit 0da29fa

25 files changed

+379
-71
lines changed

CHANGELOG.md

+19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file. Dates are d
44

55
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
66

7+
#### [v1.14.3](https://github.com/nyaruka/floweditor/compare/v1.14.1...v1.14.3)
8+
9+
> 20 September 2021
10+
11+
- Let components control how new objects are created [`#1013`](https://github.com/nyaruka/floweditor/pull/1013)
12+
- Use topic rather than subject for open ticket events in simulator [`#1012`](https://github.com/nyaruka/floweditor/pull/1012)
13+
- Bump axios from 0.21.1 to 0.21.2 [`#1011`](https://github.com/nyaruka/floweditor/pull/1011)
14+
- Change topic to be an object rather than string [`521994f`](https://github.com/nyaruka/floweditor/commit/521994f536a45618c7adf7cfd2b5cc6adeed2d9e)
15+
16+
#### [v1.14.1](https://github.com/nyaruka/floweditor/compare/v1.14.0...v1.14.1)
17+
18+
> 15 September 2021
19+
20+
- Topic and assignee [`#1010`](https://github.com/nyaruka/floweditor/pull/1010)
21+
- Include latest translations from transifex [`#1006`](https://github.com/nyaruka/floweditor/pull/1006)
22+
- Add topic and assignee to open ticket action [`f3f6274`](https://github.com/nyaruka/floweditor/commit/f3f6274e0169de45d81e302be899b7010b289f5e)
23+
- Update snapshots [`07a9bef`](https://github.com/nyaruka/floweditor/commit/07a9befef7699da7d41f235ddee31e44bb475899)
24+
- Update snapshots [`95de60a`](https://github.com/nyaruka/floweditor/commit/95de60a6b89860baf573858a5e02995d4e3c2230)
25+
726
#### [v1.14.0](https://github.com/nyaruka/floweditor/compare/v1.13.19...v1.14.0)
827

928
> 14 July 2021

lambda/topics.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { v4 as generateUUID } from 'uuid';
2+
3+
import { respond } from './utils/index.js';
4+
const topics = {
5+
next: null,
6+
previous: null,
7+
results: [
8+
{
9+
uuid: '6f38eba0-d673-4a35-82df-21bae2b6d466',
10+
name: 'General',
11+
created_on: '2021-09-01T01:06:39.178493Z'
12+
}
13+
]
14+
};
15+
16+
exports.handler = (request, context, callback) => {
17+
if (request.httpMethod === 'POST') {
18+
const body = JSON.parse(request.body);
19+
respond(callback, {
20+
uuid: generateUUID(),
21+
name: body.name,
22+
query: null,
23+
status: 'ready',
24+
count: 0
25+
});
26+
} else {
27+
respond(callback, topics);
28+
}
29+
};

lambda/users.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { v4 as generateUUID } from 'uuid';
2+
3+
import { respond } from './utils/index.js';
4+
const users = {
5+
next: null,
6+
previous: null,
7+
results: [
8+
{
9+
10+
first_name: 'Agent',
11+
last_name: 'User',
12+
role: 'agent',
13+
created_on: '2021-06-10T21:44:30.971221Z'
14+
},
15+
{
16+
17+
first_name: 'Viewer',
18+
last_name: 'User',
19+
role: 'viewer',
20+
created_on: '2020-11-09T23:02:10.095493Z'
21+
},
22+
{
23+
24+
first_name: 'Admin',
25+
last_name: 'User',
26+
role: 'administrator',
27+
created_on: '2020-08-18T19:07:08.984182Z'
28+
}
29+
]
30+
};
31+
32+
exports.handler = (request, context, callback) => {
33+
if (request.httpMethod === 'POST') {
34+
const body = JSON.parse(request.body);
35+
respond(callback, {
36+
uuid: generateUUID(),
37+
name: body.name,
38+
query: null,
39+
status: 'ready',
40+
count: 0
41+
});
42+
} else {
43+
respond(callback, users);
44+
}
45+
};

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@nyaruka/flow-editor",
33
"license": "AGPL-3.0",
44
"repository": "git://github.com/nyaruka/floweditor.git",
5-
"version": "1.14.0",
5+
"version": "1.14.3",
66
"description": "'Standalone flow editing tool designed for use within the RapidPro suite of messaging tools but can be adopted for use outside of that ecosystem.'",
77
"browser": "umd/flow-editor.min.js",
88
"unpkg": "umd/flow-editor.min.js",
@@ -70,7 +70,7 @@
7070
"@babel/core": "^7.4.4",
7171
"@babel/preset-env": "^7.4.4",
7272
"@babel/preset-react": "7.0.0",
73-
"@nyaruka/temba-components": "0.11.13",
73+
"@nyaruka/temba-components": "0.16.1",
7474
"@testing-library/jest-dom": "4.0.0",
7575
"@testing-library/react": "8.0.1",
7676
"@types/common-tags": "^1.8.0",
@@ -96,7 +96,7 @@
9696
"array-move": "2.1.0",
9797
"auto-bind": "2.1.0",
9898
"auto-changelog": "1.13.0",
99-
"axios": "0.21.1",
99+
"axios": "0.21.2",
100100
"camelcase": "^5.3.1",
101101
"classnames": "2.2.6",
102102
"common-tags": "1.8.0",

src/components/__snapshots__/index.test.ts.snap

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Array [
2323
"simulateStart": "",
2424
"templates": "/assets/templates.json",
2525
"ticketers": "/assets/ticketers.json",
26+
"topics": "/assets/topics.json",
27+
"users": "/assets/users.json",
2628
},
2729
"a4f64f1b-85bc-477e-b706-de313a022979",
2830
undefined,

src/components/flow/actions/openticket/OpenTicket.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { OpenTicket } from 'flowTypes';
33
import { fakePropType } from 'config/ConfigProvider';
44

55
const OpenTicketComp: React.SFC<OpenTicket> = (
6-
{ ticketer, subject },
6+
{ ticketer, subject, topic },
77
context: any
88
): JSX.Element => {
99
const showTicketer = ticketer.name.indexOf(context.config.brand) === -1;
1010
return (
1111
<div>
12-
<div>{subject}</div>
12+
<div>{subject ? subject : topic ? topic.name : null}</div>
1313
{showTicketer ? (
1414
<div style={{ fontSize: '80%' }}>
1515
Using <span style={{ fontWeight: 400 }}>{ticketer.name}</span>

src/components/flow/routers/ticket/TicketRouterForm.test.tsx

+17-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { render, fireEvent, fireChangeText, fireTembaSelect } from 'test/utils';
99

1010
mock(utils, 'createUUID', utils.seededUUIDs());
1111

12+
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
1213
const ticketForm = getRouterFormProps({
1314
node: createOpenTicketNode('Need help', 'Where are my cookies'),
1415
ui: { type: Types.split_by_ticket }
@@ -30,17 +31,28 @@ describe(TicketRouterForm.name, () => {
3031
expect(baseElement).toMatchSnapshot();
3132

3233
const okButton = getByText('Ok');
33-
const subject = getByTestId('Subject');
3434
const resultName = getByTestId('Result Name');
3535

36-
// our ticketer, subject, body and result name are required
37-
fireChangeText(subject, '');
36+
// our ticketer, body and result name are required
3837
fireChangeText(resultName, '');
3938
fireEvent.click(okButton);
4039
expect(ticketForm.updateRouter).not.toBeCalled();
4140

42-
// set our subject and result name
43-
fireChangeText(subject, 'Need help');
41+
// we need a topic
42+
fireTembaSelect(getByTestId('temba_select_assignee'), {
43+
44+
first_name: 'Agent',
45+
last_name: 'User',
46+
role: 'agent',
47+
created_on: '2021-06-10T21:44:30.971221Z'
48+
});
49+
50+
// we need a topic
51+
fireTembaSelect(getByTestId('temba_select_topic'), {
52+
name: 'General',
53+
uuid: '6f38eba0-d673-4a35-82df-21bae2b6d466'
54+
});
55+
4456
fireChangeText(resultName, 'My Ticket Result');
4557

4658
fireEvent.click(okButton);

src/components/flow/routers/ticket/TicketRouterForm.tsx

+63-11
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,13 @@ import { Asset } from 'store/flowContext';
1919
import styles from './TicketRouterForm.module.scss';
2020
import i18n from 'config/i18n';
2121
import TextInputElement from 'components/form/textinput/TextInputElement';
22+
import TembaSelect from 'temba/TembaSelect';
23+
import { fakePropType } from 'config/ConfigProvider';
24+
import { Topic, User } from 'flowTypes';
2225

2326
export interface TicketRouterFormState extends FormState {
27+
assignee: FormEntry;
28+
topic: FormEntry;
2429
ticketer: FormEntry;
2530
subject: StringEntry;
2631
body: StringEntry;
@@ -31,6 +36,10 @@ export default class TicketRouterForm extends React.Component<
3136
RouterFormProps,
3237
TicketRouterFormState
3338
> {
39+
public static contextTypes = {
40+
config: fakePropType
41+
};
42+
3443
constructor(props: RouterFormProps) {
3544
super(props);
3645

@@ -45,6 +54,8 @@ export default class TicketRouterForm extends React.Component<
4554
}
4655
private handleUpdate(
4756
keys: {
57+
assignee?: User;
58+
topic?: Topic;
4859
ticketer?: Asset;
4960
subject?: string;
5061
body?: string;
@@ -54,16 +65,26 @@ export default class TicketRouterForm extends React.Component<
5465
): boolean {
5566
const updates: Partial<TicketRouterFormState> = {};
5667

68+
if (keys.hasOwnProperty('assignee')) {
69+
updates.assignee = validate(i18n.t('forms.assignee', 'Assignee'), keys.assignee, [
70+
shouldRequireIf(submitting)
71+
]);
72+
}
73+
74+
if (keys.hasOwnProperty('topic')) {
75+
updates.topic = validate(i18n.t('forms.topic', 'Topic'), keys.topic, [
76+
shouldRequireIf(submitting)
77+
]);
78+
}
79+
5780
if (keys.hasOwnProperty('ticketer')) {
5881
updates.ticketer = validate(i18n.t('forms.ticketer', 'Ticketer'), keys.ticketer, [
5982
shouldRequireIf(submitting)
6083
]);
6184
}
6285

6386
if (keys.hasOwnProperty('subject')) {
64-
updates.subject = validate(i18n.t('forms.subject', 'Subject'), keys.subject, [
65-
shouldRequireIf(submitting)
66-
]);
87+
updates.subject = validate(i18n.t('forms.subject', 'Subject'), keys.subject, []);
6788
}
6889

6990
if (keys.hasOwnProperty('body')) {
@@ -89,6 +110,14 @@ export default class TicketRouterForm extends React.Component<
89110
this.handleUpdate({ ticketer: selected[0] });
90111
}
91112

113+
private handleAssigneeUpdate(assignee: User): void {
114+
this.handleUpdate({ assignee });
115+
}
116+
117+
private handleTopicUpdate(topic: Topic): void {
118+
this.handleUpdate({ topic });
119+
}
120+
92121
private handleSubjectUpdate(subject: string, name: string, submitting = false): boolean {
93122
return this.handleUpdate({ subject }, submitting);
94123
}
@@ -165,14 +194,37 @@ export default class TicketRouterForm extends React.Component<
165194
''
166195
)}
167196

168-
<div className={styles.subject}>
169-
<TextInputElement
170-
name={i18n.t('forms.subject', 'Subject')}
171-
placeholder={i18n.t('forms.enter_a_subject', 'Enter a subject')}
172-
entry={this.state.subject}
173-
onChange={this.handleSubjectUpdate}
174-
autocomplete={true}
175-
/>
197+
<div style={{ display: 'flex', width: '100%', marginTop: '0.5em' }}>
198+
<div style={{ flexBasis: 250 }}>
199+
<TembaSelect
200+
key="select_topic"
201+
name={i18n.t('forms.topic', 'Topic')}
202+
endpoint={this.context.config.endpoints.topics}
203+
onChange={this.handleTopicUpdate}
204+
value={this.state.topic.value}
205+
createPrefix={i18n.t('forms.topic_prefix', 'Create Topic: ')}
206+
searchable={true}
207+
/>
208+
</div>
209+
210+
<div style={{ flexGrow: 1, marginLeft: '0.5em' }}>
211+
<TembaSelect
212+
key="select_assignee"
213+
name={i18n.t('forms.assignee', 'Assignee')}
214+
placeholder="Assign to (Optional)"
215+
valueKey="email"
216+
endpoint={this.context.config.endpoints.users}
217+
onChange={this.handleAssigneeUpdate}
218+
clearable={true}
219+
value={this.state.assignee.value}
220+
getName={(user: User) => {
221+
if (!user.first_name && !user.last_name) {
222+
return user.email || '';
223+
}
224+
return `${user.first_name} ${user.last_name}`;
225+
}}
226+
/>
227+
</div>
176228
</div>
177229
<div className={styles.body}>
178230
<TextInputElement

0 commit comments

Comments
 (0)