Skip to content
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

Events page refactoring with entity data table usage #20831

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

maxiadlovskii
Copy link
Contributor

@maxiadlovskii maxiadlovskii commented Oct 30, 2024

Description

This PR implements an events page on a general perspective with Entity Data Table usage
Now we can choose which columns to show. The rest is hidden under the expanded row
Screenshot 2024-11-05 at 11 50 49
Event actions are in the action column now
Screenshot 2024-11-05 at 11 58 02
We have the option to filtrate events by type and timestamp
Screenshot 2024-11-05 at 12 00 25
And now it's possible to sort events by some of the fields

Screenshot 2024-11-05 at 12 02 40

The changes also touch the default event details of the events widget
Screenshot 2024-11-05 at 12 05 41

Motivation and Context

As the current implementation of the Events page uses the legacy code, we need to do refactoring first before implementing the new functionality. We need to use Entity Data Table on the page as we use it on other pages. This would allow us to use common approaches. We have to do refactoring for the general approach first and then reuse it on a security perspective as well.
fix: #20881

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Refactoring (non-breaking change)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.

/jpd https://github.com/Graylog2/graylog-plugin-enterprise/pull/9020

@maxiadlovskii maxiadlovskii marked this pull request as ready for review November 5, 2024 11:07
@maxiadlovskii maxiadlovskii changed the title Refactoring/events general perspective preparation Events page refactoring with entity data table usage Nov 5, 2024
fix linter error
Copy link
Contributor

@kingzacko1 kingzacko1 left a comment

Choose a reason for hiding this comment

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

I do not have enough frontend expertise to sign off on the entire PR, but for the presentation of the More Actions drop down logic on the EventActions component it LGTM!

Copy link
Contributor

@linuspahl linuspahl left a comment

Choose a reason for hiding this comment

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

I like this change a lot! So far I have not found a bug, but I found some problems with the implemented types.

Besides that I only added a bunch of suggestions for code improvements.

One general thing. Imo it is currently hard to understand that you can view further details by clicking on the title. Before you could click everywhere in the row, which made it at least a bit easier to understand.

Maybe we can also show a button in the action column like Details, which tollges the section.

I also think we should improve the styling when all details exist as columns and there the section is empty.

image

Thinking about it, maybe we can discuss always showing all details in the section, even when they exist as columns? I would like to compare both solutions. I can imagine it will be easier to understand and be beneficial to have a place where you can always find all information about an event, displayed in a way that is very easy to read.

@@ -0,0 +1,5 @@
type = "a"
message = "Implement commont entity data table with sorting and filtering for events page"
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a typo in common.

<>{isPermitted(permissions,
`eventdefinitions:edit:${eventDefinitionContext.id}`)
? <Link to={Routes.ALERTS.DEFINITIONS.edit(eventDefinitionContext.id)}>{eventDefinitionContext.title}</Link>
: eventDefinitionContext.title}
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a personal preference, but imo this is easier to read:

if (isPermitted(permissions, `eventdefinitions:edit:${eventDefinitionContext.id}`)) {
  return (
    <Link to={Routes.ALERTS.DEFINITIONS.edit(eventDefinitionContext.id)}>
      {eventDefinitionContext.title}
    </Link>
  )
}

return <>{eventDefinitionContext.title}</>

import useMetaDataContext from 'components/common/EntityDataTable/hooks/useMetaDataContext';
import { Timestamp } from 'components/common';

const EventDefinitionRenderer = ({ eventDefinitionId, permissions }: { eventDefinitionId: string, permissions: Immutable.List<string> }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't every component a renderer? what about EventDefinitionTitle?

Copy link
Contributor

Choose a reason for hiding this comment

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

ah, it's because we called it columnRenderers. In similar places we call it EventDefinitionTitle or EventDefinitionCell


const PriorityRenderer = ({ priority }: { priority: number }) => <PriorityName priority={priority} />;

const FieldsRenderer = ({ fields }: { fields: Record<string, string> }) => (
Copy link
Contributor

Choose a reason for hiding this comment

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

I learned recently that you should only use a Record when it has fixed keys. Otherwise it is cleaner to use an index signature, like { [fieldName: string]: string }.

renderCell: (_eventDefinitionId: string) => <EventDefinitionRenderer permissions={permissions} eventDefinitionId={_eventDefinitionId} />,
},
priority: {
renderCell: (_priority: number) => <PriorityRenderer priority={_priority} />,
Copy link
Contributor

Choose a reason for hiding this comment

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

Here we could render PriorityName directly.

<MetaDataProvider<EventsAdditionalData> meta={meta}>
<EventDetailsTable attributesList={attributesList} event={event} meta={meta} />
<EventActions event={event} wrapper={ActionsWrapper} />
</MetaDataProvider>
Copy link
Contributor

Choose a reason for hiding this comment

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

Do I understand it correctly that we are overwriting the meta data context, provided by the entity data table, here? So depending on where in the table you consume the context you get different data? Can't we just get rid of the context here and just provide the eventDefinition as a prop?

const { entityActions, expandedSections } = useTableElements({ defaultLayout });

return (
<PaginatedEntityTable<Event> humanName="events"
Copy link
Contributor

Choose a reason for hiding this comment

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

Here we can define a type for meta.

export const keyFn = (searchParams: SearchParams) => ['events', 'search', searchParams];

export type EventsAdditionalData = {
context: {event_definitions?: EventDefinitionContext, streams?: EventDefinitionContext},
Copy link
Contributor

Choose a reason for hiding this comment

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

If I am not mistaken this type is wrong. It reads like this is just one event definition while it is actually an object where the keys are the event definition ids and the values are the vent definitions.

Can you please check why this did not result in a TS error when using the context.

},
event_definition_id: {
renderCell: (_eventDefinitionId: string) => <EventDefinitionRenderer permissions={permissions} eventDefinitionId={_eventDefinitionId} />,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Imo we can define a relating relative width here and make the column a bit smaller and maybe give it a slightly larger min width.

image

</tbody>
</Table>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

I saw that we are rendering a placeholder for e.g. the remediation steps, when the value is empty is empty, but not for the additional fields. Can we unify this?

image

Also can you remove the padding for the additional fields value?
image

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.

Replace current implementation with Entity data table on general perspective
3 participants