mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-27 04:41:48 +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>
117 lines
3.2 KiB
TypeScript
117 lines
3.2 KiB
TypeScript
import { DatabaseAccount } from "Contracts/DataModels";
|
|
import { CopyJobErrorType } from "./Types/CopyJobTypes";
|
|
|
|
const azurePortalMpacEndpoint = "https://ms.portal.azure.com/";
|
|
|
|
export const buildResourceLink = (resource: DatabaseAccount): string => {
|
|
const resourceId = resource.id;
|
|
let parentOrigin = window.location.ancestorOrigins?.[0] ?? window.location.origin;
|
|
|
|
if (/\/\/localhost:/.test(parentOrigin)) {
|
|
parentOrigin = azurePortalMpacEndpoint;
|
|
} else if (/\/\/cosmos\.azure/.test(parentOrigin)) {
|
|
parentOrigin = parentOrigin.replace("cosmos.azure", "portal.azure");
|
|
}
|
|
|
|
parentOrigin = parentOrigin.replace(/\/$/, "");
|
|
|
|
return `${parentOrigin}/#resource${resourceId}`;
|
|
};
|
|
|
|
export const COSMOS_SQL_COMPONENT = "CosmosDBSql";
|
|
|
|
export const COPY_JOB_API_VERSION = "2025-05-01-preview";
|
|
|
|
export function buildDataTransferJobPath({
|
|
subscriptionId,
|
|
resourceGroup,
|
|
accountName,
|
|
jobName,
|
|
action,
|
|
}: {
|
|
subscriptionId: string;
|
|
resourceGroup: string;
|
|
accountName: string;
|
|
jobName?: string;
|
|
action?: string;
|
|
}) {
|
|
let path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/dataTransferJobs`;
|
|
if (jobName) {
|
|
path += `/${jobName}`;
|
|
}
|
|
if (action) {
|
|
path += `/${action}`;
|
|
}
|
|
return path;
|
|
}
|
|
|
|
export function convertTime(timeStr: string): string | null {
|
|
const timeParts = timeStr.split(":").map(Number);
|
|
|
|
if (timeParts.length !== 3 || timeParts.some(isNaN)) {
|
|
return null;
|
|
}
|
|
const formatPart = (value: number, unit: string) => {
|
|
if (unit === "seconds") {
|
|
value = Math.round(value);
|
|
}
|
|
return value > 0 ? `${value.toString().padStart(2, "0")} ${unit}` : "";
|
|
};
|
|
|
|
const [hours, minutes, seconds] = timeParts;
|
|
const formattedTimeParts = [
|
|
formatPart(hours, "hours"),
|
|
formatPart(minutes, "minutes"),
|
|
formatPart(seconds, "seconds"),
|
|
]
|
|
.filter(Boolean)
|
|
.join(", ");
|
|
|
|
return formattedTimeParts || "0 seconds";
|
|
}
|
|
|
|
export function formatUTCDateTime(utcStr: string): { formattedDateTime: string; timestamp: number } | null {
|
|
const date = new Date(utcStr);
|
|
if (isNaN(date.getTime())) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
formattedDateTime: new Intl.DateTimeFormat("en-US", {
|
|
dateStyle: "short",
|
|
timeStyle: "medium",
|
|
timeZone: "UTC",
|
|
}).format(date),
|
|
timestamp: date.getTime(),
|
|
};
|
|
}
|
|
|
|
export function convertToCamelCase(str: string): string {
|
|
const formattedStr = str
|
|
.split(/\s+/)
|
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
.join("");
|
|
return formattedStr;
|
|
}
|
|
|
|
export function extractErrorMessage(error: CopyJobErrorType): CopyJobErrorType {
|
|
return {
|
|
...error,
|
|
message: error.message.split("\r\n\r\n")[0],
|
|
};
|
|
}
|
|
|
|
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);
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
const [_, subscriptionId, resourceGroup, accountName] = matches || [];
|
|
return { subscriptionId, resourceGroup, accountName };
|
|
}
|