Restore dashboards: Update permissions
This commit is contained in:
@@ -29,5 +29,6 @@ export async function initOpenFeature() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function evaluateBooleanFlag(flagName: FeatureFlagName, defaultValue: boolean): boolean {
|
export function evaluateBooleanFlag(flagName: FeatureFlagName, defaultValue: boolean): boolean {
|
||||||
|
console.log('deets', OpenFeature.getClient().getBooleanDetails('recentlyViewedDashboards', false));
|
||||||
return OpenFeature.getClient().getBooleanValue(flagName, defaultValue);
|
return OpenFeature.getClient().getBooleanValue(flagName, defaultValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ func (s *ServiceImpl) buildDashboardNavLinks(c *contextmodel.ReqContext) []*navt
|
|||||||
}
|
}
|
||||||
|
|
||||||
//nolint:staticcheck // not yet migrated to OpenFeature
|
//nolint:staticcheck // not yet migrated to OpenFeature
|
||||||
if s.features.IsEnabled(c.Req.Context(), featuremgmt.FlagRestoreDashboards) && (c.GetOrgRole() == org.RoleAdmin || c.IsGrafanaAdmin) {
|
if s.features.IsEnabled(c.Req.Context(), featuremgmt.FlagRestoreDashboards) && hasAccess(ac.EvalPermission(dashboards.ActionDashboardsDelete)) {
|
||||||
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
|
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
|
||||||
Text: "Recently deleted",
|
Text: "Recently deleted",
|
||||||
SubTitle: "Any items listed here for more than 30 days will be automatically deleted.",
|
SubTitle: "Any items listed here for more than 30 days will be automatically deleted.",
|
||||||
|
|||||||
@@ -113,6 +113,29 @@ describe('browse-dashboards BrowseDashboardsPage', () => {
|
|||||||
expect(await screen.findByRole('button', { name: 'New' })).toBeInTheDocument();
|
expect(await screen.findByRole('button', { name: 'New' })).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows the "Recently deleted" button when restore is enabled and user can delete dashboards', async () => {
|
||||||
|
const previousFlag = config.featureToggles.restoreDashboards;
|
||||||
|
config.featureToggles.restoreDashboards = true;
|
||||||
|
|
||||||
|
render(<BrowseDashboardsPage queryParams={{}} />);
|
||||||
|
await screen.findByPlaceholderText('Search for dashboards and folders');
|
||||||
|
expect(await screen.findByRole('link', { name: 'Recently deleted' })).toBeInTheDocument();
|
||||||
|
|
||||||
|
config.featureToggles.restoreDashboards = previousFlag;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show the "Recently deleted" button when user cannot delete dashboards', async () => {
|
||||||
|
const previousFlag = config.featureToggles.restoreDashboards;
|
||||||
|
config.featureToggles.restoreDashboards = true;
|
||||||
|
mockPermissions.canDeleteDashboards = false;
|
||||||
|
|
||||||
|
render(<BrowseDashboardsPage queryParams={{}} />);
|
||||||
|
await screen.findByPlaceholderText('Search for dashboards and folders');
|
||||||
|
expect(screen.queryByRole('link', { name: 'Recently deleted' })).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
config.featureToggles.restoreDashboards = previousFlag;
|
||||||
|
});
|
||||||
|
|
||||||
it('does not show the "New" button if the user does not have permissions', async () => {
|
it('does not show the "New" button if the user does not have permissions', async () => {
|
||||||
mockPermissions.canCreateDashboards = false;
|
mockPermissions.canCreateDashboards = false;
|
||||||
mockPermissions.canCreateFolders = false;
|
mockPermissions.canCreateFolders = false;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { getConfig } from 'app/core/config';
|
|||||||
import { useDispatch } from 'app/types/store';
|
import { useDispatch } from 'app/types/store';
|
||||||
|
|
||||||
import { FolderRepo } from '../../core/components/NestedFolderPicker/FolderRepo';
|
import { FolderRepo } from '../../core/components/NestedFolderPicker/FolderRepo';
|
||||||
import { contextSrv } from '../../core/services/context_srv';
|
|
||||||
import { ManagerKind } from '../apiserver/types';
|
import { ManagerKind } from '../apiserver/types';
|
||||||
import { TemplateDashboardModal } from '../dashboard/dashgrid/DashboardLibrary/TemplateDashboardModal';
|
import { TemplateDashboardModal } from '../dashboard/dashgrid/DashboardLibrary/TemplateDashboardModal';
|
||||||
import { buildNavModel, getDashboardsTabID } from '../folders/state/navModel';
|
import { buildNavModel, getDashboardsTabID } from '../folders/state/navModel';
|
||||||
@@ -104,7 +103,6 @@ const BrowseDashboardsPage = memo(({ queryParams }: { queryParams: Record<string
|
|||||||
canCreateDashboards,
|
canCreateDashboards,
|
||||||
canCreateFolders,
|
canCreateFolders,
|
||||||
} = getFolderPermissions(folder);
|
} = getFolderPermissions(folder);
|
||||||
const hasAdminRights = contextSrv.hasRole('Admin') || contextSrv.isGrafanaAdmin;
|
|
||||||
const isProvisionedFolder = folder?.managedBy === ManagerKind.Repo;
|
const isProvisionedFolder = folder?.managedBy === ManagerKind.Repo;
|
||||||
const showEditTitle = canEditFolders && folderUID && !isProvisionedFolder;
|
const showEditTitle = canEditFolders && folderUID && !isProvisionedFolder;
|
||||||
const permissions = {
|
const permissions = {
|
||||||
@@ -155,7 +153,7 @@ const BrowseDashboardsPage = memo(({ queryParams }: { queryParams: Record<string
|
|||||||
renderTitle={renderTitle}
|
renderTitle={renderTitle}
|
||||||
actions={
|
actions={
|
||||||
<>
|
<>
|
||||||
{config.featureToggles.restoreDashboards && hasAdminRights && (
|
{config.featureToggles.restoreDashboards && canDeleteDashboards && (
|
||||||
<LinkButton
|
<LinkButton
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
href={getConfig().appSubUrl + '/dashboard/recently-deleted'}
|
href={getConfig().appSubUrl + '/dashboard/recently-deleted'}
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ export const DeleteModal = ({ onConfirm, onDismiss, selectedItems, ...props }: P
|
|||||||
<Text element="p">
|
<Text element="p">
|
||||||
<Trans i18nKey="browse-dashboards.action.delete-modal-restore-dashboards-text">
|
<Trans i18nKey="browse-dashboards.action.delete-modal-restore-dashboards-text">
|
||||||
This action will delete the selected folders immediately. Deleted dashboards will be kept in the
|
This action will delete the selected folders immediately. Deleted dashboards will be kept in the
|
||||||
history for up to 12 months and can be restored by your organization administrator during that time.
|
history for up to 12 months. Users with delete permissions can restore the dashboards they deleted,
|
||||||
The history is limited to 1000 dashboards — older ones may be removed sooner if the limit is reached.
|
and admins can restore any user's deleted dashboards. The history is limited to 1000 dashboards — older
|
||||||
Folders cannot be restored.
|
ones may be removed sooner if the limit is reached. Folders cannot be restored.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
<Space v={2} />
|
<Space v={2} />
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ export const RecentlyDeletedEmptyState = ({ searchState }: RecentlyDeletedEmptyS
|
|||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<Trans i18nKey={'recently-deleted.page.no-deleted-dashboards-text'}>
|
<Trans i18nKey={'recently-deleted.page.no-deleted-dashboards-text'}>
|
||||||
When you delete a dashboard, it will appear here for 30 days before being permanently deleted. Your organization
|
When you delete a dashboard, it will appear here for 30 days before being permanently deleted. Users with delete
|
||||||
administrator can restore recently-deleted dashboards.
|
permissions can restore the dashboards they deleted, and admins can restore any user's deleted dashboards.
|
||||||
</Trans>
|
</Trans>
|
||||||
</EmptyState>
|
</EmptyState>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -81,8 +81,9 @@ export function DeleteDashboardModal({ dashboardTitle, onConfirm, onClose }: Del
|
|||||||
<Text element="p">
|
<Text element="p">
|
||||||
<Trans i18nKey="dashboard-settings.delete-modal-restore-dashboards-text">
|
<Trans i18nKey="dashboard-settings.delete-modal-restore-dashboards-text">
|
||||||
This action will delete the dashboard. Deleted dashboards will be kept in the history for up to 12
|
This action will delete the dashboard. Deleted dashboards will be kept in the history for up to 12
|
||||||
months and can be restored by your organization administrator during that time. The history is limited
|
months. Users with delete permissions can restore the dashboards they deleted, and admins can restore
|
||||||
to 1000 dashboards—older ones will be removed sooner if the limit is reached.
|
any user's deleted dashboards. The history is limited to 1000 dashboards—older ones will be removed
|
||||||
|
sooner if the limit is reached.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
<Space v={1} />
|
<Space v={1} />
|
||||||
|
|||||||
@@ -534,7 +534,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
|||||||
},
|
},
|
||||||
config.featureToggles.restoreDashboards && {
|
config.featureToggles.restoreDashboards && {
|
||||||
path: '/dashboard/recently-deleted',
|
path: '/dashboard/recently-deleted',
|
||||||
roles: () => ['Admin', 'ServerAdmin'],
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.DashboardsDelete]),
|
||||||
component: SafeDynamicImport(
|
component: SafeDynamicImport(
|
||||||
() => import(/* webpackChunkName: "RecentlyDeletedPage" */ 'app/features/browse-dashboards/RecentlyDeletedPage')
|
() => import(/* webpackChunkName: "RecentlyDeletedPage" */ 'app/features/browse-dashboards/RecentlyDeletedPage')
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user