Skip to content

add the feature for sorting agent table and searching by name ! - #722

Open
Rupam-It wants to merge 8 commits into
antrea-io:mainfrom
Rupam-It:issue-310
Open

add the feature for sorting agent table and searching by name !#722
Rupam-It wants to merge 8 commits into
antrea-io:mainfrom
Rupam-It:issue-310

Conversation

@Rupam-It

@Rupam-It Rupam-It commented Apr 22, 2025

Copy link
Copy Markdown

#310
added feature

  1. pagination 10 agent
  2. you can sort by one column at a time
  3. search feature by name is added

Signed-off-by: Rupam-It <mannarupam3@gmail.com>
Signed-off-by: Rupam-It <mannarupam3@gmail.com>

@antoninbas antoninbas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

some initial comments

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

aren't the logos backwards?
this one should be descending because it goes from larger at the top to smaller at the bottom

</g>
</svg>
);
} No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

add missing newline character


function ComponentSummary<T>(props: {title: string, data: T[], propertyNames: Property[], getProperties: (x: T) => string[]}) {
const itemsPerPage = 10; // Display 10 items per page for Agents table
const isAgentTable = props.title === 'Agents';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

rather than this, could we have a "sortable" property?

);
}

function generateFakeAgents(n: number): AgentInfo[] {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you should add unit tests in summary.test.tsx for the new sorting feature. The tests can use the synthetic data that you have here.

as a matter of fact, I think the test file already has some helper functions potentially to help with synthetic data generation?

Comment on lines +400 to +401
// If in development mode, generate fake agent data for UI testing
if (import.meta.env.DEV) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Even in development mode, one usually connects to an actual K8s cluster and wants real agent data?

I understand that this is convenient, as usually the test clusters used for development are small and don't have a large number of Nodes / agents. So I think we can keep it, but 1) the generation of the synthetic data should be in a separate file if possible for readability, 2) this should be driven by a variable that can be set in .env.development / .env.development.local. You could set the variable in .env.development for reference, but it should be commented out by default. I don't know if there is a better / more standard way of doing it.

const isAgentTable = props.title === 'Agents';

const [currentPage, setCurrentPage] = useState(1);
const [sortConfig, setSortConfig] = useState<SortConfig | null>(null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

assuming my understanding of the code is correct, by default there is no sorting (which is the current behavior)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Rupam-It please confirm

Signed-off-by: Rupam-It <mannarupam3@gmail.com>
@Rupam-It

Rupam-It commented May 3, 2025

Copy link
Copy Markdown
Author

Hey @antoninbas ,

  1. Added sorting, search, and pagination to the Agents table for better usability with large datasets.
  2. Made ComponentSummary generic to support configurable table features across components.
  3. Moved generateFakeAgents to utils/fakeData.ts; added VITE_USE_FAKE_AGENTS to control mock data in dev.
  4. Improved UI with modern chevron sort icons, proper sort directions, and visual feedback.
  5. Disabled pagination buttons at boundaries for better UX.
  6. Added unit tests for sorting (all data types), search, and pagination to ensure reliability.

Screenshot from 2025-05-03 21-40-35

Rupam-It added 2 commits May 3, 2025 23:07
Signed-off-by: Rupam-It <mannarupam3@gmail.com>
Signed-off-by: Rupam-It <mannarupam3@gmail.com>
@Rupam-It

Rupam-It commented May 3, 2025

Copy link
Copy Markdown
Author

I also have test in the web page !
all working fine

  1. searching by name
  2. sorting by column
  3. pagination (default 10 , i have test it with 2 it working)

VITE_API_SERVER=http://localhost:8080

# Uncomment the line below to enable fakeData(agent name) in development mode
VITE_USE_SYNTHETIC_DATA=true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remember to comment the line out for the code you check in

Comment thread client/web/antrea-ui/.env.development Outdated
@@ -1 +1,4 @@
VITE_API_SERVER=http://localhost:8080

# Uncomment the line below to enable fakeData(agent name) in development mode

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Uncomment the line below to enable fakeData(agent name) in development mode
# Uncomment the line below to enable synthetic Agent data in development mode.

export function generateFakeAgents(n: number): AgentInfo[] {
// Helper function to generate random agent names
const generateAgentName = () => {
const prefixes = ['antrea', 'k8s', 'node', 'worker', 'master'];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please avoid using "master", and prefer more inclusive terminology

Comment on lines +6 to +13
const prefixes = ['antrea', 'k8s', 'node', 'worker', 'master'];
const suffixes = ['-agent', '-node', '-vm', '-host', ''];
const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
const suffix = suffixes[Math.floor(Math.random() * suffixes.length)];
const id = Math.random() < 0.3 ?
Math.random().toString(36).substring(2, 6) : // alphanumeric
Math.floor(Math.random() * 1000).toString(); // numeric
return `${prefix}${suffix}-${id}`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't understand the value of having such "complicated" code for generating agent names?
why not simply use k8s-node-control-plane-1, k8s-node-worker-1, k8s-node-worker-2, ...?

Comment on lines +18 to +21
const major = Math.floor(Math.random() * 3);
const minor = Math.floor(Math.random() * 10);
const patch = Math.floor(Math.random() * 20);
return `v${major}.${minor}.${patch}`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

here again, I see little value in having totally random version numbers
I would actually suggest having 2 possible different version numbers (e.g., 2.2.3 and 2.3.0), which would be representative of what you could have when you are in the middle of updating Antrea in a large cluster

return `v${major}.${minor}.${patch}`;
};

// Helper function to generate random timestamps within last 30 days

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

probably much too large of a window when it comes to the heartbeat timestamp, maybe use 5 minutes instead of 30 days?

Comment on lines +35 to +43
const generateSubnets = () => {
const count = Math.floor(Math.random() * 3) + 1; // 1-3 subnets
const subnets = [];
for (let i = 0; i < count; i++) {
const ipv4 = `${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.0`;
const ipv6 = `fd${Math.random().toString(16).substr(2, 2)}:${Math.random().toString(16).substr(2, 4)}::`;
subnets.push(Math.random() > 0.5 ? `${ipv4}/24` : `${ipv6}/64`);
}
return subnets;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

here as well, please use something more representative than a random subnet, you can use consecutive subnets

};

// Helper function to generate OVS version
const generateOVSVersion = () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same comment as above (for the Antrea version)

const isAgentTable = props.title === 'Agents';

const [currentPage, setCurrentPage] = useState(1);
const [sortConfig, setSortConfig] = useState<SortConfig | null>(null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Rupam-It please confirm

const aValue = getProperties(a)[sortKeyIndex];
const bValue = getProperties(b)[sortKeyIndex];

// Custom numerical sort for 'Name' column (agent-N)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is not good, once you start doing that the ComponentSummary is not generic at all anymore

either you have to use default string sorting (lexicographic) for all properties, or you need to update getProperties so that it's not limited to returning an array of strings. Maybe it could return (string | number | someType)[] and then the sorting logic would be different based on the type?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

if we sort every thing as a string then
after node-1 come node-10 not node-2!
as i have already implemented that string+num sorting !
so in our logic node-2 will comes after node-1 as it is more acceptable to all !
what's your thought?

@Rupam-It

Rupam-It commented May 8, 2025

Copy link
Copy Markdown
Author

#722 (comment)
hey @antoninbas i have make the desire change i
1. Refined fakeData.ts

  • Replaced "master" terminology with more inclusive "control-plane"
  • Created structured, predictable agent naming scheme (k8s-node-control-plane-1, k8s-node-worker-N)
  • Limited version numbers to two specific versions (v2.2.3 and v2.3.0) to simulate clusters during upgrades
  • Reduced heartbeat timestamp window from 30 days to 5 minutes for more realistic data
  • Implemented sequential, representative subnet patterns instead of random ones
  • Added option for randomized agent order to properly test sorting functionality

Made node names match agent names for consistency

2. Made ComponentSummary Truly Generic

  • Redesigned the component to use proper type-based sorting rather than special cases
  • Implemented PropertyValuePair approach that separates display values from sort values
  • Added support for multiple data types (string, number, Date, tuple) with appropriate sorting logic
  • Created a hierarchical sorting system for node names that maintains proper ordering:

Control-plane nodes appear before worker nodes
Node numbers sort properly (1, 2, 3... 10, 11) instead of lexicographically
3. Enhanced Code Maintainability

  • Removed hard-coded column-specific sorting logic
  • Made the component follow the "Open/Closed Principle" - extendable without modifying core code
  • Improved comments throughout for better code comprehension
  • Maintained all the original functionality while making the code more robust

see this video for more clearness!
Screencast from 2025-05-08 20-35-13.webm

Rupam-It added 2 commits May 8, 2025 20:41
…akeData, added type-based sorting and better code maintainability.

Signed-off-by: Rupam-It <mannarupam3@gmail.com>
Signed-off-by: Rupam-It <mannarupam3@gmail.com>
Comment on lines +61 to +64
const generateOVSVersion = () => {
// Only two possible OVS versions to simulate a cluster during upgrade
return actualIndex % 4 === 0 ? '3.0.0' : '2.17.3';
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you should generate the Antrea version and OVS version at the same time, because there should be a 1-1 mapping between them

Comment on lines +45 to +55
// Generate sequential IPv4 subnets
if (count > 0) {
// Base subnet with sequential third octet
subnets.push(`10.10.${actualIndex % 255}.0/24`);
}

// Add IPv6 subnet for some nodes
if (count > 1) {
// Sequential IPv6 subnets
subnets.push(`fd00:10:10:${actualIndex % 100}::/64`);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All Nodes should have "consistent" subnets (e.g., a single IPv4 subnet, or one IPv4 subnet + one IPv6 subnet).
I don't think it's worth having an error case here (Node missing subnet)

// Generate sequential IPv4 subnets
if (count > 0) {
// Base subnet with sequential third octet
subnets.push(`10.10.${actualIndex % 255}.0/24`);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you have too many fake agents, you will have duplicate subnets. Should there be an assertion to limit the number of agents?

Comment thread client/web/antrea-ui/.env.development Outdated

# Uncomment the line below to enable synthetic Agent data in development mode.
# VITE_USE_SYNTHETIC_DATA=true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove empty line

Comment on lines +88 to +103
// Helper function to extract node type and numeric suffix for proper sorting
function getNodeNameSortValue(name: string): [string, number] {
// Match patterns like "k8s-node-worker-123" or "k8s-node-control-plane-1"
const match = name.match(/^(.*?)(control-plane|worker)-(\d+)$/);
if (match) {
// Extract the node type and number
const prefix = match[1];
const nodeType = match[2]; // 'control-plane' or 'worker'
const numericPart = parseInt(match[3], 10);

// Return as tuple with nodeType first (for primary sorting) and number second
// This ensures control-plane comes before worker when sorting
return [nodeType, numericPart];
}
// Fall back to a default value if pattern doesn't match
return ['unknown', 0];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why even have a specific pattern here? this won't match most clusters
the code should be generic

Comment on lines +111 to +119
{ display: agent.metadata.name, sortValue: getNodeNameSortValue(agent.metadata.name) },
{ display: agent?.version ?? 'Unknown', sortValue: agent?.version ?? 'Unknown' },
{ display: refToString(agent.podRef), sortValue: refToString(agent.podRef) },
{ display: refToString(agent.nodeRef), sortValue: refToString(agent.nodeRef) },
{ display: localPodNum.toString(), sortValue: localPodNum },
{ display: agent.nodeSubnets?.join(',') ?? 'None', sortValue: agent.nodeSubnets?.join(',') ?? 'None' },
{ display: agent?.ovsInfo?.version ?? 'Unknown', sortValue: agent?.ovsInfo?.version ?? 'Unknown' },
{ display: healthy, sortValue: healthy },
{ display: lastHeartbeat, sortValue: new Date(lastHeartbeat) },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You didn't reply to my original comment (#722 (comment)), so I don't know your thought process, but I don't think this is better than sorting purely based on the value type

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

so , i have write the sorting logic more refine you can take a look now!

…e the hard coded name form the agent name

Signed-off-by: Rupam-It <mannarupam3@gmail.com>
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.

2 participants