@checkflow/sdk 1.1.3 → 1.1.5
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/chunk-NRA75GGU.mjs +1737 -0
- package/dist/highlighter-D0FpwCSU.d.mts +18 -0
- package/dist/highlighter-D0FpwCSU.d.ts +18 -0
- package/dist/{chunk-CD33QAA6.mjs → highlighter-EMSU6IYQ.mjs} +2 -3
- package/dist/index.d.mts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.js +1578 -370
- package/dist/index.mjs +56 -504
- package/dist/react.d.mts +48 -2
- package/dist/react.d.ts +48 -2
- package/dist/react.js +1568 -217
- package/dist/react.mjs +33 -2
- package/dist/types-fCeePy5c.d.mts +101 -0
- package/dist/types-fCeePy5c.d.ts +101 -0
- package/dist/vue.d.mts +2 -1
- package/dist/vue.d.ts +2 -1
- package/dist/vue.js +1532 -216
- package/dist/vue.mjs +1 -1
- package/dist/widget-LD24NDDL.mjs +10 -0
- package/package.json +1 -1
- package/dist/highlighter-Dx2zURb6.d.mts +0 -73
- package/dist/highlighter-Dx2zURb6.d.ts +0 -73
- package/dist/highlighter-W4XDALRE.mjs +0 -8
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mountWidget,
|
|
3
|
+
unmountWidget
|
|
4
|
+
} from "./chunk-NRA75GGU.mjs";
|
|
1
5
|
import {
|
|
2
6
|
captureScreenshot,
|
|
3
7
|
clearScreenshot
|
|
4
8
|
} from "./chunk-6EVTRC5X.mjs";
|
|
5
|
-
import {
|
|
6
|
-
startHighlighting
|
|
7
|
-
} from "./chunk-CD33QAA6.mjs";
|
|
8
9
|
|
|
9
10
|
// src/collector.ts
|
|
10
11
|
function collectContext() {
|
|
@@ -179,501 +180,6 @@ function clearNetworkLogs() {
|
|
|
179
180
|
logs2 = [];
|
|
180
181
|
}
|
|
181
182
|
|
|
182
|
-
// src/widget.ts
|
|
183
|
-
var DEFAULT_CONFIG = {
|
|
184
|
-
position: "bottom-right",
|
|
185
|
-
color: "#1e3a5f",
|
|
186
|
-
text: "Report Bug",
|
|
187
|
-
showOnInit: true
|
|
188
|
-
};
|
|
189
|
-
var container = null;
|
|
190
|
-
var onSubmitCallback = null;
|
|
191
|
-
var screenshotDataUrl = null;
|
|
192
|
-
var annotationsData = [];
|
|
193
|
-
var isExpanded = false;
|
|
194
|
-
function mountWidget(config2 = {}, onSubmit, opts) {
|
|
195
|
-
if (container) return;
|
|
196
|
-
onSubmitCallback = onSubmit;
|
|
197
|
-
const cfg = { ...DEFAULT_CONFIG, ...config2 };
|
|
198
|
-
container = document.createElement("div");
|
|
199
|
-
container.id = "checkflow-widget";
|
|
200
|
-
injectStyles(cfg);
|
|
201
|
-
container.innerHTML = getTriggerHTML(cfg);
|
|
202
|
-
document.body.appendChild(container);
|
|
203
|
-
const btn = container.querySelector("#cf-trigger");
|
|
204
|
-
btn?.addEventListener("click", () => openModal(cfg, opts));
|
|
205
|
-
}
|
|
206
|
-
function openModal(cfg, opts) {
|
|
207
|
-
if (!container) return;
|
|
208
|
-
const existing = document.getElementById("cf-modal-backdrop");
|
|
209
|
-
if (existing) existing.remove();
|
|
210
|
-
isExpanded = false;
|
|
211
|
-
screenshotDataUrl = null;
|
|
212
|
-
annotationsData = [];
|
|
213
|
-
const backdrop = document.createElement("div");
|
|
214
|
-
backdrop.id = "cf-modal-backdrop";
|
|
215
|
-
backdrop.innerHTML = getModalHTML(cfg, false);
|
|
216
|
-
document.body.appendChild(backdrop);
|
|
217
|
-
backdrop.addEventListener("click", (e) => {
|
|
218
|
-
if (e.target === backdrop) closeModal();
|
|
219
|
-
});
|
|
220
|
-
bindModalEvents(cfg, opts);
|
|
221
|
-
}
|
|
222
|
-
function closeModal() {
|
|
223
|
-
const backdrop = document.getElementById("cf-modal-backdrop");
|
|
224
|
-
if (backdrop) backdrop.remove();
|
|
225
|
-
isExpanded = false;
|
|
226
|
-
screenshotDataUrl = null;
|
|
227
|
-
annotationsData = [];
|
|
228
|
-
}
|
|
229
|
-
function expandModal(cfg, opts) {
|
|
230
|
-
const backdrop = document.getElementById("cf-modal-backdrop");
|
|
231
|
-
if (!backdrop) return;
|
|
232
|
-
const name = backdrop.querySelector("#cf-name")?.value || "";
|
|
233
|
-
const email = backdrop.querySelector("#cf-email")?.value || "";
|
|
234
|
-
const desc = backdrop.querySelector("#cf-desc")?.value || "";
|
|
235
|
-
isExpanded = true;
|
|
236
|
-
backdrop.innerHTML = getModalHTML(cfg, true);
|
|
237
|
-
bindModalEvents(cfg, opts);
|
|
238
|
-
const nameEl = backdrop.querySelector("#cf-name");
|
|
239
|
-
const emailEl = backdrop.querySelector("#cf-email");
|
|
240
|
-
const descEl = backdrop.querySelector("#cf-desc");
|
|
241
|
-
if (nameEl) nameEl.value = name;
|
|
242
|
-
if (emailEl) emailEl.value = email;
|
|
243
|
-
if (descEl) descEl.value = desc;
|
|
244
|
-
}
|
|
245
|
-
function collapseModal(cfg, opts) {
|
|
246
|
-
const backdrop = document.getElementById("cf-modal-backdrop");
|
|
247
|
-
if (!backdrop) return;
|
|
248
|
-
const name = backdrop.querySelector("#cf-name")?.value || "";
|
|
249
|
-
const email = backdrop.querySelector("#cf-email")?.value || "";
|
|
250
|
-
const desc = backdrop.querySelector("#cf-desc")?.value || "";
|
|
251
|
-
isExpanded = false;
|
|
252
|
-
screenshotDataUrl = null;
|
|
253
|
-
annotationsData = [];
|
|
254
|
-
backdrop.innerHTML = getModalHTML(cfg, false);
|
|
255
|
-
bindModalEvents(cfg, opts);
|
|
256
|
-
const nameEl = backdrop.querySelector("#cf-name");
|
|
257
|
-
const emailEl = backdrop.querySelector("#cf-email");
|
|
258
|
-
const descEl = backdrop.querySelector("#cf-desc");
|
|
259
|
-
if (nameEl) nameEl.value = name;
|
|
260
|
-
if (emailEl) emailEl.value = email;
|
|
261
|
-
if (descEl) descEl.value = desc;
|
|
262
|
-
}
|
|
263
|
-
function bindModalEvents(cfg, opts) {
|
|
264
|
-
const backdrop = document.getElementById("cf-modal-backdrop");
|
|
265
|
-
if (!backdrop) return;
|
|
266
|
-
backdrop.querySelector("#cf-cancel")?.addEventListener("click", closeModal);
|
|
267
|
-
backdrop.querySelector("#cf-screenshot-btn")?.addEventListener("click", async () => {
|
|
268
|
-
if (!opts?.onScreenshot) return;
|
|
269
|
-
backdrop.style.display = "none";
|
|
270
|
-
try {
|
|
271
|
-
const data = await opts.onScreenshot();
|
|
272
|
-
if (data) {
|
|
273
|
-
screenshotDataUrl = data;
|
|
274
|
-
backdrop.style.display = "flex";
|
|
275
|
-
expandModal(cfg, opts);
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
} catch {
|
|
279
|
-
}
|
|
280
|
-
backdrop.style.display = "flex";
|
|
281
|
-
});
|
|
282
|
-
backdrop.querySelector("#cf-remove-screenshot")?.addEventListener("click", () => {
|
|
283
|
-
collapseModal(cfg, opts);
|
|
284
|
-
});
|
|
285
|
-
backdrop.querySelector("#cf-highlight-btn")?.addEventListener("click", async () => {
|
|
286
|
-
if (!opts?.onHighlight) return;
|
|
287
|
-
backdrop.style.display = "none";
|
|
288
|
-
try {
|
|
289
|
-
const annotations = await opts.onHighlight();
|
|
290
|
-
if (annotations && annotations.length > 0) {
|
|
291
|
-
annotationsData = annotations;
|
|
292
|
-
}
|
|
293
|
-
} catch {
|
|
294
|
-
}
|
|
295
|
-
backdrop.style.display = "flex";
|
|
296
|
-
const hlBtn = backdrop.querySelector("#cf-highlight-btn");
|
|
297
|
-
if (hlBtn && annotationsData.length > 0) {
|
|
298
|
-
hlBtn.textContent = `Surligner (${annotationsData.length})`;
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
backdrop.querySelector("#cf-mask-btn")?.addEventListener("click", async () => {
|
|
302
|
-
if (!opts?.onHighlight) return;
|
|
303
|
-
backdrop.style.display = "none";
|
|
304
|
-
try {
|
|
305
|
-
const annotations = await opts.onHighlight();
|
|
306
|
-
if (annotations && annotations.length > 0) {
|
|
307
|
-
annotationsData = [...annotationsData, ...annotations];
|
|
308
|
-
}
|
|
309
|
-
} catch {
|
|
310
|
-
}
|
|
311
|
-
backdrop.style.display = "flex";
|
|
312
|
-
});
|
|
313
|
-
backdrop.querySelector("#cf-submit")?.addEventListener("click", () => {
|
|
314
|
-
const desc = backdrop.querySelector("#cf-desc")?.value;
|
|
315
|
-
const name = backdrop.querySelector("#cf-name")?.value;
|
|
316
|
-
const email = backdrop.querySelector("#cf-email")?.value;
|
|
317
|
-
if (!desc?.trim()) {
|
|
318
|
-
const descEl = backdrop.querySelector("#cf-desc");
|
|
319
|
-
if (descEl) {
|
|
320
|
-
descEl.style.borderColor = "#e74c3c";
|
|
321
|
-
descEl.focus();
|
|
322
|
-
}
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
onSubmitCallback?.({
|
|
326
|
-
title: desc.trim().slice(0, 100),
|
|
327
|
-
description: desc.trim(),
|
|
328
|
-
type: "BUG",
|
|
329
|
-
priority: "MEDIUM",
|
|
330
|
-
screenshot: screenshotDataUrl || void 0,
|
|
331
|
-
annotations: annotationsData.length > 0 ? annotationsData : void 0,
|
|
332
|
-
reporter_name: name?.trim() || void 0,
|
|
333
|
-
reporter_email: email?.trim() || void 0
|
|
334
|
-
});
|
|
335
|
-
closeModal();
|
|
336
|
-
showToast("Rapport envoy\xE9 avec succ\xE8s !");
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
function unmountWidget() {
|
|
340
|
-
closeModal();
|
|
341
|
-
if (container) {
|
|
342
|
-
container.remove();
|
|
343
|
-
container = null;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
function showToast(msg) {
|
|
347
|
-
const toast = document.createElement("div");
|
|
348
|
-
toast.textContent = msg;
|
|
349
|
-
toast.style.cssText = 'position:fixed;bottom:80px;right:20px;background:#10b981;color:#fff;padding:10px 20px;border-radius:10px;font-size:14px;z-index:100010;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;box-shadow:0 4px 16px rgba(0,0,0,.18);animation:cf-toast-in .3s ease;';
|
|
350
|
-
document.body.appendChild(toast);
|
|
351
|
-
setTimeout(() => {
|
|
352
|
-
toast.style.opacity = "0";
|
|
353
|
-
toast.style.transition = "opacity .3s";
|
|
354
|
-
}, 2500);
|
|
355
|
-
setTimeout(() => toast.remove(), 3e3);
|
|
356
|
-
}
|
|
357
|
-
function injectStyles(cfg) {
|
|
358
|
-
const style = document.createElement("style");
|
|
359
|
-
style.id = "cf-widget-styles";
|
|
360
|
-
style.textContent = `
|
|
361
|
-
@keyframes cf-toast-in { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:translateY(0); } }
|
|
362
|
-
@keyframes cf-modal-in { from { opacity:0; transform:scale(.96) translateY(8px); } to { opacity:1; transform:scale(1) translateY(0); } }
|
|
363
|
-
|
|
364
|
-
#cf-trigger {
|
|
365
|
-
position:fixed;
|
|
366
|
-
${getPositionCSS(cfg.position)}
|
|
367
|
-
z-index:100000;
|
|
368
|
-
background:${cfg.color};
|
|
369
|
-
color:#fff;
|
|
370
|
-
border:none;
|
|
371
|
-
border-radius:50px;
|
|
372
|
-
padding:11px 20px;
|
|
373
|
-
font-size:14px;
|
|
374
|
-
font-weight:500;
|
|
375
|
-
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
|
|
376
|
-
cursor:pointer;
|
|
377
|
-
box-shadow:0 4px 16px rgba(0,0,0,.18);
|
|
378
|
-
display:flex;
|
|
379
|
-
align-items:center;
|
|
380
|
-
gap:8px;
|
|
381
|
-
transition:transform .15s,box-shadow .15s;
|
|
382
|
-
}
|
|
383
|
-
#cf-trigger:hover { transform:scale(1.04); box-shadow:0 6px 24px rgba(0,0,0,.22); }
|
|
384
|
-
#cf-trigger svg { width:18px; height:18px; }
|
|
385
|
-
|
|
386
|
-
#cf-modal-backdrop {
|
|
387
|
-
position:fixed;
|
|
388
|
-
top:0;left:0;right:0;bottom:0;
|
|
389
|
-
background:rgba(0,0,0,.45);
|
|
390
|
-
z-index:100001;
|
|
391
|
-
display:flex;
|
|
392
|
-
align-items:center;
|
|
393
|
-
justify-content:center;
|
|
394
|
-
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.cf-modal {
|
|
398
|
-
background:#fff;
|
|
399
|
-
border-radius:16px;
|
|
400
|
-
box-shadow:0 24px 80px rgba(0,0,0,.25);
|
|
401
|
-
overflow:hidden;
|
|
402
|
-
animation:cf-modal-in .25s ease;
|
|
403
|
-
display:flex;
|
|
404
|
-
flex-direction:column;
|
|
405
|
-
max-height:90vh;
|
|
406
|
-
}
|
|
407
|
-
.cf-modal--compact { width:420px; }
|
|
408
|
-
.cf-modal--expanded { width:min(1100px,92vw); flex-direction:column; }
|
|
409
|
-
|
|
410
|
-
.cf-modal-header {
|
|
411
|
-
display:flex;
|
|
412
|
-
align-items:center;
|
|
413
|
-
justify-content:space-between;
|
|
414
|
-
padding:20px 24px 16px;
|
|
415
|
-
border-bottom:1px solid #f0f0f0;
|
|
416
|
-
}
|
|
417
|
-
.cf-modal-header h2 {
|
|
418
|
-
margin:0;
|
|
419
|
-
font-size:20px;
|
|
420
|
-
font-weight:700;
|
|
421
|
-
color:#1a1a2e;
|
|
422
|
-
}
|
|
423
|
-
.cf-modal-header .cf-logo {
|
|
424
|
-
width:28px;
|
|
425
|
-
height:28px;
|
|
426
|
-
color:${cfg.color};
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
.cf-modal-body { display:flex; flex:1; overflow:hidden; }
|
|
430
|
-
|
|
431
|
-
.cf-screenshot-panel {
|
|
432
|
-
flex:1;
|
|
433
|
-
min-width:0;
|
|
434
|
-
background:#1a1a2e;
|
|
435
|
-
display:flex;
|
|
436
|
-
flex-direction:column;
|
|
437
|
-
position:relative;
|
|
438
|
-
}
|
|
439
|
-
.cf-screenshot-panel img {
|
|
440
|
-
width:100%;
|
|
441
|
-
height:100%;
|
|
442
|
-
object-fit:contain;
|
|
443
|
-
max-height:60vh;
|
|
444
|
-
}
|
|
445
|
-
.cf-screenshot-tools {
|
|
446
|
-
position:absolute;
|
|
447
|
-
bottom:16px;
|
|
448
|
-
left:50%;
|
|
449
|
-
transform:translateX(-50%);
|
|
450
|
-
display:flex;
|
|
451
|
-
gap:8px;
|
|
452
|
-
}
|
|
453
|
-
.cf-screenshot-tools button {
|
|
454
|
-
padding:8px 18px;
|
|
455
|
-
border-radius:8px;
|
|
456
|
-
font-size:13px;
|
|
457
|
-
font-weight:500;
|
|
458
|
-
cursor:pointer;
|
|
459
|
-
font-family:inherit;
|
|
460
|
-
border:none;
|
|
461
|
-
transition:all .15s;
|
|
462
|
-
}
|
|
463
|
-
.cf-tool-highlight {
|
|
464
|
-
background:${cfg.color};
|
|
465
|
-
color:#fff;
|
|
466
|
-
}
|
|
467
|
-
.cf-tool-highlight:hover { opacity:.9; }
|
|
468
|
-
.cf-tool-mask {
|
|
469
|
-
background:#fff;
|
|
470
|
-
color:#1a1a2e;
|
|
471
|
-
border:1px solid #e0e0e0 !important;
|
|
472
|
-
}
|
|
473
|
-
.cf-tool-mask:hover { background:#f5f5f5; }
|
|
474
|
-
|
|
475
|
-
.cf-form-panel {
|
|
476
|
-
width:100%;
|
|
477
|
-
padding:20px 24px;
|
|
478
|
-
display:flex;
|
|
479
|
-
flex-direction:column;
|
|
480
|
-
gap:14px;
|
|
481
|
-
overflow-y:auto;
|
|
482
|
-
}
|
|
483
|
-
.cf-modal--expanded .cf-form-panel {
|
|
484
|
-
width:340px;
|
|
485
|
-
flex-shrink:0;
|
|
486
|
-
border-left:1px solid #f0f0f0;
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
.cf-field label {
|
|
490
|
-
display:block;
|
|
491
|
-
font-size:13px;
|
|
492
|
-
font-weight:500;
|
|
493
|
-
color:#1a1a2e;
|
|
494
|
-
margin-bottom:6px;
|
|
495
|
-
}
|
|
496
|
-
.cf-field label span { font-weight:400; color:#999; }
|
|
497
|
-
.cf-field input, .cf-field textarea {
|
|
498
|
-
width:100%;
|
|
499
|
-
padding:10px 14px;
|
|
500
|
-
border:1px solid #e0e0e0;
|
|
501
|
-
border-radius:10px;
|
|
502
|
-
font-size:14px;
|
|
503
|
-
font-family:inherit;
|
|
504
|
-
box-sizing:border-box;
|
|
505
|
-
outline:none;
|
|
506
|
-
transition:border-color .15s,box-shadow .15s;
|
|
507
|
-
color:#1a1a2e;
|
|
508
|
-
background:#fff;
|
|
509
|
-
}
|
|
510
|
-
.cf-field input::placeholder, .cf-field textarea::placeholder { color:#bbb; }
|
|
511
|
-
.cf-field input:focus, .cf-field textarea:focus {
|
|
512
|
-
border-color:${cfg.color};
|
|
513
|
-
box-shadow:0 0 0 3px ${cfg.color}18;
|
|
514
|
-
}
|
|
515
|
-
.cf-field textarea { resize:vertical; min-height:100px; }
|
|
516
|
-
|
|
517
|
-
.cf-screenshot-action {
|
|
518
|
-
width:100%;
|
|
519
|
-
padding:12px;
|
|
520
|
-
border:1px solid #e0e0e0;
|
|
521
|
-
border-radius:10px;
|
|
522
|
-
background:#fff;
|
|
523
|
-
font-size:14px;
|
|
524
|
-
color:#1a1a2e;
|
|
525
|
-
cursor:pointer;
|
|
526
|
-
font-family:inherit;
|
|
527
|
-
transition:all .15s;
|
|
528
|
-
text-align:center;
|
|
529
|
-
}
|
|
530
|
-
.cf-screenshot-action:hover { background:#f8f8f8; border-color:#ccc; }
|
|
531
|
-
|
|
532
|
-
.cf-remove-screenshot {
|
|
533
|
-
width:100%;
|
|
534
|
-
padding:10px;
|
|
535
|
-
border:1px solid #e0e0e0;
|
|
536
|
-
border-radius:10px;
|
|
537
|
-
background:#fff;
|
|
538
|
-
font-size:13px;
|
|
539
|
-
color:#666;
|
|
540
|
-
cursor:pointer;
|
|
541
|
-
font-family:inherit;
|
|
542
|
-
transition:all .15s;
|
|
543
|
-
text-align:center;
|
|
544
|
-
}
|
|
545
|
-
.cf-remove-screenshot:hover { background:#fff0f0; color:#e74c3c; border-color:#e74c3c; }
|
|
546
|
-
|
|
547
|
-
.cf-submit-btn {
|
|
548
|
-
width:100%;
|
|
549
|
-
padding:13px;
|
|
550
|
-
border:none;
|
|
551
|
-
border-radius:10px;
|
|
552
|
-
background:${cfg.color};
|
|
553
|
-
color:#fff;
|
|
554
|
-
font-size:15px;
|
|
555
|
-
font-weight:600;
|
|
556
|
-
cursor:pointer;
|
|
557
|
-
font-family:inherit;
|
|
558
|
-
transition:all .15s;
|
|
559
|
-
}
|
|
560
|
-
.cf-submit-btn:hover { opacity:.92; transform:translateY(-1px); box-shadow:0 4px 12px ${cfg.color}40; }
|
|
561
|
-
.cf-submit-btn:disabled { opacity:.5; cursor:not-allowed; transform:none; }
|
|
562
|
-
|
|
563
|
-
.cf-cancel-btn {
|
|
564
|
-
width:100%;
|
|
565
|
-
padding:11px;
|
|
566
|
-
border:1px solid #e0e0e0;
|
|
567
|
-
border-radius:10px;
|
|
568
|
-
background:#fff;
|
|
569
|
-
color:#1a1a2e;
|
|
570
|
-
font-size:14px;
|
|
571
|
-
font-weight:500;
|
|
572
|
-
cursor:pointer;
|
|
573
|
-
font-family:inherit;
|
|
574
|
-
transition:all .15s;
|
|
575
|
-
text-align:center;
|
|
576
|
-
}
|
|
577
|
-
.cf-cancel-btn:hover { background:#f8f8f8; }
|
|
578
|
-
|
|
579
|
-
.cf-footer {
|
|
580
|
-
text-align:center;
|
|
581
|
-
padding:12px;
|
|
582
|
-
border-top:1px solid #f0f0f0;
|
|
583
|
-
font-size:11px;
|
|
584
|
-
color:#bbb;
|
|
585
|
-
}
|
|
586
|
-
.cf-footer a {
|
|
587
|
-
color:#999;
|
|
588
|
-
text-decoration:none;
|
|
589
|
-
font-weight:500;
|
|
590
|
-
}
|
|
591
|
-
.cf-footer a:hover { color:${cfg.color}; }
|
|
592
|
-
`;
|
|
593
|
-
document.head.appendChild(style);
|
|
594
|
-
}
|
|
595
|
-
function getPositionCSS(pos) {
|
|
596
|
-
switch (pos) {
|
|
597
|
-
case "bottom-left":
|
|
598
|
-
return "bottom:20px;left:20px;";
|
|
599
|
-
case "top-right":
|
|
600
|
-
return "top:20px;right:20px;";
|
|
601
|
-
case "top-left":
|
|
602
|
-
return "top:20px;left:20px;";
|
|
603
|
-
default:
|
|
604
|
-
return "bottom:20px;right:20px;";
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
function getTriggerHTML(cfg) {
|
|
608
|
-
return `
|
|
609
|
-
<button id="cf-trigger">
|
|
610
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
|
611
|
-
${cfg.text}
|
|
612
|
-
</button>
|
|
613
|
-
`;
|
|
614
|
-
}
|
|
615
|
-
function getCheckflowLogo() {
|
|
616
|
-
return `<svg class="cf-logo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12C2 6.5 6.5 2 12 2a10 10 0 0 1 8 4"/><path d="M5 19.5C5.5 18 6 15 6 12c0-.7.12-1.37.34-2"/><path d="M17.29 21.02c.12-.6.43-2.3.5-3.02"/><path d="M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"/><path d="M8.65 22c.21-.66.45-1.32.57-2"/><path d="M14 13.12c0 2.38 0 6.38-1 8.88"/><path d="M2 16h.01"/><path d="M21.8 16c.2-2 .131-5.354 0-6"/><path d="M9 6.8a6 6 0 0 1 9 5.2v2"/></svg>`;
|
|
617
|
-
}
|
|
618
|
-
function getModalHTML(cfg, expanded) {
|
|
619
|
-
const modalClass = expanded ? "cf-modal cf-modal--expanded" : "cf-modal cf-modal--compact";
|
|
620
|
-
const formFields = `
|
|
621
|
-
<div class="cf-field">
|
|
622
|
-
<label>Nom <span>(obligatoire)</span></label>
|
|
623
|
-
<input id="cf-name" type="text" placeholder="Votre nom" />
|
|
624
|
-
</div>
|
|
625
|
-
<div class="cf-field">
|
|
626
|
-
<label>Email <span>(obligatoire)</span></label>
|
|
627
|
-
<input id="cf-email" type="email" placeholder="votre.email@exemple.com" />
|
|
628
|
-
</div>
|
|
629
|
-
<div class="cf-field">
|
|
630
|
-
<label>Description <span>(obligatoire)</span></label>
|
|
631
|
-
<textarea id="cf-desc" placeholder="Quel est le probl\xE8me ? Que vous attendiez-vous \xE0 voir ?"></textarea>
|
|
632
|
-
</div>
|
|
633
|
-
`;
|
|
634
|
-
if (expanded && screenshotDataUrl) {
|
|
635
|
-
return `
|
|
636
|
-
<div class="${modalClass}">
|
|
637
|
-
<div class="cf-modal-header">
|
|
638
|
-
<h2>Envoyer le rapport</h2>
|
|
639
|
-
${getCheckflowLogo()}
|
|
640
|
-
</div>
|
|
641
|
-
<div class="cf-modal-body">
|
|
642
|
-
<div class="cf-screenshot-panel">
|
|
643
|
-
<img src="${screenshotDataUrl}" alt="Capture d'\xE9cran" />
|
|
644
|
-
<div class="cf-screenshot-tools">
|
|
645
|
-
<button class="cf-tool-highlight" id="cf-highlight-btn">Surligner</button>
|
|
646
|
-
<button class="cf-tool-mask" id="cf-mask-btn">Masquer</button>
|
|
647
|
-
</div>
|
|
648
|
-
</div>
|
|
649
|
-
<div class="cf-form-panel">
|
|
650
|
-
${formFields}
|
|
651
|
-
<button class="cf-remove-screenshot" id="cf-remove-screenshot">Supprimer la capture d'\xE9cran</button>
|
|
652
|
-
<button class="cf-submit-btn" id="cf-submit">Envoyer le rapport</button>
|
|
653
|
-
<button class="cf-cancel-btn" id="cf-cancel">Annuler</button>
|
|
654
|
-
</div>
|
|
655
|
-
</div>
|
|
656
|
-
<div class="cf-footer">Powered by <a href="https://checkflow.space" target="_blank" rel="noopener">Checkflow</a></div>
|
|
657
|
-
</div>
|
|
658
|
-
`;
|
|
659
|
-
}
|
|
660
|
-
return `
|
|
661
|
-
<div class="${modalClass}">
|
|
662
|
-
<div class="cf-modal-header">
|
|
663
|
-
<h2>Envoyer le rapport</h2>
|
|
664
|
-
${getCheckflowLogo()}
|
|
665
|
-
</div>
|
|
666
|
-
<div class="cf-form-panel">
|
|
667
|
-
${formFields}
|
|
668
|
-
<button class="cf-screenshot-action" id="cf-screenshot-btn">Ajouter une capture d'\xE9cran</button>
|
|
669
|
-
<button class="cf-submit-btn" id="cf-submit">Envoyer le rapport</button>
|
|
670
|
-
<button class="cf-cancel-btn" id="cf-cancel">Annuler</button>
|
|
671
|
-
</div>
|
|
672
|
-
<div class="cf-footer">Powered by <a href="https://checkflow.space" target="_blank" rel="noopener">Checkflow</a></div>
|
|
673
|
-
</div>
|
|
674
|
-
`;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
183
|
// src/index.ts
|
|
678
184
|
var SDK_VERSION = "1.1.0";
|
|
679
185
|
var DEFAULT_ENDPOINT = "https://api.checkflow.space/api/v1";
|
|
@@ -705,7 +211,7 @@ function init(cfg) {
|
|
|
705
211
|
},
|
|
706
212
|
{
|
|
707
213
|
onScreenshot: () => captureScreenshot(),
|
|
708
|
-
|
|
214
|
+
user: config.user
|
|
709
215
|
}
|
|
710
216
|
);
|
|
711
217
|
}
|
|
@@ -735,12 +241,22 @@ async function sendFeedback(data) {
|
|
|
735
241
|
if (data.annotations && data.annotations.length > 0) {
|
|
736
242
|
payload.annotations = data.annotations;
|
|
737
243
|
}
|
|
738
|
-
if (
|
|
244
|
+
if (config.user?.name) {
|
|
245
|
+
payload.reporter_name = config.user.name;
|
|
246
|
+
} else if (data.reporter_name) {
|
|
739
247
|
payload.reporter_name = data.reporter_name;
|
|
740
248
|
}
|
|
741
|
-
if (
|
|
249
|
+
if (config.user?.email) {
|
|
250
|
+
payload.reporter_email = config.user.email;
|
|
251
|
+
} else if (data.reporter_email) {
|
|
742
252
|
payload.reporter_email = data.reporter_email;
|
|
743
253
|
}
|
|
254
|
+
if (config.user?.id) {
|
|
255
|
+
payload.user_id = config.user.id;
|
|
256
|
+
}
|
|
257
|
+
if (config.user?.avatar) {
|
|
258
|
+
payload.user_avatar = config.user.avatar;
|
|
259
|
+
}
|
|
744
260
|
try {
|
|
745
261
|
const res = await fetch(`${config.endpoint}/sdk/feedback`, {
|
|
746
262
|
method: "POST",
|
|
@@ -777,10 +293,44 @@ function showWidget() {
|
|
|
777
293
|
},
|
|
778
294
|
{
|
|
779
295
|
onScreenshot: () => captureScreenshot(),
|
|
780
|
-
|
|
296
|
+
user: config.user
|
|
781
297
|
}
|
|
782
298
|
);
|
|
783
299
|
}
|
|
300
|
+
function setUser(user) {
|
|
301
|
+
if (config) {
|
|
302
|
+
config.user = user;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function clearUser() {
|
|
306
|
+
if (config) {
|
|
307
|
+
config.user = void 0;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function openFeedbackModal() {
|
|
311
|
+
if (!config) return;
|
|
312
|
+
import("./widget-LD24NDDL.mjs").then(({ openFeedbackModal: openModal }) => {
|
|
313
|
+
openModal(
|
|
314
|
+
config.widget,
|
|
315
|
+
(data) => {
|
|
316
|
+
sendFeedback({
|
|
317
|
+
title: data.title,
|
|
318
|
+
description: data.description,
|
|
319
|
+
type: data.type,
|
|
320
|
+
priority: data.priority,
|
|
321
|
+
screenshot_data: data.screenshot,
|
|
322
|
+
annotations: data.annotations,
|
|
323
|
+
reporter_name: data.reporter_name,
|
|
324
|
+
reporter_email: data.reporter_email
|
|
325
|
+
});
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
onScreenshot: () => captureScreenshot(),
|
|
329
|
+
user: config.user
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
784
334
|
function hideWidget() {
|
|
785
335
|
unmountWidget();
|
|
786
336
|
}
|
|
@@ -793,10 +343,12 @@ function destroy() {
|
|
|
793
343
|
}
|
|
794
344
|
export {
|
|
795
345
|
captureScreenshot,
|
|
346
|
+
clearUser,
|
|
796
347
|
destroy,
|
|
797
348
|
hideWidget,
|
|
798
349
|
init,
|
|
350
|
+
openFeedbackModal,
|
|
799
351
|
sendFeedback,
|
|
800
|
-
|
|
801
|
-
|
|
352
|
+
setUser,
|
|
353
|
+
showWidget
|
|
802
354
|
};
|
package/dist/react.d.mts
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { H as HighlightAnnotation } from './highlighter-D0FpwCSU.mjs';
|
|
2
|
+
import { B as ButtonConfig, U as UserProfile, a as FeedbackResponse, C as CheckflowConfig } from './types-fCeePy5c.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Initialize Checkflow in a React/Next.js app.
|
|
5
6
|
* Call this in your root layout or _app file.
|
|
7
|
+
*
|
|
8
|
+
* @param config - SDK configuration including apiKey, user profile, and widget options
|
|
6
9
|
*/
|
|
7
10
|
declare function useCheckflowInit(config: CheckflowConfig): void;
|
|
11
|
+
/**
|
|
12
|
+
* Update the user profile after initialization.
|
|
13
|
+
* Useful when user logs in/out.
|
|
14
|
+
*/
|
|
15
|
+
declare function setUser(user: UserProfile | undefined): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Clear the user profile.
|
|
18
|
+
*/
|
|
19
|
+
declare function clearUser(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Open the feedback modal programmatically.
|
|
22
|
+
* Use this when you want to trigger the modal from a custom button.
|
|
23
|
+
*/
|
|
24
|
+
declare function openFeedbackModal(): Promise<void>;
|
|
8
25
|
/**
|
|
9
26
|
* Hook to send feedback programmatically from React components.
|
|
10
27
|
*/
|
|
@@ -19,10 +36,39 @@ declare function useCheckflowFeedback(): {
|
|
|
19
36
|
highlight: () => Promise<HighlightAnnotation[]>;
|
|
20
37
|
show: () => Promise<void>;
|
|
21
38
|
hide: () => Promise<void>;
|
|
39
|
+
openModal: typeof openFeedbackModal;
|
|
40
|
+
setUser: typeof setUser;
|
|
41
|
+
clearUser: typeof clearUser;
|
|
22
42
|
};
|
|
23
43
|
/**
|
|
24
44
|
* Cleanup function for React useEffect.
|
|
25
45
|
*/
|
|
26
46
|
declare function destroyCheckflow(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Props for the FeedbackButton component.
|
|
49
|
+
* All button styling can be customized via className, style, or button config.
|
|
50
|
+
*/
|
|
51
|
+
interface FeedbackButtonProps {
|
|
52
|
+
/** Button text content */
|
|
53
|
+
children?: string;
|
|
54
|
+
/** Custom CSS class */
|
|
55
|
+
className?: string;
|
|
56
|
+
/** Inline styles */
|
|
57
|
+
style?: Record<string, string | number>;
|
|
58
|
+
/** Button configuration for SDK styling */
|
|
59
|
+
buttonConfig?: ButtonConfig;
|
|
60
|
+
/** Click handler (called before opening modal) */
|
|
61
|
+
onClick?: () => void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the onClick handler for a feedback button.
|
|
65
|
+
* Use this to create your own custom button that opens the feedback modal.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* <button onClick={getFeedbackButtonHandler()}>Report Bug</button>
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
declare function getFeedbackButtonHandler(onClick?: () => void): () => void;
|
|
27
73
|
|
|
28
|
-
export { destroyCheckflow, useCheckflowFeedback, useCheckflowInit };
|
|
74
|
+
export { type FeedbackButtonProps, clearUser, destroyCheckflow, getFeedbackButtonHandler, openFeedbackModal, setUser, useCheckflowFeedback, useCheckflowInit };
|