refactor(provisioning): remove auto-select logic for export
- Remove useAutoSelectUnmanagedDashboards hook - Remove autoExport URL parameter handling - Simplify navigation in RepositoryList to just go to dashboards page - Users can manually select dashboards to export
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useLocation } from 'react-router-dom-v5-compat';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { config, locationService, reportInteraction } from '@grafana/runtime';
|
||||
@@ -9,7 +8,6 @@ import { ManagerKind } from 'app/features/apiserver/types';
|
||||
import { BulkDeleteProvisionedResource } from 'app/features/provisioning/components/BulkActions/BulkDeleteProvisionedResource';
|
||||
import { BulkExportProvisionedResource } from 'app/features/provisioning/components/BulkActions/BulkExportProvisionedResource';
|
||||
import { BulkMoveProvisionedResource } from 'app/features/provisioning/components/BulkActions/BulkMoveProvisionedResource';
|
||||
import { useAutoSelectUnmanagedDashboards } from 'app/features/provisioning/hooks/useAutoSelectUnmanagedDashboards';
|
||||
import { useSelectionProvisioningStatus } from 'app/features/provisioning/hooks/useSelectionProvisioningStatus';
|
||||
import { useSelectionUnmanagedStatus } from 'app/features/provisioning/hooks/useSelectionUnmanagedStatus';
|
||||
import { useSearchStateManager } from 'app/features/search/state/SearchStateManager';
|
||||
@@ -47,8 +45,6 @@ export function BrowseActions({ folderDTO }: Props) {
|
||||
const [moveDashboards] = useMoveDashboardsMutation();
|
||||
const [, stateManager] = useSearchStateManager();
|
||||
const provisioningEnabled = config.featureToggles.provisioning;
|
||||
const location = useLocation();
|
||||
const selectAllUnmanagedDashboards = useAutoSelectUnmanagedDashboards();
|
||||
|
||||
const { hasProvisioned, hasNonProvisioned } = useSelectionProvisioningStatus(
|
||||
selectedItems,
|
||||
@@ -58,37 +54,6 @@ export function BrowseActions({ folderDTO }: Props) {
|
||||
|
||||
const isSearching = stateManager.hasSearchFilters();
|
||||
|
||||
// Handle autoExport URL parameter
|
||||
useEffect(() => {
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
if (searchParams.get('autoExport') === 'true' && provisioningEnabled) {
|
||||
// Remove the parameter from URL
|
||||
searchParams.delete('autoExport');
|
||||
const newSearch = searchParams.toString();
|
||||
locationService.replace({
|
||||
pathname: location.pathname,
|
||||
search: newSearch ? `?${newSearch}` : '',
|
||||
});
|
||||
|
||||
// Wait for dashboards to load, then auto-select unmanaged dashboards and open export drawer
|
||||
const attemptAutoSelect = async () => {
|
||||
// Try multiple times with delays to ensure dashboards are loaded
|
||||
for (let i = 0; i < 5; i++) {
|
||||
await selectAllUnmanagedDashboards();
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
}
|
||||
|
||||
// Open the drawer after attempting to select
|
||||
setShowBulkExportProvisionedResource(true);
|
||||
};
|
||||
|
||||
// Start after a short delay to allow page to render
|
||||
setTimeout(() => {
|
||||
attemptAutoSelect();
|
||||
}, 500);
|
||||
}
|
||||
}, [location.search, location.pathname, provisioningEnabled, selectAllUnmanagedDashboards]);
|
||||
|
||||
const onActionComplete = () => {
|
||||
dispatch(setAllSelection({ isSelected: false, folderUID: undefined }));
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ export function RepositoryList({ items }: Props) {
|
||||
const { instanceConnected } = checkSyncSettings(items);
|
||||
|
||||
const handlePushUnmanaged = () => {
|
||||
// Navigate to dashboards page with autoExport parameter
|
||||
locationService.push('/dashboards?autoExport=true');
|
||||
// Navigate to dashboards page
|
||||
locationService.push('/dashboards');
|
||||
};
|
||||
|
||||
const getResourceCountSection = () => {
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { config } from '@grafana/runtime';
|
||||
import { ManagerKind } from 'app/features/apiserver/types';
|
||||
import { isProvisionedDashboard as isProvisionedDashboardFromMeta } from 'app/features/browse-dashboards/api/isProvisioned';
|
||||
import { findItem } from 'app/features/browse-dashboards/state/utils';
|
||||
import { getDashboardAPI } from 'app/features/dashboard/api/dashboard_api';
|
||||
import { DashboardViewItem } from 'app/features/search/types';
|
||||
import { useSearchStateManager } from 'app/features/search/state/SearchStateManager';
|
||||
import { useDispatch, useSelector } from 'app/types/store';
|
||||
|
||||
import { setItemSelectionState } from '../../browse-dashboards/state/slice';
|
||||
import { BrowseDashboardsState } from '../../browse-dashboards/types';
|
||||
|
||||
/**
|
||||
* Hook to auto-select all unmanaged dashboards when triggered
|
||||
* Returns a function that can be called to select all unmanaged dashboards
|
||||
*/
|
||||
export function useAutoSelectUnmanagedDashboards() {
|
||||
const dispatch = useDispatch();
|
||||
const browseState = useSelector((state) => state.browseDashboards);
|
||||
const [, stateManager] = useSearchStateManager();
|
||||
const isSearching = stateManager.hasSearchFilters();
|
||||
const provisioningEnabled = config.featureToggles.provisioning;
|
||||
|
||||
const findItemInState = useCallback(
|
||||
(uid: string, state: BrowseDashboardsState) => {
|
||||
const item = findItem(state.rootItems?.items || [], state.childrenByParentUID, uid);
|
||||
return item ? { parentUID: item.parentUID, managedBy: item.managedBy } : undefined;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const getAllDashboards = useCallback(
|
||||
(state: BrowseDashboardsState): DashboardViewItem[] => {
|
||||
const dashboards: DashboardViewItem[] = [];
|
||||
|
||||
// Helper to recursively collect dashboards from a collection
|
||||
const collectDashboards = (collection: typeof state.rootItems, parentUID?: string) => {
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const item of collection.items) {
|
||||
if (item.kind === 'dashboard') {
|
||||
dashboards.push(item);
|
||||
} else if (item.kind === 'folder') {
|
||||
// Recursively collect from children
|
||||
const children = state.childrenByParentUID[item.uid];
|
||||
if (children) {
|
||||
collectDashboards(children, item.uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Start from root items
|
||||
collectDashboards(state.rootItems);
|
||||
|
||||
return dashboards;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const checkDashboardUnmanaged = useCallback(
|
||||
async (dashboard: DashboardViewItem, state: BrowseDashboardsState): Promise<boolean> => {
|
||||
if (isSearching) {
|
||||
// In search mode, fetch dashboard metadata
|
||||
try {
|
||||
const dto = await getDashboardAPI().getDashboardDTO(dashboard.uid);
|
||||
return !isProvisionedDashboardFromMeta(dto);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check parent folder first
|
||||
if (dashboard.parentUID) {
|
||||
const parent = findItemInState(dashboard.parentUID, state);
|
||||
if (parent?.managedBy === ManagerKind.Repo) {
|
||||
// If parent is managed, dashboard is managed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check dashboard itself
|
||||
const item = findItemInState(dashboard.uid, state);
|
||||
return item?.managedBy !== ManagerKind.Repo;
|
||||
},
|
||||
[isSearching, findItemInState]
|
||||
);
|
||||
|
||||
const selectAllUnmanagedDashboards = useCallback(async () => {
|
||||
if (!provisioningEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current state at the time of execution
|
||||
const currentState = browseState;
|
||||
const allDashboards = getAllDashboards(currentState);
|
||||
|
||||
if (allDashboards.length === 0) {
|
||||
// No dashboards loaded yet, wait a bit and try again
|
||||
return;
|
||||
}
|
||||
|
||||
const unmanagedDashboards: DashboardViewItem[] = [];
|
||||
|
||||
// Check each dashboard to see if it's unmanaged
|
||||
for (const dashboard of allDashboards) {
|
||||
const isUnmanaged = await checkDashboardUnmanaged(dashboard, currentState);
|
||||
if (isUnmanaged) {
|
||||
unmanagedDashboards.push(dashboard);
|
||||
}
|
||||
}
|
||||
|
||||
// Select all unmanaged dashboards
|
||||
for (const dashboard of unmanagedDashboards) {
|
||||
dispatch(
|
||||
setItemSelectionState({
|
||||
item: {
|
||||
kind: dashboard.kind,
|
||||
uid: dashboard.uid,
|
||||
parentUID: dashboard.parentUID,
|
||||
managedBy: dashboard.managedBy,
|
||||
},
|
||||
isSelected: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
}, [provisioningEnabled, browseState, getAllDashboards, checkDashboardUnmanaged, dispatch]);
|
||||
|
||||
return selectAllUnmanagedDashboards;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user