@sippet-ai/operator-widget 0.0.12
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/LICENSE +2 -0
- package/README.md +136 -0
- package/cdn/loader.js +146 -0
- package/custom-elements.json +2241 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/voip-widget/index.d.ts +18 -0
- package/dist/components/voip-widget/index.js +4 -0
- package/dist/components/voip-widget/voip-widget-contacts-tab.d.ts +14 -0
- package/dist/components/voip-widget/voip-widget-contacts-tab.js +45 -0
- package/dist/components/voip-widget/voip-widget-history-tab.d.ts +13 -0
- package/dist/components/voip-widget/voip-widget-history-tab.js +43 -0
- package/dist/components/voip-widget/voip-widget-launcher.d.ts +18 -0
- package/dist/components/voip-widget/voip-widget-launcher.js +100 -0
- package/dist/components/voip-widget/voip-widget-panel.d.ts +21 -0
- package/dist/components/voip-widget/voip-widget-panel.js +193 -0
- package/dist/components/voip-widget/voip-widget-phone-tab.d.ts +21 -0
- package/dist/components/voip-widget/voip-widget-phone-tab.js +187 -0
- package/dist/components/voip-widget/voip-widget-queue-tab.d.ts +14 -0
- package/dist/components/voip-widget/voip-widget-queue-tab.js +49 -0
- package/dist/components/voip-widget/voip-widget-settings-tab.d.ts +21 -0
- package/dist/components/voip-widget/voip-widget-settings-tab.js +135 -0
- package/dist/components/voip-widget/voip-widget.d.ts +142 -0
- package/dist/components/voip-widget/voip-widget.js +1329 -0
- package/dist/components/voip-widget/voip-widget.types.d.ts +22 -0
- package/dist/components/voip-widget/voip-widget.types.js +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/lib/realtime.d.ts +1 -0
- package/dist/lib/realtime.js +1 -0
- package/dist/lib/sippet.d.ts +40 -0
- package/dist/lib/sippet.js +197 -0
- package/dist/lib/tailwindMixin.d.ts +6 -0
- package/dist/lib/tailwindMixin.js +24 -0
- package/dist/styles/tailwind.global.css +2 -0
- package/dist/styles/tailwind.global.css.js +1 -0
- package/package.json +126 -0
- package/react/SippetAIVoipWidget.d.ts +158 -0
- package/react/SippetAIVoipWidget.js +72 -0
- package/react/SippetAIVoipWidgetContactsTab.d.ts +67 -0
- package/react/SippetAIVoipWidgetContactsTab.js +29 -0
- package/react/SippetAIVoipWidgetHistoryTab.d.ts +55 -0
- package/react/SippetAIVoipWidgetHistoryTab.js +26 -0
- package/react/SippetAIVoipWidgetLauncher.d.ts +83 -0
- package/react/SippetAIVoipWidgetLauncher.js +41 -0
- package/react/SippetAIVoipWidgetPanel.d.ts +87 -0
- package/react/SippetAIVoipWidgetPanel.js +43 -0
- package/react/SippetAIVoipWidgetPhoneTab.d.ts +87 -0
- package/react/SippetAIVoipWidgetPhoneTab.js +43 -0
- package/react/SippetAIVoipWidgetQueueTab.d.ts +67 -0
- package/react/SippetAIVoipWidgetQueueTab.js +27 -0
- package/react/SippetAIVoipWidgetSettingsTab.d.ts +91 -0
- package/react/SippetAIVoipWidgetSettingsTab.js +47 -0
- package/react/index.d.ts +8 -0
- package/react/index.js +8 -0
- package/react/react-utils.js +67 -0
- package/types/custom-element-jsx.d.ts +956 -0
- package/types/custom-element-svelte.d.ts +264 -0
- package/types/custom-element-vuejs.d.ts +234 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './voip-widget/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './voip-widget/index.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SippetAIVoipWidget } from './voip-widget.js';
|
|
2
|
+
export type * from './voip-widget.js';
|
|
3
|
+
declare global {
|
|
4
|
+
/**
|
|
5
|
+
* adds component custom elements to the global HTML element map
|
|
6
|
+
* no other changes need to be made here
|
|
7
|
+
*/
|
|
8
|
+
interface HTMLElementTagNameMap {
|
|
9
|
+
'sippetai-voip-widget': SippetAIVoipWidget;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* adds component custom events to the global JS event map
|
|
13
|
+
* add new custom events here
|
|
14
|
+
*/
|
|
15
|
+
interface GlobalEventHandlersEventMap {
|
|
16
|
+
'custom-event': CustomEvent;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { Contact } from './voip-widget.types.js';
|
|
3
|
+
declare const TwLitElement: typeof LitElement;
|
|
4
|
+
export declare class SippetAIVoipWidgetContactsTab extends TwLitElement {
|
|
5
|
+
contacts: Contact[];
|
|
6
|
+
private emit;
|
|
7
|
+
render(): import("lit").TemplateResult<1>;
|
|
8
|
+
}
|
|
9
|
+
declare global {
|
|
10
|
+
interface HTMLElementTagNameMap {
|
|
11
|
+
'sippetai-voip-widget-contacts-tab': SippetAIVoipWidgetContactsTab;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, LitElement } from 'lit';
|
|
8
|
+
import { property } from 'lit/decorators.js';
|
|
9
|
+
import { TW } from '../../lib/tailwindMixin.js';
|
|
10
|
+
const TwLitElement = TW(LitElement);
|
|
11
|
+
export class SippetAIVoipWidgetContactsTab extends TwLitElement {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.contacts = [];
|
|
15
|
+
}
|
|
16
|
+
emit(name, detail) {
|
|
17
|
+
this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true }));
|
|
18
|
+
}
|
|
19
|
+
render() {
|
|
20
|
+
return html `
|
|
21
|
+
<div class="flex flex-col gap-2">
|
|
22
|
+
${this.contacts.map((contact) => html `
|
|
23
|
+
<div class="flex items-center justify-between gap-3 rounded-2xl bg-white px-3 py-2">
|
|
24
|
+
<div>
|
|
25
|
+
<div class="text-xs font-semibold text-slate-900">${contact.name}</div>
|
|
26
|
+
<div class="text-[11px] text-slate-900">${contact.number}</div>
|
|
27
|
+
</div>
|
|
28
|
+
<button
|
|
29
|
+
class="rounded-xl voip-primary px-3 py-1 text-xs font-semibold transition-shadow"
|
|
30
|
+
@click=${() => this.emit('voip-contact-call', { number: contact.number })}
|
|
31
|
+
>
|
|
32
|
+
Call
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
`)}
|
|
36
|
+
</div>
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
__decorate([
|
|
41
|
+
property({ type: Array })
|
|
42
|
+
], SippetAIVoipWidgetContactsTab.prototype, "contacts", void 0);
|
|
43
|
+
if (!customElements.get('sippetai-voip-widget-contacts-tab')) {
|
|
44
|
+
customElements.define('sippetai-voip-widget-contacts-tab', SippetAIVoipWidgetContactsTab);
|
|
45
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { HistoryEntry } from './voip-widget.types.js';
|
|
3
|
+
declare const TwLitElement: typeof LitElement;
|
|
4
|
+
export declare class SippetAIVoipWidgetHistoryTab extends TwLitElement {
|
|
5
|
+
history: HistoryEntry[];
|
|
6
|
+
render(): import("lit").TemplateResult<1>;
|
|
7
|
+
}
|
|
8
|
+
declare global {
|
|
9
|
+
interface HTMLElementTagNameMap {
|
|
10
|
+
'sippetai-voip-widget-history-tab': SippetAIVoipWidgetHistoryTab;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, LitElement } from 'lit';
|
|
8
|
+
import { property } from 'lit/decorators.js';
|
|
9
|
+
import { TW } from '../../lib/tailwindMixin.js';
|
|
10
|
+
const TwLitElement = TW(LitElement);
|
|
11
|
+
export class SippetAIVoipWidgetHistoryTab extends TwLitElement {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.history = [];
|
|
15
|
+
}
|
|
16
|
+
render() {
|
|
17
|
+
const history = Array.isArray(this.history) ? this.history : [];
|
|
18
|
+
return html `
|
|
19
|
+
<div class="flex flex-col gap-2">
|
|
20
|
+
${history.map((entry) => html `
|
|
21
|
+
<div class="flex items-center justify-between gap-3 rounded-2xl bg-white px-3 py-2">
|
|
22
|
+
<div>
|
|
23
|
+
<div class="text-xs font-semibold text-slate-900">${entry.name}</div>
|
|
24
|
+
<div class="text-[11px] text-slate-900">${entry.number}</div>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="flex items-center gap-2 text-[10px] uppercase tracking-wide text-slate-900">
|
|
27
|
+
<span>${entry.time}</span>
|
|
28
|
+
<span class="rounded-full bg-slate-900 px-2 py-0.5 text-[9px] font-semibold text-white">
|
|
29
|
+
${entry.type}
|
|
30
|
+
</span>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
`)}
|
|
34
|
+
</div>
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
__decorate([
|
|
39
|
+
property({ type: Array })
|
|
40
|
+
], SippetAIVoipWidgetHistoryTab.prototype, "history", void 0);
|
|
41
|
+
if (!customElements.get('sippetai-voip-widget-history-tab')) {
|
|
42
|
+
customElements.define('sippetai-voip-widget-history-tab', SippetAIVoipWidgetHistoryTab);
|
|
43
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
declare const TwLitElement: typeof LitElement;
|
|
3
|
+
export declare class SippetAIVoipWidgetLauncher extends TwLitElement {
|
|
4
|
+
open: boolean;
|
|
5
|
+
queueCount: number;
|
|
6
|
+
incomingCall: boolean;
|
|
7
|
+
incomingFromQueue: boolean;
|
|
8
|
+
incomingCallerName: string;
|
|
9
|
+
updated(): void;
|
|
10
|
+
private emit;
|
|
11
|
+
render(): import("lit").TemplateResult<1>;
|
|
12
|
+
}
|
|
13
|
+
declare global {
|
|
14
|
+
interface HTMLElementTagNameMap {
|
|
15
|
+
'sippetai-voip-widget-launcher': SippetAIVoipWidgetLauncher;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, LitElement } from 'lit';
|
|
8
|
+
import { property } from 'lit/decorators.js';
|
|
9
|
+
import { createIcons, Phone, PhoneCall, PhoneOff, Pause } from 'lucide';
|
|
10
|
+
import { TW } from '../../lib/tailwindMixin.js';
|
|
11
|
+
const TwLitElement = TW(LitElement);
|
|
12
|
+
export class SippetAIVoipWidgetLauncher extends TwLitElement {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.open = false;
|
|
16
|
+
this.queueCount = 0;
|
|
17
|
+
this.incomingCall = false;
|
|
18
|
+
this.incomingFromQueue = false;
|
|
19
|
+
this.incomingCallerName = 'Colleague';
|
|
20
|
+
}
|
|
21
|
+
updated() {
|
|
22
|
+
createIcons({ icons: { Phone, PhoneCall, PhoneOff, Pause }, root: this.renderRoot });
|
|
23
|
+
}
|
|
24
|
+
emit(name, detail) {
|
|
25
|
+
this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true }));
|
|
26
|
+
}
|
|
27
|
+
render() {
|
|
28
|
+
const showBadge = !this.open && this.queueCount > 0;
|
|
29
|
+
const showClosedIncoming = !this.open && this.incomingCall && !this.incomingFromQueue;
|
|
30
|
+
return html `
|
|
31
|
+
<div class="relative flex flex-col items-end gap-3">
|
|
32
|
+
<button
|
|
33
|
+
class="relative grid h-14 w-14 place-items-center rounded-2xl voip-primary transition-shadow"
|
|
34
|
+
@click=${() => this.emit('voip-toggle')}
|
|
35
|
+
>
|
|
36
|
+
<i data-lucide="phone" class="h-5 w-5"></i>
|
|
37
|
+
${showBadge
|
|
38
|
+
? html `
|
|
39
|
+
<span
|
|
40
|
+
class="absolute -right-1 -top-1 rounded-full border-2 border-slate-900 bg-red-600 px-1.5 text-[10px] font-semibold text-white"
|
|
41
|
+
>
|
|
42
|
+
${this.queueCount}
|
|
43
|
+
</span>
|
|
44
|
+
`
|
|
45
|
+
: null}
|
|
46
|
+
</button>
|
|
47
|
+
|
|
48
|
+
${showClosedIncoming
|
|
49
|
+
? html `
|
|
50
|
+
<div class="w-60 rounded-2xl border border-slate-200 bg-white p-3 shadow-xl">
|
|
51
|
+
<div class="text-sm font-semibold text-slate-900">Incoming call</div>
|
|
52
|
+
<div class="text-xs text-slate-900">${this.incomingCallerName}</div>
|
|
53
|
+
<div class="mt-2 flex flex-wrap gap-2">
|
|
54
|
+
<button
|
|
55
|
+
class="inline-flex items-center gap-1 rounded-xl bg-emerald-600 px-3 py-1 text-xs font-semibold text-white"
|
|
56
|
+
@click=${() => this.emit('voip-accept')}
|
|
57
|
+
>
|
|
58
|
+
<i data-lucide="phone-call" class="h-3 w-3"></i>
|
|
59
|
+
Accept
|
|
60
|
+
</button>
|
|
61
|
+
<button
|
|
62
|
+
class="inline-flex items-center gap-1 rounded-xl bg-amber-400 px-3 py-1 text-xs font-semibold text-slate-900"
|
|
63
|
+
@click=${() => this.emit('voip-hold')}
|
|
64
|
+
>
|
|
65
|
+
<i data-lucide="pause" class="h-3 w-3"></i>
|
|
66
|
+
Hold
|
|
67
|
+
</button>
|
|
68
|
+
<button
|
|
69
|
+
class="inline-flex items-center gap-1 rounded-xl bg-red-600 px-3 py-1 text-xs font-semibold text-white"
|
|
70
|
+
@click=${() => this.emit('voip-decline')}
|
|
71
|
+
>
|
|
72
|
+
<i data-lucide="phone-off" class="h-3 w-3"></i>
|
|
73
|
+
Decline
|
|
74
|
+
</button>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
`
|
|
78
|
+
: null}
|
|
79
|
+
</div>
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
__decorate([
|
|
84
|
+
property({ type: Boolean })
|
|
85
|
+
], SippetAIVoipWidgetLauncher.prototype, "open", void 0);
|
|
86
|
+
__decorate([
|
|
87
|
+
property({ type: Number })
|
|
88
|
+
], SippetAIVoipWidgetLauncher.prototype, "queueCount", void 0);
|
|
89
|
+
__decorate([
|
|
90
|
+
property({ type: Boolean })
|
|
91
|
+
], SippetAIVoipWidgetLauncher.prototype, "incomingCall", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
property({ type: Boolean })
|
|
94
|
+
], SippetAIVoipWidgetLauncher.prototype, "incomingFromQueue", void 0);
|
|
95
|
+
__decorate([
|
|
96
|
+
property({ type: String })
|
|
97
|
+
], SippetAIVoipWidgetLauncher.prototype, "incomingCallerName", void 0);
|
|
98
|
+
if (!customElements.get('sippetai-voip-widget-launcher')) {
|
|
99
|
+
customElements.define('sippetai-voip-widget-launcher', SippetAIVoipWidgetLauncher);
|
|
100
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { VoipTab } from './voip-widget.types.js';
|
|
3
|
+
declare const TwLitElement: typeof LitElement;
|
|
4
|
+
export declare class SippetAIVoipWidgetPanel extends TwLitElement {
|
|
5
|
+
userName: string;
|
|
6
|
+
availability: string;
|
|
7
|
+
activeTab: VoipTab;
|
|
8
|
+
incomingCall: boolean;
|
|
9
|
+
incomingFromQueue: boolean;
|
|
10
|
+
incomingCallerName: string;
|
|
11
|
+
private showAvailability;
|
|
12
|
+
updated(): void;
|
|
13
|
+
private emit;
|
|
14
|
+
render(): import("lit").TemplateResult<1>;
|
|
15
|
+
}
|
|
16
|
+
declare global {
|
|
17
|
+
interface HTMLElementTagNameMap {
|
|
18
|
+
'sippetai-voip-widget-panel': SippetAIVoipWidgetPanel;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, LitElement } from 'lit';
|
|
8
|
+
import { property, state } from 'lit/decorators.js';
|
|
9
|
+
import { createIcons, Clock, ListOrdered, Phone, Settings, Users, X, } from 'lucide';
|
|
10
|
+
import { TW } from '../../lib/tailwindMixin.js';
|
|
11
|
+
const TwLitElement = TW(LitElement);
|
|
12
|
+
export class SippetAIVoipWidgetPanel extends TwLitElement {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.userName = 'Agent Parker';
|
|
16
|
+
this.availability = 'available';
|
|
17
|
+
this.activeTab = 'phone';
|
|
18
|
+
this.incomingCall = false;
|
|
19
|
+
this.incomingFromQueue = false;
|
|
20
|
+
this.incomingCallerName = 'Colleague';
|
|
21
|
+
this.showAvailability = false;
|
|
22
|
+
}
|
|
23
|
+
updated() {
|
|
24
|
+
createIcons({
|
|
25
|
+
icons: { Phone, ListOrdered, Users, Clock, Settings, X },
|
|
26
|
+
root: this.renderRoot,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
emit(name, detail) {
|
|
30
|
+
this.dispatchEvent(new CustomEvent(name, { detail, bubbles: true, composed: true }));
|
|
31
|
+
}
|
|
32
|
+
render() {
|
|
33
|
+
const initials = this.userName
|
|
34
|
+
.split(' ')
|
|
35
|
+
.map(part => part[0])
|
|
36
|
+
.join('')
|
|
37
|
+
.slice(0, 2)
|
|
38
|
+
.toUpperCase();
|
|
39
|
+
const statusColor = this.availability === 'available'
|
|
40
|
+
? 'bg-emerald-500'
|
|
41
|
+
: this.availability === 'on_break'
|
|
42
|
+
? 'bg-amber-400'
|
|
43
|
+
: 'bg-red-500';
|
|
44
|
+
return html `
|
|
45
|
+
<div
|
|
46
|
+
class="flex h-[480px] w-80 flex-col overflow-hidden rounded-3xl bg-slate-50 shadow-2xl"
|
|
47
|
+
>
|
|
48
|
+
<div
|
|
49
|
+
class="flex cursor-grab items-center justify-between gap-3 bg-gradient-to-br from-amber-100 via-orange-50 to-sky-100 px-4 py-4"
|
|
50
|
+
@pointerdown=${(event) => this.emit('voip-drag-start', {
|
|
51
|
+
x: event.clientX,
|
|
52
|
+
y: event.clientY,
|
|
53
|
+
id: event.pointerId,
|
|
54
|
+
})}
|
|
55
|
+
@pointermove=${(event) => this.emit('voip-drag-move', {
|
|
56
|
+
x: event.clientX,
|
|
57
|
+
y: event.clientY,
|
|
58
|
+
buttons: event.buttons,
|
|
59
|
+
})}
|
|
60
|
+
@pointerup=${(event) => this.emit('voip-drag-end', { id: event.pointerId })}
|
|
61
|
+
>
|
|
62
|
+
<div class="relative flex items-center gap-3">
|
|
63
|
+
<button
|
|
64
|
+
class="relative grid h-11 w-11 place-items-center rounded-2xl bg-slate-900 text-xs font-semibold text-white"
|
|
65
|
+
@click=${() => {
|
|
66
|
+
this.showAvailability = !this.showAvailability;
|
|
67
|
+
}}
|
|
68
|
+
aria-label="Open profile menu"
|
|
69
|
+
>
|
|
70
|
+
${initials || 'AG'}
|
|
71
|
+
<span
|
|
72
|
+
class=${`absolute -right-1 -top-1 h-4 w-4 rounded-full border-2 border-white shadow ${statusColor}`}
|
|
73
|
+
></span>
|
|
74
|
+
</button>
|
|
75
|
+
<span class="text-sm font-semibold text-slate-900"
|
|
76
|
+
>${this.userName}</span
|
|
77
|
+
>
|
|
78
|
+
${this.showAvailability
|
|
79
|
+
? html `
|
|
80
|
+
<div
|
|
81
|
+
class="absolute left-0 top-12 z-10 w-44 rounded-2xl border border-slate-200 bg-white p-2 shadow-lg"
|
|
82
|
+
>
|
|
83
|
+
<div class="px-2 py-1 text-xs font-semibold text-slate-900">
|
|
84
|
+
${this.userName}
|
|
85
|
+
</div>
|
|
86
|
+
<div class="mt-1 grid gap-1">
|
|
87
|
+
${[
|
|
88
|
+
{
|
|
89
|
+
label: 'Available',
|
|
90
|
+
value: 'available',
|
|
91
|
+
color: 'bg-emerald-500',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
label: 'On break',
|
|
95
|
+
value: 'on_break',
|
|
96
|
+
color: 'bg-amber-400',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: 'Logged out',
|
|
100
|
+
value: 'logged_out',
|
|
101
|
+
color: 'bg-red-500',
|
|
102
|
+
},
|
|
103
|
+
].map(option => html `
|
|
104
|
+
<button
|
|
105
|
+
class=${`flex items-center justify-between rounded-lg px-2 py-1 text-xs ${this.availability === option.value
|
|
106
|
+
? 'voip-primary text-white'
|
|
107
|
+
: 'text-slate-900 hover:bg-slate-100'}`}
|
|
108
|
+
@click=${() => {
|
|
109
|
+
this.emit('voip-availability', {
|
|
110
|
+
value: option.value,
|
|
111
|
+
});
|
|
112
|
+
this.showAvailability = false;
|
|
113
|
+
}}
|
|
114
|
+
>
|
|
115
|
+
<span>${option.label}</span>
|
|
116
|
+
<span
|
|
117
|
+
class=${`h-2 w-2 rounded-full ${option.color}`}
|
|
118
|
+
></span>
|
|
119
|
+
</button>
|
|
120
|
+
`)}
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
`
|
|
124
|
+
: null}
|
|
125
|
+
</div>
|
|
126
|
+
<div class="flex items-center gap-2">
|
|
127
|
+
<button
|
|
128
|
+
class="grid h-8 w-8 place-items-center rounded-lg bg-slate-200 text-slate-900"
|
|
129
|
+
@click=${() => this.emit('voip-settings')}
|
|
130
|
+
>
|
|
131
|
+
<i data-lucide="settings" class="h-4 w-4"></i>
|
|
132
|
+
</button>
|
|
133
|
+
<button
|
|
134
|
+
class="grid h-8 w-8 place-items-center rounded-lg bg-slate-200 text-slate-900"
|
|
135
|
+
@click=${() => this.emit('voip-close')}
|
|
136
|
+
>
|
|
137
|
+
<i data-lucide="x" class="h-4 w-4"></i>
|
|
138
|
+
</button>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<div
|
|
143
|
+
class="grid grid-cols-4 border-b border-slate-200 bg-white text-xs"
|
|
144
|
+
>
|
|
145
|
+
${[
|
|
146
|
+
{ tab: 'phone', label: 'Phone', icon: 'phone' },
|
|
147
|
+
{ tab: 'queue', label: 'Queue', icon: 'list-ordered' },
|
|
148
|
+
{ tab: 'contacts', label: 'Contacts', icon: 'users' },
|
|
149
|
+
{ tab: 'history', label: 'History', icon: 'clock' },
|
|
150
|
+
].map(({ tab, label, icon }) => html `
|
|
151
|
+
<button
|
|
152
|
+
class=${`flex flex-col items-center gap-1 px-2 py-2 text-[10px] font-semibold uppercase tracking-wide ${this.activeTab === tab
|
|
153
|
+
? 'voip-primary text-white'
|
|
154
|
+
: 'text-slate-900'}`}
|
|
155
|
+
@click=${() => this.emit('voip-tab', { tab })}
|
|
156
|
+
>
|
|
157
|
+
<i data-lucide=${icon} class="h-4 w-4"></i>
|
|
158
|
+
${label}
|
|
159
|
+
</button>
|
|
160
|
+
`)}
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<div class="flex-1 overflow-y-auto bg-slate-50 px-4 py-4">
|
|
164
|
+
<slot></slot>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
__decorate([
|
|
171
|
+
property({ type: String })
|
|
172
|
+
], SippetAIVoipWidgetPanel.prototype, "userName", void 0);
|
|
173
|
+
__decorate([
|
|
174
|
+
property({ type: String })
|
|
175
|
+
], SippetAIVoipWidgetPanel.prototype, "availability", void 0);
|
|
176
|
+
__decorate([
|
|
177
|
+
property({ type: String })
|
|
178
|
+
], SippetAIVoipWidgetPanel.prototype, "activeTab", void 0);
|
|
179
|
+
__decorate([
|
|
180
|
+
property({ type: Boolean })
|
|
181
|
+
], SippetAIVoipWidgetPanel.prototype, "incomingCall", void 0);
|
|
182
|
+
__decorate([
|
|
183
|
+
property({ type: Boolean })
|
|
184
|
+
], SippetAIVoipWidgetPanel.prototype, "incomingFromQueue", void 0);
|
|
185
|
+
__decorate([
|
|
186
|
+
property({ type: String })
|
|
187
|
+
], SippetAIVoipWidgetPanel.prototype, "incomingCallerName", void 0);
|
|
188
|
+
__decorate([
|
|
189
|
+
state()
|
|
190
|
+
], SippetAIVoipWidgetPanel.prototype, "showAvailability", void 0);
|
|
191
|
+
if (!customElements.get('sippetai-voip-widget-panel')) {
|
|
192
|
+
customElements.define('sippetai-voip-widget-panel', SippetAIVoipWidgetPanel);
|
|
193
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { CallState, SipStatus } from './voip-widget.types.js';
|
|
3
|
+
declare const TwLitElement: typeof LitElement;
|
|
4
|
+
export declare class SippetAIVoipWidgetPhoneTab extends TwLitElement {
|
|
5
|
+
dialNumber: string;
|
|
6
|
+
sipStatus: SipStatus;
|
|
7
|
+
callState: CallState;
|
|
8
|
+
callSeconds: number;
|
|
9
|
+
isMuted: boolean;
|
|
10
|
+
isHeld: boolean;
|
|
11
|
+
updated(): void;
|
|
12
|
+
private emit;
|
|
13
|
+
private playDtmfTone;
|
|
14
|
+
render(): import("lit").TemplateResult<1>;
|
|
15
|
+
}
|
|
16
|
+
declare global {
|
|
17
|
+
interface HTMLElementTagNameMap {
|
|
18
|
+
'sippetai-voip-widget-phone-tab': SippetAIVoipWidgetPhoneTab;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export {};
|