-
Notifications
You must be signed in to change notification settings - Fork 60
CNV-79276:Virtual machine networks page - row overlapping #3566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,4 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import React, { FC, useState } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import React, { FC, useEffect, useRef, useState } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { modelToGroupVersionKind, NamespaceModel } from '@kubevirt-ui-ext/kubevirt-api/console'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -23,27 +23,56 @@ const ExpandableProjectList: FC<ExpandableProjectListProps> = ({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { t } = useKubevirtTranslation(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [expand, setExpand] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isFirstRun = useRef(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!loaded) return <Skeleton />; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isEmpty(projectNames)) return <span>{emptyMessage ?? t('No projects matched')}</span>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {projectNames.slice(0, expand ? projectNames.length : maxItems).map((project) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ResourceLink | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| groupVersionKind={modelToGroupVersionKind(NamespaceModel)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={project} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name={project} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {projectNames.length > maxItems && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Button onClick={() => setExpand(!expand)} variant={ButtonVariant.link}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {expand ? t('Show less') : t('+{{num}} more', { num: projectNames.length - maxItems })} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Notify virtualized table to re-measure after expand/collapse so row overlap is avoided | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isFirstRun.current) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isFirstRun.current = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const id = requestAnimationFrame(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| requestAnimationFrame(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window.dispatchEvent(new Event('resize')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return () => cancelAnimationFrame(id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [expand]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cat -n src/utils/components/ExpandableProjectList/ExpandableProjectList.tsx | head -50Repository: kubevirt-ui/kubevirt-plugin Length of output: 1911 🏁 Script executed: rg "CNV-79276" --type ts --type tsxRepository: kubevirt-ui/kubevirt-plugin Length of output: 98 🏁 Script executed: rg "CNV-79276"Repository: kubevirt-ui/kubevirt-plugin Length of output: 53 🏁 Script executed: # Check if there are any comments or references to issues in the ExpandableProjectList file
cat src/utils/components/ExpandableProjectList/ExpandableProjectList.tsx | grep -i "cny\|cnv\|issue\|jira\|bug"Repository: kubevirt-ui/kubevirt-plugin Length of output: 53 🏁 Script executed: # Check if there's a constants file for this component
ls -la src/utils/components/ExpandableProjectList/Repository: kubevirt-ui/kubevirt-plugin Length of output: 326 🏁 Script executed: cat src/utils/components/ExpandableProjectList/constants.tsRepository: kubevirt-ui/kubevirt-plugin Length of output: 103 🏁 Script executed: # Check if there are any other references to this pattern or related issues
rg "requestAnimationFrame" src/utils/components/ExpandableProjectList/ -A 5 -B 2Repository: kubevirt-ui/kubevirt-plugin Length of output: 920 Cancel both animation-frame callbacks in the resize workaround. Line 35 schedules a second Add a variable to capture the nested animation frame ID and cancel it in the cleanup function: 🔧 Proposed fix // Notify virtualized table to re-measure after expand/collapse so row overlap is avoided
useEffect(() => {
if (isFirstRun.current) {
isFirstRun.current = false;
return;
}
+ let nestedId: number | undefined;
const id = requestAnimationFrame(() => {
- requestAnimationFrame(() => {
+ nestedId = requestAnimationFrame(() => {
window.dispatchEvent(new Event('resize'));
});
});
- return () => cancelAnimationFrame(id);
+ return () => {
+ cancelAnimationFrame(id);
+ if (nestedId !== undefined) cancelAnimationFrame(nestedId);
+ };
}, [expand]);If this is a workaround for a tracked issue, update the comment to reference it per coding guidelines. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!loaded) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div style={{ alignItems: 'center', display: 'flex', minHeight: '48px' }}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Skeleton /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cellContent = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div style={{ minHeight: '48px' }}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {isEmpty(projectNames) ? ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span>{emptyMessage ?? t('No projects matched')}</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {projectNames.slice(0, expand ? projectNames.length : maxItems).map((project) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <ResourceLink | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| groupVersionKind={modelToGroupVersionKind(NamespaceModel)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={project} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name={project} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ))} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {projectNames.length > maxItems && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Button onClick={() => setExpand(!expand)} variant={ButtonVariant.link}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {expand | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? t('Show less') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : t('+{{num}} more', { num: projectNames.length - maxItems })} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return cellContent; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default ExpandableProjectList; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,47 +1,56 @@ | ||||||||||||||||||||||||||||||||||
| import React, { FC } from 'react'; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| import KubevirtTable from '@kubevirt-utils/components/KubevirtTable/KubevirtTable'; | ||||||||||||||||||||||||||||||||||
| import StateHandler from '@kubevirt-utils/components/StateHandler/StateHandler'; | ||||||||||||||||||||||||||||||||||
| import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation'; | ||||||||||||||||||||||||||||||||||
| import { getName } from '@kubevirt-utils/resources/shared'; | ||||||||||||||||||||||||||||||||||
| import { ClusterUserDefinedNetworkKind } from '@kubevirt-utils/resources/udn/types'; | ||||||||||||||||||||||||||||||||||
| import { isEmpty } from '@kubevirt-utils/utils/utils'; | ||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||
| ListPageBody, | ||||||||||||||||||||||||||||||||||
| ListPageFilter, | ||||||||||||||||||||||||||||||||||
| useListPageFilter, | ||||||||||||||||||||||||||||||||||
| VirtualizedTable, | ||||||||||||||||||||||||||||||||||
| } from '@openshift-console/dynamic-plugin-sdk'; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| import useVMNetworks from '../hooks/useVMNetworks'; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| import LocalnetEmptyState from './components/LocalnetEmptyState/LocalnetEmptyState'; | ||||||||||||||||||||||||||||||||||
| import VMNetworkRow from './components/VMNetworkRow'; | ||||||||||||||||||||||||||||||||||
| import useVMNetworkColumns from './hooks/useVMNetworkColumns'; | ||||||||||||||||||||||||||||||||||
| import useVMNetworkTableColumns from './hooks/useVMNetworkTableColumns'; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| type VMNetworkListProps = { | ||||||||||||||||||||||||||||||||||
| onCreate: () => void; | ||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| const VMNetworkList: FC<VMNetworkListProps> = ({ onCreate }) => { | ||||||||||||||||||||||||||||||||||
| const { t } = useKubevirtTranslation(); | ||||||||||||||||||||||||||||||||||
| const [vmNetworks, loaded, error] = useVMNetworks(); | ||||||||||||||||||||||||||||||||||
| const [data, filteredData, onFilterChange] = useListPageFilter(vmNetworks); | ||||||||||||||||||||||||||||||||||
| const columns = useVMNetworkColumns(); | ||||||||||||||||||||||||||||||||||
| const columns = useVMNetworkTableColumns(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| let body: React.ReactNode = null; | ||||||||||||||||||||||||||||||||||
| if (isEmpty(data)) { | ||||||||||||||||||||||||||||||||||
| body = <LocalnetEmptyState onCreate={onCreate} />; | ||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||
| body = ( | ||||||||||||||||||||||||||||||||||
| <ListPageBody> | ||||||||||||||||||||||||||||||||||
| <ListPageFilter data={data} loaded={loaded} onFilterChange={onFilterChange} /> | ||||||||||||||||||||||||||||||||||
| <KubevirtTable<ClusterUserDefinedNetworkKind> | ||||||||||||||||||||||||||||||||||
| ariaLabel={t('VirtualMachine networks')} | ||||||||||||||||||||||||||||||||||
| columns={columns} | ||||||||||||||||||||||||||||||||||
| data={filteredData} | ||||||||||||||||||||||||||||||||||
| getRowId={(row) => getName(row) ?? ''} | ||||||||||||||||||||||||||||||||||
| loaded={loaded} | ||||||||||||||||||||||||||||||||||
| loadError={error} | ||||||||||||||||||||||||||||||||||
| noFilteredDataEmptyMsg={t('No virtualmachine networks found')} | ||||||||||||||||||||||||||||||||||
| unfilteredData={data} | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normalize VM network labels to avoid typo and i18n key drift. Line 44 uses 💡 Suggested fix- ariaLabel={t('VirtualMachine networks')}
+ ariaLabel={t('Virtual machine networks')}
...
- noFilteredDataEmptyMsg={t('No virtualmachine networks found')}
+ noFilteredDataEmptyMsg={t('No virtual machine networks found')}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||
| </ListPageBody> | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||
| <StateHandler error={error} hasData={!!data} loaded={loaded} showSkeletonLoading withBullseye> | ||||||||||||||||||||||||||||||||||
| {isEmpty(data) ? ( | ||||||||||||||||||||||||||||||||||
| <LocalnetEmptyState onCreate={onCreate} /> | ||||||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||||||
| <ListPageBody> | ||||||||||||||||||||||||||||||||||
| <ListPageFilter data={data} loaded={loaded} onFilterChange={onFilterChange} /> | ||||||||||||||||||||||||||||||||||
| <VirtualizedTable<ClusterUserDefinedNetworkKind> | ||||||||||||||||||||||||||||||||||
| columns={columns} | ||||||||||||||||||||||||||||||||||
| data={filteredData} | ||||||||||||||||||||||||||||||||||
| loaded={loaded} | ||||||||||||||||||||||||||||||||||
| loadError={error} | ||||||||||||||||||||||||||||||||||
| Row={VMNetworkRow} | ||||||||||||||||||||||||||||||||||
| unfilteredData={data} | ||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||
| </ListPageBody> | ||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||
| {body} | ||||||||||||||||||||||||||||||||||
| </StateHandler> | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,70 @@ | ||||||||||||||||||||||
| import React, { useMemo } from 'react'; | ||||||||||||||||||||||
| import { Link } from 'react-router-dom-v5-compat'; | ||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Simpler fix availableThe root cause diagnosis is correct, but the solution can be simplified. Issues with this PRThe
Cleaner approachSame number of files (VMNetworkList, new hook, deleted hook, 6 locales), but no changes to
AI prompt to generate this fix
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also - please note that while it is not part of the Jira - I think it's work adding a loading state to the table.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import { ColumnConfig } from '@kubevirt-utils/hooks/useDataViewTableSort/types'; | ||||||||||||||||||||||
| import { useKubevirtTranslation } from '@kubevirt-utils/hooks/useKubevirtTranslation'; | ||||||||||||||||||||||
| import { getName } from '@kubevirt-utils/resources/shared'; | ||||||||||||||||||||||
| import { getLocalnet, getMTU, getVLANID } from '@kubevirt-utils/resources/udn/selectors'; | ||||||||||||||||||||||
| import { ClusterUserDefinedNetworkKind } from '@kubevirt-utils/resources/udn/types'; | ||||||||||||||||||||||
| import { NO_DATA_DASH } from '@kubevirt-utils/resources/vm/utils/constants'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import VMNetworkActions from '../../actions/VMNetworkActions'; | ||||||||||||||||||||||
| import { VM_NETWORKS_PATH } from '../../constants'; | ||||||||||||||||||||||
| import MatchedProjects from '../components/MatchedProjects'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const useVMNetworkTableColumns = (): ColumnConfig<ClusterUserDefinedNetworkKind>[] => { | ||||||||||||||||||||||
| const { t } = useKubevirtTranslation(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return useMemo( | ||||||||||||||||||||||
| (): ColumnConfig<ClusterUserDefinedNetworkKind>[] => [ | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| getValue: (row) => getName(row) ?? '', | ||||||||||||||||||||||
| key: 'name', | ||||||||||||||||||||||
| label: t('Name'), | ||||||||||||||||||||||
| renderCell: (row) => { | ||||||||||||||||||||||
| const name = getName(row); | ||||||||||||||||||||||
| return <Link to={`${VM_NETWORKS_PATH}/${name}`}>{name}</Link>; | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| sortable: true, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| key: 'connected-projects', | ||||||||||||||||||||||
| label: t('Connected projects'), | ||||||||||||||||||||||
| renderCell: (row) => <MatchedProjects obj={row} />, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| getValue: (row) => getLocalnet(row)?.physicalNetworkName ?? '', | ||||||||||||||||||||||
| key: 'physicalNetworkName', | ||||||||||||||||||||||
| label: t('Physical network name'), | ||||||||||||||||||||||
| renderCell: (row) => getLocalnet(row)?.physicalNetworkName || NO_DATA_DASH, | ||||||||||||||||||||||
| sortable: true, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| getValue: (row) => String(getVLANID(row) ?? ''), | ||||||||||||||||||||||
| key: 'vlanID', | ||||||||||||||||||||||
| label: t('VLAN ID'), | ||||||||||||||||||||||
| renderCell: (row) => getVLANID(row) ?? NO_DATA_DASH, | ||||||||||||||||||||||
| sortable: true, | ||||||||||||||||||||||
|
Comment on lines
+43
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix VLAN sorting to be numeric, not lexicographic. Line 43 converts VLAN ID to 🔧 Suggested fix- getValue: (row) => String(getVLANID(row) ?? ''),
+ getValue: (row) => getVLANID(row) ?? -1,📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| getValue: (row) => getMTU(row) ?? 0, | ||||||||||||||||||||||
| key: 'mtu', | ||||||||||||||||||||||
| label: t('MTU'), | ||||||||||||||||||||||
| renderCell: (row) => { | ||||||||||||||||||||||
| const mtu = getMTU(row); | ||||||||||||||||||||||
| return mtu ?? <div className="pf-v6-u-text-color-subtle">{t('Not available')}</div>; | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| sortable: true, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| key: 'actions', | ||||||||||||||||||||||
| label: '', | ||||||||||||||||||||||
| props: { className: 'pf-v6-c-table__action' }, | ||||||||||||||||||||||
| renderCell: (row) => <VMNetworkActions obj={row} />, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| ], | ||||||||||||||||||||||
| [t], | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export default useVMNetworkTableColumns; | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent casing:
virtualmachineshould beVirtualMachine.This entry uses
virtualmachine(lowercase) while the rest of the file consistently usesVirtualMachine(PascalCase) for the resource name—see lines 1291–1293 for similar "No ... found" patterns.🔧 Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents