Skip to content

Commit

Permalink
Merge pull request #1436 from jpuzz0/MTV-1880-move-plan-name-field
Browse files Browse the repository at this point in the history
[MTV-1880] Move 'Plan name' field to step 1 of create migration plan wizard
  • Loading branch information
metalice authored Jan 23, 2025
2 parents 460d2b8 + d2a4440 commit bbb2a04
Show file tree
Hide file tree
Showing 19 changed files with 101 additions and 225 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"{{total}} VM": "{{total}} VM",
"{{total}} VM_plural": "{{total}} VMs",
"{{total}} VMs": "{{total}} VMs",
"{{vmCount}} VMs selected ": "{{vmCount}} VMs selected ",
"{{vmCount}} VMs selected": "{{vmCount}} VMs selected",
"{children}": "{children}",
"24 hours": "24 hours",
"31 days": "31 days",
Expand Down Expand Up @@ -158,7 +158,6 @@
"Edit migration plan transfer network": "Edit migration plan transfer network",
"Edit NetworkMap": "Edit NetworkMap",
"Edit Plan": "Edit Plan",
"Edit plan name": "Edit plan name",
"Edit Precopy interval (minutes)": "Edit Precopy interval (minutes)",
"Edit Provider": "Edit Provider",
"Edit Provider Credentials": "Edit Provider Credentials",
Expand Down Expand Up @@ -424,7 +423,6 @@
"Select virtual machines": "Select virtual machines",
"Select vSphere provider endpoint type.": "Select vSphere provider endpoint type.",
"Selected columns will be displayed in the table.": "Selected columns will be displayed in the table.",
"Selected VMs": "Selected VMs",
"Service account bearer token": "Service account bearer token",
"Set cutover": "Set cutover",
"Set default transfer network": "Set default transfer network",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.forklift-page__main-title {
padding-bottom: 0;
}

.forklift-page__toolbar-item__selected-count {
color: var(--pf-v5-global--Color--200);
margin-inline-start: auto;
align-self: center;
}
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ export interface StandardPageProps<T> {
* Expanded ids
*/
expandedIds?: string[];

/**
* Label to show count of selected items
*/
selectedCountLabel?: (selectedIdCount: number) => string;
}

/**
Expand Down Expand Up @@ -280,6 +285,8 @@ export function StandardPage<T>({
toId,
expandedIds,
className,
selectedIds,
selectedCountLabel,
}: StandardPageProps<T>) {
const { t } = useForkliftTranslation();
const [sortedData, setSortedData] = useState([]);
Expand Down Expand Up @@ -412,6 +419,13 @@ export function StandardPage<T>({
<Action key={index} dataOnScreen={showPagination ? pageData : filteredData} />
))}
</ToolbarToggleGroup>

{selectedCountLabel && (
<ToolbarItem className="forklift-page__toolbar-item__selected-count">
{selectedCountLabel(selectedIds.length ?? 0)}
</ToolbarItem>
)}

{showPagination && (
<ToolbarItem variant="pagination">
<Pagination
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export function withIdBasedSelection<T>({
<StandardPage
{...rest}
expandedIds={expandedIds}
selectedIds={selectedIds}
toId={toId}
RowMapper={RowMapper}
HeaderMapper={HeaderMapper}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import { Wizard } from '@patternfly/react-core/deprecated';
import { findProviderByID } from './components';
import { planCreatePageInitialState, planCreatePageReducer } from './states';
import { SelectSourceProvider } from './steps';
import { validateSourceProviderStep } from './utils';

import './PlanCreatePage.style.css';

export const PlanCreatePage: React.FC<{ namespace: string }> = ({ namespace }) => {
// Get optional initial state context
const { data } = useCreateVmMigrationData();
const history = useHistory();
const startAtStep = data?.provider !== undefined ? 2 : 1;
const [activeNamespace, setActiveNamespace] = useActiveNamespace();
const defaultNamespace = process?.env?.DEFAULT_NAMESPACE || 'default';
const projectName =
Expand Down Expand Up @@ -59,6 +59,11 @@ export const PlanCreatePage: React.FC<{ namespace: string }> = ({ namespace }) =
});
useSaveEffect(state, dispatch);

const isFirstStepValid = React.useMemo(
() => validateSourceProviderStep(state, filterState),
[state, filterState],
);

const steps = [
{
id: 'step-1',
Expand All @@ -74,7 +79,7 @@ export const PlanCreatePage: React.FC<{ namespace: string }> = ({ namespace }) =
selectedProvider={selectedProvider}
/>
),
enableNext: filterState?.selectedVMs?.length > 0,
enableNext: isFirstStepValid,
},
{
id: 'step-2',
Expand All @@ -93,7 +98,7 @@ export const PlanCreatePage: React.FC<{ namespace: string }> = ({ namespace }) =
Object.values(state?.validation || []).some((validation) => validation === 'error') ||
state?.validation?.planName === 'default'
),
canJumpTo: filterState?.selectedVMs?.length > 0,
canJumpTo: isFirstStepValid,
nextButtonText: 'Create migration plan',
},
];
Expand All @@ -116,7 +121,6 @@ export const PlanCreatePage: React.FC<{ namespace: string }> = ({ namespace }) =
dispatch(startCreate());
}}
onClose={() => history.goBack()}
startAtStep={startAtStep}
/>
</PageSection>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { VmData } from 'src/modules/Providers/views';
import { useCreateVmMigrationData } from 'src/modules/Providers/views/migrate';
import {
PageAction,
setPlanName,
setProjectName as setProjectNameAction,
} from 'src/modules/Providers/views/migrate/reducer/actions';
import { CreateVmMigrationPageState } from 'src/modules/Providers/views/migrate/types';
Expand All @@ -19,6 +20,7 @@ import { PlanCreatePageState } from '../states';
import { ChipsToolbarProviders } from './ChipsToolbarProviders';
import { createProviderCardItems } from './createProviderCardItems';
import { FiltersToolbarProviders } from './FiltersToolbarProviders';
import { PlanNameTextField } from './PlanNameTextField';
import { ProjectNameSelect } from './ProjectNameSelect';

export type PlanCreateFormProps = {
Expand All @@ -40,6 +42,7 @@ export type PlanCreateFormProps = {
export const PlanCreateForm: React.FC<PlanCreateFormProps> = ({
providers,
filterState,
state,
projectName,
filterDispatch,
dispatch,
Expand All @@ -58,6 +61,17 @@ export const PlanCreateForm: React.FC<PlanCreateFormProps> = ({
return (
<div className="forklift-create-provider-edit-section">
<Form isWidthLimited className="forklift-section-secret-edit">
<PlanNameTextField
isRequired
value={state.underConstruction.plan.metadata.name}
validated={state.validation.planName}
isDisabled={state.flow.editingDone}
onChange={(_, value) => {
dispatch(setPlanName(value?.trim() ?? ''));
setData({ ...data, planName: value });
}}
/>

<ProjectNameSelect
value={projectName}
options={providerNamespaces.map((namespace) => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Validation } from 'src/modules/Providers';
import { ForkliftTrans, useForkliftTranslation } from 'src/utils';
import { useForkliftTranslation } from 'src/utils';

import { FormGroupWithHelpText } from '@kubev2v/common';
import { TextInput } from '@patternfly/react-core';
Expand Down Expand Up @@ -30,10 +30,8 @@ export const PlanNameTextField: React.FC<PlanNameTextFieldProps> = ({
fieldId="planName"
{...(isUpdated && {
validated: validated,
helperTextInvalid: (
<ForkliftTrans>
Name is required and must be a unique within a namespace and valid Kubernetes name.
</ForkliftTrans>
helperTextInvalid: t(
'Name is required and must be a unique within a namespace and valid Kubernetes name.',
),
})}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,17 @@ export const ProviderVirtualMachinesList: React.FC<{
initialSelectedIds?: string[];
showActions: boolean;
className?: string;
}> = ({ title, name, namespace, onSelect, initialSelectedIds, showActions, className }) => {
selectedCountLabel?: (selectedIdCount: number) => string;
}> = ({
title,
name,
namespace,
onSelect,
initialSelectedIds,
showActions,
className,
selectedCountLabel,
}) => {
const [provider, providerLoaded, providerLoadError] = useK8sWatchResource<V1beta1Provider>({
groupVersionKind: ProviderModelGroupVersionKind,
namespaced: true,
Expand All @@ -37,6 +47,7 @@ export const ProviderVirtualMachinesList: React.FC<{
initialSelectedIds={initialSelectedIds}
showActions={showActions}
className={className}
selectedCountLabel={selectedCountLabel}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface ProviderVirtualMachinesListProps {
onSelect: (selectedVms: VmData[]) => void;
initialSelectedIds: string[];
showActions: boolean;
selectedCountLabel?: (selectedIdCount: number) => string;
}

export const MemoizedProviderVirtualMachinesList = memo(
Expand All @@ -20,6 +21,7 @@ export const MemoizedProviderVirtualMachinesList = memo(
onSelect,
initialSelectedIds,
showActions,
selectedCountLabel,
}: ProviderVirtualMachinesListProps) => {
return (
<ProviderVirtualMachinesList
Expand All @@ -29,6 +31,7 @@ export const MemoizedProviderVirtualMachinesList = memo(
onSelect={onSelect}
initialSelectedIds={initialSelectedIds}
showActions={showActions}
selectedCountLabel={selectedCountLabel}
/>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export const SelectSourceProvider: React.FC<{
}
initialSelectedIds={filterState.selectedVMs.map((vm) => vm.vm.id)}
showActions={false}
selectedCountLabel={(selectedIdCount) =>
t('{{vmCount}} VMs selected', { vmCount: selectedIdCount })
}
/>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { CreateVmMigrationPageState } from 'src/modules/Providers/views/migrate/types';

import { PlanCreatePageState } from './states';

export const validateSourceProviderStep = (
state: CreateVmMigrationPageState,
filterState: PlanCreatePageState,
) =>
state.underConstruction.plan.metadata.name &&
state.validation.planName !== 'error' &&
filterState?.selectedVMs?.length > 0;
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,11 @@ export const oVirtVmFieldsMetadataFactory: ResourceFieldFactory = (t) => [
},
];

export const OVirtVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = ({
title,
obj,
loaded,
loadError,
onSelect,
initialSelectedIds,
showActions,
className,
}) => (
export const OVirtVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = (props) => (
<ProviderVirtualMachinesList
title={title}
obj={obj}
loaded={loaded}
loadError={loadError}
{...props}
cellMapper={OVirtVirtualMachinesCells}
fieldsMetadataFactory={oVirtVmFieldsMetadataFactory}
pageId="OVirtVirtualMachinesList"
onSelect={onSelect}
initialSelectedIds={initialSelectedIds}
showActions={showActions}
className={className}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -73,27 +73,11 @@ export const openShiftVmFieldsMetadataFactory: ResourceFieldFactory = (t) => [
},
];

export const OpenShiftVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = ({
title,
obj,
loaded,
loadError,
onSelect,
initialSelectedIds,
showActions,
className,
}) => (
export const OpenShiftVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = (props) => (
<ProviderVirtualMachinesList
title={title}
obj={obj}
loaded={loaded}
loadError={loadError}
{...props}
cellMapper={OpenShiftVirtualMachinesCells}
fieldsMetadataFactory={openShiftVmFieldsMetadataFactory}
pageId="OpenShiftVirtualMachinesList"
onSelect={onSelect}
initialSelectedIds={initialSelectedIds}
showActions={showActions}
className={className}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -104,27 +104,11 @@ export const openStackVmFieldsMetadataFactory: ResourceFieldFactory = (t) => [
},
];

export const OpenStackVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = ({
title,
obj,
loaded,
loadError,
onSelect,
initialSelectedIds,
showActions,
className,
}) => (
export const OpenStackVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = (props) => (
<ProviderVirtualMachinesList
title={title}
obj={obj}
loaded={loaded}
loadError={loadError}
{...props}
cellMapper={OpenStackVirtualMachinesCells}
fieldsMetadataFactory={openStackVmFieldsMetadataFactory}
pageId="OpenStackVirtualMachinesList"
onSelect={onSelect}
initialSelectedIds={initialSelectedIds}
showActions={showActions}
className={className}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,11 @@ export const ovaVmFieldsMetadataFactory: ResourceFieldFactory = (t) => [
},
];

export const OvaVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = ({
title,
obj,
loaded,
loadError,
onSelect,
initialSelectedIds,
showActions,
className,
}) => (
export const OvaVirtualMachinesList: React.FC<ProviderVirtualMachinesProps> = (props) => (
<ProviderVirtualMachinesList
title={title}
obj={obj}
loaded={loaded}
loadError={loadError}
{...props}
cellMapper={OvaVirtualMachinesCells}
fieldsMetadataFactory={ovaVmFieldsMetadataFactory}
pageId="OvaVirtualMachinesList"
onSelect={onSelect}
initialSelectedIds={initialSelectedIds}
showActions={showActions}
className={className}
/>
);
Loading

0 comments on commit bbb2a04

Please sign in to comment.