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 { useState } from 'react';
|
||||||
import { useLocation } from 'react-router-dom-v5-compat';
|
|
||||||
|
|
||||||
import { Trans, t } from '@grafana/i18n';
|
import { Trans, t } from '@grafana/i18n';
|
||||||
import { config, locationService, reportInteraction } from '@grafana/runtime';
|
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 { BulkDeleteProvisionedResource } from 'app/features/provisioning/components/BulkActions/BulkDeleteProvisionedResource';
|
||||||
import { BulkExportProvisionedResource } from 'app/features/provisioning/components/BulkActions/BulkExportProvisionedResource';
|
import { BulkExportProvisionedResource } from 'app/features/provisioning/components/BulkActions/BulkExportProvisionedResource';
|
||||||
import { BulkMoveProvisionedResource } from 'app/features/provisioning/components/BulkActions/BulkMoveProvisionedResource';
|
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 { useSelectionProvisioningStatus } from 'app/features/provisioning/hooks/useSelectionProvisioningStatus';
|
||||||
import { useSelectionUnmanagedStatus } from 'app/features/provisioning/hooks/useSelectionUnmanagedStatus';
|
import { useSelectionUnmanagedStatus } from 'app/features/provisioning/hooks/useSelectionUnmanagedStatus';
|
||||||
import { useSearchStateManager } from 'app/features/search/state/SearchStateManager';
|
import { useSearchStateManager } from 'app/features/search/state/SearchStateManager';
|
||||||
@@ -47,8 +45,6 @@ export function BrowseActions({ folderDTO }: Props) {
|
|||||||
const [moveDashboards] = useMoveDashboardsMutation();
|
const [moveDashboards] = useMoveDashboardsMutation();
|
||||||
const [, stateManager] = useSearchStateManager();
|
const [, stateManager] = useSearchStateManager();
|
||||||
const provisioningEnabled = config.featureToggles.provisioning;
|
const provisioningEnabled = config.featureToggles.provisioning;
|
||||||
const location = useLocation();
|
|
||||||
const selectAllUnmanagedDashboards = useAutoSelectUnmanagedDashboards();
|
|
||||||
|
|
||||||
const { hasProvisioned, hasNonProvisioned } = useSelectionProvisioningStatus(
|
const { hasProvisioned, hasNonProvisioned } = useSelectionProvisioningStatus(
|
||||||
selectedItems,
|
selectedItems,
|
||||||
@@ -58,37 +54,6 @@ export function BrowseActions({ folderDTO }: Props) {
|
|||||||
|
|
||||||
const isSearching = stateManager.hasSearchFilters();
|
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 = () => {
|
const onActionComplete = () => {
|
||||||
dispatch(setAllSelection({ isSelected: false, folderUID: undefined }));
|
dispatch(setAllSelection({ isSelected: false, folderUID: undefined }));
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export function RepositoryList({ items }: Props) {
|
|||||||
const { instanceConnected } = checkSyncSettings(items);
|
const { instanceConnected } = checkSyncSettings(items);
|
||||||
|
|
||||||
const handlePushUnmanaged = () => {
|
const handlePushUnmanaged = () => {
|
||||||
// Navigate to dashboards page with autoExport parameter
|
// Navigate to dashboards page
|
||||||
locationService.push('/dashboards?autoExport=true');
|
locationService.push('/dashboards');
|
||||||
};
|
};
|
||||||
|
|
||||||
const getResourceCountSection = () => {
|
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