@designfever/web-review-kit 0.3.0 → 0.4.1
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 +201 -0
- package/README.md +18 -1
- package/dist/{chunk-I76WEDLA.js → chunk-6L2KJ7XL.js} +1115 -110
- package/dist/chunk-6L2KJ7XL.js.map +1 -0
- package/dist/index.cjs +1114 -109
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/react-shell.cjs +3256 -855
- package/dist/react-shell.cjs.map +1 -1
- package/dist/react-shell.d.cts +11 -3
- package/dist/react-shell.d.ts +11 -3
- package/dist/react-shell.js +2089 -689
- package/dist/react-shell.js.map +1 -1
- package/dist/{types-Cf2x5ky6.d.cts → types-D_qYtwTs.d.cts} +4 -1
- package/dist/{types-Cf2x5ky6.d.ts → types-D_qYtwTs.d.ts} +4 -1
- package/docs/adaptor.sample.ts +2 -0
- package/docs/architecture.md +3 -0
- package/docs/installation.md +26 -1
- package/docs/release-notes-0.3.0.md +94 -0
- package/docs/release-notes-0.4.0.md +144 -0
- package/package.json +2 -2
- package/dist/chunk-I76WEDLA.js.map +0 -1
package/dist/react-shell.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
createWebReviewKit,
|
|
4
4
|
getNumberedReviewItems,
|
|
5
5
|
normalizeReviewItemStatus
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6L2KJ7XL.js";
|
|
7
7
|
|
|
8
8
|
// src/react-shell.tsx
|
|
9
9
|
import React2 from "react";
|
|
@@ -148,9 +148,11 @@ function ensureReviewShellStyle() {
|
|
|
148
148
|
--df-review-shadow-device: 0 24px 60px rgba(0, 0, 0, 0.38);
|
|
149
149
|
--df-review-shadow-panel: 0 18px 48px rgba(0, 0, 0, 0.38);
|
|
150
150
|
--df-review-shadow-modal: 0 24px 70px rgba(0, 0, 0, 0.48);
|
|
151
|
+
--df-review-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d7e0ec' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
151
152
|
|
|
152
153
|
/* Semantic aliases consumed by the existing shell chrome. */
|
|
153
154
|
--df-review-bg: var(--df-review-color-canvas);
|
|
155
|
+
--df-review-surface: var(--df-review-color-surface);
|
|
154
156
|
--df-review-topbar: var(--df-review-color-surface);
|
|
155
157
|
--df-review-panel: var(--df-review-color-panel);
|
|
156
158
|
--df-review-panel-strong: var(--df-review-color-panel-strong);
|
|
@@ -243,6 +245,7 @@ function ensureReviewShellStyle() {
|
|
|
243
245
|
--df-review-shadow-device: 0 24px 60px rgba(15, 23, 42, 0.18);
|
|
244
246
|
--df-review-shadow-panel: 0 18px 48px rgba(15, 23, 42, 0.18);
|
|
245
247
|
--df-review-shadow-modal: 0 24px 70px rgba(15, 23, 42, 0.2);
|
|
248
|
+
--df-review-select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2317202c' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
246
249
|
}
|
|
247
250
|
|
|
248
251
|
button,
|
|
@@ -260,7 +263,7 @@ function ensureReviewShellStyle() {
|
|
|
260
263
|
--df-review-frame-gutter-x: var(--df-review-space-4);
|
|
261
264
|
display: grid;
|
|
262
265
|
grid-template-columns: minmax(0, 1fr) 0 32px;
|
|
263
|
-
grid-template-rows: auto minmax(0, 1fr);
|
|
266
|
+
grid-template-rows: auto auto minmax(0, 1fr);
|
|
264
267
|
width: 100%;
|
|
265
268
|
height: 100%;
|
|
266
269
|
overflow: hidden;
|
|
@@ -287,6 +290,20 @@ function ensureReviewShellStyle() {
|
|
|
287
290
|
box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.025);
|
|
288
291
|
}
|
|
289
292
|
|
|
293
|
+
.df-review-presence-row {
|
|
294
|
+
grid-column: 1;
|
|
295
|
+
grid-row: 2;
|
|
296
|
+
position: relative;
|
|
297
|
+
z-index: 590;
|
|
298
|
+
display: flex;
|
|
299
|
+
align-items: center;
|
|
300
|
+
justify-content: flex-start;
|
|
301
|
+
min-width: 0;
|
|
302
|
+
padding: var(--df-review-space-2) var(--df-review-frame-gutter-x);
|
|
303
|
+
border-bottom: 1px solid var(--df-review-line-soft);
|
|
304
|
+
background: var(--df-review-panel);
|
|
305
|
+
}
|
|
306
|
+
|
|
290
307
|
.df-review-address {
|
|
291
308
|
display: grid;
|
|
292
309
|
grid-template-columns: auto minmax(160px, 1fr) auto auto;
|
|
@@ -347,7 +364,7 @@ function ensureReviewShellStyle() {
|
|
|
347
364
|
.df-review-prompt-block-header button:hover,
|
|
348
365
|
.df-review-item-actions button:hover,
|
|
349
366
|
.df-review-item-visibility:hover,
|
|
350
|
-
.df-review-item-
|
|
367
|
+
.df-review-item-link-copy:hover,
|
|
351
368
|
.df-review-item-prompt-copy:hover,
|
|
352
369
|
.df-review-item-delete:hover,
|
|
353
370
|
.df-review-presets button.is-active,
|
|
@@ -410,7 +427,7 @@ function ensureReviewShellStyle() {
|
|
|
410
427
|
z-index: 1;
|
|
411
428
|
display: grid;
|
|
412
429
|
grid-template-rows: auto minmax(0, 1fr);
|
|
413
|
-
width: min(
|
|
430
|
+
width: min(940px, calc(100vw - 48px));
|
|
414
431
|
max-height: min(720px, calc(100vh - 48px));
|
|
415
432
|
overflow: hidden;
|
|
416
433
|
border: 1px solid var(--df-review-line);
|
|
@@ -465,18 +482,45 @@ function ensureReviewShellStyle() {
|
|
|
465
482
|
background: var(--df-review-control-hover);
|
|
466
483
|
}
|
|
467
484
|
|
|
485
|
+
.df-review-sitemap-controls {
|
|
486
|
+
display: flex;
|
|
487
|
+
align-items: center;
|
|
488
|
+
gap: 8px;
|
|
489
|
+
min-width: 0;
|
|
490
|
+
padding: 10px 12px;
|
|
491
|
+
border-bottom: 1px solid var(--df-review-line-soft);
|
|
492
|
+
background: var(--df-review-panel);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
.df-review-sitemap-controls select {
|
|
496
|
+
min-width: 138px;
|
|
497
|
+
min-height: 32px;
|
|
498
|
+
border: 1px solid var(--df-review-line-soft);
|
|
499
|
+
border-radius: var(--df-review-radius-sm);
|
|
500
|
+
padding: 0 26px 0 10px;
|
|
501
|
+
color: var(--df-review-text);
|
|
502
|
+
background: var(--df-review-control);
|
|
503
|
+
box-shadow: var(--df-review-shadow-control);
|
|
504
|
+
font-size: var(--df-review-font-size-xs);
|
|
505
|
+
font-weight: 850;
|
|
506
|
+
}
|
|
507
|
+
|
|
468
508
|
.df-review-sitemap-list {
|
|
509
|
+
--df-review-sitemap-grid-template: minmax(190px, 1fr) 74px 78px 64px minmax(108px, 160px);
|
|
510
|
+
position: relative;
|
|
469
511
|
display: grid;
|
|
470
512
|
align-content: start;
|
|
471
513
|
min-height: 0;
|
|
472
|
-
overflow:
|
|
514
|
+
overflow-x: hidden;
|
|
515
|
+
overflow-y: auto;
|
|
516
|
+
overscroll-behavior: contain;
|
|
473
517
|
padding: 8px;
|
|
474
518
|
}
|
|
475
519
|
|
|
476
520
|
.df-review-sitemap-table-head,
|
|
477
521
|
.df-review-sitemap-row {
|
|
478
522
|
display: grid;
|
|
479
|
-
grid-template-columns:
|
|
523
|
+
grid-template-columns: var(--df-review-sitemap-grid-template);
|
|
480
524
|
align-items: center;
|
|
481
525
|
column-gap: 0;
|
|
482
526
|
}
|
|
@@ -484,20 +528,64 @@ function ensureReviewShellStyle() {
|
|
|
484
528
|
.df-review-sitemap-table-head {
|
|
485
529
|
position: sticky;
|
|
486
530
|
top: 0;
|
|
487
|
-
z-index:
|
|
531
|
+
z-index: 3;
|
|
488
532
|
min-height: 32px;
|
|
489
533
|
border-bottom: 1px solid var(--df-review-line);
|
|
490
534
|
padding: 0 10px;
|
|
491
|
-
background: var(--df-review-
|
|
535
|
+
background: var(--df-review-panel);
|
|
536
|
+
box-shadow:
|
|
537
|
+
0 -8px 0 0 var(--df-review-panel),
|
|
538
|
+
0 1px 0 var(--df-review-line);
|
|
492
539
|
color: var(--df-review-muted);
|
|
493
540
|
font-size: var(--df-review-font-size-xs);
|
|
494
|
-
font-weight:
|
|
495
|
-
letter-spacing: 0.
|
|
541
|
+
font-weight: 720;
|
|
542
|
+
letter-spacing: 0.03em;
|
|
496
543
|
text-transform: uppercase;
|
|
497
544
|
}
|
|
498
545
|
|
|
499
|
-
.df-review-sitemap-
|
|
546
|
+
.df-review-sitemap-sort {
|
|
547
|
+
display: inline-flex;
|
|
548
|
+
align-items: center;
|
|
549
|
+
justify-content: flex-end;
|
|
550
|
+
gap: 4px;
|
|
551
|
+
min-width: 0;
|
|
552
|
+
min-height: 28px;
|
|
553
|
+
border: 0;
|
|
554
|
+
border-radius: 0;
|
|
555
|
+
padding: 0 0 0 8px;
|
|
556
|
+
color: inherit;
|
|
557
|
+
background: transparent;
|
|
558
|
+
box-shadow: none;
|
|
559
|
+
font: inherit;
|
|
560
|
+
letter-spacing: inherit;
|
|
500
561
|
text-align: right;
|
|
562
|
+
text-transform: inherit;
|
|
563
|
+
cursor: pointer;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.df-review-sitemap-sort.is-page {
|
|
567
|
+
justify-content: flex-start;
|
|
568
|
+
padding-left: 0;
|
|
569
|
+
text-align: left;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.df-review-sitemap-sort-indicator {
|
|
573
|
+
width: 8px;
|
|
574
|
+
min-width: 8px;
|
|
575
|
+
color: var(--df-review-accent);
|
|
576
|
+
text-align: center;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.df-review-sitemap-sort-label {
|
|
580
|
+
min-width: 0;
|
|
581
|
+
overflow: hidden;
|
|
582
|
+
text-overflow: ellipsis;
|
|
583
|
+
white-space: nowrap;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.df-review-sitemap-sort:hover,
|
|
587
|
+
.df-review-sitemap-sort.is-active {
|
|
588
|
+
color: var(--df-review-text);
|
|
501
589
|
}
|
|
502
590
|
|
|
503
591
|
.df-review-sitemap-row {
|
|
@@ -515,6 +603,18 @@ function ensureReviewShellStyle() {
|
|
|
515
603
|
cursor: pointer;
|
|
516
604
|
}
|
|
517
605
|
|
|
606
|
+
.df-review-sitemap-row.is-summary {
|
|
607
|
+
position: sticky;
|
|
608
|
+
bottom: 0;
|
|
609
|
+
z-index: 3;
|
|
610
|
+
border-top: 1px solid var(--df-review-line);
|
|
611
|
+
border-bottom: 0;
|
|
612
|
+
background: var(--df-review-panel);
|
|
613
|
+
box-shadow:
|
|
614
|
+
0 8px 0 0 var(--df-review-panel),
|
|
615
|
+
0 -1px 0 var(--df-review-line);
|
|
616
|
+
}
|
|
617
|
+
|
|
518
618
|
.df-review-sitemap-row.is-folder {
|
|
519
619
|
cursor: default;
|
|
520
620
|
}
|
|
@@ -531,11 +631,12 @@ function ensureReviewShellStyle() {
|
|
|
531
631
|
.df-review-sitemap-path {
|
|
532
632
|
display: inline-flex;
|
|
533
633
|
align-items: center;
|
|
634
|
+
gap: 7px;
|
|
534
635
|
min-width: 0;
|
|
535
636
|
overflow-wrap: anywhere;
|
|
536
637
|
color: var(--df-review-text);
|
|
537
638
|
font-size: var(--df-review-font-size-md);
|
|
538
|
-
font-weight:
|
|
639
|
+
font-weight: 650;
|
|
539
640
|
line-height: 1.35;
|
|
540
641
|
}
|
|
541
642
|
|
|
@@ -547,26 +648,33 @@ function ensureReviewShellStyle() {
|
|
|
547
648
|
flex: 0 0 auto;
|
|
548
649
|
color: var(--df-review-muted);
|
|
549
650
|
font-family: var(--df-review-font-mono);
|
|
550
|
-
font-weight:
|
|
651
|
+
font-weight: 500;
|
|
551
652
|
white-space: pre;
|
|
552
653
|
}
|
|
553
654
|
|
|
655
|
+
.df-review-sitemap-label {
|
|
656
|
+
min-width: 0;
|
|
657
|
+
overflow: hidden;
|
|
658
|
+
text-overflow: ellipsis;
|
|
659
|
+
}
|
|
660
|
+
|
|
554
661
|
.df-review-sitemap-cell {
|
|
555
662
|
min-width: 0;
|
|
556
663
|
color: var(--df-review-muted);
|
|
557
664
|
font-size: var(--df-review-font-size-sm);
|
|
558
665
|
font-variant-numeric: tabular-nums;
|
|
559
|
-
font-weight:
|
|
666
|
+
font-weight: 650;
|
|
560
667
|
line-height: 1;
|
|
561
668
|
text-align: right;
|
|
562
669
|
}
|
|
563
670
|
|
|
564
|
-
.df-review-sitemap-cell.is-
|
|
671
|
+
.df-review-sitemap-cell.is-total {
|
|
565
672
|
color: var(--df-review-accent);
|
|
673
|
+
font-weight: 760;
|
|
566
674
|
}
|
|
567
675
|
|
|
568
|
-
.df-review-sitemap-cell.is-
|
|
569
|
-
|
|
676
|
+
.df-review-sitemap-cell.is-total strong {
|
|
677
|
+
font: inherit;
|
|
570
678
|
}
|
|
571
679
|
|
|
572
680
|
.df-review-sitemap-cell.is-online {
|
|
@@ -1379,7 +1487,7 @@ function ensureReviewShellStyle() {
|
|
|
1379
1487
|
|
|
1380
1488
|
.df-review-side-rail {
|
|
1381
1489
|
grid-column: 3;
|
|
1382
|
-
grid-row: 1 / span
|
|
1490
|
+
grid-row: 1 / span 3;
|
|
1383
1491
|
position: relative;
|
|
1384
1492
|
z-index: 600;
|
|
1385
1493
|
display: flex;
|
|
@@ -1439,7 +1547,7 @@ function ensureReviewShellStyle() {
|
|
|
1439
1547
|
|
|
1440
1548
|
.df-review-qa-panel {
|
|
1441
1549
|
grid-column: 2;
|
|
1442
|
-
grid-row: 1 / span
|
|
1550
|
+
grid-row: 1 / span 3;
|
|
1443
1551
|
position: relative;
|
|
1444
1552
|
z-index: 600;
|
|
1445
1553
|
display: grid;
|
|
@@ -1512,101 +1620,114 @@ function ensureReviewShellStyle() {
|
|
|
1512
1620
|
font-variant-numeric: tabular-nums;
|
|
1513
1621
|
}
|
|
1514
1622
|
|
|
1515
|
-
.df-review-presence-
|
|
1516
|
-
display:
|
|
1517
|
-
|
|
1518
|
-
|
|
1623
|
+
.df-review-presence-overlay {
|
|
1624
|
+
display: flex;
|
|
1625
|
+
align-items: center;
|
|
1626
|
+
flex-wrap: wrap;
|
|
1519
1627
|
gap: 5px;
|
|
1520
|
-
|
|
1628
|
+
max-width: 100%;
|
|
1629
|
+
pointer-events: none;
|
|
1521
1630
|
}
|
|
1522
1631
|
|
|
1523
|
-
.df-review-presence-
|
|
1632
|
+
.df-review-presence-row .df-review-presence-overlay {
|
|
1633
|
+
width: 100%;
|
|
1634
|
+
max-width: 1440px;
|
|
1635
|
+
margin: 0 auto;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
.df-review-presence-chip {
|
|
1639
|
+
--df-review-presence-color: var(--df-review-accent);
|
|
1524
1640
|
display: inline-flex;
|
|
1525
1641
|
align-items: center;
|
|
1526
|
-
gap: 4px;
|
|
1527
1642
|
min-width: 0;
|
|
1528
|
-
|
|
1643
|
+
max-width: min(220px, calc(100% - 20px));
|
|
1644
|
+
min-height: 24px;
|
|
1645
|
+
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
1646
|
+
border-radius: var(--df-review-radius-pill);
|
|
1647
|
+
padding: 0 8px;
|
|
1648
|
+
color: #17202c;
|
|
1649
|
+
background: rgba(255, 255, 255, 0.92);
|
|
1650
|
+
box-shadow: 0 8px 22px rgba(15, 23, 42, 0.14);
|
|
1529
1651
|
font-size: var(--df-review-font-size-2xs);
|
|
1530
1652
|
font-weight: 900;
|
|
1531
|
-
line-height: 1;
|
|
1653
|
+
line-height: 1.1;
|
|
1654
|
+
overflow: hidden;
|
|
1655
|
+
text-overflow: ellipsis;
|
|
1532
1656
|
white-space: nowrap;
|
|
1657
|
+
backdrop-filter: blur(8px);
|
|
1533
1658
|
}
|
|
1534
1659
|
|
|
1535
|
-
.df-review-presence-
|
|
1536
|
-
width:
|
|
1537
|
-
height: 12px;
|
|
1538
|
-
fill: none;
|
|
1539
|
-
stroke: currentColor;
|
|
1540
|
-
stroke-linecap: round;
|
|
1541
|
-
stroke-linejoin: round;
|
|
1542
|
-
stroke-width: 2;
|
|
1660
|
+
.df-review-presence-row .df-review-presence-chip {
|
|
1661
|
+
max-width: none;
|
|
1543
1662
|
}
|
|
1544
1663
|
|
|
1545
|
-
.df-review-presence-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
flex-wrap: wrap;
|
|
1664
|
+
.df-review-presence-chip.is-self {
|
|
1665
|
+
border-color: var(--df-review-presence-color);
|
|
1666
|
+
box-shadow:
|
|
1667
|
+
inset 0 0 0 1px var(--df-review-presence-color),
|
|
1668
|
+
0 8px 22px rgba(15, 23, 42, 0.14);
|
|
1551
1669
|
}
|
|
1552
1670
|
|
|
1553
|
-
.df-review-presence-
|
|
1554
|
-
--df-review-presence-color: var(--df-review-accent);
|
|
1671
|
+
.df-review-presence-more {
|
|
1555
1672
|
display: inline-flex;
|
|
1556
1673
|
align-items: center;
|
|
1557
|
-
|
|
1558
|
-
min-width:
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
border: 1px solid var(--df-review-line-soft);
|
|
1674
|
+
justify-content: center;
|
|
1675
|
+
min-width: 28px;
|
|
1676
|
+
min-height: 24px;
|
|
1677
|
+
border: 1px solid rgba(15, 23, 42, 0.12);
|
|
1562
1678
|
border-radius: var(--df-review-radius-pill);
|
|
1563
|
-
padding: 0
|
|
1564
|
-
color:
|
|
1565
|
-
background:
|
|
1679
|
+
padding: 0 8px;
|
|
1680
|
+
color: #17202c;
|
|
1681
|
+
background: rgba(255, 255, 255, 0.92);
|
|
1682
|
+
box-shadow: 0 8px 22px rgba(15, 23, 42, 0.14);
|
|
1683
|
+
cursor: pointer;
|
|
1684
|
+
font: inherit;
|
|
1566
1685
|
font-size: var(--df-review-font-size-2xs);
|
|
1567
1686
|
font-weight: 900;
|
|
1568
|
-
line-height: 1
|
|
1569
|
-
|
|
1687
|
+
line-height: 1;
|
|
1688
|
+
pointer-events: auto;
|
|
1689
|
+
backdrop-filter: blur(8px);
|
|
1570
1690
|
}
|
|
1571
1691
|
|
|
1572
|
-
.df-review-presence-
|
|
1573
|
-
border-color:
|
|
1574
|
-
|
|
1692
|
+
.df-review-presence-more:hover {
|
|
1693
|
+
border-color: rgba(0, 102, 255, 0.42);
|
|
1694
|
+
color: #005be8;
|
|
1695
|
+
background: rgba(255, 255, 255, 0.98);
|
|
1575
1696
|
}
|
|
1576
1697
|
|
|
1577
|
-
.df-review-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
border-radius: var(--df-review-radius-pill);
|
|
1582
|
-
background: var(--df-review-presence-color);
|
|
1698
|
+
.df-review-list-controls {
|
|
1699
|
+
display: flex;
|
|
1700
|
+
align-items: center;
|
|
1701
|
+
gap: 4px;
|
|
1583
1702
|
}
|
|
1584
1703
|
|
|
1585
|
-
.df-review-
|
|
1586
|
-
|
|
1704
|
+
.df-review-source-select,
|
|
1705
|
+
.df-review-status-filter-select {
|
|
1706
|
+
min-height: 30px;
|
|
1707
|
+
border: 1px solid var(--df-review-line-soft);
|
|
1708
|
+
border-radius: var(--df-review-radius-sm);
|
|
1709
|
+
padding: 0 24px 0 8px;
|
|
1710
|
+
color: var(--df-review-text);
|
|
1711
|
+
background: var(--df-review-control);
|
|
1712
|
+
box-shadow: var(--df-review-shadow-control);
|
|
1713
|
+
font-size: var(--df-review-font-size-xs);
|
|
1714
|
+
font-weight: 800;
|
|
1587
1715
|
}
|
|
1588
1716
|
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
gap: 4px;
|
|
1593
|
-
}
|
|
1717
|
+
.df-review-source-select {
|
|
1718
|
+
width: 104px;
|
|
1719
|
+
}
|
|
1594
1720
|
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
border: 1px solid var(--df-review-line-soft);
|
|
1599
|
-
border-radius: var(--df-review-radius-sm);
|
|
1600
|
-
padding: 0 24px 0 8px;
|
|
1601
|
-
color: var(--df-review-text);
|
|
1602
|
-
background: var(--df-review-control);
|
|
1603
|
-
box-shadow: var(--df-review-shadow-control);
|
|
1604
|
-
font-size: var(--df-review-font-size-xs);
|
|
1605
|
-
font-weight: 800;
|
|
1606
|
-
}
|
|
1721
|
+
.df-review-status-filter-select {
|
|
1722
|
+
width: 124px;
|
|
1723
|
+
}
|
|
1607
1724
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1725
|
+
.df-review-list-title .df-review-status-filter-select {
|
|
1726
|
+
margin-left: auto;
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
.df-review-source-refresh {
|
|
1730
|
+
position: relative;
|
|
1610
1731
|
display: inline-grid;
|
|
1611
1732
|
place-items: center;
|
|
1612
1733
|
width: 30px;
|
|
@@ -1942,6 +2063,34 @@ function ensureReviewShellStyle() {
|
|
|
1942
2063
|
background: var(--df-review-area-soft);
|
|
1943
2064
|
}
|
|
1944
2065
|
|
|
2066
|
+
.df-review-source-select,
|
|
2067
|
+
.df-review-status-filter-select,
|
|
2068
|
+
.df-review-item-status-select,
|
|
2069
|
+
.df-review-item-status-select.is-status-todo,
|
|
2070
|
+
.df-review-item-status-select.is-status-doing,
|
|
2071
|
+
.df-review-item-status-select.is-status-review,
|
|
2072
|
+
.df-review-item-status-select.is-status-hold,
|
|
2073
|
+
.df-review-item-status-select.is-status-done,
|
|
2074
|
+
.df-review-sitemap-controls select {
|
|
2075
|
+
--df-review-select-padding-x: 12px;
|
|
2076
|
+
--df-review-select-chevron-size: 14px;
|
|
2077
|
+
--df-review-select-chevron-gap: 8px;
|
|
2078
|
+
appearance: none;
|
|
2079
|
+
-webkit-appearance: none;
|
|
2080
|
+
background-image: var(--df-review-select-chevron);
|
|
2081
|
+
background-repeat: no-repeat;
|
|
2082
|
+
background-position: right var(--df-review-select-padding-x) center;
|
|
2083
|
+
background-size:
|
|
2084
|
+
var(--df-review-select-chevron-size)
|
|
2085
|
+
var(--df-review-select-chevron-size);
|
|
2086
|
+
padding-right: calc(
|
|
2087
|
+
var(--df-review-select-padding-x) +
|
|
2088
|
+
var(--df-review-select-chevron-size) +
|
|
2089
|
+
var(--df-review-select-chevron-gap)
|
|
2090
|
+
);
|
|
2091
|
+
padding-left: var(--df-review-select-padding-x);
|
|
2092
|
+
}
|
|
2093
|
+
|
|
1945
2094
|
.df-review-item-status-badge.is-error {
|
|
1946
2095
|
border-color: rgba(255, 143, 97, 0.36);
|
|
1947
2096
|
color: var(--df-review-danger);
|
|
@@ -1967,8 +2116,8 @@ function ensureReviewShellStyle() {
|
|
|
1967
2116
|
|
|
1968
2117
|
.df-review-item-delete,
|
|
1969
2118
|
.df-review-item-edit,
|
|
2119
|
+
.df-review-item-link-copy,
|
|
1970
2120
|
.df-review-item-prompt-copy,
|
|
1971
|
-
.df-review-item-source-open,
|
|
1972
2121
|
.df-review-item-visibility {
|
|
1973
2122
|
display: inline-grid;
|
|
1974
2123
|
place-items: center;
|
|
@@ -1985,7 +2134,7 @@ function ensureReviewShellStyle() {
|
|
|
1985
2134
|
|
|
1986
2135
|
.df-review-item-visibility:hover,
|
|
1987
2136
|
.df-review-item-edit:hover,
|
|
1988
|
-
.df-review-item-
|
|
2137
|
+
.df-review-item-link-copy:hover,
|
|
1989
2138
|
.df-review-item-prompt-copy:hover {
|
|
1990
2139
|
border-color: rgba(124, 199, 255, 0.34);
|
|
1991
2140
|
color: var(--df-review-accent);
|
|
@@ -2007,14 +2156,15 @@ function ensureReviewShellStyle() {
|
|
|
2007
2156
|
color: var(--df-review-subtle);
|
|
2008
2157
|
}
|
|
2009
2158
|
|
|
2159
|
+
.df-review-item-link-copy.is-copied,
|
|
2010
2160
|
.df-review-item-prompt-copy.is-copied {
|
|
2011
2161
|
color: var(--df-review-accent);
|
|
2012
2162
|
}
|
|
2013
2163
|
|
|
2014
2164
|
.df-review-item-delete svg,
|
|
2015
2165
|
.df-review-item-edit svg,
|
|
2166
|
+
.df-review-item-link-copy svg,
|
|
2016
2167
|
.df-review-item-prompt-copy svg,
|
|
2017
|
-
.df-review-item-source-open svg,
|
|
2018
2168
|
.df-review-item-visibility svg {
|
|
2019
2169
|
width: 14px;
|
|
2020
2170
|
height: 14px;
|
|
@@ -2037,6 +2187,15 @@ function ensureReviewShellStyle() {
|
|
|
2037
2187
|
cursor: auto;
|
|
2038
2188
|
}
|
|
2039
2189
|
|
|
2190
|
+
.df-review-item-prompt-actions {
|
|
2191
|
+
display: inline-flex;
|
|
2192
|
+
grid-column: 2;
|
|
2193
|
+
align-items: center;
|
|
2194
|
+
justify-self: end;
|
|
2195
|
+
min-width: 0;
|
|
2196
|
+
cursor: auto;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2040
2199
|
.df-review-item-remote-actions {
|
|
2041
2200
|
display: inline-flex;
|
|
2042
2201
|
grid-column: 3;
|
|
@@ -2114,7 +2273,7 @@ function ensureReviewShellStyle() {
|
|
|
2114
2273
|
|
|
2115
2274
|
.df-review-stage {
|
|
2116
2275
|
grid-column: 1;
|
|
2117
|
-
grid-row:
|
|
2276
|
+
grid-row: 3;
|
|
2118
2277
|
display: grid;
|
|
2119
2278
|
min-width: 0;
|
|
2120
2279
|
min-height: 0;
|
|
@@ -2153,9 +2312,17 @@ function ensureReviewShellStyle() {
|
|
|
2153
2312
|
height: max-content;
|
|
2154
2313
|
min-width: 100%;
|
|
2155
2314
|
min-height: 100%;
|
|
2156
|
-
padding: 34px
|
|
2315
|
+
padding: 34px 58px 12px 40px;
|
|
2157
2316
|
}
|
|
2158
2317
|
|
|
2318
|
+
.df-review-target-stack {
|
|
2319
|
+
display: grid;
|
|
2320
|
+
justify-items: start;
|
|
2321
|
+
gap: 8px;
|
|
2322
|
+
width: max-content;
|
|
2323
|
+
max-width: 100%;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2159
2326
|
.df-review-device {
|
|
2160
2327
|
box-sizing: border-box;
|
|
2161
2328
|
flex: 0 0 auto;
|
|
@@ -2178,86 +2345,264 @@ function ensureReviewShellStyle() {
|
|
|
2178
2345
|
background: #fff;
|
|
2179
2346
|
}
|
|
2180
2347
|
|
|
2181
|
-
.df-review-
|
|
2182
|
-
position:
|
|
2183
|
-
|
|
2184
|
-
|
|
2348
|
+
.df-review-frame-link-stack {
|
|
2349
|
+
position: absolute;
|
|
2350
|
+
z-index: 14;
|
|
2351
|
+
top: 0;
|
|
2352
|
+
right: -44px;
|
|
2353
|
+
display: grid;
|
|
2354
|
+
gap: 8px;
|
|
2185
2355
|
}
|
|
2186
2356
|
|
|
2187
|
-
.df-review-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2357
|
+
.df-review-frame-link {
|
|
2358
|
+
display: grid;
|
|
2359
|
+
place-items: center;
|
|
2360
|
+
width: 34px;
|
|
2361
|
+
height: 34px;
|
|
2362
|
+
border: 1px solid rgba(15, 23, 42, 0.16);
|
|
2363
|
+
border-radius: var(--df-review-radius-md);
|
|
2364
|
+
color: #17202c;
|
|
2365
|
+
background: rgba(255, 255, 255, 0.92);
|
|
2366
|
+
box-shadow: 0 10px 26px rgba(15, 23, 42, 0.18);
|
|
2367
|
+
text-decoration: none;
|
|
2368
|
+
backdrop-filter: blur(8px);
|
|
2369
|
+
transition: transform 140ms ease, border-color 140ms ease, color 140ms ease,
|
|
2370
|
+
background 140ms ease;
|
|
2197
2371
|
}
|
|
2198
2372
|
|
|
2199
|
-
.df-review-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
user-select: none;
|
|
2373
|
+
.df-review-frame-link:hover {
|
|
2374
|
+
transform: translateY(-1px);
|
|
2375
|
+
border-color: rgba(0, 102, 255, 0.42);
|
|
2376
|
+
color: #005be8;
|
|
2377
|
+
background: rgba(255, 255, 255, 0.98);
|
|
2205
2378
|
}
|
|
2206
2379
|
|
|
2207
|
-
.df-review-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
top: -26px;
|
|
2211
|
-
height: 26px;
|
|
2212
|
-
border-bottom: 1px solid var(--df-review-line-soft);
|
|
2213
|
-
background-image:
|
|
2214
|
-
linear-gradient(
|
|
2215
|
-
to right,
|
|
2216
|
-
var(--df-review-color-ruler-tick-major) 1px,
|
|
2217
|
-
transparent 1px
|
|
2218
|
-
),
|
|
2219
|
-
linear-gradient(
|
|
2220
|
-
to right,
|
|
2221
|
-
var(--df-review-color-ruler-tick-minor) 1px,
|
|
2222
|
-
transparent 1px
|
|
2223
|
-
);
|
|
2224
|
-
background-size:
|
|
2225
|
-
calc(var(--df-review-ruler-step-x) * 5) 11px,
|
|
2226
|
-
var(--df-review-ruler-step-x) 6px;
|
|
2227
|
-
background-position: left bottom;
|
|
2228
|
-
background-repeat: repeat-x;
|
|
2380
|
+
.df-review-frame-link svg {
|
|
2381
|
+
width: 18px;
|
|
2382
|
+
height: 18px;
|
|
2229
2383
|
}
|
|
2230
2384
|
|
|
2231
|
-
.df-review-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
width: 26px;
|
|
2236
|
-
border-right: 1px solid var(--df-review-line-soft);
|
|
2237
|
-
background-image:
|
|
2238
|
-
linear-gradient(
|
|
2239
|
-
to bottom,
|
|
2240
|
-
var(--df-review-color-ruler-tick-major) 1px,
|
|
2241
|
-
transparent 1px
|
|
2242
|
-
),
|
|
2243
|
-
linear-gradient(
|
|
2244
|
-
to bottom,
|
|
2245
|
-
var(--df-review-color-ruler-tick-minor) 1px,
|
|
2246
|
-
transparent 1px
|
|
2247
|
-
);
|
|
2248
|
-
background-size:
|
|
2249
|
-
11px calc(var(--df-review-ruler-step-y) * 5),
|
|
2250
|
-
6px var(--df-review-ruler-step-y);
|
|
2251
|
-
background-position: right top;
|
|
2252
|
-
background-repeat: repeat-y;
|
|
2385
|
+
.df-review-frame-link.is-target svg {
|
|
2386
|
+
fill: none;
|
|
2387
|
+
stroke: currentColor;
|
|
2388
|
+
stroke-width: 2;
|
|
2253
2389
|
}
|
|
2254
2390
|
|
|
2255
|
-
.df-review-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2391
|
+
.df-review-frame-link.is-figma svg {
|
|
2392
|
+
fill: currentColor;
|
|
2393
|
+
stroke: none;
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
.df-review-source-outline {
|
|
2397
|
+
position: fixed;
|
|
2398
|
+
z-index: 880;
|
|
2399
|
+
pointer-events: none;
|
|
2400
|
+
border: 2px solid rgba(124, 199, 255, 0.96);
|
|
2401
|
+
border-radius: 4px;
|
|
2402
|
+
box-shadow:
|
|
2403
|
+
0 0 0 1px rgba(15, 18, 24, 0.58),
|
|
2404
|
+
0 0 0 5px rgba(124, 199, 255, 0.16);
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
.df-review-source-outline.is-pinned {
|
|
2408
|
+
border-color: var(--df-review-note);
|
|
2409
|
+
box-shadow:
|
|
2410
|
+
0 0 0 1px rgba(15, 18, 24, 0.58),
|
|
2411
|
+
0 0 0 5px rgba(243, 183, 95, 0.16);
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
.df-review-source-popover {
|
|
2415
|
+
--df-review-source-popover-line: rgba(226, 233, 245, 0.16);
|
|
2416
|
+
--df-review-source-popover-text: #edf3fb;
|
|
2417
|
+
--df-review-source-popover-muted: rgba(237, 243, 251, 0.68);
|
|
2418
|
+
--df-review-source-popover-subtle: rgba(237, 243, 251, 0.5);
|
|
2419
|
+
--df-review-source-popover-hover: rgba(124, 199, 255, 0.14);
|
|
2420
|
+
position: fixed;
|
|
2421
|
+
z-index: 890;
|
|
2422
|
+
display: grid;
|
|
2423
|
+
width: fit-content;
|
|
2424
|
+
min-width: min(240px, calc(100vw - 24px));
|
|
2425
|
+
max-width: min(440px, calc(100vw - 24px));
|
|
2426
|
+
max-height: 260px;
|
|
2427
|
+
overflow: hidden;
|
|
2428
|
+
border: 1px solid var(--df-review-source-popover-line);
|
|
2429
|
+
border-radius: var(--df-review-radius-md);
|
|
2430
|
+
padding: 8px 6px 6px;
|
|
2431
|
+
color: var(--df-review-source-popover-text);
|
|
2432
|
+
color-scheme: dark;
|
|
2433
|
+
background: rgba(19, 24, 33, 0.96);
|
|
2434
|
+
box-shadow: var(--df-review-shadow-panel);
|
|
2435
|
+
backdrop-filter: blur(10px);
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
.df-review-source-popover-close {
|
|
2439
|
+
position: absolute;
|
|
2440
|
+
top: 5px;
|
|
2441
|
+
right: 5px;
|
|
2442
|
+
z-index: 1;
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
.df-review-source-popover-close button {
|
|
2446
|
+
display: grid;
|
|
2447
|
+
place-items: center;
|
|
2448
|
+
width: 24px;
|
|
2449
|
+
height: 24px;
|
|
2450
|
+
border: 1px solid transparent;
|
|
2451
|
+
border-radius: var(--df-review-radius-sm);
|
|
2452
|
+
padding: 0;
|
|
2453
|
+
color: var(--df-review-source-popover-subtle);
|
|
2454
|
+
background: transparent;
|
|
2455
|
+
font-size: 16px;
|
|
2456
|
+
font-weight: 800;
|
|
2457
|
+
line-height: 1;
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2460
|
+
.df-review-source-popover-close button:hover {
|
|
2461
|
+
border-color: var(--df-review-source-popover-line);
|
|
2462
|
+
color: var(--df-review-source-popover-text);
|
|
2463
|
+
background: var(--df-review-source-popover-hover);
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
.df-review-source-candidate-list {
|
|
2467
|
+
display: grid;
|
|
2468
|
+
gap: 0;
|
|
2469
|
+
max-height: min(220px, calc(100vh - 96px));
|
|
2470
|
+
min-height: 0;
|
|
2471
|
+
overflow-x: hidden;
|
|
2472
|
+
overflow-y: auto;
|
|
2473
|
+
padding-right: 2px;
|
|
2474
|
+
scrollbar-gutter: stable;
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
.df-review-source-candidate {
|
|
2478
|
+
display: grid;
|
|
2479
|
+
width: 100%;
|
|
2480
|
+
min-height: 54px;
|
|
2481
|
+
border: 0;
|
|
2482
|
+
border-radius: var(--df-review-radius-sm);
|
|
2483
|
+
padding: 6px 30px 6px 8px;
|
|
2484
|
+
color: var(--df-review-source-popover-text);
|
|
2485
|
+
background: transparent;
|
|
2486
|
+
text-align: left;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
.df-review-source-candidate:hover {
|
|
2490
|
+
background: var(--df-review-source-popover-hover);
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
.df-review-source-candidate-main {
|
|
2494
|
+
display: grid;
|
|
2495
|
+
gap: 2px;
|
|
2496
|
+
min-width: 0;
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
.df-review-source-candidate-main strong,
|
|
2500
|
+
.df-review-source-candidate-main small {
|
|
2501
|
+
overflow: hidden;
|
|
2502
|
+
text-overflow: ellipsis;
|
|
2503
|
+
white-space: nowrap;
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
.df-review-source-candidate-main strong {
|
|
2507
|
+
font-size: var(--df-review-font-size-xs);
|
|
2508
|
+
font-weight: 900;
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
.df-review-source-candidate-main span {
|
|
2512
|
+
overflow-wrap: anywhere;
|
|
2513
|
+
color: var(--df-review-source-popover-muted);
|
|
2514
|
+
font-family: var(--df-review-font-mono);
|
|
2515
|
+
font-size: var(--df-review-font-size-2xs);
|
|
2516
|
+
line-height: 1.25;
|
|
2517
|
+
white-space: normal;
|
|
2518
|
+
}
|
|
2519
|
+
|
|
2520
|
+
.df-review-source-candidate-main small {
|
|
2521
|
+
color: var(--df-review-source-popover-subtle);
|
|
2522
|
+
font-family: var(--df-review-font-mono);
|
|
2523
|
+
font-size: var(--df-review-font-size-2xs);
|
|
2524
|
+
}
|
|
2525
|
+
|
|
2526
|
+
.df-review-device-frame {
|
|
2527
|
+
position: relative;
|
|
2528
|
+
box-sizing: border-box;
|
|
2529
|
+
flex: 0 0 auto;
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
.df-review-ruler-corner {
|
|
2533
|
+
position: absolute;
|
|
2534
|
+
left: -26px;
|
|
2535
|
+
top: -26px;
|
|
2536
|
+
width: 26px;
|
|
2537
|
+
height: 26px;
|
|
2538
|
+
z-index: 6;
|
|
2539
|
+
border-right: 1px solid var(--df-review-line-soft);
|
|
2540
|
+
border-bottom: 1px solid var(--df-review-line-soft);
|
|
2541
|
+
background: var(--df-review-color-ruler-surface);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
.df-review-ruler-gutter {
|
|
2545
|
+
position: absolute;
|
|
2546
|
+
z-index: 6;
|
|
2547
|
+
background: var(--df-review-color-ruler-surface);
|
|
2548
|
+
color: var(--df-review-muted);
|
|
2549
|
+
user-select: none;
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
.df-review-ruler-gutter.is-x {
|
|
2553
|
+
left: 0;
|
|
2554
|
+
right: 0;
|
|
2555
|
+
top: -26px;
|
|
2556
|
+
height: 26px;
|
|
2557
|
+
border-bottom: 1px solid var(--df-review-line-soft);
|
|
2558
|
+
background-image:
|
|
2559
|
+
linear-gradient(
|
|
2560
|
+
to right,
|
|
2561
|
+
var(--df-review-color-ruler-tick-major) 1px,
|
|
2562
|
+
transparent 1px
|
|
2563
|
+
),
|
|
2564
|
+
linear-gradient(
|
|
2565
|
+
to right,
|
|
2566
|
+
var(--df-review-color-ruler-tick-minor) 1px,
|
|
2567
|
+
transparent 1px
|
|
2568
|
+
);
|
|
2569
|
+
background-size:
|
|
2570
|
+
calc(var(--df-review-ruler-step-x) * 5) 11px,
|
|
2571
|
+
var(--df-review-ruler-step-x) 6px;
|
|
2572
|
+
background-position: left bottom;
|
|
2573
|
+
background-repeat: repeat-x;
|
|
2574
|
+
}
|
|
2575
|
+
|
|
2576
|
+
.df-review-ruler-gutter.is-y {
|
|
2577
|
+
left: -26px;
|
|
2578
|
+
top: 0;
|
|
2579
|
+
bottom: 0;
|
|
2580
|
+
width: 26px;
|
|
2581
|
+
border-right: 1px solid var(--df-review-line-soft);
|
|
2582
|
+
background-image:
|
|
2583
|
+
linear-gradient(
|
|
2584
|
+
to bottom,
|
|
2585
|
+
var(--df-review-color-ruler-tick-major) 1px,
|
|
2586
|
+
transparent 1px
|
|
2587
|
+
),
|
|
2588
|
+
linear-gradient(
|
|
2589
|
+
to bottom,
|
|
2590
|
+
var(--df-review-color-ruler-tick-minor) 1px,
|
|
2591
|
+
transparent 1px
|
|
2592
|
+
);
|
|
2593
|
+
background-size:
|
|
2594
|
+
11px calc(var(--df-review-ruler-step-y) * 5),
|
|
2595
|
+
6px var(--df-review-ruler-step-y);
|
|
2596
|
+
background-position: right top;
|
|
2597
|
+
background-repeat: repeat-y;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
.df-review-ruler-frame-label {
|
|
2601
|
+
position: absolute;
|
|
2602
|
+
right: 6px;
|
|
2603
|
+
top: 50%;
|
|
2604
|
+
transform: translateY(-50%);
|
|
2605
|
+
display: flex;
|
|
2261
2606
|
align-items: center;
|
|
2262
2607
|
gap: 6px;
|
|
2263
2608
|
padding: 4px 8px;
|
|
@@ -2383,7 +2728,7 @@ function ensureReviewShellStyle() {
|
|
|
2383
2728
|
.df-review-shell,
|
|
2384
2729
|
.df-review-shell.is-list-visible {
|
|
2385
2730
|
grid-template-columns: minmax(0, 1fr) 0 32px;
|
|
2386
|
-
grid-template-rows: auto minmax(0, 1fr);
|
|
2731
|
+
grid-template-rows: auto auto minmax(0, 1fr);
|
|
2387
2732
|
}
|
|
2388
2733
|
|
|
2389
2734
|
.df-review-shell.is-list-visible {
|
|
@@ -2439,8 +2784,9 @@ function ensureReviewShellStyle() {
|
|
|
2439
2784
|
import {
|
|
2440
2785
|
useCallback as useCallback11,
|
|
2441
2786
|
useEffect as useEffect10,
|
|
2442
|
-
|
|
2443
|
-
|
|
2787
|
+
useMemo as useMemo7,
|
|
2788
|
+
useRef as useRef5,
|
|
2789
|
+
useState as useState10
|
|
2444
2790
|
} from "react";
|
|
2445
2791
|
|
|
2446
2792
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/createLucideIcon.mjs
|
|
@@ -2547,31 +2893,42 @@ var createLucideIcon = (iconName, iconNode) => {
|
|
|
2547
2893
|
return Component;
|
|
2548
2894
|
};
|
|
2549
2895
|
|
|
2550
|
-
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/
|
|
2896
|
+
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/bot.mjs
|
|
2551
2897
|
var __iconNode = [
|
|
2898
|
+
["path", { d: "M12 8V4H8", key: "hb8ula" }],
|
|
2899
|
+
["rect", { width: "16", height: "12", x: "4", y: "8", rx: "2", key: "enze0r" }],
|
|
2900
|
+
["path", { d: "M2 14h2", key: "vft8re" }],
|
|
2901
|
+
["path", { d: "M20 14h2", key: "4cs60a" }],
|
|
2902
|
+
["path", { d: "M15 13v2", key: "1xurst" }],
|
|
2903
|
+
["path", { d: "M9 13v2", key: "rq6x2g" }]
|
|
2904
|
+
];
|
|
2905
|
+
var Bot = createLucideIcon("bot", __iconNode);
|
|
2906
|
+
|
|
2907
|
+
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/circle-question-mark.mjs
|
|
2908
|
+
var __iconNode2 = [
|
|
2552
2909
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
2553
2910
|
["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3", key: "1u773s" }],
|
|
2554
2911
|
["path", { d: "M12 17h.01", key: "p32p05" }]
|
|
2555
2912
|
];
|
|
2556
|
-
var CircleQuestionMark = createLucideIcon("circle-question-mark",
|
|
2913
|
+
var CircleQuestionMark = createLucideIcon("circle-question-mark", __iconNode2);
|
|
2557
2914
|
|
|
2558
2915
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/copy.mjs
|
|
2559
|
-
var
|
|
2916
|
+
var __iconNode3 = [
|
|
2560
2917
|
["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
|
|
2561
2918
|
["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
|
|
2562
2919
|
];
|
|
2563
|
-
var Copy = createLucideIcon("copy",
|
|
2920
|
+
var Copy = createLucideIcon("copy", __iconNode3);
|
|
2564
2921
|
|
|
2565
2922
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/external-link.mjs
|
|
2566
|
-
var
|
|
2923
|
+
var __iconNode4 = [
|
|
2567
2924
|
["path", { d: "M15 3h6v6", key: "1q9fwt" }],
|
|
2568
2925
|
["path", { d: "M10 14 21 3", key: "gplh6r" }],
|
|
2569
2926
|
["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
|
|
2570
2927
|
];
|
|
2571
|
-
var ExternalLink = createLucideIcon("external-link",
|
|
2928
|
+
var ExternalLink = createLucideIcon("external-link", __iconNode4);
|
|
2572
2929
|
|
|
2573
2930
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/eye-off.mjs
|
|
2574
|
-
var
|
|
2931
|
+
var __iconNode5 = [
|
|
2575
2932
|
[
|
|
2576
2933
|
"path",
|
|
2577
2934
|
{
|
|
@@ -2589,10 +2946,10 @@ var __iconNode4 = [
|
|
|
2589
2946
|
],
|
|
2590
2947
|
["path", { d: "m2 2 20 20", key: "1ooewy" }]
|
|
2591
2948
|
];
|
|
2592
|
-
var EyeOff = createLucideIcon("eye-off",
|
|
2949
|
+
var EyeOff = createLucideIcon("eye-off", __iconNode5);
|
|
2593
2950
|
|
|
2594
2951
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/eye.mjs
|
|
2595
|
-
var
|
|
2952
|
+
var __iconNode6 = [
|
|
2596
2953
|
[
|
|
2597
2954
|
"path",
|
|
2598
2955
|
{
|
|
@@ -2602,22 +2959,7 @@ var __iconNode5 = [
|
|
|
2602
2959
|
],
|
|
2603
2960
|
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
|
|
2604
2961
|
];
|
|
2605
|
-
var Eye = createLucideIcon("eye",
|
|
2606
|
-
|
|
2607
|
-
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/file-code-corner.mjs
|
|
2608
|
-
var __iconNode6 = [
|
|
2609
|
-
[
|
|
2610
|
-
"path",
|
|
2611
|
-
{
|
|
2612
|
-
d: "M4 12.15V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2h-3.35",
|
|
2613
|
-
key: "1wthlu"
|
|
2614
|
-
}
|
|
2615
|
-
],
|
|
2616
|
-
["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }],
|
|
2617
|
-
["path", { d: "m5 16-3 3 3 3", key: "331omg" }],
|
|
2618
|
-
["path", { d: "m9 22 3-3-3-3", key: "lsp7cz" }]
|
|
2619
|
-
];
|
|
2620
|
-
var FileCodeCorner = createLucideIcon("file-code-corner", __iconNode6);
|
|
2962
|
+
var Eye = createLucideIcon("eye", __iconNode6);
|
|
2621
2963
|
|
|
2622
2964
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/grip-vertical.mjs
|
|
2623
2965
|
var __iconNode7 = [
|
|
@@ -2647,16 +2989,24 @@ var __iconNode9 = [
|
|
|
2647
2989
|
];
|
|
2648
2990
|
var LayoutGrid = createLucideIcon("layout-grid", __iconNode9);
|
|
2649
2991
|
|
|
2650
|
-
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/
|
|
2992
|
+
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/link-2.mjs
|
|
2651
2993
|
var __iconNode10 = [
|
|
2994
|
+
["path", { d: "M9 17H7A5 5 0 0 1 7 7h2", key: "8i5ue5" }],
|
|
2995
|
+
["path", { d: "M15 7h2a5 5 0 1 1 0 10h-2", key: "1b9ql8" }],
|
|
2996
|
+
["line", { x1: "8", x2: "16", y1: "12", y2: "12", key: "1jonct" }]
|
|
2997
|
+
];
|
|
2998
|
+
var Link2 = createLucideIcon("link-2", __iconNode10);
|
|
2999
|
+
|
|
3000
|
+
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/list-filter.mjs
|
|
3001
|
+
var __iconNode11 = [
|
|
2652
3002
|
["path", { d: "M2 5h20", key: "1fs1ex" }],
|
|
2653
3003
|
["path", { d: "M6 12h12", key: "8npq4p" }],
|
|
2654
3004
|
["path", { d: "M9 19h6", key: "456am0" }]
|
|
2655
3005
|
];
|
|
2656
|
-
var ListFilter = createLucideIcon("list-filter",
|
|
3006
|
+
var ListFilter = createLucideIcon("list-filter", __iconNode11);
|
|
2657
3007
|
|
|
2658
3008
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/map.mjs
|
|
2659
|
-
var
|
|
3009
|
+
var __iconNode12 = [
|
|
2660
3010
|
[
|
|
2661
3011
|
"path",
|
|
2662
3012
|
{
|
|
@@ -2667,27 +3017,27 @@ var __iconNode11 = [
|
|
|
2667
3017
|
["path", { d: "M15 5.764v15", key: "1pn4in" }],
|
|
2668
3018
|
["path", { d: "M9 3.236v15", key: "1uimfh" }]
|
|
2669
3019
|
];
|
|
2670
|
-
var Map2 = createLucideIcon("map",
|
|
3020
|
+
var Map2 = createLucideIcon("map", __iconNode12);
|
|
2671
3021
|
|
|
2672
3022
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/maximize-2.mjs
|
|
2673
|
-
var
|
|
3023
|
+
var __iconNode13 = [
|
|
2674
3024
|
["path", { d: "M15 3h6v6", key: "1q9fwt" }],
|
|
2675
3025
|
["path", { d: "m21 3-7 7", key: "1l2asr" }],
|
|
2676
3026
|
["path", { d: "m3 21 7-7", key: "tjx5ai" }],
|
|
2677
3027
|
["path", { d: "M9 21H3v-6", key: "wtvkvv" }]
|
|
2678
3028
|
];
|
|
2679
|
-
var Maximize2 = createLucideIcon("maximize-2",
|
|
3029
|
+
var Maximize2 = createLucideIcon("maximize-2", __iconNode13);
|
|
2680
3030
|
|
|
2681
3031
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/monitor.mjs
|
|
2682
|
-
var
|
|
3032
|
+
var __iconNode14 = [
|
|
2683
3033
|
["rect", { width: "20", height: "14", x: "2", y: "3", rx: "2", key: "48i651" }],
|
|
2684
3034
|
["line", { x1: "8", x2: "16", y1: "21", y2: "21", key: "1svkeh" }],
|
|
2685
3035
|
["line", { x1: "12", x2: "12", y1: "17", y2: "21", key: "vw1qmm" }]
|
|
2686
3036
|
];
|
|
2687
|
-
var Monitor = createLucideIcon("monitor",
|
|
3037
|
+
var Monitor = createLucideIcon("monitor", __iconNode14);
|
|
2688
3038
|
|
|
2689
3039
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/pencil.mjs
|
|
2690
|
-
var
|
|
3040
|
+
var __iconNode15 = [
|
|
2691
3041
|
[
|
|
2692
3042
|
"path",
|
|
2693
3043
|
{
|
|
@@ -2697,25 +3047,25 @@ var __iconNode14 = [
|
|
|
2697
3047
|
],
|
|
2698
3048
|
["path", { d: "m15 5 4 4", key: "1mk7zo" }]
|
|
2699
3049
|
];
|
|
2700
|
-
var Pencil = createLucideIcon("pencil",
|
|
3050
|
+
var Pencil = createLucideIcon("pencil", __iconNode15);
|
|
2701
3051
|
|
|
2702
3052
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/rectangle-horizontal.mjs
|
|
2703
|
-
var
|
|
3053
|
+
var __iconNode16 = [
|
|
2704
3054
|
["rect", { width: "20", height: "12", x: "2", y: "6", rx: "2", key: "9lu3g6" }]
|
|
2705
3055
|
];
|
|
2706
|
-
var RectangleHorizontal = createLucideIcon("rectangle-horizontal",
|
|
3056
|
+
var RectangleHorizontal = createLucideIcon("rectangle-horizontal", __iconNode16);
|
|
2707
3057
|
|
|
2708
3058
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/refresh-cw.mjs
|
|
2709
|
-
var
|
|
3059
|
+
var __iconNode17 = [
|
|
2710
3060
|
["path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8", key: "v9h5vc" }],
|
|
2711
3061
|
["path", { d: "M21 3v5h-5", key: "1q7to0" }],
|
|
2712
3062
|
["path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16", key: "3uifl3" }],
|
|
2713
3063
|
["path", { d: "M8 16H3v5", key: "1cv678" }]
|
|
2714
3064
|
];
|
|
2715
|
-
var RefreshCw = createLucideIcon("refresh-cw",
|
|
3065
|
+
var RefreshCw = createLucideIcon("refresh-cw", __iconNode17);
|
|
2716
3066
|
|
|
2717
3067
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/ruler.mjs
|
|
2718
|
-
var
|
|
3068
|
+
var __iconNode18 = [
|
|
2719
3069
|
[
|
|
2720
3070
|
"path",
|
|
2721
3071
|
{
|
|
@@ -2728,19 +3078,19 @@ var __iconNode17 = [
|
|
|
2728
3078
|
["path", { d: "m8.5 6.5 2-2", key: "vc6u1g" }],
|
|
2729
3079
|
["path", { d: "m17.5 15.5 2-2", key: "wo5hmg" }]
|
|
2730
3080
|
];
|
|
2731
|
-
var Ruler = createLucideIcon("ruler",
|
|
3081
|
+
var Ruler = createLucideIcon("ruler", __iconNode18);
|
|
2732
3082
|
|
|
2733
3083
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/scan.mjs
|
|
2734
|
-
var
|
|
3084
|
+
var __iconNode19 = [
|
|
2735
3085
|
["path", { d: "M3 7V5a2 2 0 0 1 2-2h2", key: "aa7l1z" }],
|
|
2736
3086
|
["path", { d: "M17 3h2a2 2 0 0 1 2 2v2", key: "4qcy5o" }],
|
|
2737
3087
|
["path", { d: "M21 17v2a2 2 0 0 1-2 2h-2", key: "6vwrx8" }],
|
|
2738
3088
|
["path", { d: "M7 21H5a2 2 0 0 1-2-2v-2", key: "ioqczr" }]
|
|
2739
3089
|
];
|
|
2740
|
-
var Scan = createLucideIcon("scan",
|
|
3090
|
+
var Scan = createLucideIcon("scan", __iconNode19);
|
|
2741
3091
|
|
|
2742
3092
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/settings.mjs
|
|
2743
|
-
var
|
|
3093
|
+
var __iconNode20 = [
|
|
2744
3094
|
[
|
|
2745
3095
|
"path",
|
|
2746
3096
|
{
|
|
@@ -2750,17 +3100,17 @@ var __iconNode19 = [
|
|
|
2750
3100
|
],
|
|
2751
3101
|
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
|
|
2752
3102
|
];
|
|
2753
|
-
var Settings = createLucideIcon("settings",
|
|
3103
|
+
var Settings = createLucideIcon("settings", __iconNode20);
|
|
2754
3104
|
|
|
2755
3105
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/smartphone.mjs
|
|
2756
|
-
var
|
|
3106
|
+
var __iconNode21 = [
|
|
2757
3107
|
["rect", { width: "14", height: "20", x: "5", y: "2", rx: "2", ry: "2", key: "1yt0o3" }],
|
|
2758
3108
|
["path", { d: "M12 18h.01", key: "mhygvu" }]
|
|
2759
3109
|
];
|
|
2760
|
-
var Smartphone = createLucideIcon("smartphone",
|
|
3110
|
+
var Smartphone = createLucideIcon("smartphone", __iconNode21);
|
|
2761
3111
|
|
|
2762
3112
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/square-mouse-pointer.mjs
|
|
2763
|
-
var
|
|
3113
|
+
var __iconNode22 = [
|
|
2764
3114
|
[
|
|
2765
3115
|
"path",
|
|
2766
3116
|
{
|
|
@@ -2770,10 +3120,10 @@ var __iconNode21 = [
|
|
|
2770
3120
|
],
|
|
2771
3121
|
["path", { d: "M21 11V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h6", key: "14rsvq" }]
|
|
2772
3122
|
];
|
|
2773
|
-
var SquareMousePointer = createLucideIcon("square-mouse-pointer",
|
|
3123
|
+
var SquareMousePointer = createLucideIcon("square-mouse-pointer", __iconNode22);
|
|
2774
3124
|
|
|
2775
3125
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/sticky-note.mjs
|
|
2776
|
-
var
|
|
3126
|
+
var __iconNode23 = [
|
|
2777
3127
|
[
|
|
2778
3128
|
"path",
|
|
2779
3129
|
{
|
|
@@ -2783,24 +3133,15 @@ var __iconNode22 = [
|
|
|
2783
3133
|
],
|
|
2784
3134
|
["path", { d: "M15 3v5a1 1 0 0 0 1 1h5", key: "6s6qgf" }]
|
|
2785
3135
|
];
|
|
2786
|
-
var StickyNote = createLucideIcon("sticky-note",
|
|
3136
|
+
var StickyNote = createLucideIcon("sticky-note", __iconNode23);
|
|
2787
3137
|
|
|
2788
3138
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/upload.mjs
|
|
2789
|
-
var
|
|
3139
|
+
var __iconNode24 = [
|
|
2790
3140
|
["path", { d: "M12 3v12", key: "1x0j5s" }],
|
|
2791
3141
|
["path", { d: "m17 8-5-5-5 5", key: "7q97r8" }],
|
|
2792
3142
|
["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }]
|
|
2793
3143
|
];
|
|
2794
|
-
var Upload = createLucideIcon("upload",
|
|
2795
|
-
|
|
2796
|
-
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/users.mjs
|
|
2797
|
-
var __iconNode24 = [
|
|
2798
|
-
["path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2", key: "1yyitq" }],
|
|
2799
|
-
["path", { d: "M16 3.128a4 4 0 0 1 0 7.744", key: "16gr8j" }],
|
|
2800
|
-
["path", { d: "M22 21v-2a4 4 0 0 0-3-3.87", key: "kshegd" }],
|
|
2801
|
-
["circle", { cx: "9", cy: "7", r: "4", key: "nufk8" }]
|
|
2802
|
-
];
|
|
2803
|
-
var Users = createLucideIcon("users", __iconNode24);
|
|
3144
|
+
var Upload = createLucideIcon("upload", __iconNode24);
|
|
2804
3145
|
|
|
2805
3146
|
// node_modules/.pnpm/lucide-react@1.20.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/x.mjs
|
|
2806
3147
|
var __iconNode25 = [
|
|
@@ -2844,6 +3185,45 @@ var normalizeTarget = (value, reviewPathPrefix = DEFAULT_REVIEW_PATH_PREFIX) =>
|
|
|
2844
3185
|
const reviewPrefix = normalizeReviewPathPrefix(reviewPathPrefix);
|
|
2845
3186
|
return normalized === reviewPrefix || normalized.startsWith(`${reviewPrefix}/`) ? "/" : normalized;
|
|
2846
3187
|
};
|
|
3188
|
+
var parseReviewAddressInput = (value, reviewPathPrefix = DEFAULT_REVIEW_PATH_PREFIX) => {
|
|
3189
|
+
const raw = value.trim();
|
|
3190
|
+
if (!raw) return { target: "/" };
|
|
3191
|
+
const parsedUrl = parseSameOriginUrl(raw);
|
|
3192
|
+
if (!parsedUrl) {
|
|
3193
|
+
return { target: normalizeTarget(raw, reviewPathPrefix) };
|
|
3194
|
+
}
|
|
3195
|
+
const reviewPrefix = normalizeReviewPathPrefix(reviewPathPrefix);
|
|
3196
|
+
const isReviewUrl = parsedUrl.pathname === reviewPrefix || parsedUrl.pathname.startsWith(`${reviewPrefix}/`);
|
|
3197
|
+
if (!isReviewUrl) {
|
|
3198
|
+
return {
|
|
3199
|
+
target: normalizeTarget(parsedUrl.pathname, reviewPathPrefix)
|
|
3200
|
+
};
|
|
3201
|
+
}
|
|
3202
|
+
const source = parsedUrl.searchParams.get("source")?.trim();
|
|
3203
|
+
return {
|
|
3204
|
+
height: getPositiveParamNumber(parsedUrl.searchParams, "h"),
|
|
3205
|
+
itemId: parsedUrl.searchParams.get("item"),
|
|
3206
|
+
source: source ? source : void 0,
|
|
3207
|
+
target: normalizeTarget(
|
|
3208
|
+
parsedUrl.searchParams.get("target") ?? "/",
|
|
3209
|
+
reviewPathPrefix
|
|
3210
|
+
),
|
|
3211
|
+
width: getPositiveParamNumber(parsedUrl.searchParams, "w")
|
|
3212
|
+
};
|
|
3213
|
+
};
|
|
3214
|
+
function parseSameOriginUrl(value) {
|
|
3215
|
+
if (typeof window === "undefined") return null;
|
|
3216
|
+
try {
|
|
3217
|
+
const url = new URL(value, window.location.origin);
|
|
3218
|
+
return url.origin === window.location.origin ? url : null;
|
|
3219
|
+
} catch {
|
|
3220
|
+
return null;
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
function getPositiveParamNumber(params, name) {
|
|
3224
|
+
const value = Number(params.get(name));
|
|
3225
|
+
return Number.isFinite(value) && value > 0 ? value : void 0;
|
|
3226
|
+
}
|
|
2847
3227
|
var getInitialTarget = (reviewPathPrefix = DEFAULT_REVIEW_PATH_PREFIX) => {
|
|
2848
3228
|
if (typeof window === "undefined") return "/";
|
|
2849
3229
|
const target = new URLSearchParams(window.location.search).get("target");
|
|
@@ -2884,6 +3264,10 @@ var updateShellUrl = (target, size, source) => {
|
|
|
2884
3264
|
window.history.replaceState(null, "", `${url.pathname}${url.search}`);
|
|
2885
3265
|
};
|
|
2886
3266
|
var updateShellUrlForItem = (target, size, itemId, source) => {
|
|
3267
|
+
const url = getShellUrlForItem(target, size, itemId, source);
|
|
3268
|
+
window.history.replaceState(null, "", `${url.pathname}${url.search}`);
|
|
3269
|
+
};
|
|
3270
|
+
var getShellUrlForItem = (target, size, itemId, source) => {
|
|
2887
3271
|
const url = new URL(window.location.href);
|
|
2888
3272
|
url.searchParams.set("target", target);
|
|
2889
3273
|
url.searchParams.set("w", String(size.width));
|
|
@@ -2894,7 +3278,7 @@ var updateShellUrlForItem = (target, size, itemId, source) => {
|
|
|
2894
3278
|
} else {
|
|
2895
3279
|
url.searchParams.delete("source");
|
|
2896
3280
|
}
|
|
2897
|
-
|
|
3281
|
+
return url;
|
|
2898
3282
|
};
|
|
2899
3283
|
var getInitialItemId = () => {
|
|
2900
3284
|
if (typeof window === "undefined") return null;
|
|
@@ -2976,7 +3360,9 @@ var toReviewViewportPresets = (presets) => presets.map((preset) => ({
|
|
|
2976
3360
|
label: preset.label,
|
|
2977
3361
|
width: preset.width,
|
|
2978
3362
|
height: preset.height,
|
|
2979
|
-
scope: getViewportPresetKind(preset)
|
|
3363
|
+
scope: getViewportPresetKind(preset),
|
|
3364
|
+
designWidth: preset.designWidth,
|
|
3365
|
+
designHeight: preset.designHeight
|
|
2980
3366
|
}));
|
|
2981
3367
|
var getIsFigmaOverlayAvailable = (preset) => {
|
|
2982
3368
|
const kind = getViewportPresetKind(preset);
|
|
@@ -3450,11 +3836,40 @@ var ReviewSettingsModal = ({
|
|
|
3450
3836
|
);
|
|
3451
3837
|
};
|
|
3452
3838
|
|
|
3839
|
+
// src/react-shell/sitemap/modal.tsx
|
|
3840
|
+
import {
|
|
3841
|
+
useMemo as useMemo2,
|
|
3842
|
+
useState
|
|
3843
|
+
} from "react";
|
|
3844
|
+
|
|
3453
3845
|
// src/react-shell/sitemap/tree.ts
|
|
3454
|
-
var
|
|
3846
|
+
var WORKFLOW_STATUSES = [
|
|
3847
|
+
"todo",
|
|
3848
|
+
"doing",
|
|
3849
|
+
"review",
|
|
3850
|
+
"hold",
|
|
3851
|
+
"done"
|
|
3852
|
+
];
|
|
3853
|
+
var createEmptySitemapQaCount = () => ({
|
|
3854
|
+
total: 0,
|
|
3855
|
+
remaining: 0,
|
|
3455
3856
|
local: 0,
|
|
3456
|
-
remote: 0
|
|
3457
|
-
|
|
3857
|
+
remote: 0,
|
|
3858
|
+
status: {
|
|
3859
|
+
todo: 0,
|
|
3860
|
+
doing: 0,
|
|
3861
|
+
review: 0,
|
|
3862
|
+
hold: 0,
|
|
3863
|
+
done: 0
|
|
3864
|
+
},
|
|
3865
|
+
scope: {},
|
|
3866
|
+
viewport: {}
|
|
3867
|
+
});
|
|
3868
|
+
var createSitemapViewportColumn = (preset, index) => ({
|
|
3869
|
+
key: `${index}:${preset.width}x${preset.height}`,
|
|
3870
|
+
label: preset.label,
|
|
3871
|
+
title: `${preset.label} ${preset.width}x${preset.height}`
|
|
3872
|
+
});
|
|
3458
3873
|
var normalizeSitemapHref = (href) => {
|
|
3459
3874
|
const [path = "/"] = href.split(/[?#]/);
|
|
3460
3875
|
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
@@ -3479,10 +3894,45 @@ var mergeSitemapUsers = (users) => {
|
|
|
3479
3894
|
return Array.from(userByKey.values());
|
|
3480
3895
|
};
|
|
3481
3896
|
var addSitemapQaCounts = (first, second) => ({
|
|
3897
|
+
total: first.total + second.total,
|
|
3898
|
+
remaining: first.remaining + second.remaining,
|
|
3482
3899
|
local: first.local + second.local,
|
|
3483
|
-
remote: first.remote + second.remote
|
|
3900
|
+
remote: first.remote + second.remote,
|
|
3901
|
+
status: WORKFLOW_STATUSES.reduce(
|
|
3902
|
+
(statusCounts, status) => ({
|
|
3903
|
+
...statusCounts,
|
|
3904
|
+
[status]: first.status[status] + second.status[status]
|
|
3905
|
+
}),
|
|
3906
|
+
{}
|
|
3907
|
+
),
|
|
3908
|
+
scope: Array.from(
|
|
3909
|
+
/* @__PURE__ */ new Set([
|
|
3910
|
+
...Object.keys(first.scope),
|
|
3911
|
+
...Object.keys(second.scope)
|
|
3912
|
+
])
|
|
3913
|
+
).reduce(
|
|
3914
|
+
(scopeCounts, scope) => ({
|
|
3915
|
+
...scopeCounts,
|
|
3916
|
+
[scope]: (first.scope[scope] ?? 0) + (second.scope[scope] ?? 0)
|
|
3917
|
+
}),
|
|
3918
|
+
{}
|
|
3919
|
+
),
|
|
3920
|
+
viewport: Array.from(
|
|
3921
|
+
/* @__PURE__ */ new Set([...Object.keys(first.viewport), ...Object.keys(second.viewport)])
|
|
3922
|
+
).reduce(
|
|
3923
|
+
(viewportCounts, viewportKey) => ({
|
|
3924
|
+
...viewportCounts,
|
|
3925
|
+
[viewportKey]: {
|
|
3926
|
+
total: (first.viewport[viewportKey]?.total ?? 0) + (second.viewport[viewportKey]?.total ?? 0),
|
|
3927
|
+
remaining: (first.viewport[viewportKey]?.remaining ?? 0) + (second.viewport[viewportKey]?.remaining ?? 0)
|
|
3928
|
+
}
|
|
3929
|
+
}),
|
|
3930
|
+
{}
|
|
3931
|
+
)
|
|
3484
3932
|
});
|
|
3485
|
-
var createSitemapRows = (pages, activeRoute, pageQaCounts, pagePresenceUsers, getPageTarget) => {
|
|
3933
|
+
var createSitemapRows = (pages, activeRoute, pageQaCounts, pagePresenceUsers, getPageTarget, options = {}) => {
|
|
3934
|
+
const sortKey = options.sortKey ?? "page";
|
|
3935
|
+
const sortDirection = options.sortDirection ?? "asc";
|
|
3486
3936
|
const root = createSitemapNode("/", "/", false);
|
|
3487
3937
|
pages.forEach((page) => {
|
|
3488
3938
|
const pageHref = page.href.startsWith("/") ? page.href : `/${page.href}`;
|
|
@@ -3509,60 +3959,89 @@ var createSitemapRows = (pages, activeRoute, pageQaCounts, pagePresenceUsers, ge
|
|
|
3509
3959
|
});
|
|
3510
3960
|
});
|
|
3511
3961
|
const getDirectCount = (node) => {
|
|
3512
|
-
if (!node.isPage) return
|
|
3513
|
-
return pageQaCounts.get(getPageTarget(node.href)) ??
|
|
3962
|
+
if (!node.isPage) return createEmptySitemapQaCount();
|
|
3963
|
+
return pageQaCounts.get(getPageTarget(node.href)) ?? createEmptySitemapQaCount();
|
|
3514
3964
|
};
|
|
3515
3965
|
const getDirectUsers = (node) => {
|
|
3516
3966
|
if (!node.isPage) return [];
|
|
3517
3967
|
return pagePresenceUsers.get(getPageTarget(node.href)) ?? [];
|
|
3518
3968
|
};
|
|
3519
|
-
const
|
|
3520
|
-
const appendNodeRows = (node, depth, ancestorLastList, isLastNode) => {
|
|
3521
|
-
const children = Array.from(node.children.values());
|
|
3969
|
+
const createNodeSummary = (node) => {
|
|
3522
3970
|
const directCount = getDirectCount(node);
|
|
3523
3971
|
const directUsers = getDirectUsers(node);
|
|
3524
|
-
|
|
3525
|
-
if (node.isPage || depth > 0) {
|
|
3526
|
-
const prefix = depth === 0 ? "" : `${ancestorLastList.map((isLast) => isLast ? " " : "\u2502 ").join("")}${isLastNode ? "\u2514\u2500 " : "\u251C\u2500 "}`;
|
|
3527
|
-
const pageTarget = node.isPage ? getPageTarget(node.href) : null;
|
|
3528
|
-
rowIndex = rows.length;
|
|
3529
|
-
rows.push({
|
|
3530
|
-
href: node.href,
|
|
3531
|
-
label: node.label,
|
|
3532
|
-
prefix,
|
|
3533
|
-
isPage: node.isPage,
|
|
3534
|
-
isActive: pageTarget === activeRoute,
|
|
3535
|
-
qaCount: directCount,
|
|
3536
|
-
users: directUsers
|
|
3537
|
-
});
|
|
3538
|
-
}
|
|
3972
|
+
const children = Array.from(node.children.values()).map(createNodeSummary);
|
|
3539
3973
|
const childAggregate = children.reduce(
|
|
3540
|
-
(aggregate, child
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
count: addSitemapQaCounts(aggregate.count, childResult.count),
|
|
3549
|
-
users: mergeSitemapUsers([...aggregate.users, ...childResult.users])
|
|
3550
|
-
};
|
|
3551
|
-
},
|
|
3552
|
-
{ count: EMPTY_SITEMAP_QA_COUNT, users: [] }
|
|
3974
|
+
(aggregate, child) => ({
|
|
3975
|
+
count: addSitemapQaCounts(aggregate.count, child.count),
|
|
3976
|
+
users: mergeSitemapUsers([...aggregate.users, ...child.users])
|
|
3977
|
+
}),
|
|
3978
|
+
{
|
|
3979
|
+
count: createEmptySitemapQaCount(),
|
|
3980
|
+
users: []
|
|
3981
|
+
}
|
|
3553
3982
|
);
|
|
3554
|
-
if (rowIndex !== null && !node.isPage) {
|
|
3555
|
-
rows[rowIndex] = {
|
|
3556
|
-
...rows[rowIndex],
|
|
3557
|
-
qaCount: childAggregate.count,
|
|
3558
|
-
users: childAggregate.users
|
|
3559
|
-
};
|
|
3560
|
-
}
|
|
3561
3983
|
return {
|
|
3984
|
+
node,
|
|
3985
|
+
directCount,
|
|
3986
|
+
directUsers,
|
|
3562
3987
|
count: node.isPage ? addSitemapQaCounts(directCount, childAggregate.count) : childAggregate.count,
|
|
3563
|
-
users: mergeSitemapUsers([...directUsers, ...childAggregate.users])
|
|
3988
|
+
users: mergeSitemapUsers([...directUsers, ...childAggregate.users]),
|
|
3989
|
+
children
|
|
3564
3990
|
};
|
|
3565
3991
|
};
|
|
3992
|
+
const getSortValue = (summary) => {
|
|
3993
|
+
if (sortKey === "page") return summary.node.label;
|
|
3994
|
+
if (sortKey === "total") return summary.count.remaining;
|
|
3995
|
+
if (sortKey === "review") return summary.count.status.review;
|
|
3996
|
+
if (sortKey === "hold") return summary.count.status.hold;
|
|
3997
|
+
if (sortKey === "online") return summary.users.length;
|
|
3998
|
+
if (sortKey.startsWith("viewport:")) {
|
|
3999
|
+
const viewportKey = sortKey.slice("viewport:".length);
|
|
4000
|
+
return summary.count.viewport[viewportKey]?.remaining ?? 0;
|
|
4001
|
+
}
|
|
4002
|
+
return 0;
|
|
4003
|
+
};
|
|
4004
|
+
const sortSummaries = (summaries) => {
|
|
4005
|
+
return [...summaries].sort((a, b) => {
|
|
4006
|
+
const firstValue = getSortValue(a);
|
|
4007
|
+
const secondValue = getSortValue(b);
|
|
4008
|
+
const valueDiff = typeof firstValue === "string" && typeof secondValue === "string" ? firstValue.localeCompare(secondValue) : Number(firstValue) - Number(secondValue);
|
|
4009
|
+
if (valueDiff !== 0) {
|
|
4010
|
+
return sortDirection === "asc" ? valueDiff : -valueDiff;
|
|
4011
|
+
}
|
|
4012
|
+
const totalDiff = b.count.remaining - a.count.remaining;
|
|
4013
|
+
if (totalDiff !== 0) return totalDiff;
|
|
4014
|
+
return a.node.label.localeCompare(b.node.label);
|
|
4015
|
+
});
|
|
4016
|
+
};
|
|
4017
|
+
const rows = [];
|
|
4018
|
+
const appendSummaryRows = (summary, depth, ancestorLastList, isLastNode) => {
|
|
4019
|
+
const { node } = summary;
|
|
4020
|
+
const rowCount = node.isPage ? summary.directCount : summary.count;
|
|
4021
|
+
const rowUsers = node.isPage ? summary.directUsers : summary.users;
|
|
4022
|
+
if (node.isPage || depth > 0) {
|
|
4023
|
+
const prefix = depth === 0 ? "" : `${ancestorLastList.map((isLast) => isLast ? " " : "\u2502 ").join("")}${isLastNode ? "\u2514\u2500 " : "\u251C\u2500 "}`;
|
|
4024
|
+
const pageTarget = node.isPage ? getPageTarget(node.href) : null;
|
|
4025
|
+
rows.push({
|
|
4026
|
+
href: node.href,
|
|
4027
|
+
label: node.label,
|
|
4028
|
+
prefix,
|
|
4029
|
+
isPage: node.isPage,
|
|
4030
|
+
isActive: pageTarget === activeRoute,
|
|
4031
|
+
qaCount: rowCount,
|
|
4032
|
+
users: rowUsers
|
|
4033
|
+
});
|
|
4034
|
+
}
|
|
4035
|
+
const visibleChildren = sortSummaries(summary.children);
|
|
4036
|
+
visibleChildren.forEach((child, childIndex) => {
|
|
4037
|
+
appendSummaryRows(
|
|
4038
|
+
child,
|
|
4039
|
+
depth + 1,
|
|
4040
|
+
depth === 0 ? [] : [...ancestorLastList, isLastNode],
|
|
4041
|
+
childIndex === visibleChildren.length - 1
|
|
4042
|
+
);
|
|
4043
|
+
});
|
|
4044
|
+
};
|
|
3566
4045
|
if (root.isPage) {
|
|
3567
4046
|
const directCount = getDirectCount(root);
|
|
3568
4047
|
const directUsers = getDirectUsers(root);
|
|
@@ -3576,30 +4055,83 @@ var createSitemapRows = (pages, activeRoute, pageQaCounts, pagePresenceUsers, ge
|
|
|
3576
4055
|
users: directUsers
|
|
3577
4056
|
});
|
|
3578
4057
|
}
|
|
3579
|
-
|
|
3580
|
-
|
|
4058
|
+
const rootSummaries = sortSummaries(
|
|
4059
|
+
Array.from(root.children.values()).map(createNodeSummary)
|
|
4060
|
+
);
|
|
4061
|
+
rootSummaries.forEach((summary, index, siblings) => {
|
|
4062
|
+
appendSummaryRows(summary, 1, [], index === siblings.length - 1);
|
|
3581
4063
|
});
|
|
3582
4064
|
return rows;
|
|
3583
4065
|
};
|
|
3584
4066
|
|
|
3585
4067
|
// src/react-shell/sitemap/modal.tsx
|
|
3586
4068
|
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4069
|
+
var getNextSortDirection = (current, key) => {
|
|
4070
|
+
if (current.key !== key) return key === "page" ? "asc" : "desc";
|
|
4071
|
+
return current.direction === "desc" ? "asc" : "desc";
|
|
4072
|
+
};
|
|
4073
|
+
var getSortIndicator = (sort, key) => {
|
|
4074
|
+
if (sort.key !== key) return "";
|
|
4075
|
+
return sort.direction === "desc" ? "\u2193" : "\u2191";
|
|
4076
|
+
};
|
|
4077
|
+
var mergePresenceUsers = (users) => {
|
|
4078
|
+
const userByKey = /* @__PURE__ */ new Map();
|
|
4079
|
+
users.forEach((user) => {
|
|
4080
|
+
const key = user.sessionId || user.userId;
|
|
4081
|
+
const currentUser = userByKey.get(key);
|
|
4082
|
+
if (!currentUser || Date.parse(user.updatedAt) >= Date.parse(currentUser.updatedAt)) {
|
|
4083
|
+
userByKey.set(key, user);
|
|
4084
|
+
}
|
|
4085
|
+
});
|
|
4086
|
+
return Array.from(userByKey.values());
|
|
4087
|
+
};
|
|
3587
4088
|
var SitemapModal = ({
|
|
3588
4089
|
pages,
|
|
3589
4090
|
activeRoute,
|
|
4091
|
+
allQaCount,
|
|
4092
|
+
isAllQaVisible,
|
|
3590
4093
|
pageQaCounts,
|
|
3591
4094
|
pagePresenceUsers,
|
|
3592
4095
|
getPageTarget,
|
|
3593
4096
|
onClose,
|
|
4097
|
+
onSelectAllQa,
|
|
3594
4098
|
onSelectPage
|
|
3595
4099
|
}) => {
|
|
4100
|
+
const [sort, setSort] = useState({
|
|
4101
|
+
key: "total",
|
|
4102
|
+
direction: "desc"
|
|
4103
|
+
});
|
|
4104
|
+
const allQaUsers = useMemo2(
|
|
4105
|
+
() => mergePresenceUsers(Array.from(pagePresenceUsers.values()).flat()),
|
|
4106
|
+
[pagePresenceUsers]
|
|
4107
|
+
);
|
|
3596
4108
|
const sitemapRows = createSitemapRows(
|
|
3597
4109
|
pages,
|
|
3598
4110
|
activeRoute,
|
|
3599
4111
|
pageQaCounts,
|
|
3600
4112
|
pagePresenceUsers,
|
|
3601
|
-
getPageTarget
|
|
4113
|
+
getPageTarget,
|
|
4114
|
+
{
|
|
4115
|
+
sortKey: sort.key,
|
|
4116
|
+
sortDirection: sort.direction
|
|
4117
|
+
}
|
|
3602
4118
|
);
|
|
4119
|
+
const gridStyle = {
|
|
4120
|
+
"--df-review-sitemap-grid-template": "minmax(190px, 1fr) 74px 78px 64px minmax(108px, 160px)"
|
|
4121
|
+
};
|
|
4122
|
+
const sortHeaders = [
|
|
4123
|
+
{ key: "page", label: "", title: "Page", className: "is-page" },
|
|
4124
|
+
{ key: "total", label: "Total", title: "Remaining total" },
|
|
4125
|
+
{ key: "review", label: "Review" },
|
|
4126
|
+
{ key: "hold", label: "Hold" },
|
|
4127
|
+
{ key: "online", label: "Online", className: "is-online" }
|
|
4128
|
+
];
|
|
4129
|
+
const setSortKey = (key) => {
|
|
4130
|
+
setSort((current) => ({
|
|
4131
|
+
key,
|
|
4132
|
+
direction: getNextSortDirection(current, key)
|
|
4133
|
+
}));
|
|
4134
|
+
};
|
|
3603
4135
|
return /* @__PURE__ */ jsxs3(
|
|
3604
4136
|
"div",
|
|
3605
4137
|
{
|
|
@@ -3623,48 +4155,65 @@ var SitemapModal = ({
|
|
|
3623
4155
|
/* @__PURE__ */ jsx3("strong", { children: "Sitemap" }),
|
|
3624
4156
|
/* @__PURE__ */ jsxs3("span", { children: [
|
|
3625
4157
|
pages.length,
|
|
3626
|
-
" pages"
|
|
4158
|
+
" pages \xB7 ",
|
|
4159
|
+
allQaCount.remaining,
|
|
4160
|
+
" remaining \xB7",
|
|
4161
|
+
" ",
|
|
4162
|
+
allQaCount.status.review,
|
|
4163
|
+
" review \xB7 ",
|
|
4164
|
+
allQaCount.status.hold,
|
|
4165
|
+
" hold"
|
|
3627
4166
|
] })
|
|
3628
4167
|
] }),
|
|
3629
4168
|
/* @__PURE__ */ jsx3("button", { "aria-label": "Close sitemap", type: "button", onClick: onClose, children: "x" })
|
|
3630
4169
|
] }),
|
|
3631
|
-
/* @__PURE__ */ jsxs3("div", { className: "df-review-sitemap-list", children: [
|
|
3632
|
-
/* @__PURE__ */
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
4170
|
+
/* @__PURE__ */ jsxs3("div", { className: "df-review-sitemap-list", style: gridStyle, children: [
|
|
4171
|
+
/* @__PURE__ */ jsx3("div", { className: "df-review-sitemap-table-head", role: "row", children: sortHeaders.map((header) => /* @__PURE__ */ jsxs3(
|
|
4172
|
+
"button",
|
|
4173
|
+
{
|
|
4174
|
+
"aria-label": `Sort sitemap by ${header.title ?? header.label}`,
|
|
4175
|
+
className: [
|
|
4176
|
+
"df-review-sitemap-sort",
|
|
4177
|
+
header.className ?? "",
|
|
4178
|
+
sort.key === header.key ? "is-active" : ""
|
|
4179
|
+
].filter(Boolean).join(" "),
|
|
4180
|
+
title: header.title ?? header.label,
|
|
4181
|
+
type: "button",
|
|
4182
|
+
onClick: () => setSortKey(header.key),
|
|
4183
|
+
children: [
|
|
4184
|
+
/* @__PURE__ */ jsx3(
|
|
4185
|
+
"span",
|
|
4186
|
+
{
|
|
4187
|
+
"aria-hidden": "true",
|
|
4188
|
+
className: "df-review-sitemap-sort-indicator",
|
|
4189
|
+
children: getSortIndicator(sort, header.key)
|
|
4190
|
+
}
|
|
4191
|
+
),
|
|
4192
|
+
/* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-sort-label", children: header.label })
|
|
4193
|
+
]
|
|
4194
|
+
},
|
|
4195
|
+
header.key
|
|
4196
|
+
)) }),
|
|
3638
4197
|
sitemapRows.map((row) => {
|
|
3639
4198
|
const rowClassName = [
|
|
3640
4199
|
"df-review-sitemap-row",
|
|
3641
4200
|
row.isPage ? "is-page" : "is-folder",
|
|
3642
4201
|
row.isActive ? "is-active" : ""
|
|
3643
4202
|
].filter(Boolean).join(" ");
|
|
3644
|
-
const rowContent = /* @__PURE__ */
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
{
|
|
3654
|
-
className: "df-review-sitemap-user",
|
|
3655
|
-
style: {
|
|
3656
|
-
"--df-review-presence-color": user.color
|
|
3657
|
-
},
|
|
3658
|
-
children: user.userId
|
|
3659
|
-
},
|
|
3660
|
-
user.sessionId
|
|
3661
|
-
)) }) : /* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-online-empty", children: "0" }) })
|
|
3662
|
-
] });
|
|
4203
|
+
const rowContent = /* @__PURE__ */ jsx3(
|
|
4204
|
+
SitemapRowContent,
|
|
4205
|
+
{
|
|
4206
|
+
label: row.label,
|
|
4207
|
+
prefix: row.prefix,
|
|
4208
|
+
qaCount: row.qaCount,
|
|
4209
|
+
users: row.users
|
|
4210
|
+
}
|
|
4211
|
+
);
|
|
3663
4212
|
if (!row.isPage) {
|
|
3664
4213
|
return /* @__PURE__ */ jsx3(
|
|
3665
4214
|
"div",
|
|
3666
4215
|
{
|
|
3667
|
-
"aria-label": `${row.href} group /
|
|
4216
|
+
"aria-label": `${row.href} group / ${row.qaCount.remaining} remaining / ${row.qaCount.status.review} review / ${row.qaCount.status.hold} hold / ${row.users.length} online`,
|
|
3668
4217
|
className: rowClassName,
|
|
3669
4218
|
role: "row",
|
|
3670
4219
|
children: rowContent
|
|
@@ -3675,7 +4224,7 @@ var SitemapModal = ({
|
|
|
3675
4224
|
return /* @__PURE__ */ jsx3(
|
|
3676
4225
|
"button",
|
|
3677
4226
|
{
|
|
3678
|
-
"aria-label": `${row.href} /
|
|
4227
|
+
"aria-label": `${row.href} / ${row.qaCount.remaining} remaining / ${row.qaCount.status.review} review / ${row.qaCount.status.hold} hold / ${row.users.length} online`,
|
|
3679
4228
|
className: rowClassName,
|
|
3680
4229
|
type: "button",
|
|
3681
4230
|
onClick: () => onSelectPage(row.href),
|
|
@@ -3683,25 +4232,102 @@ var SitemapModal = ({
|
|
|
3683
4232
|
},
|
|
3684
4233
|
row.href
|
|
3685
4234
|
);
|
|
3686
|
-
})
|
|
4235
|
+
}),
|
|
4236
|
+
/* @__PURE__ */ jsx3(
|
|
4237
|
+
"button",
|
|
4238
|
+
{
|
|
4239
|
+
"aria-label": `All QA / ${allQaCount.remaining} remaining / ${allQaCount.status.review} review / ${allQaCount.status.hold} hold`,
|
|
4240
|
+
className: `df-review-sitemap-row is-summary${isAllQaVisible ? " is-active" : ""}`,
|
|
4241
|
+
type: "button",
|
|
4242
|
+
onClick: onSelectAllQa,
|
|
4243
|
+
children: /* @__PURE__ */ jsx3(
|
|
4244
|
+
SitemapRowContent,
|
|
4245
|
+
{
|
|
4246
|
+
label: "",
|
|
4247
|
+
prefix: "",
|
|
4248
|
+
qaCount: allQaCount,
|
|
4249
|
+
users: allQaUsers
|
|
4250
|
+
}
|
|
4251
|
+
)
|
|
4252
|
+
}
|
|
4253
|
+
)
|
|
3687
4254
|
] })
|
|
3688
4255
|
] })
|
|
3689
4256
|
]
|
|
3690
4257
|
}
|
|
3691
4258
|
);
|
|
3692
4259
|
};
|
|
4260
|
+
var SitemapRowContent = ({
|
|
4261
|
+
label,
|
|
4262
|
+
prefix,
|
|
4263
|
+
qaCount,
|
|
4264
|
+
users
|
|
4265
|
+
}) => /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
4266
|
+
/* @__PURE__ */ jsxs3("span", { className: "df-review-sitemap-path", children: [
|
|
4267
|
+
/* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-tree-prefix", children: prefix }),
|
|
4268
|
+
/* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-label", children: label })
|
|
4269
|
+
] }),
|
|
4270
|
+
/* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-cell is-total", children: /* @__PURE__ */ jsx3("strong", { children: qaCount.remaining }) }),
|
|
4271
|
+
/* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-cell is-review", children: qaCount.status.review }),
|
|
4272
|
+
/* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-cell is-hold", children: qaCount.status.hold }),
|
|
4273
|
+
/* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-cell is-online", children: users.length > 0 ? /* @__PURE__ */ jsx3("span", { className: "df-review-sitemap-users", children: users.map((user) => /* @__PURE__ */ jsx3(
|
|
4274
|
+
"span",
|
|
4275
|
+
{
|
|
4276
|
+
className: "df-review-sitemap-user",
|
|
4277
|
+
style: {
|
|
4278
|
+
"--df-review-presence-color": user.color
|
|
4279
|
+
},
|
|
4280
|
+
children: user.userId
|
|
4281
|
+
},
|
|
4282
|
+
user.sessionId
|
|
4283
|
+
)) }) : null })
|
|
4284
|
+
] });
|
|
4285
|
+
|
|
4286
|
+
// src/react-shell/figma.ts
|
|
4287
|
+
function getTargetFigmaFrameConfig(targetWindow) {
|
|
4288
|
+
try {
|
|
4289
|
+
const config = targetWindow?.__figma;
|
|
4290
|
+
if (!config || typeof config !== "object") return null;
|
|
4291
|
+
const desktopNodeId = normalizeFigmaNodeValue(config.desktopNodeId);
|
|
4292
|
+
const mobileNodeId = normalizeFigmaNodeValue(config.mobileNodeId);
|
|
4293
|
+
if (!desktopNodeId && !mobileNodeId) return null;
|
|
4294
|
+
return {
|
|
4295
|
+
desktopNodeId,
|
|
4296
|
+
mobileNodeId
|
|
4297
|
+
};
|
|
4298
|
+
} catch {
|
|
4299
|
+
return null;
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
function getFigmaFrameUrl(config, preset) {
|
|
4303
|
+
if (!config) return null;
|
|
4304
|
+
const kind = getViewportPresetKind(preset);
|
|
4305
|
+
const value = kind === "mobile" ? config.mobileNodeId : config.desktopNodeId;
|
|
4306
|
+
return value ? createFigmaFrameUrl(value) : null;
|
|
4307
|
+
}
|
|
4308
|
+
function normalizeFigmaNodeValue(value) {
|
|
4309
|
+
return typeof value === "string" ? value.trim() || void 0 : void 0;
|
|
4310
|
+
}
|
|
4311
|
+
function createFigmaFrameUrl(value) {
|
|
4312
|
+
const [fileKey, nodeId] = value.split("->").map((part) => part.trim());
|
|
4313
|
+
if (!fileKey || !nodeId) return null;
|
|
4314
|
+
const urlNodeId = encodeURIComponent(nodeId.replace(/:/g, "-"));
|
|
4315
|
+
return `https://www.figma.com/design/${encodeURIComponent(
|
|
4316
|
+
fileKey
|
|
4317
|
+
)}?node-id=${urlNodeId}`;
|
|
4318
|
+
}
|
|
3693
4319
|
|
|
3694
4320
|
// src/react-shell/qa/item.edit.modal.tsx
|
|
3695
|
-
import { useEffect, useState } from "react";
|
|
4321
|
+
import { useEffect, useState as useState2 } from "react";
|
|
3696
4322
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3697
4323
|
var QaItemEditModal = ({
|
|
3698
4324
|
item,
|
|
3699
4325
|
onClose,
|
|
3700
4326
|
onSave
|
|
3701
4327
|
}) => {
|
|
3702
|
-
const [commentDraft, setCommentDraft] =
|
|
3703
|
-
const [error, setError] =
|
|
3704
|
-
const [isSaving, setIsSaving] =
|
|
4328
|
+
const [commentDraft, setCommentDraft] = useState2(item.comment);
|
|
4329
|
+
const [error, setError] = useState2("");
|
|
4330
|
+
const [isSaving, setIsSaving] = useState2(false);
|
|
3705
4331
|
useEffect(() => {
|
|
3706
4332
|
setCommentDraft(item.comment);
|
|
3707
4333
|
setError("");
|
|
@@ -4053,88 +4679,6 @@ var ReviewItemModeIcon = ({
|
|
|
4053
4679
|
return /* @__PURE__ */ jsx7(StickyNote, { "aria-hidden": "true" });
|
|
4054
4680
|
};
|
|
4055
4681
|
|
|
4056
|
-
// src/react-shell/source.open.ts
|
|
4057
|
-
var SOURCE_SELECTOR = [
|
|
4058
|
-
"[data-wrk-source-file]",
|
|
4059
|
-
"[data-wrk-source-component]",
|
|
4060
|
-
"[data-wrk-source-line]",
|
|
4061
|
-
"[data-wrk-source-column]",
|
|
4062
|
-
"[data-file]",
|
|
4063
|
-
"[data-component]",
|
|
4064
|
-
"[data-section-index]",
|
|
4065
|
-
"[data-section-id]"
|
|
4066
|
-
].join(", ");
|
|
4067
|
-
var getSourceHintElement = (target) => {
|
|
4068
|
-
return getEventElement(target)?.closest(SOURCE_SELECTOR) ?? null;
|
|
4069
|
-
};
|
|
4070
|
-
var getElementSourceHint = (target) => {
|
|
4071
|
-
const sourceElement = getSourceHintElement(target);
|
|
4072
|
-
if (!sourceElement) return void 0;
|
|
4073
|
-
const source = {
|
|
4074
|
-
component: getSourceAttribute(
|
|
4075
|
-
sourceElement,
|
|
4076
|
-
"data-wrk-source-component",
|
|
4077
|
-
"data-component"
|
|
4078
|
-
),
|
|
4079
|
-
file: getSourceAttribute(sourceElement, "data-wrk-source-file", "data-file"),
|
|
4080
|
-
line: getSourceAttribute(sourceElement, "data-wrk-source-line"),
|
|
4081
|
-
column: getSourceAttribute(sourceElement, "data-wrk-source-column"),
|
|
4082
|
-
sectionId: getSourceAttribute(sourceElement, "data-section-id"),
|
|
4083
|
-
sectionIndex: getSourceAttribute(sourceElement, "data-section-index")
|
|
4084
|
-
};
|
|
4085
|
-
return Object.values(source).some(Boolean) ? source : void 0;
|
|
4086
|
-
};
|
|
4087
|
-
var getSourceOpenUrl = (source, sourceRoot) => {
|
|
4088
|
-
const file = source?.file?.trim();
|
|
4089
|
-
if (!file) return null;
|
|
4090
|
-
const sourcePath = getSourcePath(file, sourceRoot);
|
|
4091
|
-
if (!sourcePath) return null;
|
|
4092
|
-
const line = getSourcePosition(source?.line);
|
|
4093
|
-
const column = getSourcePosition(source?.column);
|
|
4094
|
-
const encodedPath = encodeURI(sourcePath).replace(
|
|
4095
|
-
/[#?]/g,
|
|
4096
|
-
(match) => match === "#" ? "%23" : "%3F"
|
|
4097
|
-
);
|
|
4098
|
-
return `vscode://file/${encodedPath}:${line}:${column}`;
|
|
4099
|
-
};
|
|
4100
|
-
var openSourceInEditor = (source, sourceRoot) => {
|
|
4101
|
-
const url = getSourceOpenUrl(source, sourceRoot);
|
|
4102
|
-
if (!url) return false;
|
|
4103
|
-
window.open(url, "_blank", "noreferrer");
|
|
4104
|
-
return true;
|
|
4105
|
-
};
|
|
4106
|
-
function getSourceAttribute(element, ...names) {
|
|
4107
|
-
for (const name of names) {
|
|
4108
|
-
const value = element.getAttribute(name)?.trim();
|
|
4109
|
-
if (value) return value;
|
|
4110
|
-
}
|
|
4111
|
-
return void 0;
|
|
4112
|
-
}
|
|
4113
|
-
function getEventElement(target) {
|
|
4114
|
-
if (!target || typeof target !== "object") return null;
|
|
4115
|
-
const node = target;
|
|
4116
|
-
if (node.nodeType === 1 && typeof node.closest === "function") {
|
|
4117
|
-
return node;
|
|
4118
|
-
}
|
|
4119
|
-
if (node.parentElement && typeof node.parentElement.closest === "function") {
|
|
4120
|
-
return node.parentElement;
|
|
4121
|
-
}
|
|
4122
|
-
return null;
|
|
4123
|
-
}
|
|
4124
|
-
function getSourcePath(file, sourceRoot) {
|
|
4125
|
-
const normalizedFile = file.replace(/\\/g, "/");
|
|
4126
|
-
if (normalizedFile.startsWith("/") || /^[a-zA-Z]:\//.test(normalizedFile)) {
|
|
4127
|
-
return normalizedFile;
|
|
4128
|
-
}
|
|
4129
|
-
const normalizedRoot = sourceRoot?.trim().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
4130
|
-
if (!normalizedRoot) return null;
|
|
4131
|
-
return `${normalizedRoot}/${normalizedFile.replace(/^\/+/, "")}`;
|
|
4132
|
-
}
|
|
4133
|
-
function getSourcePosition(value) {
|
|
4134
|
-
const position = Number(value);
|
|
4135
|
-
return Number.isInteger(position) && position > 0 ? position : 1;
|
|
4136
|
-
}
|
|
4137
|
-
|
|
4138
4682
|
// src/react-shell/qa/item.card.tsx
|
|
4139
4683
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4140
4684
|
var formatItemCardDate = (value) => {
|
|
@@ -4157,10 +4701,10 @@ var QaItemCard = ({
|
|
|
4157
4701
|
remoteAdapterEntry,
|
|
4158
4702
|
copiedPromptKey,
|
|
4159
4703
|
selectedItemId,
|
|
4160
|
-
sourceRoot,
|
|
4161
4704
|
onChangeItemStatus,
|
|
4162
4705
|
onClearSelectedItem,
|
|
4163
4706
|
onRemoveItem,
|
|
4707
|
+
onCopyItemLink,
|
|
4164
4708
|
onCopyItemPrompt,
|
|
4165
4709
|
onEditItem,
|
|
4166
4710
|
onRestoreReviewItem,
|
|
@@ -4175,13 +4719,14 @@ var QaItemCard = ({
|
|
|
4175
4719
|
const itemComment = item.comment.trim() || getItemTitle(item);
|
|
4176
4720
|
const itemAuthor = item.createdBy?.trim();
|
|
4177
4721
|
const promptCopyKey = `qa:${item.id}`;
|
|
4722
|
+
const linkCopyKey = `link:${item.id}`;
|
|
4178
4723
|
const isPromptCopied = copiedPromptKey === promptCopyKey;
|
|
4724
|
+
const isLinkCopied = copiedPromptKey === linkCopyKey;
|
|
4179
4725
|
const statusOptions = activeAdapterEntry.statusOptions;
|
|
4180
4726
|
const isActive = item.id === selectedItemId;
|
|
4181
4727
|
const canUpdateStatus = Boolean(activeAdapterEntry.updateStatus) && statusOptions.length > 0 && !isSubmitting;
|
|
4182
4728
|
const canEditItem = activeAdapterEntry.canUpdate && !isSubmitting;
|
|
4183
4729
|
const itemMeta = [formatItemCardDate(item.createdAt), itemAuthor].filter(Boolean).join(" | ");
|
|
4184
|
-
const sourceOpenUrl = getSourceOpenUrl(item.anchor?.source, sourceRoot);
|
|
4185
4730
|
return /* @__PURE__ */ jsxs6(
|
|
4186
4731
|
"article",
|
|
4187
4732
|
{
|
|
@@ -4233,27 +4778,15 @@ var QaItemCard = ({
|
|
|
4233
4778
|
children: isOverlayVisible ? /* @__PURE__ */ jsx8(Eye, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx8(EyeOff, { "aria-hidden": "true" })
|
|
4234
4779
|
}
|
|
4235
4780
|
),
|
|
4236
|
-
sourceOpenUrl && /* @__PURE__ */ jsx8(
|
|
4237
|
-
"a",
|
|
4238
|
-
{
|
|
4239
|
-
"aria-label": "Open source in VS Code",
|
|
4240
|
-
className: "df-review-item-source-open",
|
|
4241
|
-
href: sourceOpenUrl,
|
|
4242
|
-
rel: "noreferrer",
|
|
4243
|
-
target: "_blank",
|
|
4244
|
-
title: "Open source in VS Code",
|
|
4245
|
-
children: /* @__PURE__ */ jsx8(FileCodeCorner, { "aria-hidden": "true" })
|
|
4246
|
-
}
|
|
4247
|
-
),
|
|
4248
4781
|
/* @__PURE__ */ jsx8(
|
|
4249
4782
|
"button",
|
|
4250
4783
|
{
|
|
4251
|
-
"aria-label":
|
|
4252
|
-
className: `df-review-item-
|
|
4253
|
-
title:
|
|
4784
|
+
"aria-label": isLinkCopied ? "Copied QA link" : "Copy QA link",
|
|
4785
|
+
className: `df-review-item-link-copy${isLinkCopied ? " is-copied" : ""}`,
|
|
4786
|
+
title: isLinkCopied ? "Copied QA link" : "Copy QA link",
|
|
4254
4787
|
type: "button",
|
|
4255
|
-
onClick: () =>
|
|
4256
|
-
children: /* @__PURE__ */ jsx8(
|
|
4788
|
+
onClick: () => onCopyItemLink(numberedItem),
|
|
4789
|
+
children: /* @__PURE__ */ jsx8(Link2, { "aria-hidden": "true" })
|
|
4257
4790
|
}
|
|
4258
4791
|
),
|
|
4259
4792
|
canEditItem && /* @__PURE__ */ jsx8(
|
|
@@ -4291,6 +4824,24 @@ var QaItemCard = ({
|
|
|
4291
4824
|
onChangeItemStatus
|
|
4292
4825
|
}
|
|
4293
4826
|
),
|
|
4827
|
+
/* @__PURE__ */ jsx8(
|
|
4828
|
+
"div",
|
|
4829
|
+
{
|
|
4830
|
+
className: "df-review-item-prompt-actions",
|
|
4831
|
+
onClick: (event) => event.stopPropagation(),
|
|
4832
|
+
children: /* @__PURE__ */ jsx8(
|
|
4833
|
+
"button",
|
|
4834
|
+
{
|
|
4835
|
+
"aria-label": isPromptCopied ? "Copied QA prompt" : "Copy QA prompt",
|
|
4836
|
+
className: `df-review-item-action-button df-review-item-prompt-copy${isPromptCopied ? " is-copied" : ""}`,
|
|
4837
|
+
title: isPromptCopied ? "Copied QA prompt" : "Copy QA prompt",
|
|
4838
|
+
type: "button",
|
|
4839
|
+
onClick: () => onCopyItemPrompt(numberedItem),
|
|
4840
|
+
children: isPromptCopied ? /* @__PURE__ */ jsx8(Copy, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx8(Bot, { "aria-hidden": "true" })
|
|
4841
|
+
}
|
|
4842
|
+
)
|
|
4843
|
+
}
|
|
4844
|
+
),
|
|
4294
4845
|
/* @__PURE__ */ jsx8(
|
|
4295
4846
|
QaItemRemoteActions,
|
|
4296
4847
|
{
|
|
@@ -4309,81 +4860,57 @@ var QaItemCard = ({
|
|
|
4309
4860
|
);
|
|
4310
4861
|
};
|
|
4311
4862
|
|
|
4312
|
-
// src/react-shell/presence/row.tsx
|
|
4313
|
-
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4314
|
-
var PresenceRow = ({
|
|
4315
|
-
presenceSessionId,
|
|
4316
|
-
users
|
|
4317
|
-
}) => {
|
|
4318
|
-
if (users.length === 0) return null;
|
|
4319
|
-
return /* @__PURE__ */ jsxs7("div", { "aria-label": "Review presence", className: "df-review-presence-row", children: [
|
|
4320
|
-
/* @__PURE__ */ jsxs7("span", { className: "df-review-presence-label", children: [
|
|
4321
|
-
/* @__PURE__ */ jsx9(Users, { "aria-hidden": "true" }),
|
|
4322
|
-
"online ",
|
|
4323
|
-
users.length
|
|
4324
|
-
] }),
|
|
4325
|
-
/* @__PURE__ */ jsx9("div", { className: "df-review-presence-list", children: users.map((user) => /* @__PURE__ */ jsxs7(
|
|
4326
|
-
"span",
|
|
4327
|
-
{
|
|
4328
|
-
className: `df-review-presence-chip${user.sessionId === presenceSessionId ? " is-self" : ""}`,
|
|
4329
|
-
style: {
|
|
4330
|
-
"--df-review-presence-color": user.color
|
|
4331
|
-
},
|
|
4332
|
-
children: [
|
|
4333
|
-
/* @__PURE__ */ jsx9("span", { className: "df-review-presence-dot", "aria-hidden": "true" }),
|
|
4334
|
-
/* @__PURE__ */ jsx9("span", { className: "df-review-presence-name", children: user.userId })
|
|
4335
|
-
]
|
|
4336
|
-
},
|
|
4337
|
-
user.sessionId
|
|
4338
|
-
)) })
|
|
4339
|
-
] });
|
|
4340
|
-
};
|
|
4341
|
-
|
|
4342
4863
|
// src/react-shell/qa/panel.header.tsx
|
|
4343
|
-
import { jsx as
|
|
4864
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4344
4865
|
var QaPanelHeader = ({
|
|
4345
4866
|
activeItemCount,
|
|
4346
|
-
|
|
4867
|
+
activeRemainingItemCount,
|
|
4347
4868
|
filteredItemCount,
|
|
4869
|
+
isAllQaVisible,
|
|
4348
4870
|
label,
|
|
4349
|
-
presenceSessionId,
|
|
4350
4871
|
qaFilter,
|
|
4351
4872
|
qaFilterCounts,
|
|
4873
|
+
qaStatusFilter,
|
|
4874
|
+
qaStatusFilterCounts,
|
|
4352
4875
|
showSourceSelect,
|
|
4353
4876
|
source,
|
|
4354
4877
|
sourceEntries,
|
|
4878
|
+
statusOptions,
|
|
4355
4879
|
onChangeReviewSource,
|
|
4356
4880
|
onQaFilterChange,
|
|
4881
|
+
onQaStatusFilterChange,
|
|
4357
4882
|
onRefreshReviewData
|
|
4358
4883
|
}) => {
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4884
|
+
const statusFilterOptions = getStatusFilterOptions(statusOptions);
|
|
4885
|
+
const hasActiveFilter = qaFilter !== "all" || qaStatusFilter !== "all";
|
|
4886
|
+
return /* @__PURE__ */ jsxs7("div", { className: "df-review-list-header", children: [
|
|
4887
|
+
/* @__PURE__ */ jsxs7("div", { className: "df-review-list-toolbar", children: [
|
|
4888
|
+
/* @__PURE__ */ jsxs7("div", { className: "df-review-list-controls", children: [
|
|
4889
|
+
showSourceSelect && /* @__PURE__ */ jsx9(
|
|
4363
4890
|
"select",
|
|
4364
4891
|
{
|
|
4365
4892
|
"aria-label": "QA source",
|
|
4366
4893
|
className: "df-review-source-select",
|
|
4367
4894
|
value: source,
|
|
4368
4895
|
onChange: (event) => onChangeReviewSource(event.currentTarget.value),
|
|
4369
|
-
children: sourceEntries.map((entry) => /* @__PURE__ */
|
|
4896
|
+
children: sourceEntries.map((entry) => /* @__PURE__ */ jsx9("option", { value: entry.label, children: entry.label }, entry.label))
|
|
4370
4897
|
}
|
|
4371
4898
|
),
|
|
4372
|
-
/* @__PURE__ */
|
|
4899
|
+
/* @__PURE__ */ jsx9(
|
|
4373
4900
|
"button",
|
|
4374
4901
|
{
|
|
4375
4902
|
"aria-label": "Refresh QA",
|
|
4376
4903
|
className: "df-review-source-refresh",
|
|
4377
4904
|
type: "button",
|
|
4378
4905
|
onClick: () => void onRefreshReviewData(),
|
|
4379
|
-
children: /* @__PURE__ */
|
|
4906
|
+
children: /* @__PURE__ */ jsx9(RefreshCw, { "aria-hidden": "true" })
|
|
4380
4907
|
}
|
|
4381
4908
|
)
|
|
4382
4909
|
] }),
|
|
4383
|
-
/* @__PURE__ */
|
|
4910
|
+
/* @__PURE__ */ jsx9("div", { className: "df-review-filter-tabs", "aria-label": "QA filters", children: REVIEW_QA_FILTERS.map((filter) => {
|
|
4384
4911
|
const count = qaFilterCounts.get(filter.key) ?? 0;
|
|
4385
4912
|
const isActive = qaFilter === filter.key;
|
|
4386
|
-
return /* @__PURE__ */
|
|
4913
|
+
return /* @__PURE__ */ jsx9(
|
|
4387
4914
|
"button",
|
|
4388
4915
|
{
|
|
4389
4916
|
"aria-label": `${filter.label} QA (${count})`,
|
|
@@ -4391,86 +4918,108 @@ var QaPanelHeader = ({
|
|
|
4391
4918
|
className: `df-review-filter-tab${isActive ? " is-active" : ""}`,
|
|
4392
4919
|
type: "button",
|
|
4393
4920
|
onClick: () => onQaFilterChange(filter.key),
|
|
4394
|
-
children: /* @__PURE__ */
|
|
4921
|
+
children: /* @__PURE__ */ jsx9("span", { className: "df-review-filter-icon", children: filter.scope ? /* @__PURE__ */ jsx9(ReviewScopeIcon, { scope: filter.scope }) : /* @__PURE__ */ jsx9(ListFilter, { "aria-hidden": "true" }) })
|
|
4395
4922
|
},
|
|
4396
4923
|
filter.key
|
|
4397
4924
|
);
|
|
4398
4925
|
}) })
|
|
4399
4926
|
] }),
|
|
4400
|
-
/* @__PURE__ */
|
|
4401
|
-
/* @__PURE__ */
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4927
|
+
/* @__PURE__ */ jsxs7("div", { className: "df-review-list-title", children: [
|
|
4928
|
+
/* @__PURE__ */ jsx9("span", { children: isAllQaVisible ? `${label} QA \xB7 All pages` : `${label} QA` }),
|
|
4929
|
+
/* @__PURE__ */ jsx9("strong", { title: `${activeRemainingItemCount} remaining of ${activeItemCount}`, children: !hasActiveFilter ? `${activeRemainingItemCount}/${activeItemCount}` : `${filteredItemCount}/${activeItemCount}` }),
|
|
4930
|
+
/* @__PURE__ */ jsxs7(
|
|
4931
|
+
"select",
|
|
4932
|
+
{
|
|
4933
|
+
"aria-label": "QA status filter",
|
|
4934
|
+
className: "df-review-status-filter-select",
|
|
4935
|
+
value: qaStatusFilter,
|
|
4936
|
+
onChange: (event) => onQaStatusFilterChange(
|
|
4937
|
+
event.currentTarget.value
|
|
4938
|
+
),
|
|
4939
|
+
children: [
|
|
4940
|
+
/* @__PURE__ */ jsx9("option", { value: "all", children: `All status (${qaStatusFilterCounts.get("all") ?? 0})` }),
|
|
4941
|
+
statusFilterOptions.map((statusOption) => /* @__PURE__ */ jsx9("option", { value: statusOption.value, children: `${statusOption.label} (${qaStatusFilterCounts.get(statusOption.value) ?? 0})` }, statusOption.value))
|
|
4942
|
+
]
|
|
4943
|
+
}
|
|
4944
|
+
)
|
|
4945
|
+
] })
|
|
4417
4946
|
] });
|
|
4418
4947
|
};
|
|
4948
|
+
function getStatusFilterOptions(statusOptions) {
|
|
4949
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4950
|
+
return statusOptions.flatMap((statusOption) => {
|
|
4951
|
+
const value = normalizeReviewItemStatus(statusOption.value);
|
|
4952
|
+
if (seen.has(value)) return [];
|
|
4953
|
+
seen.add(value);
|
|
4954
|
+
return [{
|
|
4955
|
+
value,
|
|
4956
|
+
label: statusOption.label
|
|
4957
|
+
}];
|
|
4958
|
+
});
|
|
4959
|
+
}
|
|
4419
4960
|
|
|
4420
4961
|
// src/react-shell/qa/panel.tsx
|
|
4421
|
-
import { jsx as
|
|
4962
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4422
4963
|
var ReviewQaPanel = ({
|
|
4423
4964
|
activeAdapterEntry,
|
|
4424
4965
|
activeItems,
|
|
4425
|
-
|
|
4966
|
+
activeRemainingItemCount,
|
|
4426
4967
|
currentPresetScope,
|
|
4427
4968
|
filteredNumberedActiveItems,
|
|
4428
4969
|
getItemPresetScope,
|
|
4429
4970
|
hiddenOverlayItemIds,
|
|
4971
|
+
isAllQaVisible,
|
|
4430
4972
|
isListVisible,
|
|
4431
4973
|
isRemoteSource,
|
|
4432
|
-
presenceSessionId,
|
|
4433
4974
|
copiedPromptKey,
|
|
4434
4975
|
qaFilter,
|
|
4435
4976
|
qaFilterCounts,
|
|
4977
|
+
qaStatusFilter,
|
|
4978
|
+
qaStatusFilterCounts,
|
|
4436
4979
|
remoteAdapterEntry,
|
|
4437
4980
|
selectedItemId,
|
|
4438
4981
|
showSourceSelect,
|
|
4439
|
-
sourceRoot,
|
|
4440
4982
|
source,
|
|
4441
4983
|
sourceEntries,
|
|
4442
4984
|
onChangeItemStatus,
|
|
4443
4985
|
onClearSelectedItem,
|
|
4444
4986
|
onChangeReviewSource,
|
|
4987
|
+
onCopyItemLink,
|
|
4445
4988
|
onCopyItemPrompt,
|
|
4446
4989
|
onEditItem,
|
|
4447
4990
|
onQaFilterChange,
|
|
4991
|
+
onQaStatusFilterChange,
|
|
4448
4992
|
onRefreshReviewData,
|
|
4449
4993
|
onRemoveItem,
|
|
4450
4994
|
onRestoreReviewItem,
|
|
4451
4995
|
onSubmitItem,
|
|
4452
4996
|
onToggleItemOverlayVisibility
|
|
4453
4997
|
}) => {
|
|
4454
|
-
|
|
4455
|
-
|
|
4998
|
+
const emptyMessage = isAllQaVisible ? `No ${activeAdapterEntry.label} QA.` : isRemoteSource ? `No ${activeAdapterEntry.label} QA on this page.` : "No QA on this page.";
|
|
4999
|
+
return /* @__PURE__ */ jsx10("aside", { className: "df-review-qa-panel", "aria-hidden": !isListVisible, children: /* @__PURE__ */ jsx10("div", { className: "df-review-panel-body", children: /* @__PURE__ */ jsxs8("section", { className: "df-review-item-list", children: [
|
|
5000
|
+
/* @__PURE__ */ jsx10(
|
|
4456
5001
|
QaPanelHeader,
|
|
4457
5002
|
{
|
|
4458
5003
|
activeItemCount: activeItems.length,
|
|
4459
|
-
|
|
5004
|
+
activeRemainingItemCount,
|
|
4460
5005
|
filteredItemCount: filteredNumberedActiveItems.length,
|
|
5006
|
+
isAllQaVisible,
|
|
4461
5007
|
label: activeAdapterEntry.label,
|
|
4462
|
-
presenceSessionId,
|
|
4463
5008
|
qaFilter,
|
|
4464
5009
|
qaFilterCounts,
|
|
5010
|
+
qaStatusFilter,
|
|
5011
|
+
qaStatusFilterCounts,
|
|
4465
5012
|
showSourceSelect,
|
|
4466
5013
|
source,
|
|
4467
5014
|
sourceEntries,
|
|
5015
|
+
statusOptions: activeAdapterEntry.statusOptions,
|
|
4468
5016
|
onChangeReviewSource,
|
|
4469
5017
|
onQaFilterChange,
|
|
5018
|
+
onQaStatusFilterChange,
|
|
4470
5019
|
onRefreshReviewData
|
|
4471
5020
|
}
|
|
4472
5021
|
),
|
|
4473
|
-
/* @__PURE__ */
|
|
5022
|
+
/* @__PURE__ */ jsxs8(
|
|
4474
5023
|
"div",
|
|
4475
5024
|
{
|
|
4476
5025
|
className: "df-review-list-scroll",
|
|
@@ -4480,11 +5029,11 @@ var ReviewQaPanel = ({
|
|
|
4480
5029
|
}
|
|
4481
5030
|
},
|
|
4482
5031
|
children: [
|
|
4483
|
-
activeItems.length === 0 && /* @__PURE__ */
|
|
4484
|
-
activeItems.length > 0 && filteredNumberedActiveItems.length === 0 && /* @__PURE__ */
|
|
5032
|
+
activeItems.length === 0 && /* @__PURE__ */ jsx10("p", { className: "df-review-empty", children: emptyMessage }),
|
|
5033
|
+
activeItems.length > 0 && filteredNumberedActiveItems.length === 0 && /* @__PURE__ */ jsx10("p", { className: "df-review-empty", children: "No QA in this filter." }),
|
|
4485
5034
|
filteredNumberedActiveItems.map((numberedItem) => {
|
|
4486
5035
|
const { item } = numberedItem;
|
|
4487
|
-
return /* @__PURE__ */
|
|
5036
|
+
return /* @__PURE__ */ jsx10(
|
|
4488
5037
|
QaItemCard,
|
|
4489
5038
|
{
|
|
4490
5039
|
activeAdapterEntry,
|
|
@@ -4496,9 +5045,9 @@ var ReviewQaPanel = ({
|
|
|
4496
5045
|
remoteAdapterEntry,
|
|
4497
5046
|
copiedPromptKey,
|
|
4498
5047
|
selectedItemId,
|
|
4499
|
-
sourceRoot,
|
|
4500
5048
|
onChangeItemStatus,
|
|
4501
5049
|
onClearSelectedItem,
|
|
5050
|
+
onCopyItemLink,
|
|
4502
5051
|
onCopyItemPrompt,
|
|
4503
5052
|
onEditItem,
|
|
4504
5053
|
onRemoveItem,
|
|
@@ -4515,6 +5064,263 @@ var ReviewQaPanel = ({
|
|
|
4515
5064
|
] }) }) });
|
|
4516
5065
|
};
|
|
4517
5066
|
|
|
5067
|
+
// src/react-shell/presence/overlay.tsx
|
|
5068
|
+
import { useState as useState3 } from "react";
|
|
5069
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5070
|
+
var COLLAPSED_USER_COUNT = 1;
|
|
5071
|
+
var getPresenceName = (user) => user.displayName || user.userId;
|
|
5072
|
+
var PresenceOverlay = ({
|
|
5073
|
+
presenceSessionId,
|
|
5074
|
+
users
|
|
5075
|
+
}) => {
|
|
5076
|
+
const [isExpanded, setIsExpanded] = useState3(false);
|
|
5077
|
+
if (users.length === 0) return null;
|
|
5078
|
+
const visibleUsers = isExpanded ? users : users.slice(0, COLLAPSED_USER_COUNT);
|
|
5079
|
+
const hiddenUserCount = users.length - visibleUsers.length;
|
|
5080
|
+
return /* @__PURE__ */ jsxs9(
|
|
5081
|
+
"div",
|
|
5082
|
+
{
|
|
5083
|
+
"aria-label": `Review presence, ${users.length} online`,
|
|
5084
|
+
className: `df-review-presence-overlay${isExpanded ? " is-expanded" : ""}`,
|
|
5085
|
+
children: [
|
|
5086
|
+
visibleUsers.map((user) => /* @__PURE__ */ jsx11(
|
|
5087
|
+
"span",
|
|
5088
|
+
{
|
|
5089
|
+
className: `df-review-presence-chip${user.sessionId === presenceSessionId ? " is-self" : ""}`,
|
|
5090
|
+
style: {
|
|
5091
|
+
"--df-review-presence-color": user.color
|
|
5092
|
+
},
|
|
5093
|
+
title: getPresenceName(user),
|
|
5094
|
+
children: getPresenceName(user)
|
|
5095
|
+
},
|
|
5096
|
+
user.sessionId
|
|
5097
|
+
)),
|
|
5098
|
+
hiddenUserCount > 0 && /* @__PURE__ */ jsxs9(
|
|
5099
|
+
"button",
|
|
5100
|
+
{
|
|
5101
|
+
"aria-label": `Show ${hiddenUserCount} more online reviewers`,
|
|
5102
|
+
"aria-expanded": isExpanded,
|
|
5103
|
+
className: "df-review-presence-more",
|
|
5104
|
+
type: "button",
|
|
5105
|
+
onClick: () => setIsExpanded(true),
|
|
5106
|
+
children: [
|
|
5107
|
+
"+",
|
|
5108
|
+
hiddenUserCount
|
|
5109
|
+
]
|
|
5110
|
+
}
|
|
5111
|
+
)
|
|
5112
|
+
]
|
|
5113
|
+
}
|
|
5114
|
+
);
|
|
5115
|
+
};
|
|
5116
|
+
|
|
5117
|
+
// src/react-shell/source.open.ts
|
|
5118
|
+
var SOURCE_SELECTOR = [
|
|
5119
|
+
"[data-wrk-source-file]",
|
|
5120
|
+
"[data-wrk-source-component]",
|
|
5121
|
+
"[data-wrk-source-line]",
|
|
5122
|
+
"[data-wrk-source-column]",
|
|
5123
|
+
"[data-file]",
|
|
5124
|
+
"[data-component]",
|
|
5125
|
+
"[data-section-index]",
|
|
5126
|
+
"[data-section-id]"
|
|
5127
|
+
].join(", ");
|
|
5128
|
+
var getSourceCandidates = (target) => {
|
|
5129
|
+
const startElement = getEventElement(target);
|
|
5130
|
+
if (!startElement) return [];
|
|
5131
|
+
const candidates = [];
|
|
5132
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5133
|
+
let element = startElement;
|
|
5134
|
+
let depth = 0;
|
|
5135
|
+
while (element && element.nodeType === 1) {
|
|
5136
|
+
const source = getSourceHintFromElement(element);
|
|
5137
|
+
if (source?.file) {
|
|
5138
|
+
const key = getSourceCandidateKey(source);
|
|
5139
|
+
if (!seen.has(key)) {
|
|
5140
|
+
seen.add(key);
|
|
5141
|
+
candidates.push(createSourceCandidate(element, source, depth));
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
if (element === element.ownerDocument.documentElement) break;
|
|
5145
|
+
element = element.parentElement;
|
|
5146
|
+
depth += 1;
|
|
5147
|
+
}
|
|
5148
|
+
return candidates.slice(0, 8);
|
|
5149
|
+
};
|
|
5150
|
+
var getSourceOpenUrl = (source, options) => {
|
|
5151
|
+
const normalizedOptions = normalizeSourceOpenOptions(options);
|
|
5152
|
+
const file = source?.file?.trim();
|
|
5153
|
+
if (!file) return null;
|
|
5154
|
+
const sourcePath = getSourcePath(file, normalizedOptions.sourceRoot);
|
|
5155
|
+
if (!sourcePath) return null;
|
|
5156
|
+
const hasPosition = !normalizedOptions.omitPosition;
|
|
5157
|
+
const line = hasPosition ? getSourcePosition(source?.line) : null;
|
|
5158
|
+
const column = hasPosition ? getSourcePosition(source?.column) : null;
|
|
5159
|
+
const editor = normalizedOptions.editor ?? "vscode";
|
|
5160
|
+
if (normalizedOptions.urlTemplate) {
|
|
5161
|
+
return buildSourceUrlFromTemplate(normalizedOptions.urlTemplate, {
|
|
5162
|
+
column,
|
|
5163
|
+
file,
|
|
5164
|
+
line,
|
|
5165
|
+
sourcePath,
|
|
5166
|
+
sourceRoot: normalizedOptions.sourceRoot
|
|
5167
|
+
});
|
|
5168
|
+
}
|
|
5169
|
+
if (editor === "webstorm") {
|
|
5170
|
+
const params = new URLSearchParams({ file: sourcePath });
|
|
5171
|
+
if (line) params.set("line", String(line));
|
|
5172
|
+
if (column) params.set("column", String(column));
|
|
5173
|
+
return `webstorm://open?${params.toString()}`;
|
|
5174
|
+
}
|
|
5175
|
+
if (editor === "custom") return null;
|
|
5176
|
+
const encodedPath = encodePathForFileScheme(sourcePath);
|
|
5177
|
+
const scheme = editor === "cursor" ? "cursor" : "vscode";
|
|
5178
|
+
if (!line) return `${scheme}://file/${encodedPath}`;
|
|
5179
|
+
if (!column) return `${scheme}://file/${encodedPath}:${line}`;
|
|
5180
|
+
return `${scheme}://file/${encodedPath}:${line}:${column}`;
|
|
5181
|
+
};
|
|
5182
|
+
var openSourceInEditor = (source, options) => {
|
|
5183
|
+
const url = getSourceOpenUrl(source, options);
|
|
5184
|
+
if (!url) return false;
|
|
5185
|
+
window.open(url, "_blank", "noreferrer");
|
|
5186
|
+
return true;
|
|
5187
|
+
};
|
|
5188
|
+
function getSourceHintFromElement(element) {
|
|
5189
|
+
const source = {
|
|
5190
|
+
component: getSourceAttribute(
|
|
5191
|
+
element,
|
|
5192
|
+
"data-wrk-source-component",
|
|
5193
|
+
"data-component"
|
|
5194
|
+
),
|
|
5195
|
+
file: getSourceAttribute(element, "data-wrk-source-file", "data-file"),
|
|
5196
|
+
line: getSourceAttribute(element, "data-wrk-source-line"),
|
|
5197
|
+
column: getSourceAttribute(element, "data-wrk-source-column"),
|
|
5198
|
+
sectionId: getSourceAttribute(element, "data-section-id"),
|
|
5199
|
+
sectionIndex: getSourceAttribute(element, "data-section-index")
|
|
5200
|
+
};
|
|
5201
|
+
return Object.values(source).some(Boolean) ? source : void 0;
|
|
5202
|
+
}
|
|
5203
|
+
function createSourceCandidate(element, source, depth) {
|
|
5204
|
+
const confidence = getSourceConfidence(source, depth);
|
|
5205
|
+
const fileName = source.file?.split(/[\\/]/).pop() ?? source.file ?? "source";
|
|
5206
|
+
const component = source.component?.trim();
|
|
5207
|
+
const fallbackComponent = getComponentNameFromSourceFile(source.file);
|
|
5208
|
+
const tag = element.tagName.toLowerCase();
|
|
5209
|
+
const line = getSourcePosition(source.line);
|
|
5210
|
+
const column = getSourcePosition(source.column);
|
|
5211
|
+
const position = line ? `:${line}${column ? `:${column}` : ""}` : "";
|
|
5212
|
+
return {
|
|
5213
|
+
id: getSourceCandidateKey(source),
|
|
5214
|
+
depth,
|
|
5215
|
+
element,
|
|
5216
|
+
filePath: getDisplaySourcePath(source.file) ?? fileName,
|
|
5217
|
+
label: component || fallbackComponent || tag,
|
|
5218
|
+
detail: `${fileName}${position}`,
|
|
5219
|
+
positionLabel: line ? `${line}:${column ?? 1}` : "",
|
|
5220
|
+
confidence,
|
|
5221
|
+
confidenceLabel: confidence >= 0.82 ? "high" : confidence >= 0.58 ? "medium" : "low",
|
|
5222
|
+
usesPosition: confidence >= 0.72 && Boolean(line),
|
|
5223
|
+
source
|
|
5224
|
+
};
|
|
5225
|
+
}
|
|
5226
|
+
function getComponentNameFromSourceFile(file) {
|
|
5227
|
+
const normalizedFile = file?.trim().replace(/\\/g, "/");
|
|
5228
|
+
if (!normalizedFile) return void 0;
|
|
5229
|
+
const pathParts = normalizedFile.split("/").filter(Boolean);
|
|
5230
|
+
const fileName = pathParts[pathParts.length - 1];
|
|
5231
|
+
if (!fileName) return void 0;
|
|
5232
|
+
const stem = fileName.replace(/\.[^.]+$/, "");
|
|
5233
|
+
const sourceName = stem.toLowerCase() === "index" ? pathParts[pathParts.length - 2]?.replace(/\.[^.]+$/, "") : stem;
|
|
5234
|
+
return toPascalCase2(sourceName);
|
|
5235
|
+
}
|
|
5236
|
+
function toPascalCase2(value) {
|
|
5237
|
+
const words = value?.split(/[._\-\s]+/).map((part) => part.trim()).filter(Boolean);
|
|
5238
|
+
if (!words?.length) return void 0;
|
|
5239
|
+
return words.map((word) => `${word.charAt(0).toUpperCase()}${word.slice(1)}`).join("");
|
|
5240
|
+
}
|
|
5241
|
+
function getDisplaySourcePath(file) {
|
|
5242
|
+
const normalizedFile = file?.trim().replace(/\\/g, "/");
|
|
5243
|
+
if (!normalizedFile) return void 0;
|
|
5244
|
+
const sourceRootMatch = normalizedFile.match(
|
|
5245
|
+
/(?:^|\/)((?:dev\/)?src\/.+|app\/.+|pages\/.+|components\/.+)$/
|
|
5246
|
+
);
|
|
5247
|
+
return sourceRootMatch?.[1] ?? normalizedFile;
|
|
5248
|
+
}
|
|
5249
|
+
function getSourceCandidateKey(source) {
|
|
5250
|
+
return [
|
|
5251
|
+
source.file,
|
|
5252
|
+
source.component,
|
|
5253
|
+
source.line,
|
|
5254
|
+
source.column,
|
|
5255
|
+
source.sectionId,
|
|
5256
|
+
source.sectionIndex
|
|
5257
|
+
].filter(Boolean).join("|");
|
|
5258
|
+
}
|
|
5259
|
+
function getSourceConfidence(source, depth) {
|
|
5260
|
+
let score = source.file ? 0.54 : 0.12;
|
|
5261
|
+
if (source.component) score += 0.12;
|
|
5262
|
+
if (getSourcePosition(source.line)) score += 0.22;
|
|
5263
|
+
if (getSourcePosition(source.column)) score += 0.08;
|
|
5264
|
+
if (source.sectionId || source.sectionIndex) score += 0.04;
|
|
5265
|
+
score -= Math.min(depth, 5) * 0.045;
|
|
5266
|
+
return Math.max(0.1, Math.min(1, Number(score.toFixed(2))));
|
|
5267
|
+
}
|
|
5268
|
+
function normalizeSourceOpenOptions(options) {
|
|
5269
|
+
return typeof options === "string" ? { sourceRoot: options } : options ?? {};
|
|
5270
|
+
}
|
|
5271
|
+
function buildSourceUrlFromTemplate(template, values) {
|
|
5272
|
+
const replacements = {
|
|
5273
|
+
column: values.column ? String(values.column) : "",
|
|
5274
|
+
encodedPath: encodeURIComponent(values.sourcePath),
|
|
5275
|
+
file: values.file,
|
|
5276
|
+
line: values.line ? String(values.line) : "",
|
|
5277
|
+
path: values.sourcePath,
|
|
5278
|
+
sourceRoot: values.sourceRoot ?? "",
|
|
5279
|
+
uriPath: encodePathForFileScheme(values.sourcePath)
|
|
5280
|
+
};
|
|
5281
|
+
return template.replace(
|
|
5282
|
+
/\{([a-zA-Z]+)\}/g,
|
|
5283
|
+
(_, key) => replacements[key] ?? ""
|
|
5284
|
+
);
|
|
5285
|
+
}
|
|
5286
|
+
function getSourceAttribute(element, ...names) {
|
|
5287
|
+
for (const name of names) {
|
|
5288
|
+
const value = element.getAttribute(name)?.trim();
|
|
5289
|
+
if (value) return value;
|
|
5290
|
+
}
|
|
5291
|
+
return void 0;
|
|
5292
|
+
}
|
|
5293
|
+
function getEventElement(target) {
|
|
5294
|
+
if (!target || typeof target !== "object") return null;
|
|
5295
|
+
const node = target;
|
|
5296
|
+
if (node.nodeType === 1 && typeof node.closest === "function") {
|
|
5297
|
+
return node;
|
|
5298
|
+
}
|
|
5299
|
+
if (node.parentElement && typeof node.parentElement.closest === "function") {
|
|
5300
|
+
return node.parentElement;
|
|
5301
|
+
}
|
|
5302
|
+
return null;
|
|
5303
|
+
}
|
|
5304
|
+
function getSourcePath(file, sourceRoot) {
|
|
5305
|
+
const normalizedFile = file.replace(/\\/g, "/");
|
|
5306
|
+
if (normalizedFile.startsWith("/") || /^[a-zA-Z]:\//.test(normalizedFile)) {
|
|
5307
|
+
return normalizedFile;
|
|
5308
|
+
}
|
|
5309
|
+
const normalizedRoot = sourceRoot?.trim().replace(/\\/g, "/").replace(/\/+$/, "");
|
|
5310
|
+
if (!normalizedRoot) return null;
|
|
5311
|
+
return `${normalizedRoot}/${normalizedFile.replace(/^\/+/, "")}`;
|
|
5312
|
+
}
|
|
5313
|
+
function getSourcePosition(value) {
|
|
5314
|
+
const position = Number(value);
|
|
5315
|
+
return Number.isInteger(position) && position > 0 ? position : null;
|
|
5316
|
+
}
|
|
5317
|
+
function encodePathForFileScheme(path) {
|
|
5318
|
+
return encodeURI(path).replace(
|
|
5319
|
+
/[#?]/g,
|
|
5320
|
+
(match) => match === "#" ? "%23" : "%3F"
|
|
5321
|
+
);
|
|
5322
|
+
}
|
|
5323
|
+
|
|
4518
5324
|
// src/react-shell/review/mode.toolbar.tsx
|
|
4519
5325
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4520
5326
|
var ReviewModeToolbar = ({
|
|
@@ -4693,6 +5499,7 @@ var ReviewTargetFrame = ({
|
|
|
4693
5499
|
canWriteArea,
|
|
4694
5500
|
canWriteDom,
|
|
4695
5501
|
frameScrollRef,
|
|
5502
|
+
figmaFrameUrl,
|
|
4696
5503
|
iframeRef,
|
|
4697
5504
|
isRulerAvailable,
|
|
4698
5505
|
isRulerDragging,
|
|
@@ -4711,8 +5518,9 @@ var ReviewTargetFrame = ({
|
|
|
4711
5518
|
onSetReviewMode
|
|
4712
5519
|
}) => {
|
|
4713
5520
|
const showRuler = isRulerVisible && isRulerAvailable;
|
|
5521
|
+
const targetHref = getTargetOpenHref(targetSrc);
|
|
4714
5522
|
return /* @__PURE__ */ jsx15("main", { className: "df-review-stage", children: /* @__PURE__ */ jsxs13("div", { className: "df-review-frame", children: [
|
|
4715
|
-
/* @__PURE__ */ jsx15("div", { className: "df-review-frame-scroll", ref: frameScrollRef, children: /* @__PURE__ */ jsx15("div", { className: "df-review-frame-canvas", children: /* @__PURE__ */ jsxs13(
|
|
5523
|
+
/* @__PURE__ */ jsx15("div", { className: "df-review-frame-scroll", ref: frameScrollRef, children: /* @__PURE__ */ jsx15("div", { className: "df-review-frame-canvas", children: /* @__PURE__ */ jsx15("div", { className: "df-review-target-stack", children: /* @__PURE__ */ jsxs13(
|
|
4716
5524
|
"div",
|
|
4717
5525
|
{
|
|
4718
5526
|
className: `df-review-device-frame${showRuler ? " is-ruler" : ""}`,
|
|
@@ -4764,10 +5572,36 @@ var ReviewTargetFrame = ({
|
|
|
4764
5572
|
)
|
|
4765
5573
|
]
|
|
4766
5574
|
}
|
|
4767
|
-
)
|
|
5575
|
+
),
|
|
5576
|
+
/* @__PURE__ */ jsxs13("div", { className: "df-review-frame-link-stack", children: [
|
|
5577
|
+
/* @__PURE__ */ jsx15(
|
|
5578
|
+
"a",
|
|
5579
|
+
{
|
|
5580
|
+
"aria-label": "Open target page",
|
|
5581
|
+
className: "df-review-frame-link is-target",
|
|
5582
|
+
href: targetHref,
|
|
5583
|
+
rel: "noreferrer",
|
|
5584
|
+
target: "_blank",
|
|
5585
|
+
title: "Open target page",
|
|
5586
|
+
children: /* @__PURE__ */ jsx15(ExternalLink, { "aria-hidden": "true" })
|
|
5587
|
+
}
|
|
5588
|
+
),
|
|
5589
|
+
figmaFrameUrl && /* @__PURE__ */ jsx15(
|
|
5590
|
+
"a",
|
|
5591
|
+
{
|
|
5592
|
+
"aria-label": "Open Figma frame",
|
|
5593
|
+
className: "df-review-frame-link is-figma",
|
|
5594
|
+
href: figmaFrameUrl,
|
|
5595
|
+
rel: "noreferrer",
|
|
5596
|
+
target: "_blank",
|
|
5597
|
+
title: "Open Figma frame",
|
|
5598
|
+
children: /* @__PURE__ */ jsx15(FigmaIcon, {})
|
|
5599
|
+
}
|
|
5600
|
+
)
|
|
5601
|
+
] })
|
|
4768
5602
|
]
|
|
4769
5603
|
}
|
|
4770
|
-
) }) }),
|
|
5604
|
+
) }) }) }),
|
|
4771
5605
|
/* @__PURE__ */ jsx15("div", { className: "df-review-frame-actions", children: /* @__PURE__ */ jsx15(
|
|
4772
5606
|
ReviewModeToolbar,
|
|
4773
5607
|
{
|
|
@@ -4779,6 +5613,111 @@ var ReviewTargetFrame = ({
|
|
|
4779
5613
|
) })
|
|
4780
5614
|
] }) });
|
|
4781
5615
|
};
|
|
5616
|
+
function getTargetOpenHref(targetSrc) {
|
|
5617
|
+
const url = new URL(targetSrc, window.location.origin);
|
|
5618
|
+
url.searchParams.delete("__dfwr_target");
|
|
5619
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
5620
|
+
}
|
|
5621
|
+
var FigmaIcon = () => /* @__PURE__ */ jsx15(
|
|
5622
|
+
"svg",
|
|
5623
|
+
{
|
|
5624
|
+
"aria-hidden": "true",
|
|
5625
|
+
viewBox: "0 0 24 24",
|
|
5626
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5627
|
+
children: /* @__PURE__ */ jsx15("path", { d: "M15.852 8.981h-4.588V0h4.588c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.491-4.49 4.491zM12.735 7.51h3.117c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-3.117V7.51zm0 1.471H8.148c-2.476 0-4.49-2.014-4.49-4.49S5.672 0 8.148 0h4.588v8.981zm-4.587-7.51c-1.665 0-3.019 1.355-3.019 3.019s1.354 3.02 3.019 3.02h3.117V1.471H8.148zm4.587 15.019H8.148c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h4.588v8.98zM8.148 8.981c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h3.117V8.981H8.148zM8.172 24c-2.489 0-4.515-2.014-4.515-4.49s2.014-4.49 4.49-4.49h4.588v4.441C12.735 21.964 10.688 24 8.172 24zm-.024-7.51a3.023 3.023 0 0 0-3.019 3.019c0 1.665 1.365 3.019 3.044 3.019 1.705 0 3.093-1.376 3.093-3.068v-2.97H8.148zm7.704 0h-.098c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h.098c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.49-4.49 4.49zm-.097-7.509c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h.098c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-.098z" })
|
|
5628
|
+
}
|
|
5629
|
+
);
|
|
5630
|
+
|
|
5631
|
+
// src/react-shell/target/target.ts
|
|
5632
|
+
var HIDE_SCROLLBAR_STYLE_ID = "df-review-hide-scrollbar";
|
|
5633
|
+
var FIGMA_POINTER_LOCK_STYLE_ID = "df-review-figma-pointer-lock";
|
|
5634
|
+
var setTargetScrollbarHidden = (targetDocument, hidden) => {
|
|
5635
|
+
if (!targetDocument) return;
|
|
5636
|
+
const existing = targetDocument.getElementById(HIDE_SCROLLBAR_STYLE_ID);
|
|
5637
|
+
if (hidden) {
|
|
5638
|
+
if (existing) return;
|
|
5639
|
+
const style = targetDocument.createElement("style");
|
|
5640
|
+
style.id = HIDE_SCROLLBAR_STYLE_ID;
|
|
5641
|
+
style.textContent = "html{scrollbar-width:none}html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0;display:none}";
|
|
5642
|
+
targetDocument.head?.appendChild(style);
|
|
5643
|
+
} else {
|
|
5644
|
+
existing?.remove();
|
|
5645
|
+
}
|
|
5646
|
+
};
|
|
5647
|
+
var setTargetFigmaOverlayLocked = (targetDocument, locked) => {
|
|
5648
|
+
if (!targetDocument) return;
|
|
5649
|
+
const existing = targetDocument.getElementById(FIGMA_POINTER_LOCK_STYLE_ID);
|
|
5650
|
+
if (locked) {
|
|
5651
|
+
if (existing) return;
|
|
5652
|
+
const style = targetDocument.createElement("style");
|
|
5653
|
+
style.id = FIGMA_POINTER_LOCK_STYLE_ID;
|
|
5654
|
+
style.textContent = [
|
|
5655
|
+
".helper-figma-root,",
|
|
5656
|
+
".helper-figma-root *,",
|
|
5657
|
+
".helper-figma-loading-backdrop,",
|
|
5658
|
+
".helper-figma-loading-backdrop * {",
|
|
5659
|
+
"pointer-events: none !important;",
|
|
5660
|
+
"}"
|
|
5661
|
+
].join("\n");
|
|
5662
|
+
targetDocument.head?.appendChild(style);
|
|
5663
|
+
} else {
|
|
5664
|
+
existing?.remove();
|
|
5665
|
+
}
|
|
5666
|
+
};
|
|
5667
|
+
var isEditableEventTarget = (event) => {
|
|
5668
|
+
const path = event.composedPath?.() ?? [];
|
|
5669
|
+
const element = path[0] ?? event.target;
|
|
5670
|
+
if (!element || typeof element.tagName !== "string") return false;
|
|
5671
|
+
const tag = element.tagName;
|
|
5672
|
+
return tag === "INPUT" || tag === "TEXTAREA" || element.isContentEditable === true;
|
|
5673
|
+
};
|
|
5674
|
+
var TRUE_STORAGE_VALUES = /* @__PURE__ */ new Set([
|
|
5675
|
+
"1",
|
|
5676
|
+
"true",
|
|
5677
|
+
"on",
|
|
5678
|
+
"show",
|
|
5679
|
+
"shown",
|
|
5680
|
+
"visible",
|
|
5681
|
+
"enabled",
|
|
5682
|
+
"yes"
|
|
5683
|
+
]);
|
|
5684
|
+
var OVERLAY_STORAGE_KEYS = {
|
|
5685
|
+
grid: ["isHelp", "df-review-grid-overlay", "dfReviewGridOverlay"],
|
|
5686
|
+
figma: ["isFigmaHelp", "df-review-figma-overlay", "dfReviewFigmaOverlay"]
|
|
5687
|
+
};
|
|
5688
|
+
var isStoredOverlayEnabled = (value) => TRUE_STORAGE_VALUES.has(value?.trim().toLowerCase() ?? "");
|
|
5689
|
+
var getCookieValue = (targetDocument, name) => {
|
|
5690
|
+
const cookies = targetDocument?.cookie ? targetDocument.cookie.split(";") : [];
|
|
5691
|
+
const prefix = `${name}=`;
|
|
5692
|
+
const match = cookies.map((cookie) => cookie.trim()).find((cookie) => cookie.startsWith(prefix));
|
|
5693
|
+
return match ? decodeURIComponent(match.slice(prefix.length)) : null;
|
|
5694
|
+
};
|
|
5695
|
+
var getStorageValue = (storage, key) => {
|
|
5696
|
+
try {
|
|
5697
|
+
return storage?.getItem(key) ?? null;
|
|
5698
|
+
} catch {
|
|
5699
|
+
return null;
|
|
5700
|
+
}
|
|
5701
|
+
};
|
|
5702
|
+
var getStoredOverlayState = (targetDocument, overlay) => {
|
|
5703
|
+
const targetWindow = targetDocument?.defaultView;
|
|
5704
|
+
return OVERLAY_STORAGE_KEYS[overlay].some((key) => {
|
|
5705
|
+
if (isStoredOverlayEnabled(getCookieValue(targetDocument, key))) {
|
|
5706
|
+
return true;
|
|
5707
|
+
}
|
|
5708
|
+
return isStoredOverlayEnabled(getStorageValue(targetWindow?.localStorage, key)) || isStoredOverlayEnabled(getStorageValue(targetWindow?.sessionStorage, key));
|
|
5709
|
+
});
|
|
5710
|
+
};
|
|
5711
|
+
var getTargetOverlayState = (targetDocument) => ({
|
|
5712
|
+
grid: Boolean(
|
|
5713
|
+
targetDocument?.body.classList.contains("is-help") || targetDocument?.querySelector(".helper.onShow") || getStoredOverlayState(targetDocument, "grid")
|
|
5714
|
+
),
|
|
5715
|
+
figma: Boolean(
|
|
5716
|
+
targetDocument?.querySelector(
|
|
5717
|
+
".helper-figma-root, .helper-figma-loading-backdrop"
|
|
5718
|
+
) || getStoredOverlayState(targetDocument, "figma")
|
|
5719
|
+
)
|
|
5720
|
+
});
|
|
4782
5721
|
|
|
4783
5722
|
// src/react-shell/topbar.tsx
|
|
4784
5723
|
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
@@ -4897,6 +5836,7 @@ var ReviewTopbar = ({
|
|
|
4897
5836
|
"aria-disabled": !isFigmaOverlayAvailable,
|
|
4898
5837
|
"aria-label": isFigmaOverlayAvailable ? "Toggle Figma overlay" : FIGMA_OVERLAY_UNAVAILABLE_MESSAGE,
|
|
4899
5838
|
className: `df-review-overlay-button is-figma${targetOverlayState.figma ? " is-active" : ""}${isFigmaOverlayAvailable ? "" : " is-disabled"}`,
|
|
5839
|
+
disabled: !isFigmaOverlayAvailable,
|
|
4900
5840
|
type: "button",
|
|
4901
5841
|
onClick: () => onToggleTargetOverlay("figma"),
|
|
4902
5842
|
children: /* @__PURE__ */ jsx16(Image, { "aria-hidden": "true" })
|
|
@@ -4954,6 +5894,47 @@ function runWithAutoScrollBehavior(targetDocument, callback) {
|
|
|
4954
5894
|
});
|
|
4955
5895
|
}
|
|
4956
5896
|
}
|
|
5897
|
+
var RESTORE_WAIT_MAX_MS = 2600;
|
|
5898
|
+
var RESTORE_STABLE_FRAME_COUNT = 2;
|
|
5899
|
+
var waitForNextAnimationFrame = (targetWindow) => new Promise((resolve) => {
|
|
5900
|
+
targetWindow.requestAnimationFrame(() => resolve());
|
|
5901
|
+
});
|
|
5902
|
+
var getRestoreLayoutSnapshot = (targetDocument, anchorElement) => {
|
|
5903
|
+
const root = targetDocument.documentElement;
|
|
5904
|
+
const body = targetDocument.body;
|
|
5905
|
+
const anchorRect = anchorElement?.getBoundingClientRect();
|
|
5906
|
+
return [
|
|
5907
|
+
root.scrollWidth,
|
|
5908
|
+
root.scrollHeight,
|
|
5909
|
+
body?.scrollWidth ?? 0,
|
|
5910
|
+
body?.scrollHeight ?? 0,
|
|
5911
|
+
anchorRect ? Math.round(anchorRect.left) : -1,
|
|
5912
|
+
anchorRect ? Math.round(anchorRect.top) : -1,
|
|
5913
|
+
anchorRect ? Math.round(anchorRect.width) : -1,
|
|
5914
|
+
anchorRect ? Math.round(anchorRect.height) : -1
|
|
5915
|
+
].join(":");
|
|
5916
|
+
};
|
|
5917
|
+
var waitForRestoreAnchor = async (targetWindow, targetDocument, item, isCurrent) => {
|
|
5918
|
+
const startedAt = targetWindow.performance.now();
|
|
5919
|
+
let previousSnapshot = "";
|
|
5920
|
+
let stableFrameCount = 0;
|
|
5921
|
+
while (isCurrent() && targetWindow.performance.now() - startedAt < RESTORE_WAIT_MAX_MS) {
|
|
5922
|
+
const anchorElement = queryReviewItemAnchorElement(targetDocument, item);
|
|
5923
|
+
const snapshot = getRestoreLayoutSnapshot(targetDocument, anchorElement);
|
|
5924
|
+
const canRestore = item.anchor ? Boolean(anchorElement) : true;
|
|
5925
|
+
if (snapshot === previousSnapshot) {
|
|
5926
|
+
stableFrameCount += 1;
|
|
5927
|
+
} else {
|
|
5928
|
+
stableFrameCount = 0;
|
|
5929
|
+
}
|
|
5930
|
+
if (canRestore && stableFrameCount >= RESTORE_STABLE_FRAME_COUNT) {
|
|
5931
|
+
return anchorElement;
|
|
5932
|
+
}
|
|
5933
|
+
previousSnapshot = snapshot;
|
|
5934
|
+
await waitForNextAnimationFrame(targetWindow);
|
|
5935
|
+
}
|
|
5936
|
+
return queryReviewItemAnchorElement(targetDocument, item);
|
|
5937
|
+
};
|
|
4957
5938
|
var useReviewItemRestore = ({
|
|
4958
5939
|
adapter,
|
|
4959
5940
|
controllerRef,
|
|
@@ -4984,14 +5965,20 @@ var useReviewItemRestore = ({
|
|
|
4984
5965
|
selectedItemIdRef
|
|
4985
5966
|
]);
|
|
4986
5967
|
const applyItemScroll = useCallback(
|
|
4987
|
-
(item) => {
|
|
4988
|
-
if (selectedItemIdRef.current !== item.id) return;
|
|
5968
|
+
async (item) => {
|
|
5969
|
+
if (selectedItemIdRef.current !== item.id) return false;
|
|
4989
5970
|
const targetWindow = iframeRef.current?.contentWindow;
|
|
4990
5971
|
const targetDocument = iframeRef.current?.contentDocument;
|
|
4991
|
-
if (!targetWindow) return;
|
|
4992
|
-
const
|
|
4993
|
-
|
|
4994
|
-
|
|
5972
|
+
if (!targetWindow || !targetDocument) return false;
|
|
5973
|
+
const isCurrentRestore = () => selectedItemIdRef.current === item.id && iframeRef.current?.contentDocument === targetDocument;
|
|
5974
|
+
const anchorElement = await waitForRestoreAnchor(
|
|
5975
|
+
targetWindow,
|
|
5976
|
+
targetDocument,
|
|
5977
|
+
item,
|
|
5978
|
+
isCurrentRestore
|
|
5979
|
+
);
|
|
5980
|
+
if (!isCurrentRestore()) return false;
|
|
5981
|
+
runWithAutoScrollBehavior(targetDocument, () => {
|
|
4995
5982
|
setDocumentScrollInstantly(
|
|
4996
5983
|
targetWindow,
|
|
4997
5984
|
targetDocument,
|
|
@@ -5005,14 +5992,18 @@ var useReviewItemRestore = ({
|
|
|
5005
5992
|
});
|
|
5006
5993
|
onSyncTargetViewport();
|
|
5007
5994
|
controllerRef.current?.highlightItem(item.id);
|
|
5995
|
+
return true;
|
|
5008
5996
|
},
|
|
5009
5997
|
[controllerRef, iframeRef, onSyncTargetViewport, selectedItemIdRef]
|
|
5010
5998
|
);
|
|
5011
5999
|
const applyPendingRestore = useCallback(() => {
|
|
5012
6000
|
const item = pendingRestoreRef.current;
|
|
5013
6001
|
if (!item) return;
|
|
5014
|
-
applyItemScroll(item)
|
|
5015
|
-
|
|
6002
|
+
void applyItemScroll(item).then((didApply) => {
|
|
6003
|
+
if (didApply && pendingRestoreRef.current?.id === item.id) {
|
|
6004
|
+
pendingRestoreRef.current = null;
|
|
6005
|
+
}
|
|
6006
|
+
});
|
|
5016
6007
|
}, [applyItemScroll, pendingRestoreRef]);
|
|
5017
6008
|
const restoreReviewItem = useCallback(
|
|
5018
6009
|
(item) => {
|
|
@@ -5069,39 +6060,6 @@ import {
|
|
|
5069
6060
|
useEffect as useEffect2
|
|
5070
6061
|
} from "react";
|
|
5071
6062
|
|
|
5072
|
-
// src/react-shell/target/target.ts
|
|
5073
|
-
var HIDE_SCROLLBAR_STYLE_ID = "df-review-hide-scrollbar";
|
|
5074
|
-
var setTargetScrollbarHidden = (targetDocument, hidden) => {
|
|
5075
|
-
if (!targetDocument) return;
|
|
5076
|
-
const existing = targetDocument.getElementById(HIDE_SCROLLBAR_STYLE_ID);
|
|
5077
|
-
if (hidden) {
|
|
5078
|
-
if (existing) return;
|
|
5079
|
-
const style = targetDocument.createElement("style");
|
|
5080
|
-
style.id = HIDE_SCROLLBAR_STYLE_ID;
|
|
5081
|
-
style.textContent = "html{scrollbar-width:none}html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0;display:none}";
|
|
5082
|
-
targetDocument.head?.appendChild(style);
|
|
5083
|
-
} else {
|
|
5084
|
-
existing?.remove();
|
|
5085
|
-
}
|
|
5086
|
-
};
|
|
5087
|
-
var isEditableEventTarget = (event) => {
|
|
5088
|
-
const path = event.composedPath?.() ?? [];
|
|
5089
|
-
const element = path[0] ?? event.target;
|
|
5090
|
-
if (!element || typeof element.tagName !== "string") return false;
|
|
5091
|
-
const tag = element.tagName;
|
|
5092
|
-
return tag === "INPUT" || tag === "TEXTAREA" || element.isContentEditable === true;
|
|
5093
|
-
};
|
|
5094
|
-
var getTargetOverlayState = (targetDocument) => ({
|
|
5095
|
-
grid: Boolean(
|
|
5096
|
-
targetDocument?.body.classList.contains("is-help") || targetDocument?.querySelector(".helper.onShow")
|
|
5097
|
-
),
|
|
5098
|
-
figma: Boolean(
|
|
5099
|
-
targetDocument?.querySelector(
|
|
5100
|
-
".helper-figma-root, .helper-figma-loading-backdrop"
|
|
5101
|
-
)
|
|
5102
|
-
)
|
|
5103
|
-
});
|
|
5104
|
-
|
|
5105
6063
|
// src/react-shell/hooks/review.frame.navigation.ts
|
|
5106
6064
|
var bindReviewFrameNavigation = ({
|
|
5107
6065
|
pageTargets,
|
|
@@ -5227,6 +6185,7 @@ var useReviewKitLifecycle = ({
|
|
|
5227
6185
|
reviewUserId,
|
|
5228
6186
|
reviewViewportPresets,
|
|
5229
6187
|
ruler,
|
|
6188
|
+
adjustmentLabel,
|
|
5230
6189
|
sizeRef,
|
|
5231
6190
|
targetRef,
|
|
5232
6191
|
onApplyPendingRestore,
|
|
@@ -5279,6 +6238,7 @@ var useReviewKitLifecycle = ({
|
|
|
5279
6238
|
presets: reviewViewportPresets
|
|
5280
6239
|
},
|
|
5281
6240
|
ruler,
|
|
6241
|
+
adjustmentLabel,
|
|
5282
6242
|
onCreateItem,
|
|
5283
6243
|
onRestoreItem: onRestoreReviewItem,
|
|
5284
6244
|
onItemsChange: () => {
|
|
@@ -5298,8 +6258,7 @@ var useReviewKitLifecycle = ({
|
|
|
5298
6258
|
controllerRef.current.setHiddenItemIds(hiddenOverlayItemIdListRef.current);
|
|
5299
6259
|
onModeChange(controllerRef.current.getMode());
|
|
5300
6260
|
void onItemsRefresh();
|
|
5301
|
-
void onRestoreInitialItem();
|
|
5302
|
-
onApplyPendingRestore();
|
|
6261
|
+
void onRestoreInitialItem().then(onApplyPendingRestore);
|
|
5303
6262
|
onRefreshTargetOverlayState();
|
|
5304
6263
|
setTargetScrollbarHidden(
|
|
5305
6264
|
targetDocument,
|
|
@@ -5330,6 +6289,7 @@ var useReviewKitLifecycle = ({
|
|
|
5330
6289
|
reviewUserId,
|
|
5331
6290
|
reviewViewportPresets,
|
|
5332
6291
|
ruler,
|
|
6292
|
+
adjustmentLabel,
|
|
5333
6293
|
sizeRef,
|
|
5334
6294
|
targetRef
|
|
5335
6295
|
]);
|
|
@@ -5362,18 +6322,33 @@ var useReviewKitLifecycle = ({
|
|
|
5362
6322
|
};
|
|
5363
6323
|
|
|
5364
6324
|
// src/react-shell/hooks/use.review.target.overlay.ts
|
|
5365
|
-
import { useCallback as useCallback3, useEffect as useEffect3 } from "react";
|
|
6325
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useRef } from "react";
|
|
6326
|
+
var TARGET_OVERLAY_REFRESH_DELAYS = [80, 240, 600];
|
|
5366
6327
|
var useReviewTargetOverlay = ({
|
|
5367
6328
|
iframeRef,
|
|
5368
6329
|
isFigmaOverlayAvailable,
|
|
5369
6330
|
targetOverlayState,
|
|
5370
6331
|
onTargetOverlayStateChange
|
|
5371
6332
|
}) => {
|
|
5372
|
-
const
|
|
5373
|
-
|
|
5374
|
-
|
|
6333
|
+
const refreshTimersRef = useRef([]);
|
|
6334
|
+
const clearRefreshTimers = useCallback3(() => {
|
|
6335
|
+
refreshTimersRef.current.forEach((timer) => window.clearTimeout(timer));
|
|
6336
|
+
refreshTimersRef.current = [];
|
|
6337
|
+
}, []);
|
|
6338
|
+
const updateTargetOverlayState = useCallback3(() => {
|
|
6339
|
+
const state = getTargetOverlayState(
|
|
6340
|
+
iframeRef.current?.contentDocument ?? void 0
|
|
5375
6341
|
);
|
|
6342
|
+
onTargetOverlayStateChange(state);
|
|
6343
|
+
return state;
|
|
5376
6344
|
}, [iframeRef, onTargetOverlayStateChange]);
|
|
6345
|
+
const refreshTargetOverlayState = useCallback3(() => {
|
|
6346
|
+
clearRefreshTimers();
|
|
6347
|
+
updateTargetOverlayState();
|
|
6348
|
+
refreshTimersRef.current = TARGET_OVERLAY_REFRESH_DELAYS.map(
|
|
6349
|
+
(delay) => window.setTimeout(updateTargetOverlayState, delay)
|
|
6350
|
+
);
|
|
6351
|
+
}, [clearRefreshTimers, updateTargetOverlayState]);
|
|
5377
6352
|
const dispatchTargetOverlayHotkey = useCallback3(
|
|
5378
6353
|
(overlay) => {
|
|
5379
6354
|
const targetWindow = iframeRef.current?.contentWindow;
|
|
@@ -5409,19 +6384,17 @@ var useReviewTargetOverlay = ({
|
|
|
5409
6384
|
);
|
|
5410
6385
|
const closeTargetOverlay = useCallback3(
|
|
5411
6386
|
(overlay) => {
|
|
5412
|
-
const currentState =
|
|
5413
|
-
iframeRef.current?.contentDocument ?? void 0
|
|
5414
|
-
);
|
|
5415
|
-
onTargetOverlayStateChange(currentState);
|
|
6387
|
+
const currentState = updateTargetOverlayState();
|
|
5416
6388
|
if (!currentState[overlay]) return false;
|
|
5417
6389
|
return dispatchTargetOverlayHotkey(overlay);
|
|
5418
6390
|
},
|
|
5419
|
-
[dispatchTargetOverlayHotkey,
|
|
6391
|
+
[dispatchTargetOverlayHotkey, updateTargetOverlayState]
|
|
5420
6392
|
);
|
|
5421
6393
|
useEffect3(() => {
|
|
5422
6394
|
if (isFigmaOverlayAvailable || !targetOverlayState.figma) return;
|
|
5423
6395
|
closeTargetOverlay("figma");
|
|
5424
6396
|
}, [closeTargetOverlay, isFigmaOverlayAvailable, targetOverlayState.figma]);
|
|
6397
|
+
useEffect3(() => clearRefreshTimers, [clearRefreshTimers]);
|
|
5425
6398
|
return {
|
|
5426
6399
|
closeTargetOverlay,
|
|
5427
6400
|
refreshTargetOverlayState,
|
|
@@ -5535,6 +6508,7 @@ var useReviewController = ({
|
|
|
5535
6508
|
reviewUserId,
|
|
5536
6509
|
reviewViewportPresets,
|
|
5537
6510
|
ruler,
|
|
6511
|
+
adjustmentLabel,
|
|
5538
6512
|
selectedItemIdRef,
|
|
5539
6513
|
size,
|
|
5540
6514
|
sizeRef,
|
|
@@ -5623,6 +6597,7 @@ var useReviewController = ({
|
|
|
5623
6597
|
reviewUserId,
|
|
5624
6598
|
reviewViewportPresets,
|
|
5625
6599
|
ruler,
|
|
6600
|
+
adjustmentLabel,
|
|
5626
6601
|
sizeRef,
|
|
5627
6602
|
targetRef,
|
|
5628
6603
|
onApplyPendingRestore: applyPendingRestore,
|
|
@@ -5653,9 +6628,9 @@ var useReviewController = ({
|
|
|
5653
6628
|
import {
|
|
5654
6629
|
useCallback as useCallback6,
|
|
5655
6630
|
useEffect as useEffect5,
|
|
5656
|
-
useMemo as
|
|
5657
|
-
useRef,
|
|
5658
|
-
useState as
|
|
6631
|
+
useMemo as useMemo3,
|
|
6632
|
+
useRef as useRef2,
|
|
6633
|
+
useState as useState4
|
|
5659
6634
|
} from "react";
|
|
5660
6635
|
|
|
5661
6636
|
// src/react-shell/presence/presence.ts
|
|
@@ -5871,10 +6846,10 @@ var useReviewPresence = ({
|
|
|
5871
6846
|
size,
|
|
5872
6847
|
source
|
|
5873
6848
|
}) => {
|
|
5874
|
-
const presenceSessionRef =
|
|
5875
|
-
const [presenceUsers, setPresenceUsers] =
|
|
5876
|
-
const [presenceSessionVersion, setPresenceSessionVersion] =
|
|
5877
|
-
const presenceSessionId =
|
|
6849
|
+
const presenceSessionRef = useRef2(null);
|
|
6850
|
+
const [presenceUsers, setPresenceUsers] = useState4([]);
|
|
6851
|
+
const [presenceSessionVersion, setPresenceSessionVersion] = useState4(0);
|
|
6852
|
+
const presenceSessionId = useMemo3(getReviewPresenceSessionId, []);
|
|
5878
6853
|
const normalizedReviewUserId = reviewUserId.trim();
|
|
5879
6854
|
const presenceDisplayName = getReviewPresenceDisplayName(
|
|
5880
6855
|
normalizedReviewUserId
|
|
@@ -5882,7 +6857,7 @@ var useReviewPresence = ({
|
|
|
5882
6857
|
const presenceColor = getReviewPresenceColor(
|
|
5883
6858
|
normalizedReviewUserId || presenceSessionId
|
|
5884
6859
|
);
|
|
5885
|
-
const presenceViewport =
|
|
6860
|
+
const presenceViewport = useMemo3(
|
|
5886
6861
|
() => ({
|
|
5887
6862
|
label: size.label,
|
|
5888
6863
|
width: size.width,
|
|
@@ -5892,7 +6867,7 @@ var useReviewPresence = ({
|
|
|
5892
6867
|
[size]
|
|
5893
6868
|
);
|
|
5894
6869
|
const presenceStatus = mode === "idle" ? "reviewing" : "editing";
|
|
5895
|
-
const visiblePresenceUsers =
|
|
6870
|
+
const visiblePresenceUsers = useMemo3(
|
|
5896
6871
|
() => {
|
|
5897
6872
|
const projectPresenceUsers = presenceUsers.filter(
|
|
5898
6873
|
(user) => user.projectId === projectId && user.userId.trim()
|
|
@@ -5904,14 +6879,14 @@ var useReviewPresence = ({
|
|
|
5904
6879
|
},
|
|
5905
6880
|
[presenceUsers, projectId, reviewPathPrefix]
|
|
5906
6881
|
);
|
|
5907
|
-
const currentPagePresenceUsers =
|
|
6882
|
+
const currentPagePresenceUsers = useMemo3(
|
|
5908
6883
|
() => visiblePresenceUsers.filter((user) => {
|
|
5909
6884
|
const userTarget = getPresenceUserTarget(user, reviewPathPrefix);
|
|
5910
6885
|
return userTarget === activeRoute;
|
|
5911
6886
|
}),
|
|
5912
6887
|
[activeRoute, reviewPathPrefix, visiblePresenceUsers]
|
|
5913
6888
|
);
|
|
5914
|
-
const pagePresenceUsers =
|
|
6889
|
+
const pagePresenceUsers = useMemo3(() => {
|
|
5915
6890
|
const usersByTarget = /* @__PURE__ */ new Map();
|
|
5916
6891
|
visiblePresenceUsers.forEach((user) => {
|
|
5917
6892
|
const userTarget = getPresenceUserTarget(user, reviewPathPrefix);
|
|
@@ -5952,7 +6927,7 @@ var useReviewPresence = ({
|
|
|
5952
6927
|
source
|
|
5953
6928
|
]
|
|
5954
6929
|
);
|
|
5955
|
-
const getCurrentPresenceStateRef =
|
|
6930
|
+
const getCurrentPresenceStateRef = useRef2(getCurrentPresenceState);
|
|
5956
6931
|
getCurrentPresenceStateRef.current = getCurrentPresenceState;
|
|
5957
6932
|
useEffect5(() => {
|
|
5958
6933
|
if (!presence || !normalizedReviewUserId) {
|
|
@@ -6024,16 +6999,16 @@ var useReviewPresence = ({
|
|
|
6024
6999
|
import {
|
|
6025
7000
|
useCallback as useCallback8,
|
|
6026
7001
|
useEffect as useEffect7,
|
|
6027
|
-
useState as
|
|
7002
|
+
useState as useState6
|
|
6028
7003
|
} from "react";
|
|
6029
7004
|
|
|
6030
7005
|
// src/react-shell/hooks/use.review.ruler.drag.ts
|
|
6031
7006
|
import {
|
|
6032
7007
|
useCallback as useCallback7,
|
|
6033
7008
|
useEffect as useEffect6,
|
|
6034
|
-
useMemo as
|
|
6035
|
-
useRef as
|
|
6036
|
-
useState as
|
|
7009
|
+
useMemo as useMemo4,
|
|
7010
|
+
useRef as useRef3,
|
|
7011
|
+
useState as useState5
|
|
6037
7012
|
} from "react";
|
|
6038
7013
|
|
|
6039
7014
|
// src/react-shell/ruler/ruler.ts
|
|
@@ -6063,15 +7038,15 @@ var useReviewRulerDrag = ({
|
|
|
6063
7038
|
size,
|
|
6064
7039
|
targetSrc
|
|
6065
7040
|
}) => {
|
|
6066
|
-
const rulerOverlayRef =
|
|
6067
|
-
const rulerDragRectRef =
|
|
6068
|
-
const isRulerDraggingRef =
|
|
6069
|
-
const sizeRef =
|
|
6070
|
-
const [rulerStart, setRulerStart] =
|
|
6071
|
-
const [rulerPoint, setRulerPoint] =
|
|
6072
|
-
const [rulerHover, setRulerHover] =
|
|
6073
|
-
const [isRulerDragging, setIsRulerDragging] =
|
|
6074
|
-
const rulerMeasure =
|
|
7041
|
+
const rulerOverlayRef = useRef3(null);
|
|
7042
|
+
const rulerDragRectRef = useRef3(null);
|
|
7043
|
+
const isRulerDraggingRef = useRef3(false);
|
|
7044
|
+
const sizeRef = useRef3(size);
|
|
7045
|
+
const [rulerStart, setRulerStart] = useState5(null);
|
|
7046
|
+
const [rulerPoint, setRulerPoint] = useState5(null);
|
|
7047
|
+
const [rulerHover, setRulerHover] = useState5(null);
|
|
7048
|
+
const [isRulerDragging, setIsRulerDragging] = useState5(false);
|
|
7049
|
+
const rulerMeasure = useMemo4(
|
|
6075
7050
|
() => getRulerMeasure(rulerStart, rulerPoint),
|
|
6076
7051
|
[rulerPoint, rulerStart]
|
|
6077
7052
|
);
|
|
@@ -6240,7 +7215,7 @@ var useReviewRuler = ({
|
|
|
6240
7215
|
onCancelReviewMode,
|
|
6241
7216
|
onCloseTransientPanels
|
|
6242
7217
|
}) => {
|
|
6243
|
-
const [isRulerVisible, setIsRulerVisible] =
|
|
7218
|
+
const [isRulerVisible, setIsRulerVisible] = useState6(false);
|
|
6244
7219
|
const isRulerAvailable = ruler?.enabled !== false && typeof size.designWidth === "number" && size.designWidth > 0;
|
|
6245
7220
|
const rulerUnit = ruler?.unit ?? "px";
|
|
6246
7221
|
const rulerScaleX = isRulerAvailable && size.designWidth ? size.width / size.designWidth : 1;
|
|
@@ -6300,25 +7275,25 @@ var useReviewRuler = ({
|
|
|
6300
7275
|
};
|
|
6301
7276
|
|
|
6302
7277
|
// src/react-shell/hooks/use.review.settings.ts
|
|
6303
|
-
import { useCallback as useCallback9, useEffect as useEffect8, useState as
|
|
7278
|
+
import { useCallback as useCallback9, useEffect as useEffect8, useState as useState7 } from "react";
|
|
6304
7279
|
var useReviewSettings = ({
|
|
6305
7280
|
onCancelReviewMode,
|
|
6306
7281
|
onCloseInitialPrompt,
|
|
6307
7282
|
onCloseSitemap,
|
|
6308
7283
|
onReloadTargetFrame
|
|
6309
7284
|
}) => {
|
|
6310
|
-
const [figmaTokenDraft, setFigmaTokenDraft] =
|
|
6311
|
-
const [reviewUserId, setReviewUserId] =
|
|
6312
|
-
const [reviewUserIdDraft, setReviewUserIdDraft] =
|
|
7285
|
+
const [figmaTokenDraft, setFigmaTokenDraft] = useState7(getStoredFigmaToken);
|
|
7286
|
+
const [reviewUserId, setReviewUserId] = useState7(getStoredReviewUserId);
|
|
7287
|
+
const [reviewUserIdDraft, setReviewUserIdDraft] = useState7(
|
|
6313
7288
|
getStoredReviewUserId
|
|
6314
7289
|
);
|
|
6315
|
-
const [reviewTheme, setReviewTheme] =
|
|
6316
|
-
const [reviewThemeDraft, setReviewThemeDraft] =
|
|
6317
|
-
const [systemReviewTheme, setSystemReviewTheme] =
|
|
6318
|
-
const [figmaSettingsStatus, setFigmaSettingsStatus] =
|
|
6319
|
-
const [isFigmaSettingsOpen, setIsFigmaSettingsOpen] =
|
|
6320
|
-
const [isFigmaTokenVisible, setIsFigmaTokenVisible] =
|
|
6321
|
-
const [isFigmaTokenGuideOpen, setIsFigmaTokenGuideOpen] =
|
|
7290
|
+
const [reviewTheme, setReviewTheme] = useState7(getStoredReviewTheme);
|
|
7291
|
+
const [reviewThemeDraft, setReviewThemeDraft] = useState7(getStoredReviewTheme);
|
|
7292
|
+
const [systemReviewTheme, setSystemReviewTheme] = useState7(getSystemReviewTheme);
|
|
7293
|
+
const [figmaSettingsStatus, setFigmaSettingsStatus] = useState7("");
|
|
7294
|
+
const [isFigmaSettingsOpen, setIsFigmaSettingsOpen] = useState7(false);
|
|
7295
|
+
const [isFigmaTokenVisible, setIsFigmaTokenVisible] = useState7(false);
|
|
7296
|
+
const [isFigmaTokenGuideOpen, setIsFigmaTokenGuideOpen] = useState7(false);
|
|
6322
7297
|
const effectiveReviewTheme = reviewTheme === "system" ? systemReviewTheme : reviewTheme;
|
|
6323
7298
|
const closeFigmaSettings = useCallback9(() => {
|
|
6324
7299
|
setIsFigmaSettingsOpen(false);
|
|
@@ -6420,13 +7395,12 @@ var useReviewSettings = ({
|
|
|
6420
7395
|
};
|
|
6421
7396
|
|
|
6422
7397
|
// src/react-shell/hooks/use.review.shell.data.ts
|
|
6423
|
-
import { useCallback as useCallback10, useMemo as
|
|
6424
|
-
var
|
|
6425
|
-
local: 0,
|
|
6426
|
-
remote: 0
|
|
6427
|
-
});
|
|
7398
|
+
import { useCallback as useCallback10, useMemo as useMemo5, useState as useState8 } from "react";
|
|
7399
|
+
var SITEMAP_STATUS_DONE = "done";
|
|
6428
7400
|
var useReviewShellData = ({
|
|
6429
7401
|
activeRoute,
|
|
7402
|
+
isAllQaVisible,
|
|
7403
|
+
isRemoteSource,
|
|
6430
7404
|
pages,
|
|
6431
7405
|
reviewPathPrefix,
|
|
6432
7406
|
reviewViewportPresets,
|
|
@@ -6435,59 +7409,112 @@ var useReviewShellData = ({
|
|
|
6435
7409
|
target,
|
|
6436
7410
|
viewportPresets
|
|
6437
7411
|
}) => {
|
|
6438
|
-
const [items, setItems] =
|
|
6439
|
-
const [hiddenOverlayItemIds, setHiddenOverlayItemIds] =
|
|
7412
|
+
const [items, setItems] = useState8([]);
|
|
7413
|
+
const [hiddenOverlayItemIds, setHiddenOverlayItemIds] = useState8(
|
|
6440
7414
|
() => /* @__PURE__ */ new Set()
|
|
6441
7415
|
);
|
|
6442
|
-
const [qaFilter, setQaFilter] =
|
|
6443
|
-
const [
|
|
7416
|
+
const [qaFilter, setQaFilter] = useState8("all");
|
|
7417
|
+
const [qaStatusFilter, setQaStatusFilter] = useState8("all");
|
|
7418
|
+
const [sitemapItems, setSitemapItems] = useState8(() => ({
|
|
6444
7419
|
local: [],
|
|
6445
7420
|
remote: []
|
|
6446
7421
|
}));
|
|
6447
|
-
const targetSrc =
|
|
6448
|
-
const pageTargets =
|
|
7422
|
+
const targetSrc = useMemo5(() => buildTargetSrc(target), [target]);
|
|
7423
|
+
const pageTargets = useMemo5(
|
|
6449
7424
|
() => new Set(
|
|
6450
7425
|
pages.map((page) => normalizeTarget(page.href, reviewPathPrefix))
|
|
6451
7426
|
),
|
|
6452
7427
|
[pages, reviewPathPrefix]
|
|
6453
7428
|
);
|
|
6454
|
-
const
|
|
6455
|
-
() =>
|
|
6456
|
-
[
|
|
7429
|
+
const sitemapSourceItems = useMemo5(
|
|
7430
|
+
() => isRemoteSource ? sitemapItems.remote : sitemapItems.local,
|
|
7431
|
+
[isRemoteSource, sitemapItems]
|
|
7432
|
+
);
|
|
7433
|
+
const activeItems = useMemo5(
|
|
7434
|
+
() => {
|
|
7435
|
+
const sourceItems = isAllQaVisible ? sitemapSourceItems : items.filter(
|
|
7436
|
+
(item) => getItemTarget(item, reviewPathPrefix) === activeRoute
|
|
7437
|
+
);
|
|
7438
|
+
return [...sourceItems].sort(
|
|
7439
|
+
(a, b) => b.createdAt.localeCompare(a.createdAt)
|
|
7440
|
+
);
|
|
7441
|
+
},
|
|
7442
|
+
[activeRoute, isAllQaVisible, items, reviewPathPrefix, sitemapSourceItems]
|
|
6457
7443
|
);
|
|
6458
|
-
const numberedActiveItems =
|
|
7444
|
+
const numberedActiveItems = useMemo5(
|
|
6459
7445
|
() => getNumberedReviewItems(activeItems, reviewViewportPresets),
|
|
6460
7446
|
[activeItems, reviewViewportPresets]
|
|
6461
7447
|
);
|
|
6462
|
-
const
|
|
7448
|
+
const scopeFilteredNumberedActiveItems = useMemo5(
|
|
6463
7449
|
() => qaFilter === "all" ? numberedActiveItems : numberedActiveItems.filter(
|
|
6464
7450
|
(numberedItem) => numberedItem.scope === qaFilter
|
|
6465
7451
|
),
|
|
6466
7452
|
[numberedActiveItems, qaFilter]
|
|
6467
7453
|
);
|
|
6468
|
-
const
|
|
7454
|
+
const statusFilteredNumberedActiveItems = useMemo5(
|
|
7455
|
+
() => qaStatusFilter === "all" ? numberedActiveItems : numberedActiveItems.filter(
|
|
7456
|
+
(numberedItem) => normalizeReviewItemStatus(numberedItem.item.status) === qaStatusFilter
|
|
7457
|
+
),
|
|
7458
|
+
[numberedActiveItems, qaStatusFilter]
|
|
7459
|
+
);
|
|
7460
|
+
const filteredNumberedActiveItems = useMemo5(
|
|
7461
|
+
() => qaStatusFilter === "all" ? scopeFilteredNumberedActiveItems : scopeFilteredNumberedActiveItems.filter(
|
|
7462
|
+
(numberedItem) => normalizeReviewItemStatus(numberedItem.item.status) === qaStatusFilter
|
|
7463
|
+
),
|
|
7464
|
+
[qaStatusFilter, scopeFilteredNumberedActiveItems]
|
|
7465
|
+
);
|
|
7466
|
+
const hiddenOverlayItemIdList = useMemo5(
|
|
6469
7467
|
() => Array.from(hiddenOverlayItemIds),
|
|
6470
7468
|
[hiddenOverlayItemIds]
|
|
6471
7469
|
);
|
|
6472
|
-
const qaFilterCounts =
|
|
7470
|
+
const qaFilterCounts = useMemo5(() => {
|
|
6473
7471
|
const counts = /* @__PURE__ */ new Map();
|
|
6474
|
-
counts.set("all",
|
|
6475
|
-
|
|
7472
|
+
counts.set("all", statusFilteredNumberedActiveItems.length);
|
|
7473
|
+
statusFilteredNumberedActiveItems.forEach((numberedItem) => {
|
|
6476
7474
|
counts.set(numberedItem.scope, (counts.get(numberedItem.scope) ?? 0) + 1);
|
|
6477
7475
|
});
|
|
6478
7476
|
return counts;
|
|
6479
|
-
}, [
|
|
6480
|
-
const
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
7477
|
+
}, [statusFilteredNumberedActiveItems]);
|
|
7478
|
+
const qaStatusFilterCounts = useMemo5(() => {
|
|
7479
|
+
const counts = /* @__PURE__ */ new Map();
|
|
7480
|
+
counts.set("all", scopeFilteredNumberedActiveItems.length);
|
|
7481
|
+
scopeFilteredNumberedActiveItems.forEach((numberedItem) => {
|
|
7482
|
+
const status = normalizeReviewItemStatus(numberedItem.item.status);
|
|
7483
|
+
counts.set(status, (counts.get(status) ?? 0) + 1);
|
|
7484
|
+
});
|
|
7485
|
+
return counts;
|
|
7486
|
+
}, [scopeFilteredNumberedActiveItems]);
|
|
7487
|
+
const getItemPreset = useCallback10(
|
|
7488
|
+
(item) => findViewportPreset(
|
|
7489
|
+
viewportPresets,
|
|
7490
|
+
item.viewport?.width ?? 0,
|
|
7491
|
+
item.viewport?.height ?? 0
|
|
6487
7492
|
),
|
|
6488
7493
|
[viewportPresets]
|
|
6489
7494
|
);
|
|
6490
|
-
const
|
|
7495
|
+
const getItemPresetScope = useCallback10(
|
|
7496
|
+
(item) => getViewportPresetKind(getItemPreset(item)),
|
|
7497
|
+
[getItemPreset]
|
|
7498
|
+
);
|
|
7499
|
+
const getItemPresetColumn = useCallback10(
|
|
7500
|
+
(item) => {
|
|
7501
|
+
const preset = getItemPreset(item);
|
|
7502
|
+
const presetIndex = Math.max(0, viewportPresets.indexOf(preset));
|
|
7503
|
+
return createSitemapViewportColumn(preset, presetIndex);
|
|
7504
|
+
},
|
|
7505
|
+
[getItemPreset, viewportPresets]
|
|
7506
|
+
);
|
|
7507
|
+
const getItemCountScope = useCallback10(
|
|
7508
|
+
(item) => item.scope === "dom" ? "dom" : getItemPresetScope(item),
|
|
7509
|
+
[getItemPresetScope]
|
|
7510
|
+
);
|
|
7511
|
+
const activeRemainingItemCount = useMemo5(
|
|
7512
|
+
() => activeItems.filter(
|
|
7513
|
+
(item) => normalizeReviewItemStatus(item.status) !== SITEMAP_STATUS_DONE
|
|
7514
|
+
).length,
|
|
7515
|
+
[activeItems]
|
|
7516
|
+
);
|
|
7517
|
+
const presetScopeCounts = useMemo5(() => {
|
|
6491
7518
|
const counts = /* @__PURE__ */ new Map();
|
|
6492
7519
|
activeItems.forEach((item) => {
|
|
6493
7520
|
const scope = getItemPresetScope(item);
|
|
@@ -6496,7 +7523,7 @@ var useReviewShellData = ({
|
|
|
6496
7523
|
return counts;
|
|
6497
7524
|
}, [activeItems, getItemPresetScope]);
|
|
6498
7525
|
const currentPresetScope = getViewportPresetKind(size);
|
|
6499
|
-
const pageQaCounts =
|
|
7526
|
+
const pageQaCounts = useMemo5(() => {
|
|
6500
7527
|
const counts = /* @__PURE__ */ new Map();
|
|
6501
7528
|
const addItems = (sourceKey, sourceItems) => {
|
|
6502
7529
|
sourceItems.forEach((item) => {
|
|
@@ -6504,16 +7531,48 @@ var useReviewShellData = ({
|
|
|
6504
7531
|
getItemTarget(item, reviewPathPrefix),
|
|
6505
7532
|
reviewPathPrefix
|
|
6506
7533
|
);
|
|
6507
|
-
const
|
|
6508
|
-
|
|
6509
|
-
|
|
7534
|
+
const currentCount = counts.get(pageTarget) ?? createEmptySitemapQaCount();
|
|
7535
|
+
const status = normalizeReviewItemStatus(item.status);
|
|
7536
|
+
const scope = getItemCountScope(item);
|
|
7537
|
+
const viewportColumn = getItemPresetColumn(item);
|
|
7538
|
+
const currentViewportCount = currentCount.viewport[viewportColumn.key] ?? { total: 0, remaining: 0 };
|
|
7539
|
+
const isRemaining = status !== SITEMAP_STATUS_DONE;
|
|
7540
|
+
counts.set(pageTarget, {
|
|
7541
|
+
...currentCount,
|
|
7542
|
+
total: currentCount.total + 1,
|
|
7543
|
+
remaining: isRemaining ? currentCount.remaining + 1 : currentCount.remaining,
|
|
7544
|
+
local: currentCount.local + (sourceKey === "local" ? 1 : 0),
|
|
7545
|
+
remote: currentCount.remote + (sourceKey === "remote" ? 1 : 0),
|
|
7546
|
+
status: {
|
|
7547
|
+
...currentCount.status,
|
|
7548
|
+
[status]: currentCount.status[status] + 1
|
|
7549
|
+
},
|
|
7550
|
+
scope: {
|
|
7551
|
+
...currentCount.scope,
|
|
7552
|
+
[scope]: (currentCount.scope[scope] ?? 0) + 1
|
|
7553
|
+
},
|
|
7554
|
+
viewport: {
|
|
7555
|
+
...currentCount.viewport,
|
|
7556
|
+
[viewportColumn.key]: {
|
|
7557
|
+
total: currentViewportCount.total + 1,
|
|
7558
|
+
remaining: isRemaining ? currentViewportCount.remaining + 1 : currentViewportCount.remaining
|
|
7559
|
+
}
|
|
7560
|
+
}
|
|
7561
|
+
});
|
|
6510
7562
|
});
|
|
6511
7563
|
};
|
|
6512
7564
|
addItems("local", sitemapItems.local);
|
|
6513
7565
|
addItems("remote", sitemapItems.remote);
|
|
6514
7566
|
return counts;
|
|
6515
|
-
}, [reviewPathPrefix, sitemapItems]);
|
|
6516
|
-
const
|
|
7567
|
+
}, [getItemCountScope, getItemPresetColumn, reviewPathPrefix, sitemapItems]);
|
|
7568
|
+
const allQaCount = useMemo5(
|
|
7569
|
+
() => Array.from(pageQaCounts.values()).reduce(
|
|
7570
|
+
addSitemapQaCounts,
|
|
7571
|
+
createEmptySitemapQaCount()
|
|
7572
|
+
),
|
|
7573
|
+
[pageQaCounts]
|
|
7574
|
+
);
|
|
7575
|
+
const selectedNumberedItem = useMemo5(
|
|
6517
7576
|
() => selectedItemId ? numberedActiveItems.find(
|
|
6518
7577
|
(numberedItem) => numberedItem.item.id === selectedItemId
|
|
6519
7578
|
) : void 0,
|
|
@@ -6521,6 +7580,8 @@ var useReviewShellData = ({
|
|
|
6521
7580
|
);
|
|
6522
7581
|
return {
|
|
6523
7582
|
activeItems,
|
|
7583
|
+
activeRemainingItemCount,
|
|
7584
|
+
allQaCount,
|
|
6524
7585
|
currentPresetScope,
|
|
6525
7586
|
filteredNumberedActiveItems,
|
|
6526
7587
|
getItemPresetScope,
|
|
@@ -6531,10 +7592,13 @@ var useReviewShellData = ({
|
|
|
6531
7592
|
presetScopeCounts,
|
|
6532
7593
|
qaFilter,
|
|
6533
7594
|
qaFilterCounts,
|
|
7595
|
+
qaStatusFilter,
|
|
7596
|
+
qaStatusFilterCounts,
|
|
6534
7597
|
selectedNumberedItem,
|
|
6535
7598
|
setHiddenOverlayItemIds,
|
|
6536
7599
|
setItems,
|
|
6537
7600
|
setQaFilter,
|
|
7601
|
+
setQaStatusFilter,
|
|
6538
7602
|
setSitemapItems,
|
|
6539
7603
|
targetSrc
|
|
6540
7604
|
};
|
|
@@ -6635,9 +7699,9 @@ var useReviewShellHotkeys = ({
|
|
|
6635
7699
|
|
|
6636
7700
|
// src/react-shell/hooks/use.review.shell.state.ts
|
|
6637
7701
|
import {
|
|
6638
|
-
useMemo as
|
|
6639
|
-
useRef as
|
|
6640
|
-
useState as
|
|
7702
|
+
useMemo as useMemo6,
|
|
7703
|
+
useRef as useRef4,
|
|
7704
|
+
useState as useState9
|
|
6641
7705
|
} from "react";
|
|
6642
7706
|
|
|
6643
7707
|
// src/react-shell/adapters.ts
|
|
@@ -6782,11 +7846,11 @@ var useReviewShellState = ({
|
|
|
6782
7846
|
reviewPathPrefix
|
|
6783
7847
|
}) => {
|
|
6784
7848
|
const viewportPresets = presets.length > 0 ? presets : DEFAULT_REVIEW_VIEWPORT_PRESETS;
|
|
6785
|
-
const reviewViewportPresets =
|
|
7849
|
+
const reviewViewportPresets = useMemo6(
|
|
6786
7850
|
() => toReviewViewportPresets(viewportPresets),
|
|
6787
7851
|
[viewportPresets]
|
|
6788
7852
|
);
|
|
6789
|
-
const normalizedAdapters =
|
|
7853
|
+
const normalizedAdapters = useMemo6(
|
|
6790
7854
|
() => normalizeReviewShellAdapters(adapters),
|
|
6791
7855
|
[adapters]
|
|
6792
7856
|
);
|
|
@@ -6794,7 +7858,7 @@ var useReviewShellState = ({
|
|
|
6794
7858
|
const remoteAdapterEntry = normalizedAdapters.remote;
|
|
6795
7859
|
const sourceEntries = normalizedAdapters.sources;
|
|
6796
7860
|
const defaultSource = sourceEntries[0]?.label ?? "local";
|
|
6797
|
-
const [source, setSource] =
|
|
7861
|
+
const [source, setSource] = useState9(() => {
|
|
6798
7862
|
const initialSource = getInitialSource(remoteAdapterEntry?.label);
|
|
6799
7863
|
return sourceEntries.some((entry) => entry.label === initialSource) ? initialSource : defaultSource;
|
|
6800
7864
|
});
|
|
@@ -6807,40 +7871,40 @@ var useReviewShellState = ({
|
|
|
6807
7871
|
const canWriteArea = activeAdapterEntry.writeModes.includes("area");
|
|
6808
7872
|
const canWriteDom = activeAdapterEntry.writeModes.includes("dom");
|
|
6809
7873
|
const adapter = activeAdapterEntry.adapter;
|
|
6810
|
-
const iframeRef =
|
|
6811
|
-
const frameScrollRef =
|
|
6812
|
-
const controllerRef =
|
|
6813
|
-
const cleanupTargetRef =
|
|
6814
|
-
const pendingRestoreRef =
|
|
6815
|
-
const pendingInitialItemIdRef =
|
|
6816
|
-
const selectedItemIdRef =
|
|
6817
|
-
const hiddenOverlayItemIdListRef =
|
|
6818
|
-
const [target, setTarget] =
|
|
7874
|
+
const iframeRef = useRef4(null);
|
|
7875
|
+
const frameScrollRef = useRef4(null);
|
|
7876
|
+
const controllerRef = useRef4(null);
|
|
7877
|
+
const cleanupTargetRef = useRef4(null);
|
|
7878
|
+
const pendingRestoreRef = useRef4(null);
|
|
7879
|
+
const pendingInitialItemIdRef = useRef4(getInitialItemId());
|
|
7880
|
+
const selectedItemIdRef = useRef4(getInitialItemId());
|
|
7881
|
+
const hiddenOverlayItemIdListRef = useRef4([]);
|
|
7882
|
+
const [target, setTarget] = useState9(
|
|
6819
7883
|
() => getInitialTarget(reviewPathPrefix)
|
|
6820
7884
|
);
|
|
6821
|
-
const [draftTarget, setDraftTarget] =
|
|
7885
|
+
const [draftTarget, setDraftTarget] = useState9(
|
|
6822
7886
|
() => getInitialTarget(reviewPathPrefix)
|
|
6823
7887
|
);
|
|
6824
|
-
const [activeRoute, setActiveRoute] =
|
|
7888
|
+
const [activeRoute, setActiveRoute] = useState9(
|
|
6825
7889
|
() => getInitialTarget(reviewPathPrefix)
|
|
6826
7890
|
);
|
|
6827
|
-
const [size, setSize] =
|
|
7891
|
+
const [size, setSize] = useState9(
|
|
6828
7892
|
() => getInitialSize(viewportPresets)
|
|
6829
7893
|
);
|
|
6830
|
-
const [mode, setMode] =
|
|
6831
|
-
const [targetOverlayState, setTargetOverlayState] =
|
|
7894
|
+
const [mode, setMode] = useState9("idle");
|
|
7895
|
+
const [targetOverlayState, setTargetOverlayState] = useState9({
|
|
6832
7896
|
grid: false,
|
|
6833
7897
|
figma: false
|
|
6834
7898
|
});
|
|
6835
|
-
const [selectedItemId, setSelectedItemId] =
|
|
6836
|
-
const [isListVisible, setIsListVisible] =
|
|
6837
|
-
const [isSitemapOpen, setIsSitemapOpen] =
|
|
6838
|
-
const [isInitialPromptOpen, setIsInitialPromptOpen] =
|
|
6839
|
-
const [copyLabel, setCopyLabel] =
|
|
6840
|
-
const [toastMessage, setToastMessage] =
|
|
6841
|
-
const [copiedPromptKey, setCopiedPromptKey] =
|
|
6842
|
-
const targetRef =
|
|
6843
|
-
const sizeRef =
|
|
7899
|
+
const [selectedItemId, setSelectedItemId] = useState9(getInitialItemId());
|
|
7900
|
+
const [isListVisible, setIsListVisible] = useState9(true);
|
|
7901
|
+
const [isSitemapOpen, setIsSitemapOpen] = useState9(false);
|
|
7902
|
+
const [isInitialPromptOpen, setIsInitialPromptOpen] = useState9(false);
|
|
7903
|
+
const [copyLabel, setCopyLabel] = useState9("Copy URL");
|
|
7904
|
+
const [toastMessage, setToastMessage] = useState9("");
|
|
7905
|
+
const [copiedPromptKey, setCopiedPromptKey] = useState9(null);
|
|
7906
|
+
const targetRef = useRef4(target);
|
|
7907
|
+
const sizeRef = useRef4(size);
|
|
6844
7908
|
const isFigmaOverlayAvailable = getIsFigmaOverlayAvailable(size);
|
|
6845
7909
|
return {
|
|
6846
7910
|
activeAdapterEntry,
|
|
@@ -7130,12 +8194,15 @@ var removeReviewItem = async ({
|
|
|
7130
8194
|
};
|
|
7131
8195
|
|
|
7132
8196
|
// src/react-shell/review/shell.tsx
|
|
7133
|
-
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
8197
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
7134
8198
|
var getReviewModeWriteMode = (mode) => {
|
|
7135
8199
|
if (mode === "element") return "dom";
|
|
7136
8200
|
if (mode === "note" || mode === "area") return mode;
|
|
7137
8201
|
return null;
|
|
7138
8202
|
};
|
|
8203
|
+
var SOURCE_PANEL_MAX_WIDTH = 440;
|
|
8204
|
+
var SOURCE_PANEL_MIN_WIDTH = 240;
|
|
8205
|
+
var SOURCE_PANEL_MAX_HEIGHT = 260;
|
|
7139
8206
|
var ReviewShell = ({
|
|
7140
8207
|
projectId,
|
|
7141
8208
|
pages,
|
|
@@ -7143,8 +8210,10 @@ var ReviewShell = ({
|
|
|
7143
8210
|
presets = DEFAULT_REVIEW_VIEWPORT_PRESETS,
|
|
7144
8211
|
ruler,
|
|
7145
8212
|
initialPrompt = DEFAULT_INITIAL_REVIEW_PROMPT,
|
|
8213
|
+
adjustmentLabel,
|
|
7146
8214
|
reviewPathPrefix = DEFAULT_REVIEW_PATH_PREFIX,
|
|
7147
8215
|
sourceRoot,
|
|
8216
|
+
sourceInspector,
|
|
7148
8217
|
presence
|
|
7149
8218
|
}) => {
|
|
7150
8219
|
const {
|
|
@@ -7161,7 +8230,7 @@ var ReviewShell = ({
|
|
|
7161
8230
|
frameScrollRef,
|
|
7162
8231
|
hiddenOverlayItemIdListRef,
|
|
7163
8232
|
iframeRef,
|
|
7164
|
-
isFigmaOverlayAvailable,
|
|
8233
|
+
isFigmaOverlayAvailable: isViewportFigmaOverlayAvailable,
|
|
7165
8234
|
isInitialPromptOpen,
|
|
7166
8235
|
isListVisible,
|
|
7167
8236
|
isRemoteSource,
|
|
@@ -7203,9 +8272,22 @@ var ReviewShell = ({
|
|
|
7203
8272
|
presets,
|
|
7204
8273
|
reviewPathPrefix
|
|
7205
8274
|
});
|
|
7206
|
-
const sourceShortcutCleanupRef =
|
|
8275
|
+
const sourceShortcutCleanupRef = useRef5(null);
|
|
8276
|
+
const sourceInspectorInteractionRef = useRef5(false);
|
|
8277
|
+
const [sourceInspectorState, setSourceInspectorState] = useState10(null);
|
|
8278
|
+
const [isAllQaVisible, setIsAllQaVisible] = useState10(false);
|
|
8279
|
+
const sourceOpenOptions = useMemo7(
|
|
8280
|
+
() => ({
|
|
8281
|
+
...sourceInspector,
|
|
8282
|
+
sourceRoot
|
|
8283
|
+
}),
|
|
8284
|
+
[sourceInspector, sourceRoot]
|
|
8285
|
+
);
|
|
8286
|
+
const isSourceInspectorEnabled = sourceInspector?.enabled !== false;
|
|
7207
8287
|
const {
|
|
7208
8288
|
activeItems,
|
|
8289
|
+
activeRemainingItemCount,
|
|
8290
|
+
allQaCount,
|
|
7209
8291
|
currentPresetScope,
|
|
7210
8292
|
filteredNumberedActiveItems,
|
|
7211
8293
|
getItemPresetScope,
|
|
@@ -7216,14 +8298,19 @@ var ReviewShell = ({
|
|
|
7216
8298
|
presetScopeCounts,
|
|
7217
8299
|
qaFilter,
|
|
7218
8300
|
qaFilterCounts,
|
|
8301
|
+
qaStatusFilter,
|
|
8302
|
+
qaStatusFilterCounts,
|
|
7219
8303
|
selectedNumberedItem,
|
|
7220
8304
|
setHiddenOverlayItemIds,
|
|
7221
8305
|
setItems,
|
|
7222
8306
|
setQaFilter,
|
|
8307
|
+
setQaStatusFilter,
|
|
7223
8308
|
setSitemapItems,
|
|
7224
8309
|
targetSrc
|
|
7225
8310
|
} = useReviewShellData({
|
|
7226
8311
|
activeRoute,
|
|
8312
|
+
isAllQaVisible,
|
|
8313
|
+
isRemoteSource,
|
|
7227
8314
|
pages,
|
|
7228
8315
|
reviewPathPrefix,
|
|
7229
8316
|
reviewViewportPresets,
|
|
@@ -7232,7 +8319,14 @@ var ReviewShell = ({
|
|
|
7232
8319
|
target,
|
|
7233
8320
|
viewportPresets
|
|
7234
8321
|
});
|
|
7235
|
-
const [
|
|
8322
|
+
const [targetFigmaState, setTargetFigmaState] = useState10(null);
|
|
8323
|
+
const targetFigmaConfig = targetFigmaState?.targetSrc === targetSrc ? targetFigmaState.config : null;
|
|
8324
|
+
const figmaFrameUrl = useMemo7(
|
|
8325
|
+
() => getFigmaFrameUrl(targetFigmaConfig, size),
|
|
8326
|
+
[targetFigmaConfig, size]
|
|
8327
|
+
);
|
|
8328
|
+
const isFigmaOverlayAvailable = isViewportFigmaOverlayAvailable && Boolean(targetFigmaConfig);
|
|
8329
|
+
const [editingItem, setEditingItem] = useState10(null);
|
|
7236
8330
|
const initialPromptText = initialPrompt.trim();
|
|
7237
8331
|
const refreshItems = useCallback11(
|
|
7238
8332
|
() => refreshReviewItems({
|
|
@@ -7341,7 +8435,6 @@ var ReviewShell = ({
|
|
|
7341
8435
|
});
|
|
7342
8436
|
const {
|
|
7343
8437
|
clearSelectedItem,
|
|
7344
|
-
closeTargetOverlay,
|
|
7345
8438
|
initReviewKit,
|
|
7346
8439
|
reloadReviewKit,
|
|
7347
8440
|
restoreReviewItem,
|
|
@@ -7365,6 +8458,7 @@ var ReviewShell = ({
|
|
|
7365
8458
|
reviewUserId,
|
|
7366
8459
|
reviewViewportPresets,
|
|
7367
8460
|
ruler,
|
|
8461
|
+
adjustmentLabel,
|
|
7368
8462
|
selectedItemIdRef,
|
|
7369
8463
|
size,
|
|
7370
8464
|
sizeRef,
|
|
@@ -7430,18 +8524,39 @@ var ReviewShell = ({
|
|
|
7430
8524
|
window.clearTimeout(transitionTimeout);
|
|
7431
8525
|
};
|
|
7432
8526
|
}, [isListVisible, size.height, size.width, syncTargetViewport, targetSrc]);
|
|
7433
|
-
const applyTarget = () => {
|
|
7434
|
-
const
|
|
8527
|
+
const applyTarget = async () => {
|
|
8528
|
+
const parsedInput = parseReviewAddressInput(draftTarget, reviewPathPrefix);
|
|
8529
|
+
const normalizedTarget = parsedInput.target;
|
|
8530
|
+
const nextSource = parsedInput.source && sourceEntries.some((entry) => entry.label === parsedInput.source) ? parsedInput.source : source;
|
|
8531
|
+
const nextSize = parsedInput.width && parsedInput.height ? findViewportPreset(
|
|
8532
|
+
viewportPresets,
|
|
8533
|
+
parsedInput.width,
|
|
8534
|
+
parsedInput.height
|
|
8535
|
+
) : sizeRef.current;
|
|
8536
|
+
const nextAdapter = sourceEntries.find((entry) => entry.label === nextSource) ?? activeAdapterEntry;
|
|
8537
|
+
if (parsedInput.itemId) {
|
|
8538
|
+
const item = await nextAdapter.adapter.get(parsedInput.itemId);
|
|
8539
|
+
if (item) {
|
|
8540
|
+
setIsAllQaVisible(false);
|
|
8541
|
+
setSource(nextSource);
|
|
8542
|
+
restoreReviewItem(item);
|
|
8543
|
+
return;
|
|
8544
|
+
}
|
|
8545
|
+
}
|
|
7435
8546
|
clearSelectedItem();
|
|
8547
|
+
setIsAllQaVisible(false);
|
|
8548
|
+
setSource(nextSource);
|
|
7436
8549
|
targetRef.current = normalizedTarget;
|
|
7437
8550
|
setActiveRoute(normalizedTarget);
|
|
7438
8551
|
setDraftTarget(normalizedTarget);
|
|
8552
|
+
setSize(nextSize);
|
|
7439
8553
|
setTarget(normalizedTarget);
|
|
7440
|
-
updateShellUrl(normalizedTarget,
|
|
8554
|
+
updateShellUrl(normalizedTarget, nextSize, nextSource);
|
|
7441
8555
|
};
|
|
7442
8556
|
const selectPage = (href) => {
|
|
7443
8557
|
const normalizedTarget = normalizeTarget(href, reviewPathPrefix);
|
|
7444
8558
|
clearSelectedItem();
|
|
8559
|
+
setIsAllQaVisible(false);
|
|
7445
8560
|
targetRef.current = normalizedTarget;
|
|
7446
8561
|
setActiveRoute(normalizedTarget);
|
|
7447
8562
|
setDraftTarget(normalizedTarget);
|
|
@@ -7449,13 +8564,14 @@ var ReviewShell = ({
|
|
|
7449
8564
|
updateShellUrl(normalizedTarget, sizeRef.current, source);
|
|
7450
8565
|
setIsSitemapOpen(false);
|
|
7451
8566
|
};
|
|
8567
|
+
const selectAllQa = () => {
|
|
8568
|
+
setIsAllQaVisible(true);
|
|
8569
|
+
setIsSitemapOpen(false);
|
|
8570
|
+
};
|
|
7452
8571
|
const setReviewMode = (nextMode) => {
|
|
7453
8572
|
const writeMode = getReviewModeWriteMode(nextMode);
|
|
7454
8573
|
if (writeMode && !activeAdapterEntry.writeModes.includes(writeMode)) return;
|
|
7455
8574
|
closeRuler();
|
|
7456
|
-
if (nextMode === "element") {
|
|
7457
|
-
closeTargetOverlay("figma");
|
|
7458
|
-
}
|
|
7459
8575
|
setControllerReviewMode(nextMode);
|
|
7460
8576
|
};
|
|
7461
8577
|
useReviewShellHotkeys({
|
|
@@ -7486,6 +8602,139 @@ var ReviewShell = ({
|
|
|
7486
8602
|
},
|
|
7487
8603
|
[setToastMessage]
|
|
7488
8604
|
);
|
|
8605
|
+
const refreshTargetFigmaConfig = useCallback11(() => {
|
|
8606
|
+
const config = getTargetFigmaFrameConfig(
|
|
8607
|
+
iframeRef.current?.contentWindow
|
|
8608
|
+
);
|
|
8609
|
+
setTargetFigmaState(config ? { targetSrc, config } : null);
|
|
8610
|
+
}, [iframeRef, targetSrc]);
|
|
8611
|
+
useEffect10(() => {
|
|
8612
|
+
const targetDocument = iframeRef.current?.contentDocument;
|
|
8613
|
+
setTargetFigmaOverlayLocked(targetDocument, mode === "element");
|
|
8614
|
+
return () => {
|
|
8615
|
+
setTargetFigmaOverlayLocked(targetDocument, false);
|
|
8616
|
+
};
|
|
8617
|
+
}, [iframeRef, mode, targetSrc]);
|
|
8618
|
+
const clearSourceInspector = useCallback11(() => {
|
|
8619
|
+
sourceInspectorInteractionRef.current = false;
|
|
8620
|
+
setSourceInspectorState(null);
|
|
8621
|
+
}, []);
|
|
8622
|
+
const getSourceInspectorRect = useCallback11(
|
|
8623
|
+
(element) => {
|
|
8624
|
+
const frame = iframeRef.current;
|
|
8625
|
+
if (!frame) return null;
|
|
8626
|
+
const frameRect = frame.getBoundingClientRect();
|
|
8627
|
+
const elementRect = element.getBoundingClientRect();
|
|
8628
|
+
const left = Math.max(frameRect.left, frameRect.left + elementRect.left);
|
|
8629
|
+
const top = Math.max(frameRect.top, frameRect.top + elementRect.top);
|
|
8630
|
+
const right = Math.min(
|
|
8631
|
+
frameRect.right,
|
|
8632
|
+
frameRect.left + elementRect.right
|
|
8633
|
+
);
|
|
8634
|
+
const bottom = Math.min(
|
|
8635
|
+
frameRect.bottom,
|
|
8636
|
+
frameRect.top + elementRect.bottom
|
|
8637
|
+
);
|
|
8638
|
+
return {
|
|
8639
|
+
height: Math.max(2, bottom - top),
|
|
8640
|
+
left,
|
|
8641
|
+
top,
|
|
8642
|
+
width: Math.max(2, right - left)
|
|
8643
|
+
};
|
|
8644
|
+
},
|
|
8645
|
+
[iframeRef]
|
|
8646
|
+
);
|
|
8647
|
+
const getSourceInspectorPanelPosition = useCallback11(
|
|
8648
|
+
(rect) => {
|
|
8649
|
+
const margin = 12;
|
|
8650
|
+
const gap = 10;
|
|
8651
|
+
const preferredLeft = rect.left + rect.width + gap;
|
|
8652
|
+
const rightSpace = window.innerWidth - preferredLeft - margin;
|
|
8653
|
+
const leftSpace = rect.left - gap - margin;
|
|
8654
|
+
const canOpenRight = rightSpace >= SOURCE_PANEL_MIN_WIDTH;
|
|
8655
|
+
const canOpenLeft = leftSpace >= SOURCE_PANEL_MIN_WIDTH;
|
|
8656
|
+
const left = canOpenRight || !canOpenLeft ? preferredLeft : margin;
|
|
8657
|
+
const right = canOpenRight || !canOpenLeft ? null : Math.max(margin, window.innerWidth - (rect.left - gap));
|
|
8658
|
+
const maxWidth = Math.min(
|
|
8659
|
+
SOURCE_PANEL_MAX_WIDTH,
|
|
8660
|
+
Math.max(
|
|
8661
|
+
SOURCE_PANEL_MIN_WIDTH,
|
|
8662
|
+
canOpenRight ? rightSpace : canOpenLeft ? leftSpace : window.innerWidth - margin * 2
|
|
8663
|
+
)
|
|
8664
|
+
);
|
|
8665
|
+
const top = Math.min(
|
|
8666
|
+
Math.max(margin, rect.top),
|
|
8667
|
+
Math.max(margin, window.innerHeight - SOURCE_PANEL_MAX_HEIGHT - margin)
|
|
8668
|
+
);
|
|
8669
|
+
return { left, maxWidth, right, top };
|
|
8670
|
+
},
|
|
8671
|
+
[]
|
|
8672
|
+
);
|
|
8673
|
+
const showSourceInspectorForTarget = useCallback11(
|
|
8674
|
+
(target2, isPinned = false) => {
|
|
8675
|
+
const candidates = getSourceCandidates(target2).map((candidate) => ({
|
|
8676
|
+
...candidate,
|
|
8677
|
+
openUrl: getSourceOpenUrl(candidate.source, {
|
|
8678
|
+
...sourceOpenOptions,
|
|
8679
|
+
omitPosition: !candidate.usesPosition
|
|
8680
|
+
})
|
|
8681
|
+
}));
|
|
8682
|
+
const firstCandidate = candidates[0];
|
|
8683
|
+
const rect = firstCandidate ? getSourceInspectorRect(firstCandidate.element) : null;
|
|
8684
|
+
if (!firstCandidate || !rect) {
|
|
8685
|
+
setSourceInspectorState(null);
|
|
8686
|
+
return [];
|
|
8687
|
+
}
|
|
8688
|
+
const { left, maxWidth, right, top } = getSourceInspectorPanelPosition(rect);
|
|
8689
|
+
setSourceInspectorState({
|
|
8690
|
+
candidates,
|
|
8691
|
+
isPinned,
|
|
8692
|
+
panelLeft: left,
|
|
8693
|
+
panelMaxWidth: maxWidth,
|
|
8694
|
+
panelRight: right,
|
|
8695
|
+
panelTop: top,
|
|
8696
|
+
rect
|
|
8697
|
+
});
|
|
8698
|
+
return candidates;
|
|
8699
|
+
},
|
|
8700
|
+
[
|
|
8701
|
+
getSourceInspectorPanelPosition,
|
|
8702
|
+
getSourceInspectorRect,
|
|
8703
|
+
sourceOpenOptions
|
|
8704
|
+
]
|
|
8705
|
+
);
|
|
8706
|
+
const showSourceOutlineForTarget = useCallback11(
|
|
8707
|
+
(target2) => {
|
|
8708
|
+
const firstCandidate = getSourceCandidates(target2)[0];
|
|
8709
|
+
const rect = firstCandidate ? getSourceInspectorRect(firstCandidate.element) : null;
|
|
8710
|
+
if (!firstCandidate || !rect) {
|
|
8711
|
+
setSourceInspectorState(null);
|
|
8712
|
+
return null;
|
|
8713
|
+
}
|
|
8714
|
+
setSourceInspectorState({
|
|
8715
|
+
candidates: [],
|
|
8716
|
+
isPinned: false,
|
|
8717
|
+
panelLeft: 0,
|
|
8718
|
+
panelMaxWidth: SOURCE_PANEL_MAX_WIDTH,
|
|
8719
|
+
panelRight: null,
|
|
8720
|
+
panelTop: 0,
|
|
8721
|
+
rect
|
|
8722
|
+
});
|
|
8723
|
+
return firstCandidate;
|
|
8724
|
+
},
|
|
8725
|
+
[getSourceInspectorRect]
|
|
8726
|
+
);
|
|
8727
|
+
const openSourceCandidate = useCallback11(
|
|
8728
|
+
(candidate) => {
|
|
8729
|
+
const didOpen = openSourceInEditor(candidate.source, {
|
|
8730
|
+
...sourceOpenOptions,
|
|
8731
|
+
omitPosition: !candidate.usesPosition
|
|
8732
|
+
});
|
|
8733
|
+
showToast(didOpen ? "Source opened" : "Source root required");
|
|
8734
|
+
clearSourceInspector();
|
|
8735
|
+
},
|
|
8736
|
+
[clearSourceInspector, showToast, sourceOpenOptions]
|
|
8737
|
+
);
|
|
7489
8738
|
const cleanupSourceOpenShortcut = useCallback11(() => {
|
|
7490
8739
|
sourceShortcutCleanupRef.current?.();
|
|
7491
8740
|
sourceShortcutCleanupRef.current = null;
|
|
@@ -7498,8 +8747,10 @@ var ReviewShell = ({
|
|
|
7498
8747
|
} catch {
|
|
7499
8748
|
return;
|
|
7500
8749
|
}
|
|
7501
|
-
if (!frameDocument) return;
|
|
7502
|
-
const
|
|
8750
|
+
if (!frameDocument || !isSourceInspectorEnabled) return;
|
|
8751
|
+
const frameRoot = frameDocument.head ?? frameDocument.documentElement;
|
|
8752
|
+
const frameBody = frameDocument.body ?? frameDocument.documentElement;
|
|
8753
|
+
if (!frameRoot || !frameBody) return;
|
|
7503
8754
|
const optionAttribute = "data-dfwr-source-option";
|
|
7504
8755
|
const fontOverlayAttribute = "data-dfwr-source-fonts";
|
|
7505
8756
|
const style = frameDocument.createElement("style");
|
|
@@ -7510,6 +8761,13 @@ var ReviewShell = ({
|
|
|
7510
8761
|
cursor: crosshair !important;
|
|
7511
8762
|
}
|
|
7512
8763
|
|
|
8764
|
+
html[${optionAttribute}="true"] .helper-figma-root,
|
|
8765
|
+
html[${optionAttribute}="true"] .helper-figma-root *,
|
|
8766
|
+
html[${optionAttribute}="true"] .helper-figma-loading-backdrop,
|
|
8767
|
+
html[${optionAttribute}="true"] .helper-figma-loading-backdrop * {
|
|
8768
|
+
pointer-events: none !important;
|
|
8769
|
+
}
|
|
8770
|
+
|
|
7513
8771
|
html[${optionAttribute}="true"] body::before {
|
|
7514
8772
|
position: fixed !important;
|
|
7515
8773
|
z-index: 2147483647 !important;
|
|
@@ -7528,17 +8786,13 @@ var ReviewShell = ({
|
|
|
7528
8786
|
pointer-events: none !important;
|
|
7529
8787
|
}
|
|
7530
8788
|
|
|
7531
|
-
[${hoverAttribute}="true"] {
|
|
7532
|
-
outline: 2px solid rgba(124, 199, 255, 0.96) !important;
|
|
7533
|
-
outline-offset: 2px !important;
|
|
7534
|
-
}
|
|
7535
|
-
|
|
7536
8789
|
[${fontOverlayAttribute}] {
|
|
7537
8790
|
position: fixed !important;
|
|
7538
8791
|
z-index: 2147483647 !important;
|
|
7539
8792
|
display: flex !important;
|
|
7540
8793
|
flex-direction: column !important;
|
|
7541
|
-
|
|
8794
|
+
width: max-content !important;
|
|
8795
|
+
max-width: calc(100vw - 8px) !important;
|
|
7542
8796
|
border: 1px solid rgba(124, 199, 255, 0.72) !important;
|
|
7543
8797
|
border-radius: 6px !important;
|
|
7544
8798
|
padding: 4px 6px !important;
|
|
@@ -7546,28 +8800,36 @@ var ReviewShell = ({
|
|
|
7546
8800
|
background: rgba(15, 23, 42, 0.9) !important;
|
|
7547
8801
|
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.28) !important;
|
|
7548
8802
|
font: 800 11px/1.35 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace !important;
|
|
8803
|
+
overflow-wrap: anywhere !important;
|
|
7549
8804
|
pointer-events: none !important;
|
|
7550
|
-
white-space:
|
|
8805
|
+
white-space: normal !important;
|
|
7551
8806
|
}
|
|
7552
8807
|
|
|
7553
8808
|
[${fontOverlayAttribute}] > span {
|
|
7554
|
-
display:
|
|
8809
|
+
display: grid !important;
|
|
8810
|
+
grid-template-columns: auto minmax(0, 1fr) !important;
|
|
7555
8811
|
justify-content: space-between !important;
|
|
7556
8812
|
gap: 10px !important;
|
|
7557
8813
|
}
|
|
7558
8814
|
|
|
8815
|
+
[${fontOverlayAttribute}] > span > span:last-child {
|
|
8816
|
+
min-width: 0 !important;
|
|
8817
|
+
text-align: right !important;
|
|
8818
|
+
}
|
|
8819
|
+
|
|
7559
8820
|
[${fontOverlayAttribute}][hidden] {
|
|
7560
8821
|
display: none !important;
|
|
7561
8822
|
}
|
|
7562
8823
|
`;
|
|
7563
|
-
|
|
8824
|
+
frameRoot.append(style);
|
|
7564
8825
|
const fontOverlay = frameDocument.createElement("div");
|
|
7565
8826
|
fontOverlay.setAttribute(fontOverlayAttribute, "true");
|
|
7566
8827
|
fontOverlay.hidden = true;
|
|
7567
|
-
|
|
8828
|
+
frameBody.append(fontOverlay);
|
|
7568
8829
|
let hoveredElement = null;
|
|
7569
|
-
let
|
|
8830
|
+
let lastSourceTarget = null;
|
|
7570
8831
|
let isSourceSelecting = false;
|
|
8832
|
+
let isSourcePanelPinned = false;
|
|
7571
8833
|
const getFontHints = (element) => {
|
|
7572
8834
|
if (!element) return [];
|
|
7573
8835
|
const values = [];
|
|
@@ -7591,10 +8853,13 @@ var ReviewShell = ({
|
|
|
7591
8853
|
const rect = element.getBoundingClientRect();
|
|
7592
8854
|
const frameWidth = frameDocument.documentElement.clientWidth;
|
|
7593
8855
|
const showAbove = rect.top > 48;
|
|
7594
|
-
const left = Math.max(4, Math.min(rect.left, frameWidth - 96));
|
|
7595
8856
|
const top = Math.max(4, showAbove ? rect.top : rect.bottom);
|
|
7596
8857
|
fontOverlay.replaceChildren();
|
|
7597
8858
|
fontOverlay.style.minWidth = "72px";
|
|
8859
|
+
fontOverlay.style.left = "4px";
|
|
8860
|
+
fontOverlay.style.top = `${top}px`;
|
|
8861
|
+
fontOverlay.style.transform = showAbove ? "translateY(calc(-100% - 6px))" : "translateY(6px)";
|
|
8862
|
+
fontOverlay.style.visibility = "hidden";
|
|
7598
8863
|
const rows = values.map(({ tag, value }) => {
|
|
7599
8864
|
const row = frameDocument.createElement("span");
|
|
7600
8865
|
const tagText = frameDocument.createElement("span");
|
|
@@ -7605,54 +8870,70 @@ var ReviewShell = ({
|
|
|
7605
8870
|
return row;
|
|
7606
8871
|
});
|
|
7607
8872
|
fontOverlay.append(...rows);
|
|
7608
|
-
fontOverlay.style.left = `${left}px`;
|
|
7609
|
-
fontOverlay.style.top = `${top}px`;
|
|
7610
|
-
fontOverlay.style.transform = showAbove ? "translateY(calc(-100% - 6px))" : "translateY(6px)";
|
|
7611
8873
|
fontOverlay.hidden = false;
|
|
8874
|
+
const overlayWidth = fontOverlay.getBoundingClientRect().width;
|
|
8875
|
+
const left = Math.max(
|
|
8876
|
+
4,
|
|
8877
|
+
Math.min(rect.left, frameWidth - overlayWidth - 4)
|
|
8878
|
+
);
|
|
8879
|
+
fontOverlay.style.left = `${left}px`;
|
|
8880
|
+
fontOverlay.style.visibility = "";
|
|
7612
8881
|
};
|
|
7613
8882
|
const setHoveredElement = (element) => {
|
|
7614
|
-
|
|
7615
|
-
hoveredElement?.removeAttribute(hoverAttribute);
|
|
7616
|
-
hoveredElement = element;
|
|
7617
|
-
hoveredElement?.setAttribute(hoverAttribute, "true");
|
|
7618
|
-
}
|
|
8883
|
+
hoveredElement = element;
|
|
7619
8884
|
updateFontOverlay(element);
|
|
7620
8885
|
};
|
|
7621
8886
|
const setSourceSelecting = (isSelecting) => {
|
|
7622
8887
|
isSourceSelecting = isSelecting;
|
|
7623
8888
|
if (isSelecting) {
|
|
8889
|
+
isSourcePanelPinned = false;
|
|
7624
8890
|
frameDocument.documentElement.setAttribute(optionAttribute, "true");
|
|
7625
|
-
|
|
8891
|
+
const candidate = showSourceOutlineForTarget(lastSourceTarget);
|
|
8892
|
+
setHoveredElement(candidate?.element ?? hoveredElement);
|
|
7626
8893
|
return;
|
|
7627
8894
|
}
|
|
7628
8895
|
setHoveredElement(null);
|
|
7629
8896
|
fontOverlay.hidden = true;
|
|
7630
8897
|
frameDocument.documentElement.removeAttribute(optionAttribute);
|
|
8898
|
+
if (!isSourcePanelPinned && !sourceInspectorInteractionRef.current) {
|
|
8899
|
+
clearSourceInspector();
|
|
8900
|
+
}
|
|
7631
8901
|
};
|
|
7632
8902
|
const handleMouseMove = (event) => {
|
|
7633
|
-
|
|
8903
|
+
lastSourceTarget = event.target;
|
|
8904
|
+
const candidates = getSourceCandidates(event.target);
|
|
8905
|
+
const sourceElement = candidates[0]?.element ?? null;
|
|
7634
8906
|
if (event.altKey && !isSourceSelecting) {
|
|
7635
8907
|
setSourceSelecting(true);
|
|
7636
8908
|
}
|
|
7637
|
-
|
|
8909
|
+
if (isSourceSelecting && !isSourcePanelPinned) {
|
|
8910
|
+
showSourceOutlineForTarget(event.target);
|
|
8911
|
+
}
|
|
8912
|
+
setHoveredElement(isSourceSelecting ? sourceElement : null);
|
|
7638
8913
|
};
|
|
7639
8914
|
const handleClick = (event) => {
|
|
7640
8915
|
if (!isSourceSelecting && !event.altKey) return;
|
|
7641
8916
|
event.preventDefault();
|
|
7642
8917
|
event.stopPropagation();
|
|
7643
8918
|
event.stopImmediatePropagation();
|
|
7644
|
-
const
|
|
7645
|
-
if (!
|
|
8919
|
+
const candidates = showSourceInspectorForTarget(event.target, true);
|
|
8920
|
+
if (!candidates.length) {
|
|
7646
8921
|
showToast("Source hint not found");
|
|
8922
|
+
isSourcePanelPinned = false;
|
|
7647
8923
|
setSourceSelecting(false);
|
|
7648
8924
|
return;
|
|
7649
8925
|
}
|
|
7650
|
-
|
|
7651
|
-
showToast(didOpen ? "Source opened" : "Source root required");
|
|
8926
|
+
isSourcePanelPinned = true;
|
|
7652
8927
|
setSourceSelecting(false);
|
|
7653
8928
|
};
|
|
7654
8929
|
const isOptionKeyEvent = (event) => event.key === "Alt" || event.code === "AltLeft" || event.code === "AltRight" || event.altKey;
|
|
7655
8930
|
const handleKeyDown = (event) => {
|
|
8931
|
+
if (event.key === "Escape") {
|
|
8932
|
+
isSourcePanelPinned = false;
|
|
8933
|
+
setSourceSelecting(false);
|
|
8934
|
+
clearSourceInspector();
|
|
8935
|
+
return;
|
|
8936
|
+
}
|
|
7656
8937
|
if (!isOptionKeyEvent(event)) return;
|
|
7657
8938
|
cancelReviewMode();
|
|
7658
8939
|
setSourceSelecting(true);
|
|
@@ -7661,43 +8942,70 @@ var ReviewShell = ({
|
|
|
7661
8942
|
if (isOptionKeyEvent(event) || !event.altKey) setSourceSelecting(false);
|
|
7662
8943
|
};
|
|
7663
8944
|
const handleBlur = () => {
|
|
8945
|
+
isSourcePanelPinned = false;
|
|
8946
|
+
setSourceSelecting(false);
|
|
8947
|
+
};
|
|
8948
|
+
const handleWindowPointerDown = (event) => {
|
|
8949
|
+
const target2 = event.target;
|
|
8950
|
+
if (target2 instanceof Element && target2.closest(".df-review-source-popover")) {
|
|
8951
|
+
sourceInspectorInteractionRef.current = true;
|
|
8952
|
+
return;
|
|
8953
|
+
}
|
|
8954
|
+
isSourcePanelPinned = false;
|
|
8955
|
+
sourceInspectorInteractionRef.current = false;
|
|
7664
8956
|
setSourceSelecting(false);
|
|
8957
|
+
clearSourceInspector();
|
|
7665
8958
|
};
|
|
7666
8959
|
frameDocument.addEventListener("mousemove", handleMouseMove, true);
|
|
7667
8960
|
frameDocument.addEventListener("click", handleClick, true);
|
|
7668
8961
|
frameDocument.addEventListener("keydown", handleKeyDown, true);
|
|
7669
8962
|
frameDocument.addEventListener("keyup", handleKeyUp, true);
|
|
7670
|
-
frameDocument.defaultView?.addEventListener("blur", handleBlur);
|
|
7671
8963
|
window.addEventListener("keydown", handleKeyDown, true);
|
|
7672
8964
|
window.addEventListener("keyup", handleKeyUp, true);
|
|
7673
8965
|
window.addEventListener("blur", handleBlur);
|
|
8966
|
+
window.addEventListener("pointerdown", handleWindowPointerDown, true);
|
|
7674
8967
|
sourceShortcutCleanupRef.current = () => {
|
|
7675
8968
|
frameDocument.removeEventListener("mousemove", handleMouseMove, true);
|
|
7676
8969
|
frameDocument.removeEventListener("click", handleClick, true);
|
|
7677
8970
|
frameDocument.removeEventListener("keydown", handleKeyDown, true);
|
|
7678
8971
|
frameDocument.removeEventListener("keyup", handleKeyUp, true);
|
|
7679
|
-
frameDocument.defaultView?.removeEventListener("blur", handleBlur);
|
|
7680
8972
|
window.removeEventListener("keydown", handleKeyDown, true);
|
|
7681
8973
|
window.removeEventListener("keyup", handleKeyUp, true);
|
|
7682
8974
|
window.removeEventListener("blur", handleBlur);
|
|
8975
|
+
window.removeEventListener("pointerdown", handleWindowPointerDown, true);
|
|
8976
|
+
isSourcePanelPinned = false;
|
|
7683
8977
|
setSourceSelecting(false);
|
|
7684
8978
|
style.remove();
|
|
7685
8979
|
fontOverlay.remove();
|
|
7686
8980
|
};
|
|
7687
8981
|
}, [
|
|
7688
8982
|
cancelReviewMode,
|
|
8983
|
+
clearSourceInspector,
|
|
7689
8984
|
cleanupSourceOpenShortcut,
|
|
7690
8985
|
iframeRef,
|
|
8986
|
+
isSourceInspectorEnabled,
|
|
7691
8987
|
showToast,
|
|
7692
|
-
|
|
8988
|
+
showSourceOutlineForTarget,
|
|
8989
|
+
showSourceInspectorForTarget
|
|
7693
8990
|
]);
|
|
7694
8991
|
useEffect10(() => {
|
|
7695
8992
|
return cleanupSourceOpenShortcut;
|
|
7696
8993
|
}, [cleanupSourceOpenShortcut]);
|
|
7697
8994
|
const loadTargetFrame = useCallback11(() => {
|
|
7698
8995
|
initReviewKit();
|
|
8996
|
+
refreshTargetFigmaConfig();
|
|
8997
|
+
setTargetFigmaOverlayLocked(
|
|
8998
|
+
iframeRef.current?.contentDocument,
|
|
8999
|
+
mode === "element"
|
|
9000
|
+
);
|
|
7699
9001
|
bindSourceOpenShortcut();
|
|
7700
|
-
}, [
|
|
9002
|
+
}, [
|
|
9003
|
+
bindSourceOpenShortcut,
|
|
9004
|
+
iframeRef,
|
|
9005
|
+
initReviewKit,
|
|
9006
|
+
mode,
|
|
9007
|
+
refreshTargetFigmaConfig
|
|
9008
|
+
]);
|
|
7701
9009
|
useEffect10(() => {
|
|
7702
9010
|
const frame = window.requestAnimationFrame(bindSourceOpenShortcut);
|
|
7703
9011
|
return () => window.cancelAnimationFrame(frame);
|
|
@@ -7752,6 +9060,19 @@ var ReviewShell = ({
|
|
|
7752
9060
|
`qa:${numberedItem.item.id}`,
|
|
7753
9061
|
"QA prompt copied"
|
|
7754
9062
|
);
|
|
9063
|
+
const copyItemLink = (numberedItem) => {
|
|
9064
|
+
const { item } = numberedItem;
|
|
9065
|
+
return copyPrompt(
|
|
9066
|
+
getShellUrlForItem(
|
|
9067
|
+
getItemTarget(item, reviewPathPrefix),
|
|
9068
|
+
getRestoredSize(item, viewportPresets),
|
|
9069
|
+
item.id,
|
|
9070
|
+
source
|
|
9071
|
+
).href,
|
|
9072
|
+
`link:${item.id}`,
|
|
9073
|
+
"QA link copied"
|
|
9074
|
+
);
|
|
9075
|
+
};
|
|
7755
9076
|
const removeItem = (item) => removeReviewItem({
|
|
7756
9077
|
activeAdapterEntry,
|
|
7757
9078
|
isRemoteSource,
|
|
@@ -7794,15 +9115,25 @@ var ReviewShell = ({
|
|
|
7794
9115
|
onOpenSettings: openFigmaSettings
|
|
7795
9116
|
}
|
|
7796
9117
|
),
|
|
9118
|
+
currentPagePresenceUsers.length > 0 && /* @__PURE__ */ jsx17("div", { className: "df-review-presence-row", children: /* @__PURE__ */ jsx17(
|
|
9119
|
+
PresenceOverlay,
|
|
9120
|
+
{
|
|
9121
|
+
presenceSessionId,
|
|
9122
|
+
users: currentPagePresenceUsers
|
|
9123
|
+
}
|
|
9124
|
+
) }),
|
|
7797
9125
|
isSitemapOpen && /* @__PURE__ */ jsx17(
|
|
7798
9126
|
SitemapModal,
|
|
7799
9127
|
{
|
|
7800
9128
|
pages,
|
|
7801
9129
|
activeRoute,
|
|
9130
|
+
allQaCount,
|
|
9131
|
+
isAllQaVisible,
|
|
7802
9132
|
pageQaCounts,
|
|
7803
9133
|
pagePresenceUsers,
|
|
7804
9134
|
getPageTarget: (href) => normalizeTarget(href, reviewPathPrefix),
|
|
7805
9135
|
onClose: () => setIsSitemapOpen(false),
|
|
9136
|
+
onSelectAllQa: selectAllQa,
|
|
7806
9137
|
onSelectPage: selectPage
|
|
7807
9138
|
}
|
|
7808
9139
|
),
|
|
@@ -7861,29 +9192,32 @@ var ReviewShell = ({
|
|
|
7861
9192
|
{
|
|
7862
9193
|
activeAdapterEntry,
|
|
7863
9194
|
activeItems,
|
|
7864
|
-
|
|
9195
|
+
activeRemainingItemCount,
|
|
7865
9196
|
currentPresetScope,
|
|
7866
9197
|
filteredNumberedActiveItems,
|
|
7867
9198
|
getItemPresetScope,
|
|
7868
9199
|
hiddenOverlayItemIds,
|
|
7869
9200
|
isListVisible,
|
|
9201
|
+
isAllQaVisible,
|
|
7870
9202
|
isRemoteSource,
|
|
7871
|
-
presenceSessionId,
|
|
7872
9203
|
copiedPromptKey,
|
|
7873
9204
|
qaFilter,
|
|
7874
9205
|
qaFilterCounts,
|
|
9206
|
+
qaStatusFilter,
|
|
9207
|
+
qaStatusFilterCounts,
|
|
7875
9208
|
remoteAdapterEntry,
|
|
7876
9209
|
selectedItemId,
|
|
7877
9210
|
showSourceSelect,
|
|
7878
|
-
sourceRoot,
|
|
7879
9211
|
source,
|
|
7880
9212
|
sourceEntries,
|
|
7881
9213
|
onChangeItemStatus: changeItemStatus,
|
|
7882
9214
|
onClearSelectedItem: clearSelectedReviewItem,
|
|
7883
9215
|
onChangeReviewSource: changeReviewSource,
|
|
9216
|
+
onCopyItemLink: (numberedItem) => void copyItemLink(numberedItem),
|
|
7884
9217
|
onCopyItemPrompt: (numberedItem) => void copyItemPrompt(numberedItem),
|
|
7885
9218
|
onEditItem: setEditingItem,
|
|
7886
9219
|
onQaFilterChange: setQaFilter,
|
|
9220
|
+
onQaStatusFilterChange: setQaStatusFilter,
|
|
7887
9221
|
onRefreshReviewData: refreshReviewData2,
|
|
7888
9222
|
onRemoveItem: removeItem,
|
|
7889
9223
|
onRestoreReviewItem: restoreReviewItem,
|
|
@@ -7896,6 +9230,7 @@ var ReviewShell = ({
|
|
|
7896
9230
|
{
|
|
7897
9231
|
canWriteArea,
|
|
7898
9232
|
canWriteDom,
|
|
9233
|
+
figmaFrameUrl,
|
|
7899
9234
|
frameScrollRef,
|
|
7900
9235
|
iframeRef,
|
|
7901
9236
|
isRulerAvailable,
|
|
@@ -7914,7 +9249,72 @@ var ReviewShell = ({
|
|
|
7914
9249
|
onLoadTarget: loadTargetFrame,
|
|
7915
9250
|
onSetReviewMode: setReviewMode
|
|
7916
9251
|
}
|
|
7917
|
-
)
|
|
9252
|
+
),
|
|
9253
|
+
sourceInspectorState && /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
9254
|
+
/* @__PURE__ */ jsx17(
|
|
9255
|
+
"div",
|
|
9256
|
+
{
|
|
9257
|
+
className: `df-review-source-outline${sourceInspectorState.isPinned ? " is-pinned" : ""}`,
|
|
9258
|
+
style: {
|
|
9259
|
+
height: `${sourceInspectorState.rect.height}px`,
|
|
9260
|
+
left: `${sourceInspectorState.rect.left}px`,
|
|
9261
|
+
top: `${sourceInspectorState.rect.top}px`,
|
|
9262
|
+
width: `${sourceInspectorState.rect.width}px`
|
|
9263
|
+
}
|
|
9264
|
+
}
|
|
9265
|
+
),
|
|
9266
|
+
sourceInspectorState.candidates.length > 0 && /* @__PURE__ */ jsxs15(
|
|
9267
|
+
"div",
|
|
9268
|
+
{
|
|
9269
|
+
className: `df-review-source-popover${sourceInspectorState.isPinned ? " is-pinned" : ""}`,
|
|
9270
|
+
style: {
|
|
9271
|
+
left: sourceInspectorState.panelRight === null ? `${sourceInspectorState.panelLeft}px` : void 0,
|
|
9272
|
+
maxWidth: `${sourceInspectorState.panelMaxWidth}px`,
|
|
9273
|
+
right: sourceInspectorState.panelRight === null ? void 0 : `${sourceInspectorState.panelRight}px`,
|
|
9274
|
+
top: `${sourceInspectorState.panelTop}px`
|
|
9275
|
+
},
|
|
9276
|
+
onPointerDown: () => {
|
|
9277
|
+
sourceInspectorInteractionRef.current = true;
|
|
9278
|
+
},
|
|
9279
|
+
onPointerEnter: () => {
|
|
9280
|
+
sourceInspectorInteractionRef.current = true;
|
|
9281
|
+
},
|
|
9282
|
+
onPointerLeave: () => {
|
|
9283
|
+
sourceInspectorInteractionRef.current = false;
|
|
9284
|
+
},
|
|
9285
|
+
onClick: (event) => event.stopPropagation(),
|
|
9286
|
+
children: [
|
|
9287
|
+
/* @__PURE__ */ jsx17("div", { className: "df-review-source-popover-close", children: /* @__PURE__ */ jsx17(
|
|
9288
|
+
"button",
|
|
9289
|
+
{
|
|
9290
|
+
"aria-label": "Close source candidates",
|
|
9291
|
+
type: "button",
|
|
9292
|
+
onClick: clearSourceInspector,
|
|
9293
|
+
children: "\xD7"
|
|
9294
|
+
}
|
|
9295
|
+
) }),
|
|
9296
|
+
/* @__PURE__ */ jsx17("div", { className: "df-review-source-candidate-list", children: sourceInspectorState.candidates.map((candidate) => /* @__PURE__ */ jsx17(
|
|
9297
|
+
"button",
|
|
9298
|
+
{
|
|
9299
|
+
className: "df-review-source-candidate",
|
|
9300
|
+
type: "button",
|
|
9301
|
+
onClick: (event) => {
|
|
9302
|
+
event.preventDefault();
|
|
9303
|
+
event.stopPropagation();
|
|
9304
|
+
openSourceCandidate(candidate);
|
|
9305
|
+
},
|
|
9306
|
+
children: /* @__PURE__ */ jsxs15("span", { className: "df-review-source-candidate-main", children: [
|
|
9307
|
+
/* @__PURE__ */ jsx17("strong", { children: candidate.label }),
|
|
9308
|
+
/* @__PURE__ */ jsx17("span", { children: candidate.filePath }),
|
|
9309
|
+
/* @__PURE__ */ jsx17("small", { children: candidate.positionLabel || (candidate.usesPosition ? "" : "file only") })
|
|
9310
|
+
] })
|
|
9311
|
+
},
|
|
9312
|
+
candidate.id
|
|
9313
|
+
)) })
|
|
9314
|
+
]
|
|
9315
|
+
}
|
|
9316
|
+
)
|
|
9317
|
+
] })
|
|
7918
9318
|
]
|
|
7919
9319
|
}
|
|
7920
9320
|
);
|
|
@@ -8128,15 +9528,16 @@ lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs:
|
|
|
8128
9528
|
lucide-react/dist/esm/context.mjs:
|
|
8129
9529
|
lucide-react/dist/esm/Icon.mjs:
|
|
8130
9530
|
lucide-react/dist/esm/createLucideIcon.mjs:
|
|
9531
|
+
lucide-react/dist/esm/icons/bot.mjs:
|
|
8131
9532
|
lucide-react/dist/esm/icons/circle-question-mark.mjs:
|
|
8132
9533
|
lucide-react/dist/esm/icons/copy.mjs:
|
|
8133
9534
|
lucide-react/dist/esm/icons/external-link.mjs:
|
|
8134
9535
|
lucide-react/dist/esm/icons/eye-off.mjs:
|
|
8135
9536
|
lucide-react/dist/esm/icons/eye.mjs:
|
|
8136
|
-
lucide-react/dist/esm/icons/file-code-corner.mjs:
|
|
8137
9537
|
lucide-react/dist/esm/icons/grip-vertical.mjs:
|
|
8138
9538
|
lucide-react/dist/esm/icons/image.mjs:
|
|
8139
9539
|
lucide-react/dist/esm/icons/layout-grid.mjs:
|
|
9540
|
+
lucide-react/dist/esm/icons/link-2.mjs:
|
|
8140
9541
|
lucide-react/dist/esm/icons/list-filter.mjs:
|
|
8141
9542
|
lucide-react/dist/esm/icons/map.mjs:
|
|
8142
9543
|
lucide-react/dist/esm/icons/maximize-2.mjs:
|
|
@@ -8151,7 +9552,6 @@ lucide-react/dist/esm/icons/smartphone.mjs:
|
|
|
8151
9552
|
lucide-react/dist/esm/icons/square-mouse-pointer.mjs:
|
|
8152
9553
|
lucide-react/dist/esm/icons/sticky-note.mjs:
|
|
8153
9554
|
lucide-react/dist/esm/icons/upload.mjs:
|
|
8154
|
-
lucide-react/dist/esm/icons/users.mjs:
|
|
8155
9555
|
lucide-react/dist/esm/icons/x.mjs:
|
|
8156
9556
|
lucide-react/dist/esm/lucide-react.mjs:
|
|
8157
9557
|
(**
|