import { skipToken } from '@reduxjs/toolkit/query'; import { config } from '@grafana/runtime'; import { useGetFrontendSettingsQuery } from 'app/api/clients/provisioning/v0alpha1'; import { findItem } from 'app/features/browse-dashboards/state/utils'; import { DashboardTreeSelection } from 'app/features/browse-dashboards/types'; import { useIsProvisionedInstance } from 'app/features/provisioning/hooks/useIsProvisionedInstance'; import { getIsReadOnlyRepo, getItemRepositoryUid } from 'app/features/provisioning/utils/repository'; import { useSelector } from 'app/types/store'; import { useChildrenByParentUIDState, rootItemsSelector } from '../../browse-dashboards/state/hooks'; // This hook is responsible for validating if all selected resources (dashboard folders and dashboards) are in the same repository export function useSelectionRepoValidation(selectedItems: Omit) { const provisioningEnabled = config.featureToggles.provisioning; const childrenByParentUID = useChildrenByParentUIDState(); const rootItems = useSelector(rootItemsSelector)?.items ?? []; const isProvisionedInstance = useIsProvisionedInstance(); const { data: settingsData } = useGetFrontendSettingsQuery(!provisioningEnabled ? skipToken : undefined); // Function to grab repository configuration by UID const getRepositoryByUid = (repoUid: string) => { if (!settingsData?.items || repoUid === 'non_provisioned') { return undefined; } return settingsData.items.find((repo) => repo.name === repoUid); }; const getRepoUid = (uid: string) => { const item = findItem(rootItems, childrenByParentUID, uid); return item ? getItemRepositoryUid(item, rootItems, childrenByParentUID) : 'non_provisioned'; }; const selectedUIDs = [ ...Object.keys(selectedItems.folder || {}).filter((id) => selectedItems.folder[id]), ...Object.keys(selectedItems.dashboard || {}).filter((id) => selectedItems.dashboard[id]), ]; const repoUIDs = selectedUIDs.map(getRepoUid).filter((repoId): repoId is string => !!repoId); const selectedItemsRepoUID = repoUIDs.length > 0 ? repoUIDs[0] : undefined; const isCrossRepo = new Set(repoUIDs).size > 1; const isInLockedRepo = (uid: string) => { // if whole instance is provisioned, all items are considered in the locked (same) repo if (isProvisionedInstance) { return true; } return !selectedItemsRepoUID || getRepoUid(uid) === selectedItemsRepoUID; }; const isUidInReadOnlyRepo = (uid: string) => { const repo = getRepositoryByUid(getRepoUid(uid)); return repo ? getIsReadOnlyRepo(repo) : false; }; return { selectedItemsRepoUID, isInLockedRepo, isCrossRepo, // true if items are from different repositories isUidInReadOnlyRepo, }; }