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>
This commit is contained in:
Jeff Levin
2022-10-12 21:36:05 -08:00
committed by GitHub
parent c7c640d903
commit cc27214dca
20 changed files with 516 additions and 44 deletions

View File

@@ -1,4 +1,4 @@
import React, { FC, ReactNode } from 'react';
import React, { FC, ReactNode, useContext, useEffect } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { useLocation } from 'react-router-dom';
@@ -13,6 +13,7 @@ import {
useForceUpdate,
Tag,
ToolbarButtonRow,
ModalsContext,
} from '@grafana/ui';
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
import { NavToolbarSeparator } from 'app/core/components/AppChrome/NavToolbarSeparator';
@@ -51,6 +52,7 @@ export interface OwnProps {
hideTimePicker: boolean;
folderTitle?: string;
title: string;
shareModalActiveTab?: string;
onAddPanel: () => void;
}
@@ -76,6 +78,7 @@ type Props = OwnProps & ConnectedProps<typeof connector>;
export const DashNav = React.memo<Props>((props) => {
const forceUpdate = useForceUpdate();
const { chrome } = useGrafana();
const { showModal, hideModal } = useContext(ModalsContext);
// We don't really care about the event payload here only that it triggeres a re-render of this component
useBusEvent(props.dashboard.events, DashboardMetaChangedEvent);
@@ -128,6 +131,25 @@ export const DashNav = React.memo<Props>((props) => {
return playlistSrv.isPlaying;
};
// Open/Close
useEffect(() => {
const dashboard = props.dashboard;
const shareModalActiveTab = props.shareModalActiveTab;
const { canShare } = dashboard.meta;
if (canShare && shareModalActiveTab) {
// automagically open modal
showModal(ShareModal, {
dashboard,
onDismiss: hideModal,
activeTab: shareModalActiveTab,
});
}
return () => {
hideModal();
};
}, [showModal, hideModal, props.dashboard, props.shareModalActiveTab]);
const renderLeftActions = () => {
const { dashboard, kioskMode } = props;
const { canStar, canShare, isStarred } = dashboard.meta;

View File

@@ -28,15 +28,16 @@ export function addPanelShareTab(tab: ShareModalTabModel) {
}
function getInitialState(props: Props): State {
const tabs = getTabs(props);
const { tabs, activeTab } = getTabs(props);
return {
tabs,
activeTab: tabs[0].value,
activeTab,
};
}
function getTabs(props: Props) {
const { panel } = props;
const { panel, activeTab } = props;
const linkLabel = t('share-modal.tab-title.link', 'Link');
const tabs: ShareModalTabModel[] = [{ label: linkLabel, value: 'link', component: ShareLink }];
@@ -65,12 +66,18 @@ function getTabs(props: Props) {
tabs.push({ label: 'Public dashboard', value: 'share', component: SharePublicDashboard });
}
return tabs;
const at = tabs.find((t) => t.value === activeTab);
return {
tabs,
activeTab: at?.value ?? tabs[0].value,
};
}
interface Props {
dashboard: DashboardModel;
panel?: PanelModel;
activeTab?: string;
onDismiss(): void;
}
@@ -95,7 +102,7 @@ export class ShareModal extends React.Component<Props, State> {
};
getTabs() {
return getTabs(this.props);
return getTabs(this.props).tabs;
}
getActiveTab() {
@@ -107,13 +114,12 @@ export class ShareModal extends React.Component<Props, State> {
const { panel } = this.props;
const { activeTab } = this.state;
const title = panel ? t('share-modal.panel.title', 'Share Panel') : t('share-modal.dashboard.title', 'Share');
const tabs = this.getTabs();
return (
<ModalTabsHeader
title={title}
icon="share-alt"
tabs={tabs}
tabs={this.getTabs()}
activeTab={activeTab}
onChangeTab={this.onSelectTab}
/>

View File

@@ -18,7 +18,7 @@ import { configureStore } from 'app/store/configureStore';
import { ShareModal } from '../ShareModal';
const server = setupServer(
rest.get('/api/dashboards/uid/:uId/public-config', (req, res, ctx) => {
rest.get('/api/dashboards/uid/:uId/public-config', (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({

View File

@@ -4,8 +4,8 @@ import { VariableModel } from 'app/features/variables/types';
import {
PublicDashboard,
dashboardHasTemplateVariables,
generatePublicDashboardUrl,
publicDashboardPersisted,
generatePublicDashboardUrl,
} from './SharePublicDashboardUtils';
describe('dashboardHasTemplateVariables', () => {