@principal-ade/code-quality-panels 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/QualityHexagon.d.ts +11 -1
- package/dist/components/QualityHexagon.d.ts.map +1 -1
- package/dist/components/RepositoryQualityGrid.d.ts +11 -15
- package/dist/components/RepositoryQualityGrid.d.ts.map +1 -1
- package/dist/components/RepositoryQualityGrid.stories.d.ts +1 -0
- package/dist/components/RepositoryQualityGrid.stories.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/panels/RepositoryQualityGridPanel.d.ts +8 -0
- package/dist/panels/RepositoryQualityGridPanel.d.ts.map +1 -0
- package/dist/panels/RepositoryQualityGridPanel.stories.d.ts +26 -0
- package/dist/panels/RepositoryQualityGridPanel.stories.d.ts.map +1 -0
- package/dist/panels.bundle.js +420 -84
- package/dist/panels.bundle.js.map +1 -1
- package/package.json +1 -1
package/dist/panels.bundle.js
CHANGED
|
@@ -443,7 +443,10 @@ function QualityHexagon({
|
|
|
443
443
|
theme: theme2,
|
|
444
444
|
showLabels = false,
|
|
445
445
|
showValues = false,
|
|
446
|
-
className
|
|
446
|
+
className,
|
|
447
|
+
onVertexHover,
|
|
448
|
+
onVertexLeave,
|
|
449
|
+
onVertexClick
|
|
447
450
|
}) {
|
|
448
451
|
const themeColors = getThemeColors(theme2);
|
|
449
452
|
const colors = themeColors.tierColors[tier] ?? themeColors.tierColors.none;
|
|
@@ -523,38 +526,71 @@ function QualityHexagon({
|
|
|
523
526
|
style: { transition: "all 0.5s ease" }
|
|
524
527
|
}
|
|
525
528
|
),
|
|
526
|
-
metricConfig.map(({ key, angle }) => {
|
|
527
|
-
|
|
529
|
+
metricConfig.map(({ key, label, color, angle }) => {
|
|
530
|
+
const rawValue = metrics[key];
|
|
531
|
+
let value = rawValue;
|
|
528
532
|
if (key === "deadCode") {
|
|
529
533
|
value = 100 - value;
|
|
530
534
|
}
|
|
531
535
|
const point = calculateMetricPoint(center, radius, angle, 100);
|
|
532
536
|
const dataPoint = calculateMetricPoint(center, radius, angle, value);
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
)
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
537
|
+
const vertexInfo = {
|
|
538
|
+
key,
|
|
539
|
+
label,
|
|
540
|
+
value: rawValue,
|
|
541
|
+
color
|
|
542
|
+
};
|
|
543
|
+
const handleMouseEnter = () => {
|
|
544
|
+
onVertexHover == null ? void 0 : onVertexHover(vertexInfo);
|
|
545
|
+
};
|
|
546
|
+
const handleClick = (e) => {
|
|
547
|
+
e.stopPropagation();
|
|
548
|
+
onVertexClick == null ? void 0 : onVertexClick(vertexInfo);
|
|
549
|
+
};
|
|
550
|
+
return /* @__PURE__ */ jsxs(
|
|
551
|
+
"g",
|
|
552
|
+
{
|
|
553
|
+
onMouseEnter: handleMouseEnter,
|
|
554
|
+
onMouseLeave: onVertexLeave,
|
|
555
|
+
onClick: handleClick,
|
|
556
|
+
style: { cursor: onVertexHover || onVertexClick ? "pointer" : "default" },
|
|
557
|
+
children: [
|
|
558
|
+
/* @__PURE__ */ jsx(
|
|
559
|
+
"circle",
|
|
560
|
+
{
|
|
561
|
+
cx: point.x,
|
|
562
|
+
cy: point.y,
|
|
563
|
+
r: dotSize * 2.5,
|
|
564
|
+
fill: "transparent"
|
|
565
|
+
}
|
|
566
|
+
),
|
|
567
|
+
/* @__PURE__ */ jsx(
|
|
568
|
+
"circle",
|
|
569
|
+
{
|
|
570
|
+
cx: point.x,
|
|
571
|
+
cy: point.y,
|
|
572
|
+
r: dotSize,
|
|
573
|
+
fill: "white",
|
|
574
|
+
stroke: colors.stroke,
|
|
575
|
+
strokeWidth: 1.5
|
|
576
|
+
}
|
|
577
|
+
),
|
|
578
|
+
/* @__PURE__ */ jsx(
|
|
579
|
+
"circle",
|
|
580
|
+
{
|
|
581
|
+
cx: dataPoint.x,
|
|
582
|
+
cy: dataPoint.y,
|
|
583
|
+
r: dotSize * 0.7,
|
|
584
|
+
fill: colors.fill,
|
|
585
|
+
stroke: colors.stroke,
|
|
586
|
+
strokeWidth: 1,
|
|
587
|
+
style: { opacity: 0.9 }
|
|
588
|
+
}
|
|
589
|
+
)
|
|
590
|
+
]
|
|
591
|
+
},
|
|
592
|
+
key
|
|
593
|
+
);
|
|
558
594
|
}),
|
|
559
595
|
/* @__PURE__ */ jsx(
|
|
560
596
|
"text",
|
|
@@ -1457,6 +1493,14 @@ const QualityHexagonPanelContent = ({
|
|
|
1457
1493
|
const QualityHexagonPanel = (props) => {
|
|
1458
1494
|
return /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(QualityHexagonPanelContent, { ...props }) });
|
|
1459
1495
|
};
|
|
1496
|
+
const METRIC_OPTIONS = [
|
|
1497
|
+
{ key: "types", label: "Types" },
|
|
1498
|
+
{ key: "documentation", label: "Docs" },
|
|
1499
|
+
{ key: "tests", label: "Tests" },
|
|
1500
|
+
{ key: "deadCode", label: "Dead Code" },
|
|
1501
|
+
{ key: "formatting", label: "Format" },
|
|
1502
|
+
{ key: "linting", label: "Linting" }
|
|
1503
|
+
];
|
|
1460
1504
|
function flattenRepositories(repositories) {
|
|
1461
1505
|
const items = [];
|
|
1462
1506
|
for (const repo of repositories) {
|
|
@@ -1495,13 +1539,22 @@ function formatLabel(item, showRepositoryName, isSameAsRepo) {
|
|
|
1495
1539
|
}
|
|
1496
1540
|
return `${item.repositoryName} / ${item.packageName}`;
|
|
1497
1541
|
}
|
|
1542
|
+
function getValueColor(value, key, theme2) {
|
|
1543
|
+
const effectiveValue = key === "deadCode" ? 100 - value : value;
|
|
1544
|
+
if (effectiveValue >= 80) return theme2.colors.success;
|
|
1545
|
+
if (effectiveValue >= 60) return theme2.colors.warning;
|
|
1546
|
+
return theme2.colors.error;
|
|
1547
|
+
}
|
|
1498
1548
|
function RepositoryQualityGridItem({
|
|
1499
1549
|
item,
|
|
1500
1550
|
theme: theme2,
|
|
1501
1551
|
onClick,
|
|
1552
|
+
onVertexClick,
|
|
1502
1553
|
showRepositoryName = true,
|
|
1554
|
+
selectedMetric,
|
|
1503
1555
|
className
|
|
1504
1556
|
}) {
|
|
1557
|
+
const [hoveredVertex, setHoveredVertex] = React2.useState(null);
|
|
1505
1558
|
const isSameAsRepo = item.packageName === item.repositoryName;
|
|
1506
1559
|
const label = formatLabel(item, showRepositoryName, isSameAsRepo);
|
|
1507
1560
|
const tierColors = {
|
|
@@ -1511,6 +1564,27 @@ function RepositoryQualityGridItem({
|
|
|
1511
1564
|
gold: theme2.colors.accent,
|
|
1512
1565
|
platinum: theme2.colors.primary
|
|
1513
1566
|
};
|
|
1567
|
+
const displayInfo = React2.useMemo(() => {
|
|
1568
|
+
if (selectedMetric) {
|
|
1569
|
+
const option = METRIC_OPTIONS.find((o) => o.key === selectedMetric);
|
|
1570
|
+
if (option) {
|
|
1571
|
+
const value = item.metrics[selectedMetric];
|
|
1572
|
+
return {
|
|
1573
|
+
label: option.label,
|
|
1574
|
+
value,
|
|
1575
|
+
valueColor: getValueColor(value, selectedMetric, theme2)
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
if (hoveredVertex) {
|
|
1580
|
+
return {
|
|
1581
|
+
label: hoveredVertex.label,
|
|
1582
|
+
value: hoveredVertex.value,
|
|
1583
|
+
valueColor: getValueColor(hoveredVertex.value, hoveredVertex.key, theme2)
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
return null;
|
|
1587
|
+
}, [selectedMetric, hoveredVertex, item.metrics, theme2]);
|
|
1514
1588
|
return /* @__PURE__ */ jsxs(
|
|
1515
1589
|
"div",
|
|
1516
1590
|
{
|
|
@@ -1526,8 +1600,7 @@ function RepositoryQualityGridItem({
|
|
|
1526
1600
|
backgroundColor: theme2.colors.surface,
|
|
1527
1601
|
border: `1px solid ${theme2.colors.border}`,
|
|
1528
1602
|
cursor: onClick ? "pointer" : "default",
|
|
1529
|
-
transition: "all 0.2s ease"
|
|
1530
|
-
minWidth: 100
|
|
1603
|
+
transition: "all 0.2s ease"
|
|
1531
1604
|
},
|
|
1532
1605
|
onMouseEnter: (e) => {
|
|
1533
1606
|
if (onClick) {
|
|
@@ -1538,16 +1611,63 @@ function RepositoryQualityGridItem({
|
|
|
1538
1611
|
onMouseLeave: (e) => {
|
|
1539
1612
|
e.currentTarget.style.borderColor = theme2.colors.border;
|
|
1540
1613
|
e.currentTarget.style.transform = "translateY(0)";
|
|
1614
|
+
setHoveredVertex(null);
|
|
1541
1615
|
},
|
|
1542
1616
|
children: [
|
|
1543
1617
|
/* @__PURE__ */ jsx(
|
|
1544
|
-
|
|
1618
|
+
"div",
|
|
1619
|
+
{
|
|
1620
|
+
style: {
|
|
1621
|
+
height: 24,
|
|
1622
|
+
display: "flex",
|
|
1623
|
+
alignItems: "center",
|
|
1624
|
+
justifyContent: "center",
|
|
1625
|
+
gap: 8,
|
|
1626
|
+
width: "100%",
|
|
1627
|
+
minHeight: 24
|
|
1628
|
+
},
|
|
1629
|
+
children: displayInfo ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1630
|
+
/* @__PURE__ */ jsx(
|
|
1631
|
+
"span",
|
|
1632
|
+
{
|
|
1633
|
+
style: {
|
|
1634
|
+
fontSize: 14,
|
|
1635
|
+
fontWeight: 500,
|
|
1636
|
+
color: theme2.colors.text
|
|
1637
|
+
},
|
|
1638
|
+
children: displayInfo.label
|
|
1639
|
+
}
|
|
1640
|
+
),
|
|
1641
|
+
/* @__PURE__ */ jsxs(
|
|
1642
|
+
"span",
|
|
1643
|
+
{
|
|
1644
|
+
style: {
|
|
1645
|
+
fontSize: 14,
|
|
1646
|
+
fontWeight: 600,
|
|
1647
|
+
color: displayInfo.valueColor
|
|
1648
|
+
},
|
|
1649
|
+
children: [
|
|
1650
|
+
displayInfo.value,
|
|
1651
|
+
"%"
|
|
1652
|
+
]
|
|
1653
|
+
}
|
|
1654
|
+
)
|
|
1655
|
+
] }) : /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: theme2.colors.textMuted }, children: "Hover a corner" })
|
|
1656
|
+
}
|
|
1657
|
+
),
|
|
1658
|
+
/* @__PURE__ */ jsx("div", { style: { width: 200, height: 200 }, children: /* @__PURE__ */ jsx(
|
|
1659
|
+
QualityHexagon,
|
|
1545
1660
|
{
|
|
1546
1661
|
metrics: item.metrics,
|
|
1547
1662
|
tier: item.tier,
|
|
1548
|
-
theme: theme2
|
|
1663
|
+
theme: theme2,
|
|
1664
|
+
showLabels: false,
|
|
1665
|
+
showValues: false,
|
|
1666
|
+
onVertexHover: setHoveredVertex,
|
|
1667
|
+
onVertexLeave: () => setHoveredVertex(null),
|
|
1668
|
+
onVertexClick: onVertexClick ? (vertex) => onVertexClick(item, vertex) : void 0
|
|
1549
1669
|
}
|
|
1550
|
-
),
|
|
1670
|
+
) }),
|
|
1551
1671
|
/* @__PURE__ */ jsxs(
|
|
1552
1672
|
"div",
|
|
1553
1673
|
{
|
|
@@ -1555,8 +1675,7 @@ function RepositoryQualityGridItem({
|
|
|
1555
1675
|
display: "flex",
|
|
1556
1676
|
flexDirection: "column",
|
|
1557
1677
|
alignItems: "center",
|
|
1558
|
-
gap: 2
|
|
1559
|
-
maxWidth: 120
|
|
1678
|
+
gap: 2
|
|
1560
1679
|
},
|
|
1561
1680
|
children: [
|
|
1562
1681
|
/* @__PURE__ */ jsx(
|
|
@@ -1566,13 +1685,8 @@ function RepositoryQualityGridItem({
|
|
|
1566
1685
|
fontSize: 12,
|
|
1567
1686
|
fontWeight: 500,
|
|
1568
1687
|
color: theme2.colors.text,
|
|
1569
|
-
textAlign: "center"
|
|
1570
|
-
overflow: "hidden",
|
|
1571
|
-
textOverflow: "ellipsis",
|
|
1572
|
-
whiteSpace: "nowrap",
|
|
1573
|
-
maxWidth: "100%"
|
|
1688
|
+
textAlign: "center"
|
|
1574
1689
|
},
|
|
1575
|
-
title: label,
|
|
1576
1690
|
children: label
|
|
1577
1691
|
}
|
|
1578
1692
|
),
|
|
@@ -1596,16 +1710,34 @@ function RepositoryQualityGridItem({
|
|
|
1596
1710
|
}
|
|
1597
1711
|
);
|
|
1598
1712
|
}
|
|
1713
|
+
function calculateAverageScore(metrics) {
|
|
1714
|
+
const adjusted = { ...metrics };
|
|
1715
|
+
adjusted.deadCode = 100 - adjusted.deadCode;
|
|
1716
|
+
return Object.values(adjusted).reduce((a, b) => a + b, 0) / 6;
|
|
1717
|
+
}
|
|
1599
1718
|
function RepositoryQualityGrid({
|
|
1600
1719
|
repositories,
|
|
1601
1720
|
theme: theme2,
|
|
1602
1721
|
onItemClick,
|
|
1722
|
+
onVertexClick,
|
|
1603
1723
|
className,
|
|
1604
1724
|
showRepositoryName = true,
|
|
1605
1725
|
showSummary = true
|
|
1606
1726
|
}) {
|
|
1727
|
+
const [selectedMetric, setSelectedMetric] = React2.useState(null);
|
|
1607
1728
|
const items = React2.useMemo(() => flattenRepositories(repositories), [repositories]);
|
|
1608
1729
|
const overallTier = React2.useMemo(() => calculateOverallTier(items), [items]);
|
|
1730
|
+
const sortedItems = React2.useMemo(() => {
|
|
1731
|
+
return [...items].sort((a, b) => {
|
|
1732
|
+
if (selectedMetric) {
|
|
1733
|
+
const aVal = selectedMetric === "deadCode" ? 100 - a.metrics[selectedMetric] : a.metrics[selectedMetric];
|
|
1734
|
+
const bVal = selectedMetric === "deadCode" ? 100 - b.metrics[selectedMetric] : b.metrics[selectedMetric];
|
|
1735
|
+
return bVal - aVal;
|
|
1736
|
+
} else {
|
|
1737
|
+
return calculateAverageScore(b.metrics) - calculateAverageScore(a.metrics);
|
|
1738
|
+
}
|
|
1739
|
+
});
|
|
1740
|
+
}, [items, selectedMetric]);
|
|
1609
1741
|
const tierColors = {
|
|
1610
1742
|
none: theme2.colors.muted,
|
|
1611
1743
|
bronze: theme2.colors.warning,
|
|
@@ -1655,9 +1787,10 @@ function RepositoryQualityGrid({
|
|
|
1655
1787
|
display: "flex",
|
|
1656
1788
|
alignItems: "center",
|
|
1657
1789
|
justifyContent: "space-between",
|
|
1790
|
+
flexWrap: "wrap",
|
|
1791
|
+
gap: 12,
|
|
1658
1792
|
padding: "12px 16px",
|
|
1659
1793
|
backgroundColor: theme2.colors.surface,
|
|
1660
|
-
borderRadius: 8,
|
|
1661
1794
|
border: `1px solid ${theme2.colors.border}`
|
|
1662
1795
|
},
|
|
1663
1796
|
children: [
|
|
@@ -1693,44 +1826,67 @@ function RepositoryQualityGrid({
|
|
|
1693
1826
|
}
|
|
1694
1827
|
)
|
|
1695
1828
|
] }),
|
|
1696
|
-
/* @__PURE__ */ jsxs(
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
"
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1829
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
|
|
1830
|
+
/* @__PURE__ */ jsxs(
|
|
1831
|
+
"select",
|
|
1832
|
+
{
|
|
1833
|
+
value: selectedMetric ?? "",
|
|
1834
|
+
onChange: (e) => setSelectedMetric(e.target.value ? e.target.value : null),
|
|
1835
|
+
style: {
|
|
1836
|
+
padding: "4px 8px",
|
|
1837
|
+
fontSize: 13,
|
|
1838
|
+
backgroundColor: theme2.colors.background,
|
|
1839
|
+
color: theme2.colors.text,
|
|
1840
|
+
border: `1px solid ${theme2.colors.border}`,
|
|
1841
|
+
borderRadius: 4,
|
|
1842
|
+
cursor: "pointer",
|
|
1843
|
+
outline: "none"
|
|
1844
|
+
},
|
|
1845
|
+
children: [
|
|
1846
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Select metric..." }),
|
|
1847
|
+
METRIC_OPTIONS.map((option) => /* @__PURE__ */ jsx("option", { value: option.key, children: option.label }, option.key))
|
|
1848
|
+
]
|
|
1849
|
+
}
|
|
1850
|
+
),
|
|
1851
|
+
/* @__PURE__ */ jsxs(
|
|
1852
|
+
"div",
|
|
1853
|
+
{
|
|
1854
|
+
style: {
|
|
1855
|
+
display: "flex",
|
|
1856
|
+
alignItems: "center",
|
|
1857
|
+
gap: 8,
|
|
1858
|
+
padding: "4px 12px",
|
|
1859
|
+
backgroundColor: theme2.colors.backgroundLight,
|
|
1860
|
+
borderRadius: 16,
|
|
1861
|
+
border: `1px solid ${tierColors[overallTier]}`
|
|
1862
|
+
},
|
|
1863
|
+
children: [
|
|
1864
|
+
/* @__PURE__ */ jsx(
|
|
1865
|
+
"span",
|
|
1866
|
+
{
|
|
1867
|
+
style: {
|
|
1868
|
+
width: 8,
|
|
1869
|
+
height: 8,
|
|
1870
|
+
borderRadius: "50%",
|
|
1871
|
+
backgroundColor: tierColors[overallTier]
|
|
1872
|
+
}
|
|
1717
1873
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
)
|
|
1874
|
+
),
|
|
1875
|
+
/* @__PURE__ */ jsx(
|
|
1876
|
+
"span",
|
|
1877
|
+
{
|
|
1878
|
+
style: {
|
|
1879
|
+
fontSize: 13,
|
|
1880
|
+
fontWeight: 500,
|
|
1881
|
+
color: tierColors[overallTier]
|
|
1882
|
+
},
|
|
1883
|
+
children: tierLabels[overallTier]
|
|
1884
|
+
}
|
|
1885
|
+
)
|
|
1886
|
+
]
|
|
1887
|
+
}
|
|
1888
|
+
)
|
|
1889
|
+
] })
|
|
1734
1890
|
]
|
|
1735
1891
|
}
|
|
1736
1892
|
),
|
|
@@ -1738,17 +1894,20 @@ function RepositoryQualityGrid({
|
|
|
1738
1894
|
"div",
|
|
1739
1895
|
{
|
|
1740
1896
|
style: {
|
|
1741
|
-
display: "
|
|
1742
|
-
|
|
1743
|
-
gap: 12
|
|
1897
|
+
display: "grid",
|
|
1898
|
+
gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))",
|
|
1899
|
+
gap: 12,
|
|
1900
|
+
padding: 16
|
|
1744
1901
|
},
|
|
1745
|
-
children:
|
|
1902
|
+
children: sortedItems.map((item) => /* @__PURE__ */ jsx(
|
|
1746
1903
|
RepositoryQualityGridItem,
|
|
1747
1904
|
{
|
|
1748
1905
|
item,
|
|
1749
1906
|
theme: theme2,
|
|
1750
1907
|
onClick: onItemClick ? () => onItemClick(item) : void 0,
|
|
1751
|
-
|
|
1908
|
+
onVertexClick,
|
|
1909
|
+
showRepositoryName,
|
|
1910
|
+
selectedMetric
|
|
1752
1911
|
},
|
|
1753
1912
|
item.key
|
|
1754
1913
|
))
|
|
@@ -1758,6 +1917,160 @@ function RepositoryQualityGrid({
|
|
|
1758
1917
|
}
|
|
1759
1918
|
);
|
|
1760
1919
|
}
|
|
1920
|
+
const mockRepositories = [
|
|
1921
|
+
{
|
|
1922
|
+
id: "platform",
|
|
1923
|
+
name: "platform",
|
|
1924
|
+
packages: [
|
|
1925
|
+
{
|
|
1926
|
+
name: "@org/core",
|
|
1927
|
+
version: "2.0.0",
|
|
1928
|
+
metrics: { tests: 94, deadCode: 4, linting: 98, formatting: 100, types: 97, documentation: 90 }
|
|
1929
|
+
},
|
|
1930
|
+
{
|
|
1931
|
+
name: "@org/ui-components",
|
|
1932
|
+
version: "2.0.0",
|
|
1933
|
+
metrics: { tests: 85, deadCode: 8, linting: 95, formatting: 98, types: 92, documentation: 80 }
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
name: "@org/hooks",
|
|
1937
|
+
version: "2.0.0",
|
|
1938
|
+
metrics: { tests: 88, deadCode: 6, linting: 96, formatting: 100, types: 94, documentation: 85 }
|
|
1939
|
+
}
|
|
1940
|
+
]
|
|
1941
|
+
},
|
|
1942
|
+
{
|
|
1943
|
+
id: "backend",
|
|
1944
|
+
name: "backend-services",
|
|
1945
|
+
packages: [
|
|
1946
|
+
{
|
|
1947
|
+
name: "backend-services",
|
|
1948
|
+
version: "1.5.0",
|
|
1949
|
+
metrics: { tests: 80, deadCode: 15, linting: 90, formatting: 95, types: 85, documentation: 72 }
|
|
1950
|
+
}
|
|
1951
|
+
]
|
|
1952
|
+
},
|
|
1953
|
+
{
|
|
1954
|
+
id: "docs",
|
|
1955
|
+
name: "documentation-site",
|
|
1956
|
+
packages: [
|
|
1957
|
+
{
|
|
1958
|
+
name: "documentation-site",
|
|
1959
|
+
version: "1.0.0",
|
|
1960
|
+
metrics: { tests: 45, deadCode: 25, linting: 75, formatting: 85, types: 60, documentation: 95 }
|
|
1961
|
+
}
|
|
1962
|
+
]
|
|
1963
|
+
}
|
|
1964
|
+
];
|
|
1965
|
+
const RepositoryQualityGridPanelContent = ({
|
|
1966
|
+
context,
|
|
1967
|
+
events
|
|
1968
|
+
}) => {
|
|
1969
|
+
var _a;
|
|
1970
|
+
const { theme: theme2 } = useTheme();
|
|
1971
|
+
const qualitySlice = context.getSlice("repositoriesQuality");
|
|
1972
|
+
const hasQualitySlice = context.hasSlice("repositoriesQuality");
|
|
1973
|
+
const isLoading = (qualitySlice == null ? void 0 : qualitySlice.loading) ?? false;
|
|
1974
|
+
const repositories = React2__default.useMemo(() => {
|
|
1975
|
+
var _a2;
|
|
1976
|
+
if ((_a2 = qualitySlice == null ? void 0 : qualitySlice.data) == null ? void 0 : _a2.repositories) {
|
|
1977
|
+
return qualitySlice.data.repositories;
|
|
1978
|
+
}
|
|
1979
|
+
if (hasQualitySlice) {
|
|
1980
|
+
return [];
|
|
1981
|
+
}
|
|
1982
|
+
return mockRepositories;
|
|
1983
|
+
}, [(_a = qualitySlice == null ? void 0 : qualitySlice.data) == null ? void 0 : _a.repositories, hasQualitySlice]);
|
|
1984
|
+
const handleItemClick = (item) => {
|
|
1985
|
+
events.emit({
|
|
1986
|
+
type: "principal-ade.repository-quality-grid:item:click",
|
|
1987
|
+
source: "principal-ade.repository-quality-grid-panel",
|
|
1988
|
+
timestamp: Date.now(),
|
|
1989
|
+
payload: {
|
|
1990
|
+
repositoryId: item.repositoryId,
|
|
1991
|
+
repositoryName: item.repositoryName,
|
|
1992
|
+
packageName: item.packageName,
|
|
1993
|
+
tier: item.tier
|
|
1994
|
+
}
|
|
1995
|
+
});
|
|
1996
|
+
};
|
|
1997
|
+
const handleVertexClick = (item, vertex) => {
|
|
1998
|
+
events.emit({
|
|
1999
|
+
type: "principal-ade.repository-quality-grid:vertex:click",
|
|
2000
|
+
source: "principal-ade.repository-quality-grid-panel",
|
|
2001
|
+
timestamp: Date.now(),
|
|
2002
|
+
payload: {
|
|
2003
|
+
repositoryId: item.repositoryId,
|
|
2004
|
+
repositoryName: item.repositoryName,
|
|
2005
|
+
packageName: item.packageName,
|
|
2006
|
+
metric: vertex.key,
|
|
2007
|
+
label: vertex.label,
|
|
2008
|
+
value: vertex.value
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
};
|
|
2012
|
+
const handleRefresh = async () => {
|
|
2013
|
+
if (context.hasSlice("repositoriesQuality")) {
|
|
2014
|
+
await context.refresh("workspace", "repositoriesQuality");
|
|
2015
|
+
}
|
|
2016
|
+
};
|
|
2017
|
+
React2__default.useEffect(() => {
|
|
2018
|
+
const unsubscribers = [
|
|
2019
|
+
events.on("principal-ade.repository-quality-grid:refresh", async () => {
|
|
2020
|
+
await handleRefresh();
|
|
2021
|
+
})
|
|
2022
|
+
];
|
|
2023
|
+
return () => unsubscribers.forEach((unsub) => unsub());
|
|
2024
|
+
}, [events, context]);
|
|
2025
|
+
return /* @__PURE__ */ jsx(
|
|
2026
|
+
"div",
|
|
2027
|
+
{
|
|
2028
|
+
style: {
|
|
2029
|
+
fontFamily: theme2.fonts.body,
|
|
2030
|
+
height: "100%",
|
|
2031
|
+
minHeight: 0,
|
|
2032
|
+
backgroundColor: theme2.colors.background,
|
|
2033
|
+
color: theme2.colors.text,
|
|
2034
|
+
overflowY: "auto",
|
|
2035
|
+
boxSizing: "border-box"
|
|
2036
|
+
},
|
|
2037
|
+
children: isLoading ? /* @__PURE__ */ jsx(
|
|
2038
|
+
"div",
|
|
2039
|
+
{
|
|
2040
|
+
style: {
|
|
2041
|
+
padding: 40,
|
|
2042
|
+
textAlign: "center",
|
|
2043
|
+
color: theme2.colors.textMuted
|
|
2044
|
+
},
|
|
2045
|
+
children: "Loading repository quality metrics..."
|
|
2046
|
+
}
|
|
2047
|
+
) : repositories.length === 0 ? /* @__PURE__ */ jsx(
|
|
2048
|
+
"div",
|
|
2049
|
+
{
|
|
2050
|
+
style: {
|
|
2051
|
+
padding: 40,
|
|
2052
|
+
textAlign: "center",
|
|
2053
|
+
color: theme2.colors.textMuted
|
|
2054
|
+
},
|
|
2055
|
+
children: "No repositories with quality metrics found."
|
|
2056
|
+
}
|
|
2057
|
+
) : /* @__PURE__ */ jsx(
|
|
2058
|
+
RepositoryQualityGrid,
|
|
2059
|
+
{
|
|
2060
|
+
repositories,
|
|
2061
|
+
theme: theme2,
|
|
2062
|
+
onItemClick: handleItemClick,
|
|
2063
|
+
onVertexClick: handleVertexClick,
|
|
2064
|
+
showRepositoryName: true,
|
|
2065
|
+
showSummary: true
|
|
2066
|
+
}
|
|
2067
|
+
)
|
|
2068
|
+
}
|
|
2069
|
+
);
|
|
2070
|
+
};
|
|
2071
|
+
const RepositoryQualityGridPanel = (props) => {
|
|
2072
|
+
return /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(RepositoryQualityGridPanelContent, { ...props }) });
|
|
2073
|
+
};
|
|
1761
2074
|
const panels = [
|
|
1762
2075
|
{
|
|
1763
2076
|
metadata: {
|
|
@@ -1784,6 +2097,28 @@ const panels = [
|
|
|
1784
2097
|
onUnmount: async (_context) => {
|
|
1785
2098
|
console.log("Quality Hexagon Panel unmounting");
|
|
1786
2099
|
}
|
|
2100
|
+
},
|
|
2101
|
+
{
|
|
2102
|
+
metadata: {
|
|
2103
|
+
id: "principal-ade.repository-quality-grid-panel",
|
|
2104
|
+
name: "Repository Quality Grid",
|
|
2105
|
+
icon: "⬡",
|
|
2106
|
+
version: "0.1.0",
|
|
2107
|
+
author: "Principal ADE",
|
|
2108
|
+
description: "Display quality metrics for multiple repositories in a flat grid layout. Supports filtering by metric type, sorting, and comparing quality across projects.",
|
|
2109
|
+
slices: ["repositoriesQuality"],
|
|
2110
|
+
tools: []
|
|
2111
|
+
},
|
|
2112
|
+
component: RepositoryQualityGridPanel,
|
|
2113
|
+
onMount: async (context) => {
|
|
2114
|
+
console.log("Repository Quality Grid Panel mounted");
|
|
2115
|
+
if (context.hasSlice("repositoriesQuality") && !context.isSliceLoading("repositoriesQuality")) {
|
|
2116
|
+
await context.refresh("workspace", "repositoriesQuality");
|
|
2117
|
+
}
|
|
2118
|
+
},
|
|
2119
|
+
onUnmount: async (_context) => {
|
|
2120
|
+
console.log("Repository Quality Grid Panel unmounting");
|
|
2121
|
+
}
|
|
1787
2122
|
}
|
|
1788
2123
|
];
|
|
1789
2124
|
const onPackageLoad = async () => {
|
|
@@ -1800,6 +2135,7 @@ export {
|
|
|
1800
2135
|
QualityHexagonPanel,
|
|
1801
2136
|
RepositoryQualityGrid,
|
|
1802
2137
|
RepositoryQualityGridItem,
|
|
2138
|
+
RepositoryQualityGridPanel,
|
|
1803
2139
|
calculateQualityTier,
|
|
1804
2140
|
onPackageLoad,
|
|
1805
2141
|
onPackageUnload,
|