Container Copy Job implementation for SQL accounts (#2241)

* 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>
This commit is contained in:
BChoudhury-ms
2025-11-05 22:54:00 +05:30
committed by GitHub
parent 3718f5a16a
commit 2417da152d
78 changed files with 4152 additions and 36 deletions
@@ -3,11 +3,24 @@ import React from "react";
import { PanelContainerComponent, PanelContainerProps } from "./PanelContainerComponent";
describe("PaneContainerComponent test", () => {
it("should not render console with panel", () => {
const panelContainerProps: PanelContainerProps = {
headerText: "test",
panelContent: <div></div>,
isOpen: true,
hasConsole: false,
isConsoleExpanded: false,
};
const wrapper = shallow(<PanelContainerComponent {...panelContainerProps} />);
expect(wrapper).toMatchSnapshot();
});
it("should render with panel content and header", () => {
const panelContainerProps: PanelContainerProps = {
headerText: "test",
panelContent: <div></div>,
isOpen: true,
hasConsole: true,
isConsoleExpanded: false,
};
const wrapper = shallow(<PanelContainerComponent {...panelContainerProps} />);
@@ -19,6 +32,7 @@ describe("PaneContainerComponent test", () => {
headerText: "test",
panelContent: undefined,
isOpen: true,
hasConsole: true,
isConsoleExpanded: false,
};
const wrapper = shallow(<PanelContainerComponent {...panelContainerProps} />);
@@ -30,6 +44,7 @@ describe("PaneContainerComponent test", () => {
headerText: "test",
panelContent: <div></div>,
isOpen: true,
hasConsole: true,
isConsoleExpanded: true,
};
const wrapper = shallow(<PanelContainerComponent {...panelContainerProps} />);
@@ -8,6 +8,7 @@ export interface PanelContainerProps {
panelContent?: JSX.Element;
isConsoleExpanded: boolean;
isOpen: boolean;
hasConsole: boolean;
isConsoleAnimationFinished?: boolean;
panelWidth?: string;
onRenderNavigationContent?: IRenderFunction<IPanelProps>;
@@ -86,6 +87,9 @@ export class PanelContainerComponent extends React.Component<PanelContainerProps
};
private getPanelHeight = (): string => {
if (!this.props.hasConsole) {
return window.innerHeight + "px";
}
const notificationConsole = document.getElementById("explorerNotificationConsole");
if (notificationConsole) {
return window.innerHeight - notificationConsole.clientHeight + "px";
@@ -102,9 +106,10 @@ export class PanelContainerComponent extends React.Component<PanelContainerProps
export const SidePanel: React.FC = () => {
const isConsoleExpanded = useNotificationConsole((state) => state.isExpanded);
const isConsoleAnimationFinished = useNotificationConsole((state) => state.consoleAnimationFinished);
const { isOpen, panelContent, panelWidth, headerText } = useSidePanel((state) => {
const { isOpen, hasConsole, panelContent, panelWidth, headerText } = useSidePanel((state) => {
return {
isOpen: state.isOpen,
hasConsole: state.hasConsole,
panelContent: state.panelContent,
headerText: state.headerText,
panelWidth: state.panelWidth,
@@ -114,6 +119,7 @@ export const SidePanel: React.FC = () => {
// This component only exists so we can use hooks and pass them down to a non-functional component
return (
<PanelContainerComponent
hasConsole={hasConsole}
isOpen={isOpen}
panelContent={panelContent}
headerText={headerText}
@@ -39,6 +39,45 @@ exports[`PaneContainerComponent test should be resize if notification console is
</StyledPanelBase>
`;
exports[`PaneContainerComponent test should not render console with panel 1`] = `
<StyledPanelBase
closeButtonAriaLabel="Close test"
customWidth="440px"
data-test="Panel:test"
headerClassName="panelHeader"
headerText="test"
isFooterAtBottom={true}
isLightDismiss={true}
isOpen={true}
onDismiss={[Function]}
style={
{
"height": "768px",
}
}
styles={
{
"commands": {
"marginTop": 8,
"paddingTop": 0,
},
"content": {
"padding": 0,
},
"header": {
"padding": "0 0 8px 34px",
},
"navigation": {
"borderBottom": "1px solid #cccccc",
},
}
}
type={7}
>
<div />
</StyledPanelBase>
`;
exports[`PaneContainerComponent test should render nothing if content is undefined 1`] = `<Fragment />`;
exports[`PaneContainerComponent test should render with panel content and header 1`] = `