Skip to content

Conversation

@avivtur
Copy link
Collaborator

@avivtur avivtur commented Dec 10, 2025

📝 Links

https://issues.redhat.com/browse/MTV-3743

📝 Description

Standardize the mappings tab under plan details page

🎥 Demo

plan-mappings-section.mp4
plan-mappings-section2.mp4
plan-mappings-section3.mp4

📝 CC://

@codecov-commenter
Copy link

codecov-commenter commented Dec 10, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 3.44828% with 420 lines in your changes missing coverage. Please review.
✅ Project coverage is 13.40%. Comparing base (13484d0) to head (9b6a144).
⚠️ Report is 935 commits behind head on main.

Files with missing lines Patch % Lines
...geMapEdit/components/PlanStorageMapFieldsTable.tsx 0.00% 63 Missing ⚠️
...rkMapEdit/components/PlanNetworkMapFieldsTable.tsx 0.00% 57 Missing ⚠️
...c/plans/details/tabs/Mappings/PlanMappingsPage.tsx 0.00% 50 Missing ⚠️
...s/mappings/network-mappings/SourceNetworkField.tsx 0.00% 33 Missing ⚠️
...s/mappings/network-mappings/TargetNetworkField.tsx 0.00% 31 Missing ⚠️
...mponents/PlanNetworkMapEdit/PlanNetworkMapEdit.tsx 0.00% 26 Missing ⚠️
...mponents/PlanStorageMapEdit/PlanStorageMapEdit.tsx 0.00% 25 Missing ⚠️
.../tabs/Mappings/hooks/usePlanStorageMapResources.ts 0.00% 23 Missing ⚠️
.../tabs/Mappings/hooks/usePlanNetworkMapResources.ts 0.00% 20 Missing ⚠️
...pings/components/PlanStorageMapEdit/utils/utils.ts 0.00% 18 Missing ⚠️
... and 19 more
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2147       +/-   ##
===========================================
- Coverage   36.81%   13.40%   -23.41%     
===========================================
  Files         158     1065      +907     
  Lines        2548    20095    +17547     
  Branches      599     3900     +3301     
===========================================
+ Hits          938     2694     +1756     
- Misses       1428    17391    +15963     
+ Partials      182       10      -172     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@avivtur avivtur force-pushed the standardize-mappings-tab branch 5 times, most recently from 66a0635 to 78f1a53 Compare December 16, 2025 11:27
Copy link
Collaborator

@sgratch sgratch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, the mappings tab works much better now so this is a great improvement.
Please see my comments below.

},
tooltip: (index) => {
if (networkMappingFields.length <= 1) {
return t('At least one network mapping must be provided.');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This validation is not accurate.
There are cases in which there is no network mappings exists.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean we should allow an empty mapping?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this tooltip appears on the delete button when disabling the delete button when we have just one mapping

};

export const buildFormNetworkMapping = (
export const getNetworkMappingValues = (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the calculation of the source network entries for oVirt is not taking into account the data center (i.e. it's set to net1 instead of data-center1/net1)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed I was getting the name from the inventory network and not the name from the map resource

plan: V1beta1Plan,
sourceProvider: V1beta1Provider,
): Record<string, ProviderVirtualMachine> => {
const [providerVmData, isVmDataLoading] = useInventoryVms({ provider: sourceProvider });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const [providerVmData, isVmDataLoading] = useInventoryVms({ provider: sourceProvider });
const [providerVmData, isVmDataLoading, error] = useInventoryVms({ provider: sourceProvider });

Worth adding error handling for fetching vms from the inventory

[availableTargetNetworks, targetProject],
);

const message = useMemo(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move lines 92 -115 to be located after calculating the isLoading.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't, everything is wrapped in useMemo as we have get all the data here, and all hooks must run all the times meaning I can't move that block

sourceStorages={sourceStorages}
targetNetworks={targetNetworks}
targetStorages={targetStorages}
<SectionHeadingWithEdit
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding a link ot a string of the created mappings entity name for both network and storage, the same as was in old UI. Otherwise it will be hard for the user to find this mapping in the network, storage maps list page.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it to the UI, this is the best location I could think of, @mmenestr can you have an opinion on this
Screenshot - 2025-12-17T211300 059

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sgratch @avivtur I think adding a link to it is fine, but I think what we can do is add a read only field called "Network map name" like this:

image

and if we add that, we should probably also add the option to edit the name in the modal:

image

Let me know what you think!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Editing names of resources in kubernetes like network maps/plan/providers is not allowed, but I will change the display accordingly, Thank you

loadError: Error | null;
};

const PlanNetworkMapFieldsTable: FC<PlanNetworkMapFieldsTableProps> = ({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PlanNetworkMapFieldsTable component and PlanStorageMapFieldsTableshare a lot of logic. Can we combine it into a shared component used by both or is it too complicated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've explored this possibility myself, however I already use a similar component, soI can extract the logic above the component to a custom hook but it wasn't saving code, infact it doubled the code, and the the readability didn't improved (since we now also have another generic-ish hook that needs to be in use)

targetNetworks: Record<string, MappingValue>;
};

const TargetNetworkField: FC<TargetNetworkFieldProps> = ({ fieldId, targetNetworks }) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are 3 components that at least 2 of them look identical, one for create and one for edit plans and the 3d for network maps editing:

- networkMaps/create/fields/TargetNetworkField
- plans/create/steps/network-map/TargetNetworkField
-plans/details/tabs/Mappings/components/PlanNetworkMapEdit/components TargetNetworkField

Can we combine them and use one component for all?

otherSourceNetworks: MappingValue[];
};

const SourceNetworkField: FC<SourceNetworkFieldProps> = ({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two components that looks identical, one for create and one for edit plans:

  • details/tabs/Mappings/components/PlanNetworkMapEdit/components/SourceNetworkField
  • create/steps/network-map/SourceNetworkField

Can we combine them and use one component for both?

title={t('Edit network map')}
closeModal={closeModal}
variant={ModalVariant.medium}
isDisabled={!isValid || !isDirty}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please handle cases in which you can't edit the plan mappings and it should be disabled. E.g. plan is completed, archived, running while at least one vm was finished the migration successfully..)

Maybe even better to handle that in SectionHeadingWithEdit and not here.

title={t('Edit storage map')}
closeModal={closeModal}
variant={ModalVariant.medium}
isDisabled={!isValid || !isDirty}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please handle cases in which you can't edit the plan mappings and it should be disabled. E.g. plan is completed, archived, running while at least one vm was finished the migration successfully..)

Maybe even better to handle that in SectionHeadingWithEdit and not here.

@avivtur avivtur force-pushed the standardize-mappings-tab branch 4 times, most recently from 0689873 to 5378a2a Compare December 18, 2025 09:53
});

useEffect(() => {
setTimeout(async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when trying the pattern of const func = async () => { await trigger(); }; func() I'm getting the following eslint error:
Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the void operator @typescript-eslint/no-floating-promises

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u sure u need the await?

@avivtur avivtur force-pushed the standardize-mappings-tab branch from 5378a2a to 782530f Compare December 23, 2025 11:04
@avivtur
Copy link
Collaborator Author

avivtur commented Dec 23, 2025

/retest

@avivtur avivtur force-pushed the standardize-mappings-tab branch from 782530f to e1b91bc Compare December 23, 2025 12:14
@avivtur
Copy link
Collaborator Author

avivtur commented Dec 23, 2025

/retest

Comment on lines +63 to +70
useEffect(() => {
setTimeout(async () => {
await trigger();
}, 0);
}, [trigger]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? we dont any other way then this effect and timeout? IIRC check other hooks such as useLAyouteffect or others

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well we do have something like:

useEffect(() => {
    const triggerFunc = async () => {
      try {
        await trigger();
      } catch {
        // handle error if needed
      }
    };

    (async () => {
      await triggerFunc();
    })();
  }, [trigger]);

Comment on lines +56 to +58
const [networkMap] = networkMapResult ?? [];
const [sourceNetworks] = sourceNetworksResult ?? [];
const [targetNetworks] = targetNetworksResult ?? [];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems redundent, do it directly getNetworkMappingValues

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the getNetworkMappingValues is also used elsewhere so that would cause more changes

@avivtur avivtur force-pushed the standardize-mappings-tab branch 2 times, most recently from 6cd748c to 2f1f880 Compare January 5, 2026 17:35
},
tooltip: (index) => {
if (storageMappingFields.length <= 1) {
return t('At least one network mapping must be provided.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message should read "storage" mapping instead of "network".

@avivtur avivtur force-pushed the standardize-mappings-tab branch from 2f1f880 to 9b6a144 Compare January 8, 2026 09:58
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 8, 2026

@avivtur avivtur added this pull request to the merge queue Jan 8, 2026
Merged via the queue into kubev2v:main with commit c9b0d59 Jan 8, 2026
8 checks passed
@avivtur avivtur deleted the standardize-mappings-tab branch January 8, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants