@nyaruka/temba-components 0.133.0 → 0.134.1

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 (72) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/demo/components/webchat/example.html +1 -1
  3. package/dist/locales/es.js +5 -5
  4. package/dist/locales/es.js.map +1 -1
  5. package/dist/locales/fr.js +5 -5
  6. package/dist/locales/fr.js.map +1 -1
  7. package/dist/locales/locale-codes.js +2 -11
  8. package/dist/locales/locale-codes.js.map +1 -1
  9. package/dist/locales/pt.js +5 -5
  10. package/dist/locales/pt.js.map +1 -1
  11. package/dist/temba-components.js +307 -259
  12. package/dist/temba-components.js.map +1 -1
  13. package/out-tsc/src/display/Chat.js +223 -90
  14. package/out-tsc/src/display/Chat.js.map +1 -1
  15. package/out-tsc/src/display/TembaUser.js +3 -3
  16. package/out-tsc/src/display/TembaUser.js.map +1 -1
  17. package/out-tsc/src/events.js.map +1 -1
  18. package/out-tsc/src/flow/CanvasNode.js +8 -0
  19. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  20. package/out-tsc/src/flow/Editor.js +117 -28
  21. package/out-tsc/src/flow/Editor.js.map +1 -1
  22. package/out-tsc/src/flow/utils.js +141 -0
  23. package/out-tsc/src/flow/utils.js.map +1 -1
  24. package/out-tsc/src/interfaces.js.map +1 -1
  25. package/out-tsc/src/live/ContactChat.js +122 -170
  26. package/out-tsc/src/live/ContactChat.js.map +1 -1
  27. package/out-tsc/src/locales/es.js +5 -5
  28. package/out-tsc/src/locales/es.js.map +1 -1
  29. package/out-tsc/src/locales/fr.js +5 -5
  30. package/out-tsc/src/locales/fr.js.map +1 -1
  31. package/out-tsc/src/locales/locale-codes.js +2 -11
  32. package/out-tsc/src/locales/locale-codes.js.map +1 -1
  33. package/out-tsc/src/locales/pt.js +5 -5
  34. package/out-tsc/src/locales/pt.js.map +1 -1
  35. package/out-tsc/src/store/AppState.js +3 -0
  36. package/out-tsc/src/store/AppState.js.map +1 -1
  37. package/out-tsc/src/store/Store.js +5 -5
  38. package/out-tsc/src/store/Store.js.map +1 -1
  39. package/out-tsc/src/webchat/WebChat.js +22 -9
  40. package/out-tsc/src/webchat/WebChat.js.map +1 -1
  41. package/out-tsc/test/actions/send_broadcast.test.js +9 -4
  42. package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
  43. package/out-tsc/test/temba-flow-collision.test.js +673 -0
  44. package/out-tsc/test/temba-flow-collision.test.js.map +1 -0
  45. package/out-tsc/test/temba-flow-editor-node.test.js +128 -42
  46. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
  47. package/package.json +1 -1
  48. package/screenshots/truth/contacts/chat-failure.png +0 -0
  49. package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
  50. package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
  51. package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
  52. package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
  53. package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
  54. package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
  55. package/src/display/Chat.ts +303 -129
  56. package/src/display/TembaUser.ts +3 -2
  57. package/src/events.ts +11 -8
  58. package/src/flow/CanvasNode.ts +10 -0
  59. package/src/flow/Editor.ts +156 -28
  60. package/src/flow/utils.ts +207 -1
  61. package/src/interfaces.ts +7 -0
  62. package/src/live/ContactChat.ts +129 -180
  63. package/src/locales/es.ts +13 -18
  64. package/src/locales/fr.ts +13 -18
  65. package/src/locales/locale-codes.ts +2 -11
  66. package/src/locales/pt.ts +13 -18
  67. package/src/store/AppState.ts +2 -0
  68. package/src/store/Store.ts +5 -5
  69. package/src/webchat/WebChat.ts +24 -10
  70. package/test/actions/send_broadcast.test.ts +2 -1
  71. package/test/temba-flow-collision.test.ts +833 -0
  72. package/test/temba-flow-editor-node.test.ts +142 -47
@@ -24,12 +24,10 @@ import {
24
24
  CallEvent,
25
25
  ChannelEvent,
26
26
  ChatStartedEvent,
27
- ContactEvent,
28
27
  ContactGroupsEvent,
29
28
  ContactHistoryPage,
30
29
  ContactLanguageChangedEvent,
31
30
  ContactStatusChangedEvent,
32
- MsgEvent,
33
31
  NameChangedEvent,
34
32
  OptInEvent,
35
33
  RunEvent,
@@ -37,11 +35,10 @@ import {
37
35
  UpdateFieldEvent,
38
36
  URNsChangedEvent
39
37
  } from '../events';
40
- import { Chat, ChatEvent, MessageType } from '../display/Chat';
38
+ import { Chat, MessageType, ContactEvent } from '../display/Chat';
41
39
  import { DEFAULT_AVATAR } from '../webchat/assets';
42
40
  import { UserSelect } from '../form/select/UserSelect';
43
41
  import { Select } from '../form/select/Select';
44
- import { Store } from '../store/Store';
45
42
 
46
43
  /*
47
44
  export const SCROLL_THRESHOLD = 100;
@@ -176,17 +173,41 @@ export const renderTicketAction = (
176
173
  ): TemplateResult => {
177
174
  const ticketUUID = event.ticket?.uuid || event.ticket_uuid;
178
175
 
179
- if (event._user) {
180
- return html`<div>
181
- <strong>${event._user.name}</strong> ${action} a
182
- <strong><a href="/ticket/all/closed/${ticketUUID}/">ticket</a></strong>
183
- </div>`;
176
+ const actionNote = event.note
177
+ ? html`<div
178
+ style="width:85%; background: #fffac3; padding: 1em;margin-bottom: 1em 0; border: 1px solid #ffe97f;border-radius: var(--curvature);"
179
+ >
180
+ <div style="color: #8e830fff; font-size: 1em;margin-bottom:0.25em">
181
+ <strong>${event._user ? event._user.name : 'Someone'}</strong> added a
182
+ note
183
+ <temba-date
184
+ value=${event.created_on.toISOString()}
185
+ display="relative"
186
+ ></temba-date>
187
+ </div>
188
+ ${event.note}
189
+ </div>`
190
+ : null;
191
+
192
+ if (action === 'noted') {
193
+ return html`${actionNote}`;
184
194
  }
185
- return html`<div>
186
- A
187
- <strong><a href="/ticket/all/closed/${ticketUUID}/">ticket</a></strong> was
188
- <strong>${action}</strong>
189
- </div>`;
195
+
196
+ const description = event._user
197
+ ? html`<div>
198
+ <strong>${event._user.name}</strong> ${action} a
199
+ <strong><a href="/ticket/all/closed/${ticketUUID}/">ticket</a></strong>
200
+ </div>`
201
+ : html`<div>
202
+ A
203
+ <strong><a href="/ticket/all/closed/${ticketUUID}/">ticket</a></strong>
204
+ was <strong>${action}</strong>
205
+ </div>`;
206
+
207
+ return html`<div style="${actionNote ? 'margin-bottom: 1em;' : ''}">
208
+ ${description}
209
+ </div>
210
+ ${actionNote}`;
190
211
  };
191
212
 
192
213
  export const renderTicketAssigneeChanged = (
@@ -572,9 +593,16 @@ export class ContactChat extends ContactStoreElement {
572
593
  this.currentContact = this.data;
573
594
  }
574
595
 
575
- if (changedProperties.has('currentContact')) {
596
+ if (changedProperties.has('currentContact') && this.currentContact) {
576
597
  this.chat = this.shadowRoot.querySelector('temba-chat');
577
- this.reset();
598
+ if (
599
+ this.currentContact.uuid !==
600
+ changedProperties.get('currentContact')?.uuid
601
+ ) {
602
+ this.reset();
603
+ } else {
604
+ setTimeout(() => this.checkForNewMessages(), 500);
605
+ }
578
606
  this.fetchPreviousMessages();
579
607
  }
580
608
  }
@@ -637,8 +665,9 @@ export class ContactChat extends ContactStoreElement {
637
665
  postJSON(`/contact/chat/${this.currentContact.uuid}/`, payload)
638
666
  .then((response) => {
639
667
  if (response.status < 400) {
640
- const msg = this.createChatForMessageEvent(response.json.event);
641
- this.chat.addMessages([msg], null, true);
668
+ const event = response.json.event;
669
+ event.created_on = new Date(event.created_on);
670
+ this.chat.addMessages([event], null, true);
642
671
  // reset polling interval to 2 seconds after sending a message
643
672
  this.pollingInterval = 2000;
644
673
  this.checkForNewMessages();
@@ -682,185 +711,136 @@ export class ContactChat extends ContactStoreElement {
682
711
  }, this.pollingInterval);
683
712
  }
684
713
 
685
- public getEventMessage(event: ContactEvent): ChatEvent {
686
- let message = null;
714
+ public prerender(event: ContactEvent) {
687
715
  switch (event.type) {
688
716
  case Events.AIRTIME_TRANSFERRED:
689
- message = {
690
- type: MessageType.Inline,
691
- text: renderAirtimeTransferredEvent(event as AirtimeTransferredEvent)
717
+ event._rendered = {
718
+ html: renderAirtimeTransferredEvent(event as AirtimeTransferredEvent),
719
+ type: MessageType.Inline
692
720
  };
693
721
  break;
694
722
  case Events.CALL_CREATED:
695
723
  case Events.CALL_MISSED:
696
724
  case Events.CALL_RECEIVED:
697
- message = {
698
- type: MessageType.Inline,
699
- text: renderCallEvent(event as CallEvent)
725
+ event._rendered = {
726
+ html: renderCallEvent(event as CallEvent),
727
+ type: MessageType.Inline
700
728
  };
701
729
  break;
702
730
  case Events.CHAT_STARTED:
703
- message = {
704
- type: MessageType.Inline,
705
- text: renderChatStartedEvent(event as ChatStartedEvent)
731
+ event._rendered = {
732
+ html: renderChatStartedEvent(event as ChatStartedEvent),
733
+ type: MessageType.Inline
706
734
  };
707
735
  break;
708
736
  case Events.CONTACT_FIELD_CHANGED:
709
- message = {
710
- type: MessageType.Inline,
711
- text: renderUpdateEvent(event as UpdateFieldEvent)
737
+ event._rendered = {
738
+ html: renderUpdateEvent(event as UpdateFieldEvent),
739
+ type: MessageType.Inline
712
740
  };
713
741
  break;
714
742
  case Events.CONTACT_GROUPS_CHANGED:
715
- message = {
716
- type: MessageType.Inline,
717
- text: renderContactGroupsEvent(event as ContactGroupsEvent)
743
+ event._rendered = {
744
+ html: renderContactGroupsEvent(event as ContactGroupsEvent),
745
+ type: MessageType.Inline
718
746
  };
719
747
  break;
720
748
  case Events.CONTACT_LANGUAGE_CHANGED:
721
- message = {
722
- type: MessageType.Inline,
723
- text: renderContactLanguageChangedEvent(
749
+ event._rendered = {
750
+ html: renderContactLanguageChangedEvent(
724
751
  event as ContactLanguageChangedEvent
725
- )
752
+ ),
753
+ type: MessageType.Inline
726
754
  };
727
755
  break;
728
756
  case Events.CONTACT_NAME_CHANGED:
729
- message = {
730
- type: MessageType.Inline,
731
- text: renderNameChanged(event as NameChangedEvent)
757
+ event._rendered = {
758
+ html: renderNameChanged(event as NameChangedEvent),
759
+ type: MessageType.Inline
732
760
  };
733
761
  break;
734
762
  case Events.CONTACT_STATUS_CHANGED:
735
- message = {
736
- type: MessageType.Inline,
737
- text: renderContactStatusChangedEvent(
763
+ event._rendered = {
764
+ html: renderContactStatusChangedEvent(
738
765
  event as ContactStatusChangedEvent
739
- )
766
+ ),
767
+ type: MessageType.Inline
740
768
  };
741
769
  break;
742
770
  case Events.CONTACT_URNS_CHANGED:
743
- message = {
744
- type: MessageType.Inline,
745
- text: renderContactURNsChanged(event as URNsChangedEvent)
771
+ event._rendered = {
772
+ html: renderContactURNsChanged(event as URNsChangedEvent),
773
+ type: MessageType.Inline
746
774
  };
747
775
  break;
748
776
  case Events.OPTIN_REQUESTED:
749
777
  case Events.OPTIN_STARTED:
750
778
  case Events.OPTIN_STOPPED:
751
- message = {
752
- type: MessageType.Inline,
753
- text: renderOptInEvent(event as OptInEvent)
779
+ event._rendered = {
780
+ html: renderOptInEvent(event as OptInEvent),
781
+ type: MessageType.Inline
754
782
  };
755
783
  break;
756
784
  case Events.RUN_STARTED:
757
785
  case Events.RUN_ENDED:
758
- message = {
759
- type: MessageType.Inline,
760
- text: renderRunEvent(event as RunEvent)
786
+ event._rendered = {
787
+ html: renderRunEvent(event as RunEvent),
788
+ type: MessageType.Inline
761
789
  };
762
790
  break;
763
791
  case Events.TICKET_ASSIGNEE_CHANGED:
764
- message = {
765
- type: MessageType.Inline,
766
- text: renderTicketAssigneeChanged(event as TicketEvent)
792
+ event._rendered = {
793
+ html: renderTicketAssigneeChanged(event as TicketEvent),
794
+ type: MessageType.Inline
767
795
  };
768
796
  break;
769
797
  case Events.TICKET_CLOSED:
770
- message = {
771
- type: MessageType.Inline,
772
- text: renderTicketAction(event as TicketEvent, 'closed')
798
+ event._rendered = {
799
+ html: renderTicketAction(event as TicketEvent, 'closed'),
800
+ type: MessageType.Inline
773
801
  };
774
802
  break;
775
803
  case Events.TICKET_OPENED:
776
- message = {
777
- type: MessageType.Inline,
778
- text: renderTicketAction(event as TicketEvent, 'opened')
804
+ event._rendered = {
805
+ html: renderTicketAction(event as TicketEvent, 'opened'),
806
+ type: MessageType.Inline
807
+ };
808
+ break;
809
+ case Events.TICKET_NOTE_ADDED:
810
+ event._rendered = {
811
+ html: renderTicketAction(event as TicketEvent, 'noted'),
812
+ type: MessageType.Inline
779
813
  };
780
814
  break;
781
815
  case Events.TICKET_REOPENED:
782
- message = {
783
- type: MessageType.Inline,
784
- text: renderTicketAction(event as TicketEvent, 'reopened')
816
+ event._rendered = {
817
+ html: renderTicketAction(event as TicketEvent, 'reopened'),
818
+ type: MessageType.Inline
785
819
  };
786
820
  break;
787
821
  case Events.TICKET_TOPIC_CHANGED:
788
- message = {
789
- type: MessageType.Inline,
790
- text: html`<div>
822
+ event._rendered = {
823
+ html: html`<div>
791
824
  Topic changed to
792
825
  <strong>${(event as TicketEvent).topic.name}</strong>
793
- </div>`
826
+ </div>`,
827
+ type: MessageType.Inline
794
828
  };
795
829
  break;
796
830
  case Events.CHANNEL_EVENT: // deprecated
797
- message = {
798
- type: MessageType.Inline,
799
- text: renderChannelEvent(event as ChannelEvent)
831
+ event._rendered = {
832
+ html: renderChannelEvent(event as ChannelEvent),
833
+ type: MessageType.Inline
800
834
  };
801
835
  break;
802
836
  default:
803
837
  console.error('Unknown event type', event);
804
838
  }
805
-
806
- if (message) {
807
- message.id = event.uuid;
808
- message.date = new Date(event.created_on);
809
- }
810
-
811
- return message;
812
839
  }
813
840
 
814
- private getUserForEvent(event: MsgEvent | TicketEvent) {
815
- if (event.type === 'msg_received') {
816
- return {
817
- name: this.currentContact.name
818
- };
819
- } else if (event._user) {
820
- return event._user;
821
- }
822
- return null;
823
- }
824
-
825
- private createChatForMessageEvent(msgEvent: MsgEvent): any {
826
- return {
827
- id: msgEvent.uuid,
828
- type: msgEvent.type === 'msg_received' ? 'msg_in' : 'msg_out',
829
- user: this.getUserForEvent(msgEvent),
830
- date: new Date(msgEvent.created_on),
831
- attachments: msgEvent.msg.attachments,
832
- text: msgEvent.msg.text,
833
- sendError:
834
- msgEvent._status &&
835
- (msgEvent._status.status === 'errored' ||
836
- msgEvent._status.status === 'failed'),
837
- popup: html`<div
838
- style="display: flex; flex-direction: row; align-items:center; justify-content: space-between;font-size:0.9em;line-height:1em;min-width:10em"
839
- >
840
- <div style="justify-content:left;text-align:left">
841
- <temba-date
842
- value=${msgEvent.created_on}
843
- display="duration"
844
- ></temba-date>
845
-
846
- ${msgEvent.optin
847
- ? html`<div style="font-size:0.9em;color:#aaa">
848
- ${msgEvent.optin.name}
849
- </div>`
850
- : null}
851
- </div>
852
- ${msgEvent._logs_url
853
- ? html`<a style="margin-left:0.5em" href="${msgEvent._logs_url}"
854
- ><temba-icon name="log"></temba-icon
855
- ></a>`
856
- : null}
857
- </div> `
858
- };
859
- }
860
-
861
- private createMessages(page: ContactHistoryPage): ChatEvent[] {
841
+ private createMessages(page: ContactHistoryPage): ContactEvent[] {
862
842
  if (page.events) {
863
- let messages = [];
843
+ const messages: ContactEvent[] = [];
864
844
  page.events.forEach((event) => {
865
845
  // track the UUID of the newest event for polling
866
846
  if (
@@ -870,46 +850,25 @@ export class ContactChat extends ContactStoreElement {
870
850
  this.afterUUID = event.uuid;
871
851
  }
872
852
 
873
- if (event.type === 'ticket_note_added') {
874
- const ticketEvent = event as TicketEvent;
875
- messages.push({
876
- type: MessageType.Note,
877
- id: event.created_on + event.type,
878
- user: this.getUserForEvent(ticketEvent),
879
- date: new Date(ticketEvent.created_on),
880
- text: ticketEvent.note
881
- });
882
- } else if (event.type === 'ticket_opened') {
883
- // ticket open events can have a note attached
884
- const ticketEvent = event as TicketEvent;
885
- messages.push({
886
- type: MessageType.Note,
887
- id: event.created_on + event.type + '_note',
888
- user: this.getUserForEvent(ticketEvent),
889
- date: new Date(ticketEvent.created_on),
890
- text: ticketEvent.note
891
- });
853
+ // convert to dates
854
+ event.created_on = new Date(event.created_on);
892
855
 
893
- // but the opening of the ticket is a normal event
894
- messages.push(this.getEventMessage(event));
895
- } else if (
856
+ if (
896
857
  event.type === 'msg_created' ||
897
858
  event.type === 'msg_received' ||
898
859
  event.type === 'ivr_created'
899
860
  ) {
900
- const msgEvent = event as MsgEvent;
901
- messages.push(this.createChatForMessageEvent(msgEvent));
861
+ messages.push(event);
902
862
  } else {
903
- const msg = this.getEventMessage(event);
904
- if (msg) {
905
- messages.push(msg);
863
+ this.prerender(event);
864
+ if (event._rendered) {
865
+ messages.push(event);
906
866
  }
907
867
  }
908
868
  });
909
869
 
910
870
  // remove any messages we don't recognize
911
- messages = messages.filter((msg) => !!msg);
912
- return messages as ChatEvent[];
871
+ return messages.filter((msg) => !!msg);
913
872
  }
914
873
  return [];
915
874
  }
@@ -921,7 +880,6 @@ export class ContactChat extends ContactStoreElement {
921
880
  }
922
881
 
923
882
  const chat = this.chat;
924
- const contactChat = this;
925
883
  if (this.currentContact && this.afterUUID) {
926
884
  this.polling = true;
927
885
  this.lastFetchTime = Date.now();
@@ -938,13 +896,10 @@ export class ContactChat extends ContactStoreElement {
938
896
  null,
939
897
  this.afterUUID
940
898
  ).then((page: ContactHistoryPage) => {
899
+ const messages = this.createMessages(page);
900
+ messages.reverse();
941
901
  if (fetchContact === this.currentContact.uuid) {
942
- const messages = this.createMessages(page);
943
902
  const hasNewEvents = messages.length > 0;
944
- if (messages.length === 0) {
945
- contactChat.blockFetching = true;
946
- }
947
- messages.reverse();
948
903
  chat.addMessages(messages, null, true);
949
904
  this.polling = false;
950
905
  this.scheduleRefresh(hasNewEvents);
@@ -1115,15 +1070,13 @@ export class ContactChat extends ContactStoreElement {
1115
1070
  if (this.currentTicket) {
1116
1071
  fetchResults(`/api/v2/tickets.json?uuid=${this.currentTicket.uuid}`).then(
1117
1072
  (values) => {
1118
- this.store.resolveUsers(values, ['assignee']).then(() => {
1119
- if (values.length > 0) {
1120
- this.fireCustomEvent(CustomEventType.TicketUpdated, {
1121
- ticket: values[0],
1122
- previous: this.currentTicket
1123
- });
1124
- this.currentTicket = values[0];
1125
- }
1126
- });
1073
+ if (values.length > 0) {
1074
+ this.fireCustomEvent(CustomEventType.TicketUpdated, {
1075
+ ticket: values[0],
1076
+ previous: this.currentTicket
1077
+ });
1078
+ this.currentTicket = values[0];
1079
+ }
1127
1080
  }
1128
1081
  );
1129
1082
  }
@@ -1170,6 +1123,7 @@ export class ContactChat extends ContactStoreElement {
1170
1123
  @temba-fetch-complete=${this.fetchComplete}
1171
1124
  avatar=${this.avatar}
1172
1125
  agent
1126
+ ?hasFooter=${inFlow}
1173
1127
  >
1174
1128
  ${inFlow
1175
1129
  ? html`
@@ -1294,8 +1248,6 @@ export const fetchContactHistory = (
1294
1248
  url += (url.includes('?') ? '&' : '?') + params.join('&');
1295
1249
  }
1296
1250
 
1297
- const store = document.querySelector('temba-store') as Store;
1298
-
1299
1251
  getUrl(url, controller)
1300
1252
  .then((response: WebResponse) => {
1301
1253
  // on success, remove our abort controller
@@ -1305,10 +1257,7 @@ export const fetchContactHistory = (
1305
1257
  }
1306
1258
  );
1307
1259
 
1308
- const page = response.json as ContactHistoryPage;
1309
- store.resolveUsers(page.events, ['created_by']).then(() => {
1310
- resolve(page);
1311
- });
1260
+ resolve(response.json as ContactHistoryPage);
1312
1261
  })
1313
1262
  .catch(() => {
1314
1263
  // canceled
package/src/locales/es.ts CHANGED
@@ -1,18 +1,13 @@
1
-
2
- // Do not modify this file by hand!
3
- // Re-generate this file by running lit-localize
4
-
5
-
6
-
7
-
8
- /* eslint-disable no-irregular-whitespace */
9
- /* eslint-disable @typescript-eslint/no-explicit-any */
10
-
11
- export const templates = {
12
- 'scf1453991c986b25': `Tab para completar, enter para seleccionar`,
13
- 's73b4d70c02f4b4e0': `No options`,
14
- 's8f02e3a18ffc083a': `Are not currently in a flow`,
15
- 's638236250662c6b3': `Have sent a message in the last`,
16
- 's4788ee206c4570c7': `Have not started this flow in the last 90 days`,
17
- };
18
-
1
+ // Do not modify this file by hand!
2
+ // Re-generate this file by running lit-localize
3
+
4
+ /* eslint-disable no-irregular-whitespace */
5
+ /* eslint-disable @typescript-eslint/no-explicit-any */
6
+
7
+ export const templates = {
8
+ scf1453991c986b25: `Tab para completar, enter para seleccionar`,
9
+ s73b4d70c02f4b4e0: `No options`,
10
+ s8f02e3a18ffc083a: `Are not currently in a flow`,
11
+ s638236250662c6b3: `Have sent a message in the last`,
12
+ s4788ee206c4570c7: `Have not started this flow in the last 90 days`
13
+ };
package/src/locales/fr.ts CHANGED
@@ -1,18 +1,13 @@
1
-
2
- // Do not modify this file by hand!
3
- // Re-generate this file by running lit-localize
4
-
5
-
6
-
7
-
8
- /* eslint-disable no-irregular-whitespace */
9
- /* eslint-disable @typescript-eslint/no-explicit-any */
10
-
11
- export const templates = {
12
- 's73b4d70c02f4b4e0': `No options`,
13
- 'scf1453991c986b25': `Tab to complete, enter to select`,
14
- 's8f02e3a18ffc083a': `Are not currently in a flow`,
15
- 's638236250662c6b3': `Have sent a message in the last`,
16
- 's4788ee206c4570c7': `Have not started this flow in the last 90 days`,
17
- };
18
-
1
+ // Do not modify this file by hand!
2
+ // Re-generate this file by running lit-localize
3
+
4
+ /* eslint-disable no-irregular-whitespace */
5
+ /* eslint-disable @typescript-eslint/no-explicit-any */
6
+
7
+ export const templates = {
8
+ s73b4d70c02f4b4e0: `No options`,
9
+ scf1453991c986b25: `Tab to complete, enter to select`,
10
+ s8f02e3a18ffc083a: `Are not currently in a flow`,
11
+ s638236250662c6b3: `Have sent a message in the last`,
12
+ s4788ee206c4570c7: `Have not started this flow in the last 90 days`
13
+ };
@@ -10,18 +10,9 @@ export const sourceLocale = `en`;
10
10
  * The other locale codes that this application is localized into. Sorted
11
11
  * lexicographically.
12
12
  */
13
- export const targetLocales = [
14
- `es`,
15
- `fr`,
16
- `pt`,
17
- ] as const;
13
+ export const targetLocales = [`es`, `fr`, `pt`] as const;
18
14
 
19
15
  /**
20
16
  * All valid project locale codes. Sorted lexicographically.
21
17
  */
22
- export const allLocales = [
23
- `en`,
24
- `es`,
25
- `fr`,
26
- `pt`,
27
- ] as const;
18
+ export const allLocales = [`en`, `es`, `fr`, `pt`] as const;
package/src/locales/pt.ts CHANGED
@@ -1,18 +1,13 @@
1
-
2
- // Do not modify this file by hand!
3
- // Re-generate this file by running lit-localize
4
-
5
-
6
-
7
-
8
- /* eslint-disable no-irregular-whitespace */
9
- /* eslint-disable @typescript-eslint/no-explicit-any */
10
-
11
- export const templates = {
12
- 's73b4d70c02f4b4e0': `No options`,
13
- 'scf1453991c986b25': `Tab to complete, enter to select`,
14
- 's8f02e3a18ffc083a': `Are not currently in a flow`,
15
- 's638236250662c6b3': `Have sent a message in the last`,
16
- 's4788ee206c4570c7': `Have not started this flow in the last 90 days`,
17
- };
18
-
1
+ // Do not modify this file by hand!
2
+ // Re-generate this file by running lit-localize
3
+
4
+ /* eslint-disable no-irregular-whitespace */
5
+ /* eslint-disable @typescript-eslint/no-explicit-any */
6
+
7
+ export const templates = {
8
+ s73b4d70c02f4b4e0: `No options`,
9
+ scf1453991c986b25: `Tab to complete, enter to select`,
10
+ s8f02e3a18ffc083a: `Are not currently in a flow`,
11
+ s638236250662c6b3: `Have sent a message in the last`,
12
+ s4788ee206c4570c7: `Have not started this flow in the last 90 days`
13
+ };
@@ -290,6 +290,8 @@ export const zustand = createStore<AppState>()(
290
290
  destinations.every((dest) => dest === destinations[0])
291
291
  ) {
292
292
  const targetDestination = destinations[0];
293
+ // Don't reroute if the target is also being removed
294
+ if (uuids.includes(targetDestination)) return;
293
295
 
294
296
  // Find all nodes with exits pointing to the node being removed
295
297
  draft.nodes.forEach((node) => {
@@ -506,7 +506,7 @@ export class Store extends RapidElement {
506
506
 
507
507
  public resolveUsers(items: any, keys: string[]): Promise<void> {
508
508
  return new Promise<void>((resolve) => {
509
- const emails = new Set<string>();
509
+ const uuids = new Set<string>();
510
510
 
511
511
  // keys are dot notation paths to user fields
512
512
  items.forEach((item) => {
@@ -519,17 +519,17 @@ export class Store extends RapidElement {
519
519
  break;
520
520
  }
521
521
  }
522
- if (value && value.email) {
523
- emails.add(value.email);
522
+ if (value && value.uuid) {
523
+ uuids.add(value.uuid);
524
524
  }
525
525
  });
526
526
  });
527
527
 
528
528
  const promises = [];
529
529
  // we don't want to fetch all users at once so we can benefit from caching
530
- emails.forEach((email) => {
530
+ uuids.forEach((uuid) => {
531
531
  promises.push(
532
- this.getUrl(`/api/v2/users.json?email=${encodeURIComponent(email)}`, {
532
+ this.getUrl(`/api/v2/users.json?uuid=${encodeURIComponent(uuid)}`, {
533
533
  force: true
534
534
  })
535
535
  );