mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-30 22:31:56 +00:00
Integrate container creation screen to copy job flow (#2265)
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { Stack, Text } from "@fluentui/react";
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import { produce } from "immer";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import { AddCollectionPanel } from "../../../../Panes/AddCollectionPanel/AddCollectionPanel";
|
||||
import ContainerCopyMessages from "../../../ContainerCopyMessages";
|
||||
import { useCopyJobContext } from "../../../Context/CopyJobContext";
|
||||
|
||||
type AddCollectionPanelWrapperProps = {
|
||||
explorer?: Explorer;
|
||||
goBack?: () => void;
|
||||
};
|
||||
|
||||
const AddCollectionPanelWrapper: React.FunctionComponent<AddCollectionPanelWrapperProps> = ({ explorer, goBack }) => {
|
||||
const { setCopyJobState } = useCopyJobContext();
|
||||
|
||||
useEffect(() => {
|
||||
const sidePanelStore = useSidePanel.getState();
|
||||
if (sidePanelStore.headerText !== ContainerCopyMessages.createContainerHeading) {
|
||||
sidePanelStore.setHeaderText(ContainerCopyMessages.createContainerHeading);
|
||||
}
|
||||
return () => {
|
||||
sidePanelStore.setHeaderText(ContainerCopyMessages.createCopyJobPanelTitle);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleAddCollectionSuccess = useCallback(
|
||||
(collectionData: { databaseId: string; collectionId: string }) => {
|
||||
setCopyJobState(
|
||||
produce((state) => {
|
||||
state.target.databaseId = collectionData.databaseId;
|
||||
state.target.containerId = collectionData.collectionId;
|
||||
}),
|
||||
);
|
||||
goBack?.();
|
||||
},
|
||||
[goBack],
|
||||
);
|
||||
|
||||
return (
|
||||
<Stack className="addCollectionPanelWrapper">
|
||||
<Stack.Item className="addCollectionPanelHeader">
|
||||
<Text>{ContainerCopyMessages.createNewContainerSubHeading}</Text>
|
||||
</Stack.Item>
|
||||
<Stack.Item className="addCollectionPanelBody">
|
||||
<AddCollectionPanel explorer={explorer} isCopyJobFlow={true} onSubmitSuccess={handleAddCollectionSuccess} />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddCollectionPanelWrapper;
|
||||
@@ -13,6 +13,7 @@ const CreateCopyJobScreens: React.FC = () => {
|
||||
handlePrevious,
|
||||
handleCancel,
|
||||
primaryBtnText,
|
||||
showAddCollectionPanel,
|
||||
} = useCopyJobNavigation();
|
||||
const { contextError, setContextError } = useCopyJobContext();
|
||||
|
||||
@@ -32,7 +33,7 @@ const CreateCopyJobScreens: React.FC = () => {
|
||||
{contextError}
|
||||
</MessageBar>
|
||||
)}
|
||||
{currentScreen?.component}
|
||||
{React.cloneElement(currentScreen?.component as React.ReactElement, { showAddCollectionPanel })}
|
||||
</Stack.Item>
|
||||
<Stack.Item className="createCopyJobScreensFooter">
|
||||
<NavigationControls
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import React from "react";
|
||||
import CopyJobContextProvider from "../../Context/CopyJobContext";
|
||||
import CreateCopyJobScreens from "./CreateCopyJobScreens";
|
||||
|
||||
const CreateCopyJobScreensProvider = () => {
|
||||
const CreateCopyJobScreensProvider = ({ explorer }: { explorer: Explorer }) => {
|
||||
return (
|
||||
<CopyJobContextProvider>
|
||||
<CopyJobContextProvider explorer={explorer}>
|
||||
<CreateCopyJobScreens />
|
||||
</CopyJobContextProvider>
|
||||
);
|
||||
|
||||
@@ -9,7 +9,11 @@ import { DatabaseContainerSection } from "./components/DatabaseContainerSection"
|
||||
import { dropDownChangeHandler } from "./Events/DropDownChangeHandler";
|
||||
import { useMemoizedSourceAndTargetData } from "./memoizedData";
|
||||
|
||||
const SelectSourceAndTargetContainers = () => {
|
||||
type SelectSourceAndTargetContainers = {
|
||||
showAddCollectionPanel?: () => void;
|
||||
};
|
||||
|
||||
const SelectSourceAndTargetContainers = ({ showAddCollectionPanel }: SelectSourceAndTargetContainers) => {
|
||||
const { copyJobState, setCopyJobState } = useCopyJobContext();
|
||||
const { source, target, sourceDbParams, sourceContainerParams, targetDbParams, targetContainerParams } =
|
||||
useMemoizedSourceAndTargetData(copyJobState);
|
||||
@@ -62,6 +66,7 @@ const SelectSourceAndTargetContainers = () => {
|
||||
selectedContainer={target?.containerId}
|
||||
containerDisabled={!target?.databaseId}
|
||||
containerOnChange={onDropdownChange("targetContainer")}
|
||||
handleOnDemandCreateContainer={showAddCollectionPanel}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Dropdown, Stack } from "@fluentui/react";
|
||||
import { ActionButton, Dropdown, Stack } from "@fluentui/react";
|
||||
import React from "react";
|
||||
import ContainerCopyMessages from "../../../../ContainerCopyMessages";
|
||||
import { DatabaseContainerSectionProps } from "../../../../Types/CopyJobTypes";
|
||||
@@ -14,6 +14,7 @@ export const DatabaseContainerSection = ({
|
||||
selectedContainer,
|
||||
containerDisabled,
|
||||
containerOnChange,
|
||||
handleOnDemandCreateContainer,
|
||||
}: DatabaseContainerSectionProps) => (
|
||||
<Stack tokens={{ childrenGap: 15 }} className="databaseContainerSection">
|
||||
<label className="subHeading">{heading}</label>
|
||||
@@ -29,15 +30,22 @@ export const DatabaseContainerSection = ({
|
||||
/>
|
||||
</FieldRow>
|
||||
<FieldRow label={ContainerCopyMessages.containerDropdownLabel}>
|
||||
<Dropdown
|
||||
placeholder={ContainerCopyMessages.containerDropdownPlaceholder}
|
||||
ariaLabel={ContainerCopyMessages.containerDropdownLabel}
|
||||
options={containerOptions}
|
||||
required
|
||||
disabled={!!containerDisabled}
|
||||
selectedKey={selectedContainer}
|
||||
onChange={containerOnChange}
|
||||
/>
|
||||
<Stack>
|
||||
<Dropdown
|
||||
placeholder={ContainerCopyMessages.containerDropdownPlaceholder}
|
||||
ariaLabel={ContainerCopyMessages.containerDropdownLabel}
|
||||
options={containerOptions}
|
||||
required
|
||||
disabled={!!containerDisabled}
|
||||
selectedKey={selectedContainer}
|
||||
onChange={containerOnChange}
|
||||
/>
|
||||
{handleOnDemandCreateContainer && (
|
||||
<ActionButton className="create-container-link-btn" onClick={() => handleOnDemandCreateContainer()}>
|
||||
{ContainerCopyMessages.createContainerButtonLabel}
|
||||
</ActionButton>
|
||||
)}
|
||||
</Stack>
|
||||
</FieldRow>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
@@ -35,10 +35,14 @@ function navigationReducer(state: NavigationState, action: Action): NavigationSt
|
||||
export function useCopyJobNavigation() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { copyJobState, resetCopyJobState, setContextError } = useCopyJobContext();
|
||||
const screens = useCreateCopyJobScreensList();
|
||||
const { validationCache: cache } = useCopyJobPrerequisitesCache();
|
||||
const [state, dispatch] = useReducer(navigationReducer, { screenHistory: [SCREEN_KEYS.SelectAccount] });
|
||||
|
||||
const handlePrevious = useCallback(() => {
|
||||
dispatch({ type: "PREVIOUS" });
|
||||
}, [dispatch]);
|
||||
|
||||
const screens = useCreateCopyJobScreensList(handlePrevious);
|
||||
const currentScreenKey = state.screenHistory[state.screenHistory.length - 1];
|
||||
const currentScreen = screens.find((screen) => screen.key === currentScreenKey);
|
||||
|
||||
@@ -51,7 +55,9 @@ export function useCopyJobNavigation() {
|
||||
}, [currentScreen.key, copyJobState, cache, isLoading]);
|
||||
|
||||
const primaryBtnText = useMemo(() => {
|
||||
if (currentScreenKey === SCREEN_KEYS.PreviewCopyJob) {
|
||||
if (currentScreenKey === SCREEN_KEYS.CreateCollection) {
|
||||
return "Create";
|
||||
} else if (currentScreenKey === SCREEN_KEYS.PreviewCopyJob) {
|
||||
return "Copy";
|
||||
}
|
||||
return "Next";
|
||||
@@ -107,7 +113,26 @@ export function useCopyJobNavigation() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddCollectionPanelSubmit = () => {
|
||||
const form = document.getElementById("panelContainer") as HTMLFormElement;
|
||||
if (form) {
|
||||
const submitEvent = new Event("submit", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
form.dispatchEvent(submitEvent);
|
||||
}
|
||||
};
|
||||
|
||||
const showAddCollectionPanel = useCallback(() => {
|
||||
dispatch({ type: "NEXT", nextScreen: SCREEN_KEYS.CreateCollection });
|
||||
}, [dispatch]);
|
||||
|
||||
const handlePrimary = useCallback(() => {
|
||||
if (currentScreenKey === SCREEN_KEYS.CreateCollection) {
|
||||
handleAddCollectionPanelSubmit();
|
||||
return;
|
||||
}
|
||||
if (currentScreenKey === SCREEN_KEYS.SelectSourceAndTargetContainers && areContainersIdentical()) {
|
||||
setContextError(
|
||||
"Source and destination containers cannot be the same. Please select different containers to proceed.",
|
||||
@@ -132,10 +157,6 @@ export function useCopyJobNavigation() {
|
||||
}
|
||||
}, [currentScreenKey, copyJobState, areContainersIdentical, handleCopyJobSubmission]);
|
||||
|
||||
const handlePrevious = useCallback(() => {
|
||||
dispatch({ type: "PREVIOUS" });
|
||||
}, []);
|
||||
|
||||
return {
|
||||
currentScreen,
|
||||
isPrimaryDisabled,
|
||||
@@ -143,6 +164,7 @@ export function useCopyJobNavigation() {
|
||||
handlePrimary,
|
||||
handlePrevious,
|
||||
handleCancel,
|
||||
showAddCollectionPanel,
|
||||
primaryBtnText,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import React from "react";
|
||||
import { useCopyJobContext } from "../../Context/CopyJobContext";
|
||||
import { CopyJobContextState } from "../../Types/CopyJobTypes";
|
||||
import AssignPermissions from "../Screens/AssignPermissions/AssignPermissions";
|
||||
import AddCollectionPanelWrapper from "../Screens/CreateContainer/AddCollectionPanelWrapper";
|
||||
import PreviewCopyJob from "../Screens/PreviewCopyJob/PreviewCopyJob";
|
||||
import SelectAccount from "../Screens/SelectAccount/SelectAccount";
|
||||
import SelectSourceAndTargetContainers from "../Screens/SelectSourceAndTargetContainers/SelectSourceAndTargetContainers";
|
||||
|
||||
const SCREEN_KEYS = {
|
||||
CreateCollection: "CreateCollection",
|
||||
SelectAccount: "SelectAccount",
|
||||
SelectSourceAndTargetContainers: "SelectSourceAndTargetContainers",
|
||||
PreviewCopyJob: "PreviewCopyJob",
|
||||
@@ -23,7 +26,9 @@ type Screen = {
|
||||
validations: Validation[];
|
||||
};
|
||||
|
||||
function useCreateCopyJobScreensList() {
|
||||
function useCreateCopyJobScreensList(goBack: () => void): Screen[] {
|
||||
const { explorer } = useCopyJobContext();
|
||||
|
||||
return React.useMemo<Screen[]>(
|
||||
() => [
|
||||
{
|
||||
@@ -50,6 +55,11 @@ function useCreateCopyJobScreensList() {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: SCREEN_KEYS.CreateCollection,
|
||||
component: <AddCollectionPanelWrapper explorer={explorer} goBack={goBack} />,
|
||||
validations: [],
|
||||
},
|
||||
{
|
||||
key: SCREEN_KEYS.PreviewCopyJob,
|
||||
component: <PreviewCopyJob />,
|
||||
@@ -80,7 +90,7 @@ function useCreateCopyJobScreensList() {
|
||||
],
|
||||
},
|
||||
],
|
||||
[],
|
||||
[explorer],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user