@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.
@@ -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
- let value = metrics[key];
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
- return /* @__PURE__ */ jsxs("g", { children: [
534
- /* @__PURE__ */ jsx(
535
- "circle",
536
- {
537
- cx: point.x,
538
- cy: point.y,
539
- r: dotSize,
540
- fill: "white",
541
- stroke: colors.stroke,
542
- strokeWidth: 1.5
543
- }
544
- ),
545
- /* @__PURE__ */ jsx(
546
- "circle",
547
- {
548
- cx: dataPoint.x,
549
- cy: dataPoint.y,
550
- r: dotSize * 0.7,
551
- fill: colors.fill,
552
- stroke: colors.stroke,
553
- strokeWidth: 1,
554
- style: { opacity: 0.9 }
555
- }
556
- )
557
- ] }, key);
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
- QualityHexagonCompact,
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
- "div",
1698
- {
1699
- style: {
1700
- display: "flex",
1701
- alignItems: "center",
1702
- gap: 8,
1703
- padding: "4px 12px",
1704
- backgroundColor: theme2.colors.backgroundLight,
1705
- borderRadius: 16,
1706
- border: `1px solid ${tierColors[overallTier]}`
1707
- },
1708
- children: [
1709
- /* @__PURE__ */ jsx(
1710
- "span",
1711
- {
1712
- style: {
1713
- width: 8,
1714
- height: 8,
1715
- borderRadius: "50%",
1716
- backgroundColor: tierColors[overallTier]
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
- /* @__PURE__ */ jsx(
1721
- "span",
1722
- {
1723
- style: {
1724
- fontSize: 13,
1725
- fontWeight: 500,
1726
- color: tierColors[overallTier]
1727
- },
1728
- children: tierLabels[overallTier]
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: "flex",
1742
- flexWrap: "wrap",
1743
- gap: 12
1897
+ display: "grid",
1898
+ gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))",
1899
+ gap: 12,
1900
+ padding: 16
1744
1901
  },
1745
- children: items.map((item) => /* @__PURE__ */ jsx(
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
- showRepositoryName
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,