mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 17:01:13 +00:00
* Initial dev for container copy * remove padding from label * Added Copy Job prerequisites screen * Added hooks to evaluate reader role access * added copyjob pre-requsite screen along with it's validations * Added monitor copy job list screen * added copy job list refresh and reset functionality * remove arm token dependency * fetch account details from account id instead of context * Fix lint & typescript checks * show copyjob screen from portal navigation * adding copy job details screen * remove duplicate code & show sql accounts only * ui fixes for list job page * pending icon * copy job details screen ui * reset .vscode/settings.json * Fixed existing UTs * disabling action buttons until it's in progress * fixed formatting * Adding loader on submit button and show job creation errors in the panel itself * updating disabling action menu item logic * added custom pager * fix lint and ts errors * updating file names and removing comments * remove comments * modularize the arom common code * Adding content and removing tooltip * updating job details screen * updating online copy enabled screen * Adding below changes - Don't show permission screen for same account in offline mode - Don't show identity permissions for same account in online mode - Show error message if selected containers are identical - Update abort signal messages * added feedback code from explorer * Add tooltips and long polling - Added tooltips to permission sections - Implemented long polling for PITR and online copy enabled sections - Long polling automatically stops after 15 minutes - After polling ends, a refresh button will be displayed --------- Co-authored-by: nishthaAhujaa <nishtha17354@iiittd.ac.in>
102 lines
3.7 KiB
TypeScript
102 lines
3.7 KiB
TypeScript
import { HttpHeaders } from "Common/Constants";
|
|
import { QueryRequestOptions, QueryResponse } from "Contracts/AzureResourceGraph";
|
|
import useSWR from "swr";
|
|
import { userContext } from "UserContext";
|
|
import { configContext } from "../ConfigContext";
|
|
import { Subscription } from "../Contracts/DataModels";
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
|
|
interface SubscriptionListResult {
|
|
nextLink: string;
|
|
value: Subscription[];
|
|
}
|
|
|
|
export async function fetchSubscriptions(accessToken: string = ""): Promise<Subscription[]> {
|
|
if (!accessToken && !userContext.authorizationToken) {
|
|
return [];
|
|
}
|
|
const headers = new Headers();
|
|
const bearer = accessToken ? `Bearer ${accessToken}` : userContext.authorizationToken;
|
|
|
|
headers.append("Authorization", bearer);
|
|
|
|
let subscriptions: Array<Subscription> = [];
|
|
let nextLink = `${configContext.ARM_ENDPOINT}subscriptions?api-version=2020-01-01`;
|
|
|
|
while (nextLink) {
|
|
const response = await fetch(nextLink, { headers });
|
|
const result: SubscriptionListResult =
|
|
response.status === 204 || response.status === 304 ? undefined : await response.json();
|
|
if (!response.ok) {
|
|
throw result;
|
|
}
|
|
nextLink = result.nextLink;
|
|
const validSubscriptions = result.value.filter(
|
|
(sub) => sub.state === "Enabled" || sub.state === "Warned" || sub.state === "PastDue",
|
|
);
|
|
subscriptions = [...subscriptions, ...validSubscriptions];
|
|
}
|
|
return subscriptions.sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
}
|
|
|
|
export async function fetchSubscriptionsFromGraph(accessToken: string = ""): Promise<Subscription[]> {
|
|
if (!accessToken && !userContext.authorizationToken) {
|
|
return [];
|
|
}
|
|
const headers = new Headers();
|
|
const bearer = accessToken ? `Bearer ${accessToken}` : userContext.authorizationToken;
|
|
|
|
headers.append("Authorization", bearer);
|
|
headers.append(HttpHeaders.contentType, "application/json");
|
|
const subscriptionsQuery =
|
|
"resources | where type == 'microsoft.documentdb/databaseaccounts' | join kind=inner ( resourcecontainers | where type == 'microsoft.resources/subscriptions' | project subscriptionId, subscriptionName = name, subscriptionState = tostring(parse_json(properties).state) ) on subscriptionId | summarize by subscriptionId, subscriptionName, subscriptionState";
|
|
const apiVersion = "2021-03-01";
|
|
const managementResourceGraphAPIURL = `${configContext.ARM_ENDPOINT}providers/Microsoft.ResourceGraph/resources?api-version=${apiVersion}`;
|
|
|
|
const subscriptions: Subscription[] = [];
|
|
let skipToken: string;
|
|
do {
|
|
const body = {
|
|
query: subscriptionsQuery,
|
|
options: {
|
|
$allowPartialScopes: true,
|
|
$top: 150,
|
|
...(skipToken && {
|
|
$skipToken: skipToken,
|
|
}),
|
|
} as QueryRequestOptions,
|
|
};
|
|
|
|
const response = await fetch(managementResourceGraphAPIURL, {
|
|
method: "POST",
|
|
headers,
|
|
body: JSON.stringify(body),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await response.text());
|
|
}
|
|
|
|
const queryResponse: QueryResponse = (await response.json()) as QueryResponse;
|
|
skipToken = queryResponse.$skipToken;
|
|
|
|
queryResponse.data?.map((subscription: any) => {
|
|
subscriptions.push({
|
|
displayName: subscription.subscriptionName,
|
|
subscriptionId: subscription.subscriptionId,
|
|
state: subscription.subscriptionState,
|
|
} as Subscription);
|
|
});
|
|
} while (skipToken);
|
|
|
|
return subscriptions.sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
}
|
|
|
|
export function useSubscriptions(armToken: string = ""): Subscription[] | undefined {
|
|
const { data } = useSWR(
|
|
() => ["subscriptions", armToken],
|
|
(_, armToken) => fetchSubscriptionsFromGraph(armToken),
|
|
);
|
|
return data;
|
|
}
|