remove arm token dependency

This commit is contained in:
Bikram Choudhury
2025-10-27 16:12:54 +05:30
parent 6483bd146d
commit e002a4505c
17 changed files with 129 additions and 118 deletions

View File

@@ -1,7 +1,5 @@
import React from "react";
import { userContext } from "UserContext";
import { useAADAuth } from "../../../hooks/useAADAuth";
import { useConfig } from "../../../hooks/useConfig";
import { CopyJobMigrationType } from "../Enums";
import { CopyJobContextProviderType, CopyJobContextState, CopyJobFlowType } from "../Types";
@@ -39,24 +37,15 @@ const getInitialCopyJobState = (): CopyJobContextState => {
}
const CopyJobContextProvider: React.FC<CopyJobContextProviderProps> = (props) => {
const config = useConfig();
const { isLoggedIn, armToken, account } = useAADAuth(config);
const principalId = account?.localAccountId ?? "";
const [copyJobState, setCopyJobState] = React.useState<CopyJobContextState>(getInitialCopyJobState());
const [flow, setFlow] = React.useState<CopyJobFlowType | null>(null);
if (!isLoggedIn || !armToken) {
// Add a shimmer or loader here
return null;
}
const resetCopyJobState = () => {
setCopyJobState(getInitialCopyJobState());
}
return (
<CopyJobContext.Provider value={{ principalId, armToken, copyJobState, setCopyJobState, flow, setFlow, resetCopyJobState }}>
<CopyJobContext.Provider value={{ copyJobState, setCopyJobState, flow, setFlow, resetCopyJobState }}>
{props.children}
</CopyJobContext.Provider>
);

View File

@@ -79,3 +79,12 @@ export function extractErrorMessage(error: CopyJobErrorType): CopyJobErrorType {
}
}
export function getAccountDetailsFromResourceId(accountId: string | undefined) {
if (!accountId) {
return null;
}
const pattern = new RegExp('/subscriptions/([^/]+)/resourceGroups/([^/]+)/providers/Microsoft\\.DocumentDB/databaseAccounts/([^/]+)', 'i');
const matches = accountId.match(pattern);
const [_, subscriptionId, resourceGroup, accountName] = matches || [];
return { subscriptionId, resourceGroup, accountName };
}

View File

@@ -25,7 +25,7 @@ export interface PermissionSectionConfig {
Component: React.ComponentType
disabled: boolean;
completed?: boolean;
validate?: (state: CopyJobContextState, armToken?: string) => boolean | Promise<boolean>;
validate?: (state: CopyJobContextState) => boolean | Promise<boolean>;
}
// Section IDs for maintainability
@@ -66,10 +66,9 @@ const PERMISSION_SECTIONS_CONFIG: PermissionSectionConfig[] = [
title: ContainerCopyMessages.readPermissionAssigned.title,
Component: AddReadPermissionToDefaultIdentity,
disabled: true,
validate: async (state: CopyJobContextState, armToken?: string) => {
validate: async (state: CopyJobContextState) => {
const principalId = state?.target?.account?.identity?.principalId;
const rolesAssigned = await fetchRoleAssignments(
armToken,
state.source?.subscription?.subscriptionId,
state.source?.account?.resourceGroup,
state.source?.account?.name,
@@ -77,7 +76,6 @@ const PERMISSION_SECTIONS_CONFIG: PermissionSectionConfig[] = [
);
const roleDefinitions = await fetchRoleDefinitions(
armToken,
rolesAssigned ?? []
);
return checkTargetHasReaderRoleOnSource(roleDefinitions ?? []);
@@ -127,10 +125,7 @@ export function checkTargetHasReaderRoleOnSource(roleDefinitions: RoleDefinition
* Returns the permission sections configuration for the Assign Permissions screen.
* Memoizes derived values for performance and decouples logic for testability.
*/
const usePermissionSections = (
state: CopyJobContextState,
armToken: string,
): PermissionSectionConfig[] => {
const usePermissionSections = (state: CopyJobContextState): PermissionSectionConfig[] => {
const { validationCache, setValidationCache } = useCopyJobPrerequisitesCache();
const [permissionSections, setPermissionSections] = useState<PermissionSectionConfig[] | null>(null);
const isValidatingRef = useRef(false);
@@ -169,7 +164,7 @@ const usePermissionSections = (
}
// We've reached the first non-cached section - validate it
if (section.validate) {
const isValid = await section.validate(state, armToken);
const isValid = await section.validate(state);
newValidationCache.set(section.id, isValid);
result.push({ ...section, completed: isValid });
// Stop validation if current section failed
@@ -197,7 +192,7 @@ const usePermissionSections = (
return () => {
isValidatingRef.current = false;
}
}, [state, armToken, sectionToValidate]);
}, [state, sectionToValidate]);
return permissionSections ?? [];
};

View File

@@ -39,8 +39,8 @@ const PermissionSection: React.FC<PermissionSectionConfig> = ({
);
const AssignPermissions = () => {
const { armToken, copyJobState } = useCopyJobContext();
const permissionSections = usePermissionSections(copyJobState, armToken);
const { copyJobState } = useCopyJobContext();
const permissionSections = usePermissionSections(copyJobState);
const [openItems, setOpenItems] = React.useState<string[]>([]);
const indentLevels = React.useMemo<IndentLevel[]>(
@@ -48,10 +48,6 @@ const AssignPermissions = () => {
[]
);
/* const onMoveToNextSection: AccordionToggleEventHandler<string> = useCallback((_event, data) => {
setOpenItems(data.openItems);
}, []); */
useEffect(() => {
const firstIncompleteSection = permissionSections.find(section => !section.completed);
const nextOpenItems = firstIncompleteSection ? [firstIncompleteSection.id] : [];

View File

@@ -15,11 +15,11 @@ interface SelectAccountProps { }
const SelectAccount = React.memo(
(_props: SelectAccountProps) => {
const { armToken, copyJobState, setCopyJobState } = useCopyJobContext();
const { copyJobState, setCopyJobState } = useCopyJobContext();
const selectedSubscriptionId = copyJobState?.source?.subscription?.subscriptionId;
const subscriptions: Subscription[] = useSubscriptions(armToken);
const allAccounts: DatabaseAccount[] = useDatabaseAccounts(selectedSubscriptionId, armToken);
const subscriptions: Subscription[] = useSubscriptions();
const allAccounts: DatabaseAccount[] = useDatabaseAccounts(selectedSubscriptionId);
const sqlApiOnlyAccounts: DatabaseAccount[] = allAccounts?.filter(account => account.type === "SQL" || account.kind === "GlobalDocumentDB");
const { subscriptionOptions, accountOptions } = useDropdownOptions(subscriptions, sqlApiOnlyAccounts);

View File

@@ -11,7 +11,7 @@ import { useMemoizedSourceAndTargetData } from "./memoizedData";
interface SelectSourceAndTargetContainersProps { }
const SelectSourceAndTargetContainers = (_props: SelectSourceAndTargetContainersProps) => {
const { armToken, copyJobState, setCopyJobState } = useCopyJobContext();
const { copyJobState, setCopyJobState } = useCopyJobContext();
const {
source,
target,
@@ -19,7 +19,7 @@ const SelectSourceAndTargetContainers = (_props: SelectSourceAndTargetContainers
sourceContainerParams,
targetDbParams,
targetContainerParams
} = useMemoizedSourceAndTargetData(copyJobState, armToken);
} = useMemoizedSourceAndTargetData(copyJobState);
// Custom hooks
const sourceDatabases = useDatabases(...sourceDbParams) || [];

View File

@@ -1,57 +1,64 @@
import React from "react";
import { getAccountDetailsFromResourceId } from "../../../CopyJobUtils";
import { CopyJobContextState, DatabaseParams, DataContainerParams } from "../../../Types";
export function useMemoizedSourceAndTargetData(copyJobState: CopyJobContextState, armToken: string) {
export function useMemoizedSourceAndTargetData(copyJobState: CopyJobContextState) {
const { source, target } = copyJobState ?? {};
const selectedSourceAccount = source?.account;
const selectedTargetAccount = target?.account;
const {
subscriptionId: sourceSubscriptionId,
resourceGroup: sourceResourceGroup,
accountName: sourceAccountName
} = getAccountDetailsFromResourceId(selectedSourceAccount?.id);
const {
subscriptionId: targetSubscriptionId,
resourceGroup: targetResourceGroup,
accountName: targetAccountName
} = getAccountDetailsFromResourceId(selectedTargetAccount?.id);
const sourceDbParams = React.useMemo(
() =>
[
armToken,
source?.subscription?.subscriptionId,
selectedSourceAccount?.resourceGroup,
selectedSourceAccount?.name,
sourceSubscriptionId,
sourceResourceGroup,
sourceAccountName,
'SQL',
] as DatabaseParams,
[armToken, source?.subscription?.subscriptionId, selectedSourceAccount]
[sourceSubscriptionId, sourceResourceGroup, sourceAccountName]
);
const sourceContainerParams = React.useMemo(
() =>
[
armToken,
source?.subscription?.subscriptionId,
selectedSourceAccount?.resourceGroup,
selectedSourceAccount?.name,
sourceSubscriptionId,
sourceResourceGroup,
sourceAccountName,
source?.databaseId,
'SQL',
] as DataContainerParams,
[armToken, source?.subscription?.subscriptionId, selectedSourceAccount, source?.databaseId]
[sourceSubscriptionId, sourceResourceGroup, sourceAccountName, source?.databaseId]
);
const targetDbParams = React.useMemo(
() => [
armToken,
target?.subscriptionId,
selectedTargetAccount?.resourceGroup,
selectedTargetAccount?.name,
targetSubscriptionId,
targetResourceGroup,
targetAccountName,
'SQL',
] as DatabaseParams,
[armToken, target?.subscriptionId, selectedTargetAccount]
[targetSubscriptionId, targetResourceGroup, targetAccountName]
);
const targetContainerParams = React.useMemo(
() => [
armToken,
target?.subscriptionId,
selectedTargetAccount?.resourceGroup,
selectedTargetAccount?.name,
targetSubscriptionId,
targetResourceGroup,
targetAccountName,
target?.databaseId,
'SQL',
] as DataContainerParams,
[armToken, target?.subscriptionId, selectedTargetAccount, target?.databaseId]
[targetSubscriptionId, targetResourceGroup, targetAccountName, target?.databaseId]
);
return { source, target, sourceDbParams, sourceContainerParams, targetDbParams, targetContainerParams };

View File

@@ -28,14 +28,12 @@ export type DropdownOptionType = {
};
export type DatabaseParams = [
string,
string | undefined,
string | undefined,
string | undefined,
ApiType
];
export type DataContainerParams = [
string,
string | undefined,
string | undefined,
string | undefined,
@@ -80,8 +78,6 @@ export interface CopyJobFlowType {
}
export interface CopyJobContextProviderType {
principalId: string;
armToken: string;
flow: CopyJobFlowType;
setFlow: React.Dispatch<React.SetStateAction<CopyJobFlowType>>;
copyJobState: CopyJobContextState | null;