Skip to content

Commit

Permalink
Merge pull request #393 from nyaruka/temba-user
Browse files Browse the repository at this point in the history
Add temba-user component
  • Loading branch information
ericnewcomer authored Feb 7, 2024
2 parents 2a7bcb9 + af50720 commit 46619bf
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 118 deletions.
Binary file modified screenshots/truth/contacts/tickets-assignment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/truth/contacts/tickets.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 28 additions & 14 deletions src/contacts/ContactHistory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { css } from 'lit';
import { property } from 'lit/decorators.js';
import { html, TemplateResult } from 'lit-html';
import { Contact, CustomEventType, Ticket } from '../interfaces';
import { Contact, CustomEventType, Msg, Ticket } from '../interfaces';
import { RapidElement } from '../RapidElement';
import { Asset, getAssets, getClasses, postJSON, throttle } from '../utils';

Expand Down Expand Up @@ -58,6 +58,7 @@ import {
SCROLL_THRESHOLD,
} from './helpers';
import { Lightbox } from '../lightbox/Lightbox';
import { Store } from '../store/Store';

// when images load, make sure we are on the bottom of the scroll window if necessary
export const loadHandler = function (event) {
Expand All @@ -77,6 +78,7 @@ export const loadHandler = function (event) {

export class ContactHistory extends RapidElement {
public httpComplete: Promise<void | ContactHistoryPage>;
private store: Store;

public constructor() {
super();
Expand All @@ -85,6 +87,7 @@ export class ContactHistory extends RapidElement {
connectedCallback() {
super.connectedCallback();
this.shadowRoot.addEventListener('load', loadHandler, true);
this.store = document.querySelector('temba-store') as Store;
}

disconnectedCallback() {
Expand Down Expand Up @@ -632,7 +635,13 @@ export class ContactHistory extends RapidElement {
case Events.MESSAGE_CREATED:
case Events.MESSAGE_RECEIVED:
case Events.BROADCAST_CREATED:
return renderMsgEvent(event as MsgEvent, this.agent);
if ((event as MsgEvent).created_by) {
(event as MsgEvent).created_by = this.store.getUser(
(event as MsgEvent).created_by.email
);
}

return renderMsgEvent(event as MsgEvent);

case Events.FLOW_ENTERED:
case Events.FLOW_EXITED:
Expand Down Expand Up @@ -840,18 +849,23 @@ export class ContactHistory extends RapidElement {
})}
</div>
<div class="new-messages-container">
<div
@click=${() => {
this.scrollToBottom(true);
}}
class="new-messages ${getClasses({
expanded: this.showMessageAlert,
})}"
>
New Messages
</div>
</div>
${
this.contact && this.contact.status === 'active'
? html`<div class="new-messages-container">
<div
@click=${() => {
this.scrollToBottom(true);
}}
class="new-messages ${getClasses({
expanded: this.showMessageAlert,
})}"
>
New Messages
</div>
</div>`
: null
}
</div>
`;
}
Expand Down
62 changes: 28 additions & 34 deletions src/contacts/ContactTickets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import { css, html, PropertyValueMap, TemplateResult } from 'lit';
import { property } from 'lit/decorators.js';
import { CustomEventType, Ticket, TicketStatus, User } from '../interfaces';
import { StoreElement } from '../store/StoreElement';
import {
getClasses,
getFullName,
postJSON,
renderAvatar,
stopEvent,
} from '../utils';
import { getClasses, postJSON, stopEvent } from '../utils';
import { Icon } from '../vectoricon';

const dropdownUserScale = 0.7;
const inlineUserScale = 0.8;

export class ContactTickets extends StoreElement {
@property({ type: String })
agent: string;
Expand Down Expand Up @@ -129,6 +126,10 @@ export class ContactTickets extends StoreElement {
border-bottom: 1px solid #f3f3f3;
}
.option-group temba-user {
flex-grow: 1;
}
.assigned .user {
flex-grow: 1;
}
Expand Down Expand Up @@ -164,9 +165,6 @@ export class ContactTickets extends StoreElement {
background: var(--color-selection);
}
.user .avatar {
}
.user .name {
display: -webkit-box;
-webkit-line-clamp: 1;
Expand Down Expand Up @@ -243,16 +241,6 @@ export class ContactTickets extends StoreElement {
}
}

private renderUser(user: User) {
if (!user) {
return null;
}
return html`<div class="user">
<div class="avatar">${renderAvatar({ user: user, scale: 0.6 })}</div>
<div class="name">${getFullName(user)}</div>
</div>`;
}

private handleClose(uuid: string) {
postJSON(`/api/v2/ticket_actions.json`, {
tickets: [uuid],
Expand Down Expand Up @@ -285,6 +273,7 @@ export class ContactTickets extends StoreElement {
if (ticket.assignee && ticket.assignee.email === email) {
return;
}
this.blur();

postJSON(`/api/v2/ticket_actions.json`, {
tickets: [uuid],
Expand Down Expand Up @@ -352,13 +341,10 @@ export class ContactTickets extends StoreElement {
<div slot="toggle" class="toggle">
${ticket.assignee
? html`
<div>
${renderAvatar({
name: ticket.assignee.name,
user: ticket.assignee,
scale: 0.7,
})}
</div>
<temba-user
email=${ticket.assignee.email}
scale="${inlineUserScale}"
></temba-user>
`
: html`
<temba-button
Expand All @@ -384,11 +370,11 @@ export class ContactTickets extends StoreElement {
? 'current-user'
: ''}"
>
${this.renderUser(
users.find(
user => user.email === ticket.assignee.email
)
)}
<temba-user
email=${ticket.assignee.email}
name
scale="${dropdownUserScale}"
></temba-user>
<temba-button
name="Unassign"
primary
Expand Down Expand Up @@ -418,7 +404,11 @@ export class ContactTickets extends StoreElement {
);
}}
>
${this.renderUser(agent)}
<temba-user
email=${agent.email}
name
scale="${dropdownUserScale}"
></temba-user>
</div>
`
: null}
Expand All @@ -444,7 +434,11 @@ export class ContactTickets extends StoreElement {
);
}}
>
${this.renderUser(user)}
<temba-user
email=${user.email}
scale="${dropdownUserScale}"
name
></temba-user>
</div>`;
})}
</div>
Expand Down
27 changes: 8 additions & 19 deletions src/contacts/events.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { css, EventPart, html, TemplateResult } from 'lit';
import { css, html, TemplateResult } from 'lit';
import { Msg, ObjectReference, User } from '../interfaces';
import {
getClasses,
NamedObject,
oxford,
oxfordFn,
oxfordNamed,
renderAvatar,
} from '../utils';
import { getClasses, oxford, oxfordFn, oxfordNamed } from '../utils';
import { Icon } from '../vectoricon';
import { getDisplayName } from './helpers';

Expand Down Expand Up @@ -758,10 +751,7 @@ export const renderAttachment = (attachment: string): TemplateResult => {
return html`<div style="">${inner}</div>`;
};

export const renderMsgEvent = (
event: MsgEvent,
agent: string
): TemplateResult => {
export const renderMsgEvent = (event: MsgEvent): TemplateResult => {
const isInbound = event.type === Events.MESSAGE_RECEIVED;
const isError = event.status === 'E';
const isFailure = event.status === 'F';
Expand Down Expand Up @@ -874,9 +864,10 @@ export const renderMsgEvent = (
</div>
${!isInbound && event.created_by
? html`<div style="margin-left:0.8em;margin-top:0.3em;font-size:0.9em">
${renderAvatar({ user: event.created_by })}
</div>`
? html`<temba-user
style="margin-left:0.5em"
email=${event.created_by.email}
></temba-user>`
: null}
</div>`;
};
Expand Down Expand Up @@ -1010,9 +1001,7 @@ export const renderNoteCreated = (event: TicketEvent): TemplateResult => {
></temba-date>
</div>
</div>
<div style="margin-left:0.8em;margin-top:0.3em;">
${renderAvatar({ user: event.created_by })}
</div>
<temba-user email=${event.created_by.email}></temba-user>
</div>`;
};

Expand Down
3 changes: 0 additions & 3 deletions src/imagepicker/ImagePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,6 @@ export class ImagePicker extends FormElement {

picker.value = fd;
picker.closeCroppie();

console.log('image changed', picker.name, picker.value, picker.url);
// picker.dispatchEvent(new CustomEvent('image-changed', { detail: resp }));
});
}

Expand Down
9 changes: 4 additions & 5 deletions src/list/TicketList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { property } from 'lit/decorators.js';
import { TembaList } from './TembaList';
import { Contact } from '../interfaces';
import { Icon } from '../vectoricon';
import { renderAvatar } from '../utils';

export class TicketList extends TembaList {
@property({ type: String })
Expand Down Expand Up @@ -76,10 +75,10 @@ export class TicketList extends TembaList {
>
<div>
${!contact.ticket.closed_on && contact.ticket.assignee
? html`${renderAvatar({
user: contact.ticket.assignee,
scale: 0.8,
})}`
? html`<temba-user
email=${contact.ticket.assignee.email}
scale="0.8"
></temba-user>`
: null}
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/store/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ export class Store extends RapidElement {
);
}

public getUser(email: string) {
return this.users.find((user: User) => user.email === email);
}

public firstUpdated() {
this.reset();
}
Expand Down
51 changes: 13 additions & 38 deletions src/store/StoreElement.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { html, PropertyValueMap, TemplateResult } from 'lit';
import { PropertyValueMap } from 'lit';
import { property } from 'lit/decorators.js';
import { CustomEventType } from '../interfaces';
import { RapidElement } from '../RapidElement';

import { Store } from './Store';
import { StoreMonitorElement } from './StoreMonitorElement';

/**
* StoreElement is a listener for a given endpoint that re-renders
* when the underlying store element changes
*/
export class StoreElement extends RapidElement {
export class StoreElement extends StoreMonitorElement {
@property({ type: String })
url: string;

Expand All @@ -31,17 +32,15 @@ export class StoreElement extends RapidElement {
});
}

private handleStoreUpdated(event: CustomEvent) {
this.store.initialHttpComplete.then(() => {
if (event.detail.url === this.url) {
const previous = this.data;
this.data = event.detail.data;
this.fireCustomEvent(CustomEventType.Refreshed, {
data: event.detail.data,
previous,
});
}
});
protected storeUpdated(event: CustomEvent) {
if (event.detail.url === this.url) {
const previous = this.data;
this.data = event.detail.data;
this.fireCustomEvent(CustomEventType.Refreshed, {
data: event.detail.data,
previous,
});
}
}

protected updated(
Expand All @@ -59,30 +58,6 @@ export class StoreElement extends RapidElement {

connectedCallback(): void {
super.connectedCallback();
this.store = document.querySelector('temba-store') as Store;
this.handleStoreUpdated = this.handleStoreUpdated.bind(this);
this.prepareData = this.prepareData.bind(this);
if (this.store) {
this.store.addEventListener(
CustomEventType.StoreUpdated,
this.handleStoreUpdated
);
}
}

disconnectedCallback(): void {
super.disconnectedCallback();
if (this.store) {
this.store.removeEventListener(
CustomEventType.StoreUpdated,
this.handleStoreUpdated
);
}
}

public render(): TemplateResult {
if (!this.store.ready && this.showLoading) {
return html`<temba-loading></temba-loading>`;
}
}
}
Loading

0 comments on commit 46619bf

Please sign in to comment.