@nyaruka/temba-components 0.159.1 → 0.159.2
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/package.json
CHANGED
package/src/interfaces.ts
CHANGED
|
@@ -41,7 +41,7 @@ const BROADCAST_COLOR = '#8e5ea7';
|
|
|
41
41
|
// triggers use the same green as the flow pill
|
|
42
42
|
const TRIGGER_COLOR = '#16a34a';
|
|
43
43
|
|
|
44
|
-
export class
|
|
44
|
+
export class ContactTimeline extends EndpointMonitorElement {
|
|
45
45
|
@property({ type: String })
|
|
46
46
|
contact: string;
|
|
47
47
|
|
|
@@ -64,7 +64,14 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
64
64
|
lang_campaigns_label = 'Campaigns';
|
|
65
65
|
|
|
66
66
|
@property({ type: String })
|
|
67
|
-
lang_empty = 'No events
|
|
67
|
+
lang_empty = 'No upcoming events';
|
|
68
|
+
|
|
69
|
+
@property({ type: String })
|
|
70
|
+
lang_empty_help =
|
|
71
|
+
'Events appear here when a contact joins a campaign. Scheduled flows and messages will also show up here.';
|
|
72
|
+
|
|
73
|
+
@property({ type: String })
|
|
74
|
+
lang_campaigns_link = 'View campaigns';
|
|
68
75
|
|
|
69
76
|
@property({ type: String })
|
|
70
77
|
lang_projected_info =
|
|
@@ -101,11 +108,44 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
101
108
|
display: block;
|
|
102
109
|
}
|
|
103
110
|
|
|
111
|
+
/* empty state follows the list design system: centered icon, a short
|
|
112
|
+
title, muted explanatory copy, and a single call-to-action link */
|
|
104
113
|
.empty {
|
|
105
|
-
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
align-items: center;
|
|
106
117
|
text-align: center;
|
|
118
|
+
padding: 7em 1em 4em;
|
|
107
119
|
color: var(--text-color);
|
|
108
|
-
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.empty temba-icon {
|
|
123
|
+
margin-bottom: 0.75em;
|
|
124
|
+
--icon-color: var(--text-3, #7b8593);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.empty-title {
|
|
128
|
+
font-weight: 600;
|
|
129
|
+
margin-bottom: 0.4em;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.empty-help {
|
|
133
|
+
font-size: 0.875em;
|
|
134
|
+
line-height: 1.5;
|
|
135
|
+
max-width: 22em;
|
|
136
|
+
margin-bottom: 1em;
|
|
137
|
+
color: var(--text-3, #7b8593);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.empty-link {
|
|
141
|
+
font-size: 0.875em;
|
|
142
|
+
font-weight: 500;
|
|
143
|
+
color: var(--color-link-primary);
|
|
144
|
+
text-decoration: none;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.empty-link:hover {
|
|
148
|
+
text-decoration: underline;
|
|
109
149
|
}
|
|
110
150
|
|
|
111
151
|
/* row of campaign pills the contact is currently a member of */
|
|
@@ -128,7 +168,8 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
128
168
|
}
|
|
129
169
|
|
|
130
170
|
/* each pill is colored with its campaign's hue - background, border
|
|
131
|
-
and text all derived from --pill-hue.
|
|
171
|
+
and text all derived from --pill-hue. clickable links to the
|
|
172
|
+
campaign's read page */
|
|
132
173
|
.campaign-pill {
|
|
133
174
|
display: inline-flex;
|
|
134
175
|
align-items: center;
|
|
@@ -146,6 +187,21 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
146
187
|
border: 1px solid
|
|
147
188
|
color-mix(in srgb, var(--pill-hue) 25%, var(--color-widget-bg, #fff));
|
|
148
189
|
color: var(--pill-hue);
|
|
190
|
+
cursor: pointer;
|
|
191
|
+
transition: background 100ms ease-in-out;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.campaign-pill:hover {
|
|
195
|
+
background: color-mix(
|
|
196
|
+
in srgb,
|
|
197
|
+
var(--pill-hue) 22%,
|
|
198
|
+
var(--color-widget-bg, #fff)
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.campaign-pill:focus-visible {
|
|
203
|
+
outline: 2px solid var(--pill-hue);
|
|
204
|
+
outline-offset: 1px;
|
|
149
205
|
}
|
|
150
206
|
|
|
151
207
|
/* status-badge dot leading each campaign pill, in the same hue */
|
|
@@ -424,7 +480,7 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
424
480
|
const requestedContact = this.contact;
|
|
425
481
|
try {
|
|
426
482
|
const response = await this.store.getUrl(
|
|
427
|
-
`/contact/
|
|
483
|
+
`/contact/timeline/${encodeURIComponent(this.contact)}/`,
|
|
428
484
|
{ force: true }
|
|
429
485
|
);
|
|
430
486
|
if (this.contact !== requestedContact) {
|
|
@@ -570,7 +626,7 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
570
626
|
// capture the contact at request time so a paged response that returns
|
|
571
627
|
// after the user has switched contacts can't append onto the new timeline
|
|
572
628
|
const requestedContact = this.contact;
|
|
573
|
-
const url = `/contact/
|
|
629
|
+
const url = `/contact/timeline/${encodeURIComponent(
|
|
574
630
|
this.contact
|
|
575
631
|
)}/?before=${encodeURIComponent(this.nextBefore)}`;
|
|
576
632
|
|
|
@@ -609,7 +665,7 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
609
665
|
|
|
610
666
|
this.loadingMoreFuture = true;
|
|
611
667
|
const requestedContact = this.contact;
|
|
612
|
-
const url = `/contact/
|
|
668
|
+
const url = `/contact/timeline/${encodeURIComponent(
|
|
613
669
|
this.contact
|
|
614
670
|
)}/?after=${encodeURIComponent(this.nextAfter)}`;
|
|
615
671
|
|
|
@@ -710,6 +766,13 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
710
766
|
html`<div
|
|
711
767
|
class="campaign-pill"
|
|
712
768
|
style="--pill-hue:${this.getCampaignColor(campaign.uuid)}"
|
|
769
|
+
role="button"
|
|
770
|
+
tabindex="0"
|
|
771
|
+
@click=${(e: Event) => this.handlePillClicked(e, campaign)}
|
|
772
|
+
@keydown=${(e: KeyboardEvent) =>
|
|
773
|
+
this.handleActivationKey(e, () =>
|
|
774
|
+
this.handlePillClicked(e, campaign)
|
|
775
|
+
)}
|
|
713
776
|
>
|
|
714
777
|
<span class="campaign-dot"></span>${campaign.name}
|
|
715
778
|
</div>`
|
|
@@ -742,7 +805,14 @@ export class ContactEvents extends EndpointMonitorElement {
|
|
|
742
805
|
pastDescending.length === 0
|
|
743
806
|
) {
|
|
744
807
|
return html`<div class="empty">
|
|
745
|
-
<slot name="empty"
|
|
808
|
+
<slot name="empty">
|
|
809
|
+
<temba-icon name=${Icon.schedule} size="2"></temba-icon>
|
|
810
|
+
<div class="empty-title">${this.lang_empty}</div>
|
|
811
|
+
<div class="empty-help">${this.lang_empty_help}</div>
|
|
812
|
+
<a class="empty-link" href="/campaign/" onclick="goto(event)"
|
|
813
|
+
>${this.lang_campaigns_link}</a
|
|
814
|
+
>
|
|
815
|
+
</slot>
|
|
746
816
|
</div>`;
|
|
747
817
|
}
|
|
748
818
|
|
package/temba-modules.ts
CHANGED
|
@@ -31,7 +31,7 @@ import { ContactFields } from './src/live/ContactFields';
|
|
|
31
31
|
import { ContactFieldEditor } from './src/live/ContactFieldEditor';
|
|
32
32
|
|
|
33
33
|
import { ContactBadges } from './src/live/ContactBadges';
|
|
34
|
-
import {
|
|
34
|
+
import { ContactTimeline } from './src/live/ContactTimeline';
|
|
35
35
|
import { TembaSlider } from './src/form/TembaSlider';
|
|
36
36
|
import { RunList } from './src/list/RunList';
|
|
37
37
|
import { FlowStoreElement } from './src/store/FlowStoreElement';
|
|
@@ -149,7 +149,7 @@ addCustomElement('temba-dropdown', Dropdown);
|
|
|
149
149
|
addCustomElement('temba-tabs', TabPane);
|
|
150
150
|
addCustomElement('temba-tab', Tab);
|
|
151
151
|
addCustomElement('temba-contact-badges', ContactBadges);
|
|
152
|
-
addCustomElement('temba-contact-
|
|
152
|
+
addCustomElement('temba-contact-timeline', ContactTimeline);
|
|
153
153
|
addCustomElement('temba-slider', TembaSlider);
|
|
154
154
|
addCustomElement('temba-content-menu', ContentMenu);
|
|
155
155
|
addCustomElement('temba-compose', Compose);
|