Skip to content
This repository has been archived by the owner on Jan 12, 2023. It is now read-only.

Commit

Permalink
Track migrate/cutover request state locally to the button instead of …
Browse files Browse the repository at this point in the history
…at the plans page level (#537)
  • Loading branch information
mturley committed Apr 9, 2021
1 parent e089e6a commit 7742096
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 69 deletions.
38 changes: 4 additions & 34 deletions src/app/Plans/PlansPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,58 +10,31 @@ import {
} from '@patternfly/react-core';
import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing';
import { PlusCircleIcon } from '@patternfly/react-icons';
import { useHistory } from 'react-router-dom';

import {
useHasSufficientProvidersQuery,
usePlansQuery,
useCreateMigrationMutation,
useClusterProvidersQuery,
useSetCutoverMutation,
} from '@app/queries';

import PlansTable from './components/PlansTable';
import CreatePlanButton from './components/CreatePlanButton';
import {
ResolvedQuery,
QuerySpinnerMode,
ResolvedQueries,
} from '@app/common/components/ResolvedQuery';
import { IMigration } from '@app/queries/types/migrations.types';
import { ResolvedQueries } from '@app/common/components/ResolvedQuery';

const PlansPage: React.FunctionComponent = () => {
const sufficientProvidersQuery = useHasSufficientProvidersQuery();
const clusterProvidersQuery = useClusterProvidersQuery();
const plansQuery = usePlansQuery();

const history = useHistory();
const onMigrationStarted = (migration: IMigration) => {
history.push(`/plans/${migration.spec.plan.name}`);
};
const [createMigration, createMigrationResult] = useCreateMigrationMutation(onMigrationStarted);

const [setCutover, setCutoverResult] = useSetCutoverMutation();
const errorContainerRef = React.useRef<HTMLDivElement>(null);

return (
<>
<PageSection variant="light">
<Title headingLevel="h1">Migration plans</Title>
</PageSection>
<PageSection>
<ResolvedQuery
result={createMigrationResult}
errorTitle="Error starting migration"
errorsInline={false}
spinnerMode={QuerySpinnerMode.None}
className={spacing.mbMd}
/>
<ResolvedQuery
result={setCutoverResult}
errorTitle="Error setting cutover time"
errorsInline={false}
spinnerMode={QuerySpinnerMode.None}
className={spacing.mbMd}
/>
<div ref={errorContainerRef} />
<ResolvedQueries
results={[sufficientProvidersQuery.result, clusterProvidersQuery, plansQuery]}
errorTitles={[
Expand All @@ -87,10 +60,7 @@ const PlansPage: React.FunctionComponent = () => {
) : (
<PlansTable
plans={plansQuery.data?.items || []}
createMigration={createMigration}
createMigrationResult={createMigrationResult}
setCutover={setCutover}
setCutoverResult={setCutoverResult}
errorContainerRef={errorContainerRef}
/>
)}
</CardBody>
Expand Down
73 changes: 73 additions & 0 deletions src/app/Plans/components/MigrateOrCutoverButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as React from 'react';
import { createPortal } from 'react-dom';
import { useHistory } from 'react-router-dom';
import { Button, Spinner } from '@patternfly/react-core';
import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing';
import { useCreateMigrationMutation, useSetCutoverMutation } from '@app/queries';
import { IMigration } from '@app/queries/types/migrations.types';
import { IPlan } from '@app/queries/types';
import { PlanActionButtonType } from './PlansTable';
import { ResolvedQuery, QuerySpinnerMode } from '@app/common/components/ResolvedQuery';

interface IMigrateOrCutoverButtonProps {
plan: IPlan;
buttonType: PlanActionButtonType;
isBeingStarted: boolean;
errorContainerRef: React.RefObject<HTMLDivElement>;
}

const MigrateOrCutoverButton: React.FunctionComponent<IMigrateOrCutoverButtonProps> = ({
plan,
buttonType,
isBeingStarted,
errorContainerRef,
}: IMigrateOrCutoverButtonProps) => {
const history = useHistory();
const onMigrationStarted = (migration: IMigration) => {
history.push(`/plans/${migration.spec.plan.name}`);
};
const [createMigration, createMigrationResult] = useCreateMigrationMutation(onMigrationStarted);
const [setCutover, setCutoverResult] = useSetCutoverMutation();
if (isBeingStarted || createMigrationResult.isLoading || setCutoverResult.isLoading) {
return <Spinner size="md" className={spacing.mxLg} />;
}
return (
<>
<Button
variant="secondary"
onClick={() => {
if (buttonType === 'Start' || buttonType === 'Restart') {
createMigration(plan);
} else if (buttonType === 'Cutover') {
setCutover({ plan, cutover: new Date().toISOString() });
}
}}
>
{buttonType}
</Button>
{(createMigrationResult.isError || setCutoverResult.isError) && errorContainerRef.current
? createPortal(
<>
<ResolvedQuery
result={createMigrationResult}
errorTitle="Error starting migration"
errorsInline={false}
spinnerMode={QuerySpinnerMode.None}
className={spacing.mbMd}
/>
<ResolvedQuery
result={setCutoverResult}
errorTitle="Error setting cutover time"
errorsInline={false}
spinnerMode={QuerySpinnerMode.None}
className={spacing.mbMd}
/>
</>,
errorContainerRef.current
)
: null}
</>
);
};

export default MigrateOrCutoverButton;
47 changes: 12 additions & 35 deletions src/app/Plans/components/PlansTable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import {
Button,
Flex,
FlexItem,
Level,
Expand All @@ -9,7 +8,6 @@ import {
Progress,
ProgressMeasureLocation,
ProgressVariant,
Spinner,
Text,
Tooltip,
} from '@patternfly/react-core';
Expand All @@ -30,7 +28,6 @@ import {
Th,
Tr,
} from '@patternfly/react-table';
import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing';
import alignment from '@patternfly/react-styles/css/utilities/Alignment/alignment';
import { Link } from 'react-router-dom';
import { useSelectionState } from '@konveyor/lib-ui';
Expand All @@ -47,15 +44,11 @@ import TableEmptyState from '@app/common/components/TableEmptyState';
import {
findLatestMigration,
findProvidersByRefs,
ISetCutoverArgs,
useInventoryProvidersQuery,
useMigrationsQuery,
} from '@app/queries';

import './PlansTable.css';
import { IKubeResponse, KubeClientError } from '@app/client/types';
import { IMigration } from '@app/queries/types/migrations.types';
import { MutateFunction, MutationResult } from 'react-query';
import {
canPlanBeStarted,
getPlanStatusTitle,
Expand All @@ -64,21 +57,18 @@ import {
} from './helpers';
import { isSameResource } from '@app/queries/helpers';
import StatusCondition from '@app/common/components/StatusCondition';
import MigrateOrCutoverButton from './MigrateOrCutoverButton';

export type PlanActionButtonType = 'Start' | 'Restart' | 'Cutover';

interface IPlansTableProps {
plans: IPlan[];
createMigration: MutateFunction<IKubeResponse<IMigration>, KubeClientError, IPlan>;
createMigrationResult: MutationResult<IKubeResponse<IMigration>, KubeClientError>;
setCutover: MutateFunction<IKubeResponse<IMigration>, KubeClientError, ISetCutoverArgs, unknown>;
setCutoverResult: MutationResult<IKubeResponse<IMigration>, KubeClientError>;
errorContainerRef: React.RefObject<HTMLDivElement>;
}

const PlansTable: React.FunctionComponent<IPlansTableProps> = ({
plans,
createMigration,
createMigrationResult,
setCutover,
setCutoverResult,
errorContainerRef,
}: IPlansTableProps) => {
const providersQuery = useInventoryProvidersQuery();
const migrationsQuery = useMigrationsQuery();
Expand Down Expand Up @@ -196,10 +186,8 @@ const PlansTable: React.FunctionComponent<IPlansTableProps> = ({

const rows: IRow[] = [];

type ActionButtonType = 'Start' | 'Restart' | 'Cutover';

currentPageItems.forEach((plan: IPlan) => {
let buttonType: ActionButtonType | null = null;
let buttonType: PlanActionButtonType | null = null;
let title = '';
let variant: ProgressVariant | undefined;

Expand Down Expand Up @@ -302,23 +290,12 @@ const PlansTable: React.FunctionComponent<IPlansTableProps> = ({
flexWrap={{ default: 'nowrap' }}
>
<FlexItem align={{ default: 'alignRight' }}>
{isBeingStarted ? (
<Spinner size="md" className={spacing.mxLg} />
) : (
<Button
variant="secondary"
onClick={() => {
if (buttonType === 'Start' || buttonType === 'Restart') {
createMigration(plan);
} else if (buttonType === 'Cutover') {
setCutover({ plan, cutover: new Date().toISOString() });
}
}}
isDisabled={createMigrationResult.isLoading || setCutoverResult.isLoading}
>
{buttonType}
</Button>
)}
<MigrateOrCutoverButton
plan={plan}
buttonType={buttonType}
isBeingStarted={isBeingStarted}
errorContainerRef={errorContainerRef}
/>
</FlexItem>
<FlexItem>
<PlanActionsDropdown plan={plan} />
Expand Down

0 comments on commit 7742096

Please sign in to comment.