@spektra-cloudevents/application-copilot-widget 1.1.0 → 1.2.0
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/dist/index.cjs +45 -9
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +45 -9
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -77,7 +77,7 @@ var widgetStyles = `
|
|
|
77
77
|
/* Panel */
|
|
78
78
|
.acw-panel {
|
|
79
79
|
position: fixed; right: 24px; bottom: 96px; z-index: 2147483000;
|
|
80
|
-
width:
|
|
80
|
+
width: 480px; max-width: calc(100vw - 48px); height: 660px; max-height: calc(100vh - 120px);
|
|
81
81
|
display: none; flex-direction: column;
|
|
82
82
|
background: var(--acw-bg); color: var(--acw-fg);
|
|
83
83
|
border: 1px solid var(--acw-border); border-radius: 16px; overflow: hidden;
|
|
@@ -135,6 +135,26 @@ var widgetStyles = `
|
|
|
135
135
|
.acw-input:focus { outline: 2px solid var(--acw-accent); outline-offset: 0; }
|
|
136
136
|
.acw-send { border: none; border-radius: 10px; padding: 0 16px; background: var(--acw-accent); color: #fff; cursor: pointer; font-size: 14px; font-family: inherit; }
|
|
137
137
|
.acw-send:hover { background: var(--acw-accent-dark); }
|
|
138
|
+
|
|
139
|
+
/* Support-ticket draft card */
|
|
140
|
+
.acw-ticket { background: var(--acw-bg); border: 1px solid var(--acw-border); border-radius: 12px; padding: 14px; margin: 12px 0; border-left: 4px solid var(--acw-accent); }
|
|
141
|
+
.acw-ticket-title { font-size: 15px; font-weight: 600; color: var(--acw-fg); margin: 0 0 4px; }
|
|
142
|
+
.acw-ticket-sub { font-size: 12px; color: var(--acw-muted); margin: 0 0 10px; }
|
|
143
|
+
.acw-ticket-label { display: block; font-size: 12px; font-weight: 600; color: var(--acw-muted); margin: 12px 0 5px; }
|
|
144
|
+
.acw-ticket-input, .acw-ticket-desc {
|
|
145
|
+
width: 100%; box-sizing: border-box; font-family: inherit; font-size: 13px;
|
|
146
|
+
padding: 10px 12px; border: 1px solid var(--acw-border); border-radius: 10px;
|
|
147
|
+
color: var(--acw-fg); background: var(--acw-bg);
|
|
148
|
+
}
|
|
149
|
+
.acw-ticket-desc { resize: vertical; min-height: 170px; line-height: 1.5; }
|
|
150
|
+
.acw-ticket-input:focus, .acw-ticket-desc:focus { outline: 2px solid var(--acw-accent); outline-offset: 0; }
|
|
151
|
+
.acw-ticket-actions { display: flex; gap: 10px; margin-top: 14px; }
|
|
152
|
+
.acw-btn-primary { border: none; border-radius: 10px; padding: 10px 20px; cursor: pointer; background: var(--acw-accent); color: #fff; font-size: 14px; font-weight: 600; font-family: inherit; }
|
|
153
|
+
.acw-btn-primary:hover { background: var(--acw-accent-dark); }
|
|
154
|
+
.acw-btn-ghost { border: 1px solid var(--acw-border); border-radius: 10px; padding: 10px 16px; cursor: pointer; background: var(--acw-bg); color: var(--acw-fg); font-size: 14px; font-family: inherit; }
|
|
155
|
+
.acw-btn-ghost:hover { background: #f0eefe; }
|
|
156
|
+
.acw-link-btn { margin-top: 8px; border: none; background: transparent; color: var(--acw-accent); font-size: 12px; font-family: inherit; cursor: pointer; padding: 0; text-decoration: underline; }
|
|
157
|
+
.acw-link-btn:hover { color: var(--acw-accent-dark); }
|
|
138
158
|
`;
|
|
139
159
|
|
|
140
160
|
// src/widget.ts
|
|
@@ -447,12 +467,15 @@ var CopilotWidget = class {
|
|
|
447
467
|
const explicit = ctx.page?.requestId || ctx.page?.RequestId;
|
|
448
468
|
if (explicit) return String(explicit);
|
|
449
469
|
const route = ctx.page?.route || (typeof window !== "undefined" ? window.location.pathname : "");
|
|
450
|
-
const
|
|
451
|
-
|
|
470
|
+
const ms = /MS[A-Z0-9]{6,}/i.exec(route || "");
|
|
471
|
+
if (ms) return ms[0];
|
|
472
|
+
const guid = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/.exec(route || "");
|
|
473
|
+
return guid ? guid[0] : void 0;
|
|
452
474
|
}
|
|
453
475
|
/** Build a pre-filled, editable ticket draft and let the user review + Send (they trigger the API call). */
|
|
454
476
|
openTicketDraft(answer) {
|
|
455
|
-
const
|
|
477
|
+
const fromAnswer = /MS[A-Z0-9]{6,}/i.exec(answer.primaryReason || "");
|
|
478
|
+
const requestId = fromAnswer ? fromAnswer[0] : this.currentRequestId();
|
|
456
479
|
const role = answer.verifiedRoleLabel || "";
|
|
457
480
|
const reason = answer.primaryReason || "I am blocked from completing an action.";
|
|
458
481
|
const subject = requestId ? `[Cloud Events] Help needed on request ${requestId}` : "[Cloud Events] Help needed with an event request";
|
|
@@ -465,10 +488,8 @@ var CopilotWidget = class {
|
|
|
465
488
|
What the copilot reported:
|
|
466
489
|
${reason}`;
|
|
467
490
|
const card = document.createElement("div");
|
|
468
|
-
card.className = "acw-
|
|
469
|
-
|
|
470
|
-
const fld = "width:100%;box-sizing:border-box;font:inherit;font-size:13px;padding:6px 8px;border:1px solid var(--acw-border);border-radius:8px;background:var(--acw-bg);color:var(--acw-fg);";
|
|
471
|
-
card.innerHTML = `<div class="acw-reason"><strong>Review your support ticket</strong></div><label style="${lbl}">Subject</label><input class="acw-ticket-subject" type="text" style="${fld}" /><label style="${lbl}">Description</label><textarea class="acw-ticket-desc" rows="6" style="${fld}resize:vertical;"></textarea><div style="display:flex;gap:8px;margin-top:10px;"><button class="acw-ticket-send" type="button" style="border:none;border-radius:8px;padding:6px 14px;cursor:pointer;background:var(--acw-accent);color:var(--acw-accent-fg);font-size:13px;">Send ticket</button><button class="acw-ticket-cancel" type="button" style="border:1px solid var(--acw-border);border-radius:8px;padding:6px 12px;cursor:pointer;background:var(--acw-bg);color:var(--acw-fg);font-size:13px;">Cancel</button></div>`;
|
|
491
|
+
card.className = "acw-ticket";
|
|
492
|
+
card.innerHTML = `<div class="acw-ticket-title">Raise a support ticket</div><div class="acw-ticket-sub">Review the details below and click Send. It goes to the support team as a Zoho Desk ticket.</div><label class="acw-ticket-label">Subject</label><input class="acw-ticket-subject acw-ticket-input" type="text" /><label class="acw-ticket-label">Description</label><textarea class="acw-ticket-desc" rows="8"></textarea><div class="acw-ticket-actions"><button class="acw-ticket-send acw-btn-primary" type="button">Send ticket</button><button class="acw-ticket-cancel acw-btn-ghost" type="button">Cancel</button></div>`;
|
|
472
493
|
card.querySelector(".acw-ticket-subject").value = subject;
|
|
473
494
|
card.querySelector(".acw-ticket-desc").value = description;
|
|
474
495
|
card.querySelector(".acw-ticket-cancel").addEventListener("click", () => card.remove());
|
|
@@ -510,7 +531,22 @@ ${reason}`;
|
|
|
510
531
|
const num = data.ticketNumber ? `#${data.ticketNumber}` : "";
|
|
511
532
|
const el = document.createElement("div");
|
|
512
533
|
el.className = "acw-answer acw-okstate";
|
|
513
|
-
el.innerHTML = `<div class="acw-reason">Support ticket ${escapeHtml(num)} has been created. The support team will follow up.</div
|
|
534
|
+
el.innerHTML = `<div class="acw-reason">Support ticket ${escapeHtml(num)} has been created. The support team will follow up.</div>`;
|
|
535
|
+
if (data.webUrl || data.id || this.config.onOpenTicket) {
|
|
536
|
+
const open = document.createElement("button");
|
|
537
|
+
open.type = "button";
|
|
538
|
+
open.className = "acw-link-btn";
|
|
539
|
+
open.textContent = "Open the ticket";
|
|
540
|
+
open.addEventListener("click", () => {
|
|
541
|
+
const ticket = { id: data.id, number: data.ticketNumber, webUrl: data.webUrl };
|
|
542
|
+
if (this.config.onOpenTicket) {
|
|
543
|
+
this.config.onOpenTicket(ticket);
|
|
544
|
+
} else if (data.webUrl) {
|
|
545
|
+
window.open(data.webUrl, "_blank", "noopener");
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
el.appendChild(open);
|
|
549
|
+
}
|
|
514
550
|
this.body.appendChild(el);
|
|
515
551
|
this.body.scrollTop = this.body.scrollHeight;
|
|
516
552
|
} else {
|
package/dist/index.d.cts
CHANGED
|
@@ -46,6 +46,12 @@ interface WidgetConfig {
|
|
|
46
46
|
buttonText?: string;
|
|
47
47
|
/** Host navigation hook (e.g. Angular router). If omitted, the widget falls back to window.location. */
|
|
48
48
|
onNavigate?: (path: string) => void;
|
|
49
|
+
/** Host hook to open a created support ticket (e.g. the embedded Zoho ASAP widget). If omitted, the widget opens webUrl in a new tab. */
|
|
50
|
+
onOpenTicket?: (ticket: {
|
|
51
|
+
id?: string;
|
|
52
|
+
number?: string;
|
|
53
|
+
webUrl?: string;
|
|
54
|
+
}) => void;
|
|
49
55
|
}
|
|
50
56
|
interface CopilotAnswer {
|
|
51
57
|
status: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,12 @@ interface WidgetConfig {
|
|
|
46
46
|
buttonText?: string;
|
|
47
47
|
/** Host navigation hook (e.g. Angular router). If omitted, the widget falls back to window.location. */
|
|
48
48
|
onNavigate?: (path: string) => void;
|
|
49
|
+
/** Host hook to open a created support ticket (e.g. the embedded Zoho ASAP widget). If omitted, the widget opens webUrl in a new tab. */
|
|
50
|
+
onOpenTicket?: (ticket: {
|
|
51
|
+
id?: string;
|
|
52
|
+
number?: string;
|
|
53
|
+
webUrl?: string;
|
|
54
|
+
}) => void;
|
|
49
55
|
}
|
|
50
56
|
interface CopilotAnswer {
|
|
51
57
|
status: string;
|
package/dist/index.js
CHANGED
|
@@ -40,7 +40,7 @@ var widgetStyles = `
|
|
|
40
40
|
/* Panel */
|
|
41
41
|
.acw-panel {
|
|
42
42
|
position: fixed; right: 24px; bottom: 96px; z-index: 2147483000;
|
|
43
|
-
width:
|
|
43
|
+
width: 480px; max-width: calc(100vw - 48px); height: 660px; max-height: calc(100vh - 120px);
|
|
44
44
|
display: none; flex-direction: column;
|
|
45
45
|
background: var(--acw-bg); color: var(--acw-fg);
|
|
46
46
|
border: 1px solid var(--acw-border); border-radius: 16px; overflow: hidden;
|
|
@@ -98,6 +98,26 @@ var widgetStyles = `
|
|
|
98
98
|
.acw-input:focus { outline: 2px solid var(--acw-accent); outline-offset: 0; }
|
|
99
99
|
.acw-send { border: none; border-radius: 10px; padding: 0 16px; background: var(--acw-accent); color: #fff; cursor: pointer; font-size: 14px; font-family: inherit; }
|
|
100
100
|
.acw-send:hover { background: var(--acw-accent-dark); }
|
|
101
|
+
|
|
102
|
+
/* Support-ticket draft card */
|
|
103
|
+
.acw-ticket { background: var(--acw-bg); border: 1px solid var(--acw-border); border-radius: 12px; padding: 14px; margin: 12px 0; border-left: 4px solid var(--acw-accent); }
|
|
104
|
+
.acw-ticket-title { font-size: 15px; font-weight: 600; color: var(--acw-fg); margin: 0 0 4px; }
|
|
105
|
+
.acw-ticket-sub { font-size: 12px; color: var(--acw-muted); margin: 0 0 10px; }
|
|
106
|
+
.acw-ticket-label { display: block; font-size: 12px; font-weight: 600; color: var(--acw-muted); margin: 12px 0 5px; }
|
|
107
|
+
.acw-ticket-input, .acw-ticket-desc {
|
|
108
|
+
width: 100%; box-sizing: border-box; font-family: inherit; font-size: 13px;
|
|
109
|
+
padding: 10px 12px; border: 1px solid var(--acw-border); border-radius: 10px;
|
|
110
|
+
color: var(--acw-fg); background: var(--acw-bg);
|
|
111
|
+
}
|
|
112
|
+
.acw-ticket-desc { resize: vertical; min-height: 170px; line-height: 1.5; }
|
|
113
|
+
.acw-ticket-input:focus, .acw-ticket-desc:focus { outline: 2px solid var(--acw-accent); outline-offset: 0; }
|
|
114
|
+
.acw-ticket-actions { display: flex; gap: 10px; margin-top: 14px; }
|
|
115
|
+
.acw-btn-primary { border: none; border-radius: 10px; padding: 10px 20px; cursor: pointer; background: var(--acw-accent); color: #fff; font-size: 14px; font-weight: 600; font-family: inherit; }
|
|
116
|
+
.acw-btn-primary:hover { background: var(--acw-accent-dark); }
|
|
117
|
+
.acw-btn-ghost { border: 1px solid var(--acw-border); border-radius: 10px; padding: 10px 16px; cursor: pointer; background: var(--acw-bg); color: var(--acw-fg); font-size: 14px; font-family: inherit; }
|
|
118
|
+
.acw-btn-ghost:hover { background: #f0eefe; }
|
|
119
|
+
.acw-link-btn { margin-top: 8px; border: none; background: transparent; color: var(--acw-accent); font-size: 12px; font-family: inherit; cursor: pointer; padding: 0; text-decoration: underline; }
|
|
120
|
+
.acw-link-btn:hover { color: var(--acw-accent-dark); }
|
|
101
121
|
`;
|
|
102
122
|
|
|
103
123
|
// src/widget.ts
|
|
@@ -410,12 +430,15 @@ var CopilotWidget = class {
|
|
|
410
430
|
const explicit = ctx.page?.requestId || ctx.page?.RequestId;
|
|
411
431
|
if (explicit) return String(explicit);
|
|
412
432
|
const route = ctx.page?.route || (typeof window !== "undefined" ? window.location.pathname : "");
|
|
413
|
-
const
|
|
414
|
-
|
|
433
|
+
const ms = /MS[A-Z0-9]{6,}/i.exec(route || "");
|
|
434
|
+
if (ms) return ms[0];
|
|
435
|
+
const guid = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/.exec(route || "");
|
|
436
|
+
return guid ? guid[0] : void 0;
|
|
415
437
|
}
|
|
416
438
|
/** Build a pre-filled, editable ticket draft and let the user review + Send (they trigger the API call). */
|
|
417
439
|
openTicketDraft(answer) {
|
|
418
|
-
const
|
|
440
|
+
const fromAnswer = /MS[A-Z0-9]{6,}/i.exec(answer.primaryReason || "");
|
|
441
|
+
const requestId = fromAnswer ? fromAnswer[0] : this.currentRequestId();
|
|
419
442
|
const role = answer.verifiedRoleLabel || "";
|
|
420
443
|
const reason = answer.primaryReason || "I am blocked from completing an action.";
|
|
421
444
|
const subject = requestId ? `[Cloud Events] Help needed on request ${requestId}` : "[Cloud Events] Help needed with an event request";
|
|
@@ -428,10 +451,8 @@ var CopilotWidget = class {
|
|
|
428
451
|
What the copilot reported:
|
|
429
452
|
${reason}`;
|
|
430
453
|
const card = document.createElement("div");
|
|
431
|
-
card.className = "acw-
|
|
432
|
-
|
|
433
|
-
const fld = "width:100%;box-sizing:border-box;font:inherit;font-size:13px;padding:6px 8px;border:1px solid var(--acw-border);border-radius:8px;background:var(--acw-bg);color:var(--acw-fg);";
|
|
434
|
-
card.innerHTML = `<div class="acw-reason"><strong>Review your support ticket</strong></div><label style="${lbl}">Subject</label><input class="acw-ticket-subject" type="text" style="${fld}" /><label style="${lbl}">Description</label><textarea class="acw-ticket-desc" rows="6" style="${fld}resize:vertical;"></textarea><div style="display:flex;gap:8px;margin-top:10px;"><button class="acw-ticket-send" type="button" style="border:none;border-radius:8px;padding:6px 14px;cursor:pointer;background:var(--acw-accent);color:var(--acw-accent-fg);font-size:13px;">Send ticket</button><button class="acw-ticket-cancel" type="button" style="border:1px solid var(--acw-border);border-radius:8px;padding:6px 12px;cursor:pointer;background:var(--acw-bg);color:var(--acw-fg);font-size:13px;">Cancel</button></div>`;
|
|
454
|
+
card.className = "acw-ticket";
|
|
455
|
+
card.innerHTML = `<div class="acw-ticket-title">Raise a support ticket</div><div class="acw-ticket-sub">Review the details below and click Send. It goes to the support team as a Zoho Desk ticket.</div><label class="acw-ticket-label">Subject</label><input class="acw-ticket-subject acw-ticket-input" type="text" /><label class="acw-ticket-label">Description</label><textarea class="acw-ticket-desc" rows="8"></textarea><div class="acw-ticket-actions"><button class="acw-ticket-send acw-btn-primary" type="button">Send ticket</button><button class="acw-ticket-cancel acw-btn-ghost" type="button">Cancel</button></div>`;
|
|
435
456
|
card.querySelector(".acw-ticket-subject").value = subject;
|
|
436
457
|
card.querySelector(".acw-ticket-desc").value = description;
|
|
437
458
|
card.querySelector(".acw-ticket-cancel").addEventListener("click", () => card.remove());
|
|
@@ -473,7 +494,22 @@ ${reason}`;
|
|
|
473
494
|
const num = data.ticketNumber ? `#${data.ticketNumber}` : "";
|
|
474
495
|
const el = document.createElement("div");
|
|
475
496
|
el.className = "acw-answer acw-okstate";
|
|
476
|
-
el.innerHTML = `<div class="acw-reason">Support ticket ${escapeHtml(num)} has been created. The support team will follow up.</div
|
|
497
|
+
el.innerHTML = `<div class="acw-reason">Support ticket ${escapeHtml(num)} has been created. The support team will follow up.</div>`;
|
|
498
|
+
if (data.webUrl || data.id || this.config.onOpenTicket) {
|
|
499
|
+
const open = document.createElement("button");
|
|
500
|
+
open.type = "button";
|
|
501
|
+
open.className = "acw-link-btn";
|
|
502
|
+
open.textContent = "Open the ticket";
|
|
503
|
+
open.addEventListener("click", () => {
|
|
504
|
+
const ticket = { id: data.id, number: data.ticketNumber, webUrl: data.webUrl };
|
|
505
|
+
if (this.config.onOpenTicket) {
|
|
506
|
+
this.config.onOpenTicket(ticket);
|
|
507
|
+
} else if (data.webUrl) {
|
|
508
|
+
window.open(data.webUrl, "_blank", "noopener");
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
el.appendChild(open);
|
|
512
|
+
}
|
|
477
513
|
this.body.appendChild(el);
|
|
478
514
|
this.body.scrollTop = this.body.scrollHeight;
|
|
479
515
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spektra-cloudevents/application-copilot-widget",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Spektra Application Copilot widget — framework-agnostic and CSS-library agnostic via Shadow DOM isolation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|