@xcanwin/manyoyo 5.7.13 → 5.7.20
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/lib/web/frontend/app.css +210 -230
- package/lib/web/frontend/app.html +1 -1
- package/lib/web/frontend/app.js +278 -225
- package/package.json +1 -1
package/lib/web/frontend/app.css
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
--line: #d9c7ad;
|
|
15
15
|
--line-strong: #b59263;
|
|
16
16
|
--line-soft: rgba(181, 146, 99, 0.26);
|
|
17
|
+
--tree-guide: rgba(181, 146, 99, 0.44);
|
|
18
|
+
--tree-guide-soft: rgba(181, 146, 99, 0.2);
|
|
17
19
|
|
|
18
20
|
--text: #1f1a14;
|
|
19
21
|
--muted: #6a5f52;
|
|
@@ -36,6 +38,7 @@
|
|
|
36
38
|
--status-stopped-text: #9a5a09;
|
|
37
39
|
--status-history-bg: #ece7df;
|
|
38
40
|
--status-history-text: #645647;
|
|
41
|
+
--tree-history-text: #b7b0a7;
|
|
39
42
|
--status-unknown-bg: #ece9ff;
|
|
40
43
|
--status-unknown-text: #5a4bb0;
|
|
41
44
|
|
|
@@ -546,8 +549,8 @@ button.tree-toggle {
|
|
|
546
549
|
padding: 10px 12px;
|
|
547
550
|
display: flex;
|
|
548
551
|
align-items: flex-start;
|
|
549
|
-
justify-content:
|
|
550
|
-
gap:
|
|
552
|
+
justify-content: flex-start;
|
|
553
|
+
gap: 0;
|
|
551
554
|
}
|
|
552
555
|
|
|
553
556
|
button.tree-toggle:hover {
|
|
@@ -560,320 +563,267 @@ button.tree-toggle:active {
|
|
|
560
563
|
transform: none;
|
|
561
564
|
}
|
|
562
565
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
box-shadow: 0 0 0 3px rgba(196, 85, 31, 0.14);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
.tree-toggle-main {
|
|
569
|
-
min-width: 0;
|
|
566
|
+
.tree-node-block,
|
|
567
|
+
.tree-node-children {
|
|
570
568
|
display: flex;
|
|
571
569
|
flex-direction: column;
|
|
572
|
-
gap:
|
|
570
|
+
gap: 8px;
|
|
573
571
|
}
|
|
574
572
|
|
|
575
|
-
.tree-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
573
|
+
.tree-node-row {
|
|
574
|
+
display: grid;
|
|
575
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
576
|
+
align-items: stretch;
|
|
577
|
+
column-gap: 8px;
|
|
580
578
|
}
|
|
581
579
|
|
|
582
|
-
.tree-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
line-height: 1;
|
|
586
|
-
flex-shrink: 0;
|
|
587
|
-
transition: transform 140ms ease;
|
|
580
|
+
.tree-node-row.tree-node-row-container {
|
|
581
|
+
position: relative;
|
|
582
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
588
583
|
}
|
|
589
584
|
|
|
590
|
-
.tree-
|
|
591
|
-
|
|
585
|
+
.tree-prefix {
|
|
586
|
+
min-height: 38px;
|
|
587
|
+
display: inline-flex;
|
|
588
|
+
align-items: stretch;
|
|
589
|
+
gap: 3px;
|
|
590
|
+
position: relative;
|
|
592
591
|
}
|
|
593
592
|
|
|
594
|
-
.
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
593
|
+
.tree-prefix-toggle {
|
|
594
|
+
position: relative;
|
|
595
|
+
width: 16px;
|
|
596
|
+
flex: 0 0 16px;
|
|
597
|
+
display: inline-flex;
|
|
598
|
+
align-items: center;
|
|
599
|
+
justify-content: center;
|
|
599
600
|
}
|
|
600
601
|
|
|
601
|
-
.
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
align-items: center;
|
|
607
|
-
column-gap: 10px;
|
|
608
|
-
row-gap: 3px;
|
|
602
|
+
.tree-prefix-segment,
|
|
603
|
+
.tree-prefix-branch {
|
|
604
|
+
position: relative;
|
|
605
|
+
width: 10px;
|
|
606
|
+
flex: 0 0 10px;
|
|
609
607
|
}
|
|
610
608
|
|
|
611
|
-
.
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
padding: 3px 8px;
|
|
617
|
-
border-radius: 999px;
|
|
618
|
-
border: 1px solid rgba(181, 146, 99, 0.34);
|
|
619
|
-
background: rgba(255, 255, 255, 0.56);
|
|
609
|
+
.tree-prefix-branch::before,
|
|
610
|
+
.tree-prefix-branch::after {
|
|
611
|
+
content: "";
|
|
612
|
+
position: absolute;
|
|
613
|
+
background: var(--tree-guide);
|
|
620
614
|
}
|
|
621
615
|
|
|
622
|
-
.
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
overflow: hidden;
|
|
628
|
-
text-overflow: ellipsis;
|
|
629
|
-
white-space: nowrap;
|
|
630
|
-
font-family: var(--font-mono);
|
|
631
|
-
font-size: 12px;
|
|
632
|
-
font-weight: 600;
|
|
616
|
+
.tree-prefix-branch::before {
|
|
617
|
+
left: 5px;
|
|
618
|
+
top: -6px;
|
|
619
|
+
bottom: 50%;
|
|
620
|
+
width: 1px;
|
|
633
621
|
}
|
|
634
622
|
|
|
635
|
-
.
|
|
636
|
-
|
|
637
|
-
grid-row: 2;
|
|
623
|
+
.tree-prefix-branch.is-mid::before {
|
|
624
|
+
bottom: -6px;
|
|
638
625
|
}
|
|
639
626
|
|
|
640
|
-
.
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
627
|
+
.tree-prefix-branch::after {
|
|
628
|
+
left: 5px;
|
|
629
|
+
top: 50%;
|
|
630
|
+
width: 9px;
|
|
631
|
+
height: 1px;
|
|
632
|
+
background: var(--tree-guide-soft);
|
|
644
633
|
}
|
|
645
634
|
|
|
646
|
-
.
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
margin-left: 14px;
|
|
651
|
-
padding-left: 12px;
|
|
652
|
-
border-left: 1px solid var(--line-soft);
|
|
635
|
+
.tree-prefix-leaf {
|
|
636
|
+
position: relative;
|
|
637
|
+
width: 12px;
|
|
638
|
+
flex: 0 0 12px;
|
|
653
639
|
}
|
|
654
640
|
|
|
655
|
-
.
|
|
656
|
-
|
|
641
|
+
.tree-prefix-leaf::before {
|
|
642
|
+
content: "";
|
|
643
|
+
position: absolute;
|
|
644
|
+
left: 1px;
|
|
645
|
+
top: 50%;
|
|
646
|
+
width: 10px;
|
|
647
|
+
height: 1px;
|
|
648
|
+
background: var(--tree-guide-soft);
|
|
649
|
+
transform: translateY(-0.5px);
|
|
657
650
|
}
|
|
658
651
|
|
|
659
|
-
.
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
652
|
+
.disclosure-toggle {
|
|
653
|
+
width: 16px;
|
|
654
|
+
height: 16px;
|
|
655
|
+
padding: 0;
|
|
656
|
+
align-self: center;
|
|
657
|
+
display: inline-flex;
|
|
658
|
+
align-items: center;
|
|
659
|
+
justify-content: center;
|
|
660
|
+
border: none;
|
|
661
|
+
border-radius: 6px;
|
|
662
|
+
color: #8c7257;
|
|
663
|
+
background: transparent;
|
|
664
|
+
transition: transform 140ms ease, background-color 140ms ease, color 140ms ease;
|
|
666
665
|
}
|
|
667
666
|
|
|
668
|
-
.
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
667
|
+
.disclosure-toggle svg {
|
|
668
|
+
width: 12px;
|
|
669
|
+
height: 12px;
|
|
670
|
+
display: block;
|
|
671
|
+
fill: none;
|
|
672
|
+
stroke: currentColor;
|
|
673
|
+
stroke-width: 1.8;
|
|
674
|
+
stroke-linecap: round;
|
|
675
|
+
stroke-linejoin: round;
|
|
676
|
+
vector-effect: non-scaling-stroke;
|
|
675
677
|
}
|
|
676
678
|
|
|
677
|
-
.
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
679
|
+
.disclosure-toggle:hover {
|
|
680
|
+
transform: none;
|
|
681
|
+
color: var(--accent-strong);
|
|
682
|
+
background: rgba(196, 85, 31, 0.08);
|
|
681
683
|
}
|
|
682
684
|
|
|
683
|
-
.
|
|
684
|
-
|
|
685
|
-
border-radius: 16px;
|
|
686
|
-
background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(249, 242, 232, 0.98) 100%);
|
|
687
|
-
padding: 12px;
|
|
688
|
-
display: flex;
|
|
689
|
-
flex-direction: column;
|
|
690
|
-
gap: 10px;
|
|
691
|
-
box-shadow: 0 10px 22px rgba(44, 31, 15, 0.08);
|
|
685
|
+
.disclosure-toggle:active {
|
|
686
|
+
transform: none;
|
|
692
687
|
}
|
|
693
688
|
|
|
694
|
-
.
|
|
695
|
-
|
|
696
|
-
flex-wrap: wrap;
|
|
697
|
-
align-items: flex-start;
|
|
698
|
-
justify-content: space-between;
|
|
699
|
-
gap: 12px;
|
|
689
|
+
.disclosure-toggle[aria-expanded="true"] {
|
|
690
|
+
transform: rotate(90deg);
|
|
700
691
|
}
|
|
701
692
|
|
|
702
|
-
.
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
693
|
+
.disclosure-toggle[aria-expanded="true"]:hover {
|
|
694
|
+
transform: rotate(90deg);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
.tree-node-button {
|
|
698
|
+
width: 100%;
|
|
699
|
+
text-align: left;
|
|
700
|
+
border: 1px solid rgba(181, 146, 99, 0.38);
|
|
701
|
+
background: rgba(255, 255, 255, 0.94);
|
|
708
702
|
color: var(--text);
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
justify-content: space-between;
|
|
712
|
-
gap: 12px;
|
|
703
|
+
border-radius: 12px;
|
|
704
|
+
padding: 10px 11px;
|
|
713
705
|
}
|
|
714
706
|
|
|
715
|
-
|
|
716
|
-
|
|
707
|
+
.tree-node-button:hover {
|
|
708
|
+
transform: none;
|
|
709
|
+
border-color: #d1aa7f;
|
|
710
|
+
background: #fff8ef;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.tree-node-button:active {
|
|
717
714
|
transform: none;
|
|
718
|
-
background: transparent;
|
|
719
715
|
}
|
|
720
716
|
|
|
721
|
-
|
|
717
|
+
.tree-node-button:focus-visible {
|
|
722
718
|
outline: none;
|
|
723
719
|
box-shadow: 0 0 0 3px rgba(196, 85, 31, 0.14);
|
|
724
720
|
}
|
|
725
721
|
|
|
726
|
-
.
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
flex-direction: column;
|
|
731
|
-
gap: 8px;
|
|
722
|
+
.tree-node-button.active {
|
|
723
|
+
border-color: #c68d5a;
|
|
724
|
+
background: #fff3e8;
|
|
725
|
+
box-shadow: inset 3px 0 0 var(--accent), 0 0 0 2px rgba(196, 85, 31, 0.14);
|
|
732
726
|
}
|
|
733
727
|
|
|
734
|
-
.
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
gap: 10px;
|
|
738
|
-
min-width: 0;
|
|
728
|
+
.tree-node-button.tree-node-tone-history .tree-node-title,
|
|
729
|
+
.tree-node-button.tree-node-tone-history .tree-node-meta {
|
|
730
|
+
color: var(--tree-history-text);
|
|
739
731
|
}
|
|
740
732
|
|
|
741
|
-
.
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
flex-direction: column;
|
|
745
|
-
gap: 4px;
|
|
733
|
+
.tree-node-block.has-active > .tree-node-row > .tree-node-button:not(.active) {
|
|
734
|
+
border-color: #c68d5a;
|
|
735
|
+
box-shadow: 0 0 0 2px rgba(196, 85, 31, 0.08);
|
|
746
736
|
}
|
|
747
737
|
|
|
748
|
-
.
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
flex: 0 0 auto;
|
|
752
|
-
display: inline-flex;
|
|
753
|
-
align-items: center;
|
|
754
|
-
justify-content: center;
|
|
755
|
-
border-radius: 11px;
|
|
756
|
-
border: 1px solid rgba(181, 146, 99, 0.34);
|
|
757
|
-
background: linear-gradient(180deg, rgba(255, 244, 232, 0.96) 0%, rgba(255, 252, 247, 0.9) 100%);
|
|
758
|
-
color: var(--accent-strong);
|
|
759
|
-
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
|
738
|
+
.tree-node-button-directory,
|
|
739
|
+
.tree-node-button-container {
|
|
740
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(249, 242, 232, 0.98) 100%);
|
|
760
741
|
}
|
|
761
742
|
|
|
762
|
-
.
|
|
763
|
-
|
|
764
|
-
height: 18px;
|
|
765
|
-
display: block;
|
|
743
|
+
.tree-node-row-container .tree-node-button-container {
|
|
744
|
+
padding-right: 52px;
|
|
766
745
|
}
|
|
767
746
|
|
|
768
|
-
.
|
|
747
|
+
.tree-node-main {
|
|
748
|
+
min-width: 0;
|
|
769
749
|
display: flex;
|
|
770
|
-
flex-
|
|
771
|
-
gap:
|
|
772
|
-
align-items: center;
|
|
750
|
+
flex-direction: column;
|
|
751
|
+
gap: 6px;
|
|
773
752
|
}
|
|
774
753
|
|
|
775
|
-
.
|
|
776
|
-
|
|
777
|
-
align-items: center;
|
|
778
|
-
gap: 4px;
|
|
779
|
-
min-height: 26px;
|
|
780
|
-
padding: 4px 10px;
|
|
781
|
-
border-radius: 999px;
|
|
782
|
-
border: 1px solid transparent;
|
|
783
|
-
font-size: 11px;
|
|
754
|
+
.tree-node-title {
|
|
755
|
+
margin-top: 0;
|
|
784
756
|
font-weight: 700;
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
.container-status-pill {
|
|
789
|
-
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
|
|
757
|
+
font-size: 13px;
|
|
758
|
+
line-height: 1.5;
|
|
759
|
+
overflow-wrap: anywhere;
|
|
790
760
|
}
|
|
791
761
|
|
|
792
|
-
.
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
762
|
+
.tree-node-button-directory .tree-node-title,
|
|
763
|
+
.tree-node-button-container .tree-node-title {
|
|
764
|
+
font-family: var(--font-mono);
|
|
765
|
+
font-size: 12px;
|
|
766
|
+
font-weight: 600;
|
|
796
767
|
}
|
|
797
768
|
|
|
798
|
-
.
|
|
769
|
+
.tree-node-meta {
|
|
799
770
|
color: #7b6d5d;
|
|
800
771
|
font-size: 11px;
|
|
801
772
|
line-height: 1.45;
|
|
802
|
-
|
|
803
|
-
overflow: hidden;
|
|
804
|
-
text-overflow: ellipsis;
|
|
773
|
+
overflow-wrap: anywhere;
|
|
805
774
|
}
|
|
806
775
|
|
|
807
|
-
.
|
|
808
|
-
|
|
809
|
-
padding: 7px 11px;
|
|
776
|
+
.tree-node-status {
|
|
777
|
+
font-weight: 700;
|
|
810
778
|
font-size: 12px;
|
|
811
|
-
border-radius: 999px;
|
|
812
|
-
white-space: nowrap;
|
|
813
|
-
margin-bottom: 2px;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
.agent-list {
|
|
817
|
-
display: flex;
|
|
818
|
-
flex-direction: column;
|
|
819
|
-
gap: 7px;
|
|
820
779
|
}
|
|
821
780
|
|
|
822
|
-
.
|
|
823
|
-
|
|
824
|
-
padding: 10px;
|
|
825
|
-
border: 1px solid rgba(181, 146, 99, 0.28);
|
|
826
|
-
border-top-color: rgba(181, 146, 99, 0.4);
|
|
827
|
-
border-radius: 13px;
|
|
828
|
-
background: linear-gradient(180deg, rgba(244, 238, 228, 0.88) 0%, rgba(255, 255, 255, 0.98) 100%);
|
|
829
|
-
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.88);
|
|
781
|
+
.tree-node-status.running {
|
|
782
|
+
color: var(--status-running-text);
|
|
830
783
|
}
|
|
831
784
|
|
|
832
|
-
.
|
|
833
|
-
|
|
785
|
+
.tree-node-status.stopped {
|
|
786
|
+
color: var(--status-stopped-text);
|
|
834
787
|
}
|
|
835
788
|
|
|
836
|
-
.
|
|
837
|
-
|
|
838
|
-
width: 100%;
|
|
839
|
-
border: 1px solid rgba(181, 146, 99, 0.38);
|
|
840
|
-
background: rgba(255, 255, 255, 0.94);
|
|
841
|
-
color: var(--text);
|
|
842
|
-
border-radius: 12px;
|
|
843
|
-
padding: 10px 11px;
|
|
844
|
-
animation: itemIn 220ms ease both;
|
|
845
|
-
animation-delay: calc(var(--item-index, 0) * 24ms);
|
|
789
|
+
.tree-node-status.history {
|
|
790
|
+
color: var(--tree-history-text);
|
|
846
791
|
}
|
|
847
792
|
|
|
848
|
-
.
|
|
849
|
-
|
|
850
|
-
background: #fff8ef;
|
|
793
|
+
.tree-node-status.unknown {
|
|
794
|
+
color: var(--status-unknown-text);
|
|
851
795
|
}
|
|
852
796
|
|
|
853
|
-
.
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
797
|
+
.tree-node-hover-menu {
|
|
798
|
+
position: absolute;
|
|
799
|
+
top: 50%;
|
|
800
|
+
right: 10px;
|
|
801
|
+
display: inline-flex;
|
|
802
|
+
align-items: center;
|
|
803
|
+
gap: 6px;
|
|
804
|
+
opacity: 0;
|
|
805
|
+
pointer-events: none;
|
|
806
|
+
transform: translateY(-50%) translateX(4px);
|
|
807
|
+
transition: opacity 140ms ease, transform 140ms ease;
|
|
857
808
|
}
|
|
858
809
|
|
|
859
|
-
.
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
810
|
+
.tree-node-row-container:hover .tree-node-hover-menu,
|
|
811
|
+
.tree-node-hover-menu:focus-within {
|
|
812
|
+
opacity: 1;
|
|
813
|
+
pointer-events: auto;
|
|
814
|
+
transform: translateY(-50%) translateX(0);
|
|
864
815
|
}
|
|
865
816
|
|
|
866
|
-
.
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
817
|
+
.tree-node-menu-item {
|
|
818
|
+
padding: 6px 9px;
|
|
819
|
+
font-size: 11px;
|
|
820
|
+
border-radius: 999px;
|
|
821
|
+
white-space: nowrap;
|
|
822
|
+
box-shadow: 0 10px 22px rgba(44, 31, 15, 0.12);
|
|
871
823
|
}
|
|
872
824
|
|
|
873
|
-
.
|
|
874
|
-
|
|
875
|
-
font-size: 11px;
|
|
876
|
-
color: #7b6d5d;
|
|
825
|
+
.tree-node-children[hidden] {
|
|
826
|
+
display: none;
|
|
877
827
|
}
|
|
878
828
|
|
|
879
829
|
.dir-picker-modal {
|
|
@@ -1516,6 +1466,36 @@ details.trace-card > .trace-card-summary {
|
|
|
1516
1466
|
cursor: pointer;
|
|
1517
1467
|
}
|
|
1518
1468
|
|
|
1469
|
+
.trace-card.trace-card-compact {
|
|
1470
|
+
border-left-width: 2px;
|
|
1471
|
+
border-radius: 999px;
|
|
1472
|
+
background: rgba(255, 251, 245, 0.78);
|
|
1473
|
+
box-shadow: none;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
.trace-card.trace-card-compact .trace-card-summary {
|
|
1477
|
+
padding: 5px 10px;
|
|
1478
|
+
gap: 7px;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
.trace-card.trace-card-compact .trace-card-badge {
|
|
1482
|
+
min-width: 0;
|
|
1483
|
+
padding: 2px 6px;
|
|
1484
|
+
background: rgba(31, 26, 20, 0.06);
|
|
1485
|
+
font-size: 10px;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
.trace-card.trace-card-compact .trace-card-title {
|
|
1489
|
+
font-size: 11px;
|
|
1490
|
+
font-weight: 500;
|
|
1491
|
+
color: #6e6256;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
.trace-card.trace-card-compact .trace-card-phase {
|
|
1495
|
+
font-size: 10px;
|
|
1496
|
+
color: #8a7d70;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1519
1499
|
.trace-card-summary::-webkit-details-marker {
|
|
1520
1500
|
display: none;
|
|
1521
1501
|
}
|
package/lib/web/frontend/app.js
CHANGED
|
@@ -354,6 +354,34 @@
|
|
|
354
354
|
return 'neutral';
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
+
function shouldCompactTraceEvent(traceEvent) {
|
|
358
|
+
const event = traceEvent && typeof traceEvent === 'object' ? traceEvent : {};
|
|
359
|
+
const phase = event.phase ? String(event.phase) : '';
|
|
360
|
+
const kind = event.kind ? String(event.kind) : '';
|
|
361
|
+
if (phase !== 'completed') {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
return kind === 'command' || kind === 'mcp' || kind === 'tool';
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function buildCompactTraceText(traceEvent) {
|
|
368
|
+
const event = traceEvent && typeof traceEvent === 'object' ? traceEvent : {};
|
|
369
|
+
if (event.kind === 'command') {
|
|
370
|
+
const suffix = typeof event.exitCode === 'number'
|
|
371
|
+
? `exit ${event.exitCode}`
|
|
372
|
+
: (event.status ? String(event.status) : 'completed');
|
|
373
|
+
return `${event.command || event.text || '命令'} · ${suffix}`;
|
|
374
|
+
}
|
|
375
|
+
if (event.kind === 'mcp') {
|
|
376
|
+
const toolLabel = [event.server, event.tool].filter(Boolean).join('.') || event.text || 'MCP';
|
|
377
|
+
return event.argumentSummary ? `${toolLabel} · ${event.argumentSummary}` : toolLabel;
|
|
378
|
+
}
|
|
379
|
+
if (event.kind === 'tool') {
|
|
380
|
+
return event.toolName || event.text || '工具';
|
|
381
|
+
}
|
|
382
|
+
return event.text || '事件';
|
|
383
|
+
}
|
|
384
|
+
|
|
357
385
|
function appendTraceCardBody(cardBody, label, value) {
|
|
358
386
|
const text = stringifyPrettyJson(value).trim();
|
|
359
387
|
if (!text) {
|
|
@@ -377,11 +405,12 @@
|
|
|
377
405
|
|
|
378
406
|
function createTraceEventCard(traceEvent) {
|
|
379
407
|
const event = traceEvent && typeof traceEvent === 'object' ? traceEvent : {};
|
|
408
|
+
const compact = shouldCompactTraceEvent(event);
|
|
380
409
|
const bodyParts = [];
|
|
381
|
-
if (event.kind === 'command' && event.command) {
|
|
410
|
+
if (!compact && event.kind === 'command' && event.command) {
|
|
382
411
|
bodyParts.push({ label: '命令', value: event.command });
|
|
383
412
|
}
|
|
384
|
-
if (event.kind === 'mcp') {
|
|
413
|
+
if (!compact && event.kind === 'mcp') {
|
|
385
414
|
if (event.argumentSummary) {
|
|
386
415
|
bodyParts.push({ label: '参数摘要', value: event.argumentSummary });
|
|
387
416
|
}
|
|
@@ -395,7 +424,7 @@
|
|
|
395
424
|
bodyParts.push({ label: '错误', value: event.error });
|
|
396
425
|
}
|
|
397
426
|
}
|
|
398
|
-
if (event.kind === 'tool' && event.toolName) {
|
|
427
|
+
if (!compact && event.kind === 'tool' && event.toolName) {
|
|
399
428
|
bodyParts.push({ label: '工具', value: event.toolName });
|
|
400
429
|
}
|
|
401
430
|
if ((event.kind === 'agent_message' || event.kind === 'status' || event.kind === 'error') && event.detail) {
|
|
@@ -404,7 +433,7 @@
|
|
|
404
433
|
|
|
405
434
|
const hasBody = bodyParts.length > 0;
|
|
406
435
|
const card = document.createElement(hasBody ? 'details' : 'div');
|
|
407
|
-
card.className = 'trace-card trace-tone-' + resolveTraceTone(event);
|
|
436
|
+
card.className = 'trace-card trace-tone-' + resolveTraceTone(event) + (compact ? ' trace-card-compact' : '');
|
|
408
437
|
if (hasBody && event.kind === 'error') {
|
|
409
438
|
card.open = true;
|
|
410
439
|
}
|
|
@@ -419,7 +448,7 @@
|
|
|
419
448
|
|
|
420
449
|
const title = document.createElement('span');
|
|
421
450
|
title.className = 'trace-card-title';
|
|
422
|
-
title.textContent = event && event.text ? String(event.text) : '事件';
|
|
451
|
+
title.textContent = compact ? buildCompactTraceText(event) : (event && event.text ? String(event.text) : '事件');
|
|
423
452
|
header.appendChild(title);
|
|
424
453
|
|
|
425
454
|
const phaseText = humanizeTracePhase(event);
|
|
@@ -2193,7 +2222,7 @@
|
|
|
2193
2222
|
}
|
|
2194
2223
|
}
|
|
2195
2224
|
}
|
|
2196
|
-
|
|
2225
|
+
updateSidebarActiveSelection();
|
|
2197
2226
|
syncUi();
|
|
2198
2227
|
Promise.all([
|
|
2199
2228
|
loadMessagesForSession(sessionName),
|
|
@@ -2281,173 +2310,244 @@
|
|
|
2281
2310
|
return (parts || []).filter(Boolean).join(' · ');
|
|
2282
2311
|
}
|
|
2283
2312
|
|
|
2284
|
-
function
|
|
2285
|
-
const opts = options && typeof options === 'object' ? options : {};
|
|
2313
|
+
function createDisclosureButton(expanded, label) {
|
|
2286
2314
|
const button = document.createElement('button');
|
|
2287
2315
|
button.type = 'button';
|
|
2288
|
-
button.className =
|
|
2289
|
-
button.
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
const kicker = document.createElement('div');
|
|
2295
|
-
kicker.className = opts.kickerClassName || 'workbench-group-kicker';
|
|
2296
|
-
kicker.textContent = opts.kicker || '';
|
|
2297
|
-
main.appendChild(kicker);
|
|
2298
|
-
|
|
2299
|
-
const title = document.createElement('div');
|
|
2300
|
-
title.className = opts.titleClassName || 'workbench-group-title';
|
|
2301
|
-
title.textContent = opts.title || '';
|
|
2302
|
-
title.title = opts.title || '';
|
|
2303
|
-
main.appendChild(title);
|
|
2304
|
-
|
|
2305
|
-
const metaText = createTreeMetaText(opts.metaParts);
|
|
2306
|
-
if (metaText) {
|
|
2307
|
-
const meta = document.createElement('div');
|
|
2308
|
-
meta.className = 'tree-toggle-meta';
|
|
2309
|
-
meta.textContent = metaText;
|
|
2310
|
-
main.appendChild(meta);
|
|
2311
|
-
}
|
|
2312
|
-
|
|
2313
|
-
const caret = document.createElement('span');
|
|
2314
|
-
caret.className = 'tree-toggle-caret';
|
|
2315
|
-
caret.setAttribute('aria-hidden', 'true');
|
|
2316
|
-
caret.textContent = '›';
|
|
2317
|
-
|
|
2318
|
-
button.appendChild(main);
|
|
2319
|
-
button.appendChild(caret);
|
|
2320
|
-
|
|
2321
|
-
if (typeof opts.onClick === 'function') {
|
|
2322
|
-
button.addEventListener('click', opts.onClick);
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2316
|
+
button.className = 'disclosure-toggle';
|
|
2317
|
+
button.dataset.disclosureLabel = label || '';
|
|
2318
|
+
button.setAttribute('aria-expanded', expanded ? 'true' : 'false');
|
|
2319
|
+
button.setAttribute('aria-label', `${expanded ? '折叠' : '展开'}${label ? ` ${label}` : ''}`);
|
|
2320
|
+
button.innerHTML = '<svg viewBox="0 0 12 12" aria-hidden="true" focusable="false"><path d="M4 2.5L8 6L4 9.5"></path></svg>';
|
|
2325
2321
|
return button;
|
|
2326
2322
|
}
|
|
2327
2323
|
|
|
2328
|
-
function
|
|
2329
|
-
const
|
|
2330
|
-
|
|
2331
|
-
|
|
2324
|
+
function createTreePrefixSegment() {
|
|
2325
|
+
const segment = document.createElement('span');
|
|
2326
|
+
segment.className = 'tree-prefix-segment';
|
|
2327
|
+
segment.setAttribute('aria-hidden', 'true');
|
|
2328
|
+
return segment;
|
|
2329
|
+
}
|
|
2332
2330
|
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2331
|
+
function createTreePrefix(ancestorHasNext, isLastSibling, options) {
|
|
2332
|
+
const opts = options && typeof options === 'object' ? options : {};
|
|
2333
|
+
const prefix = document.createElement('div');
|
|
2334
|
+
prefix.className = 'tree-prefix';
|
|
2335
|
+
|
|
2336
|
+
(Array.isArray(ancestorHasNext) ? ancestorHasNext : []).forEach(function () {
|
|
2337
|
+
prefix.appendChild(createTreePrefixSegment());
|
|
2338
|
+
});
|
|
2339
|
+
|
|
2340
|
+
const branch = document.createElement('span');
|
|
2341
|
+
branch.className = `tree-prefix-branch ${isLastSibling ? 'is-last' : 'is-mid'}`;
|
|
2342
|
+
branch.setAttribute('aria-hidden', 'true');
|
|
2343
|
+
prefix.appendChild(branch);
|
|
2344
|
+
|
|
2345
|
+
let disclosure = null;
|
|
2346
|
+
let disclosureWrap = null;
|
|
2347
|
+
if (opts.expandable) {
|
|
2348
|
+
disclosure = createDisclosureButton(!!opts.expanded, opts.label || '');
|
|
2349
|
+
disclosureWrap = document.createElement('span');
|
|
2350
|
+
disclosureWrap.className = 'tree-prefix-toggle';
|
|
2351
|
+
disclosureWrap.appendChild(disclosure);
|
|
2352
|
+
prefix.appendChild(disclosureWrap);
|
|
2353
|
+
} else {
|
|
2354
|
+
const leaf = document.createElement('span');
|
|
2355
|
+
leaf.className = 'tree-prefix-leaf';
|
|
2356
|
+
leaf.setAttribute('aria-hidden', 'true');
|
|
2357
|
+
prefix.appendChild(leaf);
|
|
2341
2358
|
}
|
|
2342
2359
|
|
|
2343
|
-
return
|
|
2360
|
+
return { root: prefix, disclosure, disclosureWrap };
|
|
2344
2361
|
}
|
|
2345
2362
|
|
|
2346
|
-
function
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2363
|
+
function setDisclosureExpanded(control, expanded) {
|
|
2364
|
+
if (!control) {
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
const nextValue = expanded ? 'true' : 'false';
|
|
2368
|
+
if (control.button) {
|
|
2369
|
+
control.button.setAttribute('aria-expanded', nextValue);
|
|
2370
|
+
}
|
|
2371
|
+
if (control.disclosure) {
|
|
2372
|
+
control.disclosure.setAttribute('aria-expanded', nextValue);
|
|
2373
|
+
const label = control.disclosure.dataset.disclosureLabel || '';
|
|
2374
|
+
control.disclosure.setAttribute('aria-label', `${expanded ? '折叠' : '展开'}${label ? ` ${label}` : ''}`);
|
|
2375
|
+
}
|
|
2351
2376
|
}
|
|
2352
2377
|
|
|
2353
|
-
function
|
|
2354
|
-
const
|
|
2378
|
+
function createTreeItem(options) {
|
|
2379
|
+
const opts = options && typeof options === 'object' ? options : {};
|
|
2380
|
+
const row = document.createElement('div');
|
|
2381
|
+
row.className = `tree-node-row tree-node-row-${opts.kind || 'item'} ${opts.rowClassName || ''}`.trim();
|
|
2382
|
+
row.classList.toggle('has-active', !!opts.hasActive);
|
|
2383
|
+
row.setAttribute('role', 'none');
|
|
2384
|
+
|
|
2385
|
+
const prefixControl = createTreePrefix(opts.ancestorHasNext, !!opts.isLastSibling, {
|
|
2386
|
+
expandable: !!opts.expandable,
|
|
2387
|
+
expanded: !!opts.expanded,
|
|
2388
|
+
label: opts.disclosureLabel || opts.title || ''
|
|
2389
|
+
});
|
|
2390
|
+
row.appendChild(prefixControl.root);
|
|
2391
|
+
|
|
2355
2392
|
const button = document.createElement('button');
|
|
2356
2393
|
button.type = 'button';
|
|
2357
|
-
button.className =
|
|
2358
|
-
button.setAttribute('
|
|
2394
|
+
button.className = `tree-node-button tree-node-button-${opts.kind || 'item'} ${opts.className || ''}`.trim();
|
|
2395
|
+
button.setAttribute('role', 'treeitem');
|
|
2396
|
+
button.setAttribute('aria-level', String(opts.level || 1));
|
|
2397
|
+
if (opts.expandable) {
|
|
2398
|
+
button.setAttribute('aria-expanded', opts.expanded ? 'true' : 'false');
|
|
2399
|
+
}
|
|
2400
|
+
if (opts.kind === 'agent') {
|
|
2401
|
+
button.setAttribute('aria-selected', opts.active ? 'true' : 'false');
|
|
2402
|
+
}
|
|
2403
|
+
button.classList.toggle('active', !!opts.active);
|
|
2359
2404
|
|
|
2360
2405
|
const main = document.createElement('div');
|
|
2361
|
-
main.className = '
|
|
2362
|
-
|
|
2363
|
-
const titleRow = document.createElement('div');
|
|
2364
|
-
titleRow.className = 'container-title-row';
|
|
2365
|
-
titleRow.appendChild(createSidebarIcon('cube'));
|
|
2366
|
-
|
|
2367
|
-
const titleStack = document.createElement('div');
|
|
2368
|
-
titleStack.className = 'container-title-stack';
|
|
2369
|
-
|
|
2370
|
-
const kicker = document.createElement('div');
|
|
2371
|
-
kicker.className = 'container-card-kicker';
|
|
2372
|
-
kicker.textContent = '容器';
|
|
2406
|
+
main.className = 'tree-node-main';
|
|
2373
2407
|
|
|
2374
2408
|
const title = document.createElement('div');
|
|
2375
|
-
title.className = '
|
|
2376
|
-
title.textContent =
|
|
2377
|
-
title.title = title
|
|
2378
|
-
|
|
2379
|
-
titleStack.appendChild(kicker);
|
|
2380
|
-
titleStack.appendChild(title);
|
|
2381
|
-
titleRow.appendChild(titleStack);
|
|
2382
|
-
main.appendChild(titleRow);
|
|
2409
|
+
title.className = opts.titleClassName || 'tree-node-title';
|
|
2410
|
+
title.textContent = opts.title || '';
|
|
2411
|
+
title.title = opts.title || '';
|
|
2412
|
+
main.appendChild(title);
|
|
2383
2413
|
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
const infoText = createTreeMetaText([
|
|
2391
|
-
containerGroup && containerGroup.image ? containerGroup.image : '',
|
|
2392
|
-
formatDateTime(containerGroup && containerGroup.updatedAt) || '暂无更新'
|
|
2393
|
-
]);
|
|
2394
|
-
if (infoText) {
|
|
2395
|
-
const info = document.createElement('div');
|
|
2396
|
-
info.className = 'container-card-info';
|
|
2397
|
-
info.textContent = infoText;
|
|
2398
|
-
info.title = infoText;
|
|
2399
|
-
main.appendChild(info);
|
|
2400
|
-
}
|
|
2401
|
-
|
|
2402
|
-
const caret = document.createElement('span');
|
|
2403
|
-
caret.className = 'tree-toggle-caret';
|
|
2404
|
-
caret.setAttribute('aria-hidden', 'true');
|
|
2405
|
-
caret.textContent = '›';
|
|
2414
|
+
if (opts.meta) {
|
|
2415
|
+
const meta = document.createElement('div');
|
|
2416
|
+
meta.className = `tree-node-meta ${opts.metaClassName || ''}`.trim();
|
|
2417
|
+
meta.textContent = opts.meta;
|
|
2418
|
+
main.appendChild(meta);
|
|
2419
|
+
}
|
|
2406
2420
|
|
|
2407
2421
|
button.appendChild(main);
|
|
2408
|
-
|
|
2422
|
+
row.appendChild(button);
|
|
2423
|
+
if (opts.overlayNode) {
|
|
2424
|
+
row.appendChild(opts.overlayNode);
|
|
2425
|
+
}
|
|
2409
2426
|
|
|
2410
|
-
|
|
2427
|
+
const control = {
|
|
2428
|
+
root: row,
|
|
2429
|
+
button,
|
|
2430
|
+
disclosure: prefixControl.disclosure
|
|
2431
|
+
};
|
|
2432
|
+
setDisclosureExpanded(control, !!opts.expanded);
|
|
2433
|
+
return control;
|
|
2411
2434
|
}
|
|
2412
2435
|
|
|
2413
|
-
function
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2436
|
+
function buildSessionTreeNodes(grouped) {
|
|
2437
|
+
return (Array.isArray(grouped) ? grouped : []).map(function (directoryGroup) {
|
|
2438
|
+
return {
|
|
2439
|
+
kind: 'directory',
|
|
2440
|
+
title: directoryGroup.path,
|
|
2441
|
+
disclosureLabel: directoryGroup.path,
|
|
2442
|
+
expanded: isDirectoryExpanded(directoryGroup),
|
|
2443
|
+
hasActive: directoryContainsActiveSession(directoryGroup),
|
|
2444
|
+
onToggle: function (expanded) {
|
|
2445
|
+
setSidebarDirectoryExpanded(directoryGroup.path, expanded);
|
|
2446
|
+
},
|
|
2447
|
+
children: (Array.isArray(directoryGroup.containers) ? directoryGroup.containers : []).map(function (containerGroup) {
|
|
2448
|
+
const status = sessionStatusInfo(containerGroup && containerGroup.status);
|
|
2449
|
+
const historyClassName = status.tone === 'history' ? 'tree-node-tone-history' : '';
|
|
2450
|
+
const containerName = String(containerGroup && containerGroup.containerName ? containerGroup.containerName : '').trim() || '未命名容器';
|
|
2451
|
+
const hoverMenu = document.createElement('div');
|
|
2452
|
+
hoverMenu.className = 'tree-node-hover-menu';
|
|
2453
|
+
|
|
2454
|
+
const addAgentBtn = document.createElement('button');
|
|
2455
|
+
addAgentBtn.type = 'button';
|
|
2456
|
+
addAgentBtn.className = 'secondary tree-node-menu-item';
|
|
2457
|
+
addAgentBtn.textContent = '新建AGENT';
|
|
2458
|
+
addAgentBtn.addEventListener('click', function (event) {
|
|
2459
|
+
event.stopPropagation();
|
|
2460
|
+
createAgentSession(containerName);
|
|
2461
|
+
});
|
|
2462
|
+
hoverMenu.appendChild(addAgentBtn);
|
|
2463
|
+
|
|
2464
|
+
return {
|
|
2465
|
+
kind: 'container',
|
|
2466
|
+
title: containerName,
|
|
2467
|
+
meta: status.label,
|
|
2468
|
+
metaClassName: `tree-node-status ${status.tone}`,
|
|
2469
|
+
className: historyClassName,
|
|
2470
|
+
disclosureLabel: containerName,
|
|
2471
|
+
expanded: isContainerExpanded(containerGroup),
|
|
2472
|
+
hasActive: containerContainsActiveSession(containerGroup),
|
|
2473
|
+
overlayNode: hoverMenu,
|
|
2474
|
+
onToggle: function (expanded) {
|
|
2475
|
+
setSidebarContainerExpanded(containerGroup.containerName, expanded);
|
|
2476
|
+
},
|
|
2477
|
+
children: (Array.isArray(containerGroup.sessions) ? containerGroup.sessions : []).map(function (session) {
|
|
2478
|
+
return {
|
|
2479
|
+
kind: 'agent',
|
|
2480
|
+
title: session.agentName || session.name,
|
|
2481
|
+
meta: formatDateTime(session.updatedAt) || '暂无更新',
|
|
2482
|
+
className: historyClassName,
|
|
2483
|
+
active: state.active === session.name,
|
|
2484
|
+
sessionName: session.name
|
|
2485
|
+
};
|
|
2486
|
+
})
|
|
2487
|
+
};
|
|
2488
|
+
})
|
|
2489
|
+
};
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2428
2492
|
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2493
|
+
function renderSessionTreeNodes(nodes, parentNode, ancestorHasNext, itemCounter) {
|
|
2494
|
+
(Array.isArray(nodes) ? nodes : []).forEach(function (node, index) {
|
|
2495
|
+
const isLastSibling = index === nodes.length - 1;
|
|
2496
|
+
const item = createTreeItem({
|
|
2497
|
+
kind: node.kind,
|
|
2498
|
+
title: node.title,
|
|
2499
|
+
meta: node.meta,
|
|
2500
|
+
className: node.className,
|
|
2501
|
+
metaClassName: node.metaClassName,
|
|
2502
|
+
disclosureLabel: node.disclosureLabel,
|
|
2503
|
+
expandable: Array.isArray(node.children) && node.children.length > 0,
|
|
2504
|
+
expanded: !!node.expanded,
|
|
2505
|
+
active: !!node.active,
|
|
2506
|
+
hasActive: !!node.hasActive,
|
|
2507
|
+
level: ancestorHasNext.length + 1,
|
|
2508
|
+
ancestorHasNext: ancestorHasNext,
|
|
2509
|
+
isLastSibling: isLastSibling,
|
|
2510
|
+
overlayNode: node.overlayNode
|
|
2511
|
+
});
|
|
2432
2512
|
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2513
|
+
if (node.kind === 'agent') {
|
|
2514
|
+
item.button.dataset.sessionName = node.sessionName || '';
|
|
2515
|
+
item.button.style.setProperty('--item-index', String(itemCounter.value));
|
|
2516
|
+
itemCounter.value += 1;
|
|
2517
|
+
state.sessionNodeMap.set(node.sessionName, item.button);
|
|
2518
|
+
item.button.addEventListener('click', function () {
|
|
2519
|
+
handleSessionItemClick(node.sessionName || '');
|
|
2520
|
+
});
|
|
2521
|
+
parentNode.appendChild(item.root);
|
|
2522
|
+
return;
|
|
2523
|
+
}
|
|
2436
2524
|
|
|
2437
|
-
|
|
2438
|
-
|
|
2525
|
+
const block = document.createElement('section');
|
|
2526
|
+
block.className = `tree-node-block tree-node-block-${node.kind}`;
|
|
2527
|
+
block.classList.toggle('has-active', !!node.hasActive);
|
|
2528
|
+
block.appendChild(item.root);
|
|
2439
2529
|
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2530
|
+
const childrenNode = document.createElement('div');
|
|
2531
|
+
childrenNode.className = `tree-node-children tree-node-children-${node.kind}`;
|
|
2532
|
+
childrenNode.setAttribute('role', 'group');
|
|
2533
|
+
childrenNode.hidden = !node.expanded;
|
|
2534
|
+
renderSessionTreeNodes(node.children || [], childrenNode, ancestorHasNext.concat(!isLastSibling), itemCounter);
|
|
2535
|
+
block.appendChild(childrenNode);
|
|
2536
|
+
parentNode.appendChild(block);
|
|
2443
2537
|
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2538
|
+
const toggleNode = function () {
|
|
2539
|
+
const nextExpanded = childrenNode.hidden;
|
|
2540
|
+
if (typeof node.onToggle === 'function') {
|
|
2541
|
+
node.onToggle(nextExpanded);
|
|
2542
|
+
}
|
|
2543
|
+
setDisclosureExpanded(item, nextExpanded);
|
|
2544
|
+
childrenNode.hidden = !nextExpanded;
|
|
2545
|
+
};
|
|
2546
|
+
item.button.addEventListener('click', toggleNode);
|
|
2547
|
+
if (item.disclosure) {
|
|
2548
|
+
item.disclosure.addEventListener('click', toggleNode);
|
|
2549
|
+
}
|
|
2449
2550
|
});
|
|
2450
|
-
return btn;
|
|
2451
2551
|
}
|
|
2452
2552
|
|
|
2453
2553
|
function scrollActiveSessionIntoView() {
|
|
@@ -2463,6 +2563,37 @@
|
|
|
2463
2563
|
}
|
|
2464
2564
|
}
|
|
2465
2565
|
|
|
2566
|
+
function updateSidebarActiveSelection() {
|
|
2567
|
+
state.sessionNodeMap.forEach(function (buttonNode, sessionName) {
|
|
2568
|
+
const isActive = sessionName === state.active;
|
|
2569
|
+
if (!buttonNode) {
|
|
2570
|
+
return;
|
|
2571
|
+
}
|
|
2572
|
+
buttonNode.classList.toggle('active', isActive);
|
|
2573
|
+
buttonNode.setAttribute('aria-selected', isActive ? 'true' : 'false');
|
|
2574
|
+
});
|
|
2575
|
+
|
|
2576
|
+
if (!sessionList) {
|
|
2577
|
+
return;
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2580
|
+
sessionList.querySelectorAll('.tree-node-block.has-active').forEach(function (blockNode) {
|
|
2581
|
+
blockNode.classList.remove('has-active');
|
|
2582
|
+
});
|
|
2583
|
+
|
|
2584
|
+
const activeNode = state.sessionNodeMap.get(state.active);
|
|
2585
|
+
let cursor = activeNode ? activeNode.parentElement : null;
|
|
2586
|
+
while (cursor && cursor !== sessionList) {
|
|
2587
|
+
if (cursor.classList && cursor.classList.contains('tree-node-children')) {
|
|
2588
|
+
const blockNode = cursor.parentElement;
|
|
2589
|
+
if (blockNode && blockNode.classList && blockNode.classList.contains('tree-node-block')) {
|
|
2590
|
+
blockNode.classList.add('has-active');
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
cursor = cursor.parentElement;
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2466
2597
|
function renderSessions() {
|
|
2467
2598
|
const containerCount = new Set(state.sessions.map(function (session) {
|
|
2468
2599
|
return session && session.containerName ? session.containerName : '';
|
|
@@ -2492,88 +2623,10 @@
|
|
|
2492
2623
|
state.sessionRenderMode = 'tree';
|
|
2493
2624
|
|
|
2494
2625
|
const grouped = groupSessionsByDirectory(state.sessions);
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
const directoryHasActive = directoryContainsActiveSession(directoryGroup);
|
|
2500
|
-
const group = document.createElement('section');
|
|
2501
|
-
group.className = 'workbench-group';
|
|
2502
|
-
group.classList.toggle('has-active', directoryHasActive);
|
|
2503
|
-
|
|
2504
|
-
const groupHead = createTreeToggle({
|
|
2505
|
-
className: 'workbench-group-head workbench-path-bar',
|
|
2506
|
-
kickerClassName: 'workbench-group-kicker',
|
|
2507
|
-
titleClassName: 'workbench-group-title',
|
|
2508
|
-
kicker: '路径分组',
|
|
2509
|
-
title: directoryGroup.path,
|
|
2510
|
-
expanded: directoryExpanded,
|
|
2511
|
-
metaParts: [
|
|
2512
|
-
`${directoryGroup.containers.length} 容器`,
|
|
2513
|
-
`${directoryGroup.containers.reduce(function (count, containerGroup) {
|
|
2514
|
-
return count + containerGroup.sessions.length;
|
|
2515
|
-
}, 0)} AGENT`,
|
|
2516
|
-
formatDateTime(directoryGroup.updatedAt) || '暂无更新'
|
|
2517
|
-
]
|
|
2518
|
-
});
|
|
2519
|
-
group.appendChild(groupHead);
|
|
2520
|
-
|
|
2521
|
-
const containerStack = document.createElement('div');
|
|
2522
|
-
containerStack.className = 'container-stack workbench-group-body';
|
|
2523
|
-
containerStack.hidden = !directoryExpanded;
|
|
2524
|
-
groupHead.addEventListener('click', function () {
|
|
2525
|
-
const nextExpanded = containerStack.hidden;
|
|
2526
|
-
setSidebarDirectoryExpanded(directoryGroup.path, nextExpanded);
|
|
2527
|
-
groupHead.setAttribute('aria-expanded', nextExpanded ? 'true' : 'false');
|
|
2528
|
-
containerStack.hidden = !nextExpanded;
|
|
2529
|
-
});
|
|
2530
|
-
|
|
2531
|
-
directoryGroup.containers.forEach(function (containerGroup) {
|
|
2532
|
-
const containerExpanded = isContainerExpanded(containerGroup);
|
|
2533
|
-
const containerHasActive = containerContainsActiveSession(containerGroup);
|
|
2534
|
-
const containerCard = document.createElement('section');
|
|
2535
|
-
containerCard.className = 'container-card';
|
|
2536
|
-
containerCard.classList.toggle('has-active', containerHasActive);
|
|
2537
|
-
|
|
2538
|
-
const containerHead = document.createElement('div');
|
|
2539
|
-
containerHead.className = 'container-card-head';
|
|
2540
|
-
|
|
2541
|
-
const containerToggle = createContainerToggle(containerGroup, containerExpanded);
|
|
2542
|
-
|
|
2543
|
-
const addAgentBtn = document.createElement('button');
|
|
2544
|
-
addAgentBtn.type = 'button';
|
|
2545
|
-
addAgentBtn.className = 'secondary add-agent-btn';
|
|
2546
|
-
addAgentBtn.textContent = '新建AGENT';
|
|
2547
|
-
addAgentBtn.addEventListener('click', function () {
|
|
2548
|
-
createAgentSession(containerGroup.containerName);
|
|
2549
|
-
});
|
|
2550
|
-
|
|
2551
|
-
containerHead.appendChild(containerToggle);
|
|
2552
|
-
containerCard.appendChild(containerHead);
|
|
2553
|
-
|
|
2554
|
-
const agentList = document.createElement('div');
|
|
2555
|
-
agentList.className = 'agent-list container-card-body';
|
|
2556
|
-
agentList.hidden = !containerExpanded;
|
|
2557
|
-
containerToggle.addEventListener('click', function () {
|
|
2558
|
-
const nextExpanded = agentList.hidden;
|
|
2559
|
-
setSidebarContainerExpanded(containerGroup.containerName, nextExpanded);
|
|
2560
|
-
containerToggle.setAttribute('aria-expanded', nextExpanded ? 'true' : 'false');
|
|
2561
|
-
agentList.hidden = !nextExpanded;
|
|
2562
|
-
});
|
|
2563
|
-
agentList.appendChild(addAgentBtn);
|
|
2564
|
-
containerGroup.sessions.forEach(function (session) {
|
|
2565
|
-
const row = createAgentRow(session, itemIndex);
|
|
2566
|
-
state.sessionNodeMap.set(session.name, row);
|
|
2567
|
-
agentList.appendChild(row);
|
|
2568
|
-
itemIndex += 1;
|
|
2569
|
-
});
|
|
2570
|
-
containerCard.appendChild(agentList);
|
|
2571
|
-
containerStack.appendChild(containerCard);
|
|
2572
|
-
});
|
|
2573
|
-
|
|
2574
|
-
group.appendChild(containerStack);
|
|
2575
|
-
sessionList.appendChild(group);
|
|
2576
|
-
});
|
|
2626
|
+
const treeNodes = buildSessionTreeNodes(grouped);
|
|
2627
|
+
const itemCounter = { value: 0 };
|
|
2628
|
+
renderSessionTreeNodes(treeNodes, sessionList, [], itemCounter);
|
|
2629
|
+
updateSidebarActiveSelection();
|
|
2577
2630
|
|
|
2578
2631
|
scrollActiveSessionIntoView();
|
|
2579
2632
|
}
|