diff --git a/public/app/features/browse-dashboards/components/DashboardsTree.test.tsx b/public/app/features/browse-dashboards/components/DashboardsTree.test.tsx
index 1ac147c290a..42847fc3c2a 100644
--- a/public/app/features/browse-dashboards/components/DashboardsTree.test.tsx
+++ b/public/app/features/browse-dashboards/components/DashboardsTree.test.tsx
@@ -2,6 +2,7 @@ import { render as rtlRender, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
+import { assertIsDefined } from 'test/helpers/asserts';
import { wellFormedDashboard, wellFormedEmptyFolder, wellFormedFolder } from '../fixtures/dashboardsTreeItem.fixture';
@@ -38,6 +39,7 @@ describe('browse-dashboards DashboardsTree', () => {
);
expect(screen.queryByText(dashboard.item.title)).toBeInTheDocument();
expect(screen.queryByText('Dashboard')).toBeInTheDocument();
+ expect(screen.queryByText(assertIsDefined(dashboard.item.tags)[0])).toBeInTheDocument();
});
it('renders a folder item', () => {
diff --git a/public/app/features/browse-dashboards/components/DashboardsTree.tsx b/public/app/features/browse-dashboards/components/DashboardsTree.tsx
index 7f5f58cda59..11cf3529c80 100644
--- a/public/app/features/browse-dashboards/components/DashboardsTree.tsx
+++ b/public/app/features/browse-dashboards/components/DashboardsTree.tsx
@@ -11,7 +11,9 @@ import { DashboardViewItem, DashboardViewItemKind } from 'app/features/search/ty
import { DashboardsTreeItem, DashboardTreeSelection, INDENT_AMOUNT_CSS_VAR } from '../types';
import { NameCell } from './NameCell';
+import { TagsCell } from './TagsCell';
import { TypeCell } from './TypeCell';
+import { useCustomFlexLayout } from './customFlexTableLayout';
interface DashboardsTreeProps {
items: DashboardsTreeItem[];
@@ -45,6 +47,7 @@ export function DashboardsTree({
const tableColumns = useMemo(() => {
const checkboxColumn: DashboardsTreeColumn = {
id: 'checkbox',
+ width: 0,
Header: () => ,
Cell: ({ row: { original: row }, selectedItems }: DashboardsTreeCellProps) => {
const item = row.item;
@@ -65,20 +68,29 @@ export function DashboardsTree({
const nameColumn: DashboardsTreeColumn = {
id: 'name',
+ width: 3,
Header: Name,
Cell: (props: DashboardsTreeCellProps) => ,
};
const typeColumn: DashboardsTreeColumn = {
id: 'type',
+ width: 1,
Header: 'Type',
Cell: TypeCell,
};
- return [checkboxColumn, nameColumn, typeColumn];
+ const tagsColumns: DashboardsTreeColumn = {
+ id: 'tags',
+ width: 2,
+ Header: 'Tags',
+ Cell: TagsCell,
+ };
+
+ return [checkboxColumn, nameColumn, typeColumn, tagsColumns];
}, [onItemSelectionChange, onFolderClick]);
- const table = useTable({ columns: tableColumns, data: items });
+ const table = useTable({ columns: tableColumns, data: items }, useCustomFlexLayout);
const { getTableProps, getTableBodyProps, headerGroups } = table;
const virtualData = useMemo(() => {
@@ -112,7 +124,6 @@ export function DashboardsTree({
{
- const columnSizing = 'auto 2fr 1fr';
-
return {
tableRoot: css({
// Responsively
@@ -175,17 +184,10 @@ const getStyles = (theme: GrafanaTheme2) => {
},
}),
- cell: css({
- padding: theme.spacing(1),
- whiteSpace: 'nowrap',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- }),
+ // Column flex properties (cell sizing) are set by customFlexTableLayout.ts
row: css({
- display: 'grid',
- gridTemplateColumns: columnSizing,
- alignItems: 'center',
+ gap: theme.spacing(1),
}),
headerRow: css({
@@ -201,6 +203,13 @@ const getStyles = (theme: GrafanaTheme2) => {
},
}),
+ cell: css({
+ padding: theme.spacing(1),
+ whiteSpace: 'nowrap',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ }),
+
link: css({
'&:hover': {
textDecoration: 'underline',
diff --git a/public/app/features/browse-dashboards/components/TagsCell.tsx b/public/app/features/browse-dashboards/components/TagsCell.tsx
new file mode 100644
index 00000000000..52c279dce36
--- /dev/null
+++ b/public/app/features/browse-dashboards/components/TagsCell.tsx
@@ -0,0 +1,27 @@
+import { css } from '@emotion/css';
+import React from 'react';
+import { CellProps } from 'react-table';
+
+import { GrafanaTheme2 } from '@grafana/data';
+import { TagList, useStyles2 } from '@grafana/ui';
+
+import { DashboardsTreeItem } from '../types';
+
+export function TagsCell({ row: { original: data } }: CellProps) {
+ const styles = useStyles2(getStyles);
+ const item = data.item;
+ if (item.kind === 'ui-empty-folder') {
+ return <>>;
+ }
+
+ return ;
+}
+
+function getStyles(theme: GrafanaTheme2) {
+ return {
+ // TagList is annoying and has weird default alignment
+ tagList: css({
+ justifyContent: 'flex-start',
+ }),
+ };
+}
diff --git a/public/app/features/browse-dashboards/components/customFlexTableLayout.ts b/public/app/features/browse-dashboards/components/customFlexTableLayout.ts
new file mode 100644
index 00000000000..0f4f0af1211
--- /dev/null
+++ b/public/app/features/browse-dashboards/components/customFlexTableLayout.ts
@@ -0,0 +1,44 @@
+import { Hooks, UseTableColumnProps } from 'react-table';
+
+/**
+ * Simplified flex layout module for react-table.
+ * Uses the width of the column as the flex grow amount - the ratio of width between all columns
+ *
+ * Width of 0 for 'auto' width - useful for columns of fixed with that should shrink to the size
+ * of content
+ *
+ * Originally based on https://github.com/TanStack/table/blob/v7/src/plugin-hooks/useFlexLayout.js
+ */
+export function useCustomFlexLayout(hooks: Hooks) {
+ hooks.getRowProps.push((props) => [props, getRowStyles()]);
+ hooks.getHeaderGroupProps.push((props) => [props, getRowStyles()]);
+ hooks.getFooterGroupProps.push((props) => [props, getRowStyles()]);
+ hooks.getHeaderProps.push((props, { column }) => [props, getColumnStyleProps(column)]);
+ hooks.getCellProps.push((props, { cell }) => [props, getColumnStyleProps(cell.column)]);
+ hooks.getFooterProps.push((props, { column }) => [props, getColumnStyleProps(column)]);
+}
+
+useCustomFlexLayout.pluginName = 'useCustomFlexLayout';
+
+function getColumnStyleProps(column: UseTableColumnProps) {
+ return {
+ style: {
+ flex:
+ column.totalWidth === 0
+ ? // if width: 0, prevent the column from growing (or shrinking), and set basis to auto to
+ // fit column to the width of its content
+ '0 0 auto'
+ : // Otherwise, grow the content to a size in proportion to the other column widths
+ `${column.totalWidth} 0 0`,
+ },
+ };
+}
+
+function getRowStyles() {
+ return {
+ style: {
+ display: 'flex',
+ flex: '1 0 auto',
+ },
+ };
+}