mirror of https://github.com/grafana/grafana
Public Dashboards: Add audit table (#54508)
This PR adds an audit table for public dashboards allowing a user to view all public dashboards on an instance of grafana. The public dashboards team is working on a proposal for adding RBAC support to the audit table for 9.3 Co-authored-by: juanicabanas <juan.cabanas@grafana.com>pull/56543/head^2
parent
c7c640d903
commit
cc27214dca
@ -0,0 +1,17 @@ |
|||||||
|
import React from 'react'; |
||||||
|
|
||||||
|
import { Page } from 'app/core/components/Page/Page'; |
||||||
|
|
||||||
|
import { ListPublicDashboardTable } from './components/PublicDashboardListTable'; |
||||||
|
|
||||||
|
export const ListPublicDashboardPage = ({}) => { |
||||||
|
return ( |
||||||
|
<Page navId="dashboards/public"> |
||||||
|
<Page.Contents> |
||||||
|
<ListPublicDashboardTable /> |
||||||
|
</Page.Contents> |
||||||
|
</Page> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default ListPublicDashboardPage; |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
import { |
||||||
|
LIST_PUBLIC_DASHBOARD_URL, |
||||||
|
viewPublicDashboardUrl, |
||||||
|
//ListPublicDashboardTable,
|
||||||
|
} from './PublicDashboardListTable'; |
||||||
|
|
||||||
|
//import { render, screen, waitFor, act } from '@testing-library/react';
|
||||||
|
//import React from 'react';
|
||||||
|
|
||||||
|
describe('listPublicDashboardsUrl', () => { |
||||||
|
it('has the correct url', () => { |
||||||
|
expect(LIST_PUBLIC_DASHBOARD_URL).toEqual('/api/dashboards/public'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('viewPublicDashboardUrl', () => { |
||||||
|
it('has the correct url', () => { |
||||||
|
expect(viewPublicDashboardUrl('abcd')).toEqual('public-dashboards/abcd'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
jest.mock('@grafana/runtime', () => ({ |
||||||
|
...(jest.requireActual('@grafana/runtime') as unknown as object), |
||||||
|
getBackendSrv: () => ({ |
||||||
|
get: jest.fn().mockResolvedValue([ |
||||||
|
{ |
||||||
|
uid: 'SdZwuCZVz', |
||||||
|
accessToken: 'beeaf92f6ab3467f80b2be922c7741ab', |
||||||
|
title: 'New dashboardasdf', |
||||||
|
dashboardUid: 'iF36Qb6nz', |
||||||
|
isEnabled: false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
uid: 'EuiEbd3nz', |
||||||
|
accessToken: '8687b0498ccf4babb2f92810d8563b33', |
||||||
|
title: 'New dashboard', |
||||||
|
dashboardUid: 'kFlxbd37k', |
||||||
|
isEnabled: true, |
||||||
|
}, |
||||||
|
]), |
||||||
|
}), |
||||||
|
})); |
||||||
|
|
||||||
|
//describe('ListPublicDashboardTable', () => {
|
||||||
|
// test('renders properly', async() => {
|
||||||
|
// act(() => {
|
||||||
|
// render(<ListPublicDashboardTable />)
|
||||||
|
// });
|
||||||
|
|
||||||
|
// //await waitFor(() => screen.getByRole('table'));
|
||||||
|
// expect(screen.getByText("Dashboard")).toBeInTheDocument();
|
||||||
|
// //expect(screen.getAllByRole("tr")).toHaveLength(2);
|
||||||
|
// })
|
||||||
|
//})
|
||||||
@ -0,0 +1,94 @@ |
|||||||
|
import { css } from '@emotion/css'; |
||||||
|
import React, { useState } from 'react'; |
||||||
|
import useAsync from 'react-use/lib/useAsync'; |
||||||
|
|
||||||
|
import { GrafanaTheme2 } from '@grafana/data'; |
||||||
|
import { getBackendSrv } from '@grafana/runtime'; |
||||||
|
import { Link, ButtonGroup, LinkButton, Icon, Tag, useStyles2 } from '@grafana/ui'; |
||||||
|
import { getConfig } from 'app/core/config'; |
||||||
|
|
||||||
|
export interface ListPublicDashboardResponse { |
||||||
|
uid: string; |
||||||
|
accessToken: string; |
||||||
|
dashboardUid: string; |
||||||
|
title: string; |
||||||
|
isEnabled: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
export const LIST_PUBLIC_DASHBOARD_URL = `/api/dashboards/public`; |
||||||
|
export const getPublicDashboards = async (): Promise<ListPublicDashboardResponse[]> => { |
||||||
|
return getBackendSrv().get(LIST_PUBLIC_DASHBOARD_URL); |
||||||
|
}; |
||||||
|
|
||||||
|
export const viewPublicDashboardUrl = (accessToken: string): string => { |
||||||
|
return `${getConfig().appUrl}public-dashboards/${accessToken}`; |
||||||
|
}; |
||||||
|
|
||||||
|
export const ListPublicDashboardTable = () => { |
||||||
|
const styles = useStyles2(getStyles); |
||||||
|
const [publicDashboards, setPublicDashboards] = useState<ListPublicDashboardResponse[]>([]); |
||||||
|
|
||||||
|
useAsync(async () => { |
||||||
|
const publicDashboards = await getPublicDashboards(); |
||||||
|
setPublicDashboards(publicDashboards); |
||||||
|
}, [setPublicDashboards]); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="page-action-bar"> |
||||||
|
<table className="filter-table"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Dashboard</th> |
||||||
|
<th>Public dashboard enabled</th> |
||||||
|
<th></th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{publicDashboards.map((pd) => ( |
||||||
|
<tr key={pd.uid}> |
||||||
|
<td> |
||||||
|
<Link className={styles.link} href={`/d/${pd.dashboardUid}`}> |
||||||
|
{pd.title} |
||||||
|
</Link> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<Tag name={pd.isEnabled ? 'enabled' : 'disabled'} colorIndex={pd.isEnabled ? 20 : 15} /> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<ButtonGroup> |
||||||
|
<LinkButton |
||||||
|
href={viewPublicDashboardUrl(pd.accessToken)} |
||||||
|
fill="text" |
||||||
|
title={pd.isEnabled ? 'View public dashboard' : 'Public dashboard is disabled'} |
||||||
|
target="_blank" |
||||||
|
disabled={!pd.isEnabled} |
||||||
|
> |
||||||
|
<Icon name="external-link-alt" /> |
||||||
|
</LinkButton> |
||||||
|
|
||||||
|
<LinkButton |
||||||
|
fill="text" |
||||||
|
href={`/d/${pd.dashboardUid}?shareView=share`} |
||||||
|
title="Configure public dashboard" |
||||||
|
> |
||||||
|
<Icon name="cog" /> |
||||||
|
</LinkButton> |
||||||
|
</ButtonGroup> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
))} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
function getStyles(theme: GrafanaTheme2) { |
||||||
|
return { |
||||||
|
link: css` |
||||||
|
color: ${theme.colors.primary.text}; |
||||||
|
text-decoration: underline; |
||||||
|
margin-right: ${theme.spacing()}; |
||||||
|
`,
|
||||||
|
}; |
||||||
|
} |
||||||
Loading…
Reference in new issue