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

[Security Solution][Lens] New trigger actions for chart legends and table cell actions #146779

Merged
merged 31 commits into from
Dec 16, 2022

Conversation

semd
Copy link
Contributor

@semd semd commented Dec 1, 2022

Summary

Enable XY chart legends and Table cell actions to render dynamically registered "cell value" actions, scoped for Lens embeddables only.
Security Solution actions were created to be displayed in the Lens visualizations rendered.

closes #145708

New Trigger

A new uiActions trigger CELL_VALUE_TRIGGER has been created to register these actions. It is used in both TableChart cell actions and XyCharts legend actions to create additional action options.

Table cell actions

Actions registered and added to the CELL_VALUE_TRIGGER will be appended to the cell actions of the table. The action compatibility is checked for each column.

table_cell_actions

Chart legend actions

The same for XyCharts legends. All actions registered and added to the CELL_VALUE_TRIGGER will be appended to the legend actions of the charts. The action compatibility is checked for each series accessor.

chart_legend_actions

Filter for & Filter out actions:

The XY and Table charts have the "Filter for & Filter out" actions hardcoded in the components code. They manually check the value is filterable before showing the actions, but the panel items and cell actions are added explicitly for them in the components.

This logic has not changed in this PR, the actions added dynamically using CELL_VALUE_TRIGGER are just appended after the "Filter for & Filter out" options.

However, "Filter for / Filter out" actions could also be integrated into this pattern, we would only have to register these actions to the CELL_VALUE_TRIGGER with the proper order value, and then remove all hardcoded logic in the components.

Security Solution actions

The actions that we have registered from Security Solutions ("Add to timeline" and "Copy to clipboard") will be displayed only when the embeddable is rendered inside Security Solution, this is ensured via the isCompatible actions method.

security_actions

Security Solution Filter In/Out bug

There was a CSS rule present in a global Security Solution context, affecting all the EuiDataGrid cell actions popovers:

// Hide EUI's 'Filter in' and 'Filter out' footer buttons - replaced with our own buttons
.euiPopoverFooter:nth-child(2) {
.euiFlexItem:first-child,
.euiFlexItem:nth-child(2) {
display: none;
}
}

The goal of this rule was to save some vertical space, by hiding the two auto-generated Filter In/Out actions (generally the first two cell actions), so we could show the horizontal Filter In/Out custom buttons added manually to the popover top header.

old_filter_in_out

This CSS rule was causing a bug when rendering Table visualizations (they use EuiDataGrid as well), always hiding the two first cell actions in the popover.

After discussing this topic with the team, and considering there is an ongoing task to unify the cell actions experience in Security and centralize the implementation (see: #144943), we decided to remove the problematic CSS rule and the custom horizontal Filter buttons, so the auto-generated Filter actions are displayed, this way all tables in Security (alerts, events, and also embedded table charts) will have a unified and consistent UX.

new_filter_in_out

If the cell actions popover grows too much in the future we could apply a "More actions ..." footer option strategy.

Testing

The new actions will be displayed on any embedded Lens object rendered inside Security. A good place to test that is Cases, since we can attach Lens visualizations in the comments. However, Cases explicitly disables all the trigger actions passing disableTriggers to the Lens Embeddables.

The easiest way to test different chart types and tables is to remove/comment the disableTriggers prop in the Cases processor component, and then go to a Case and attach different Lens visualizations. All actions should appear in the legends and table cell hover actions.

Checklist

@semd semd added Feature:Lens Team:Threat Hunting Security Solution Threat Hunting Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. release_note:feature Makes this part of the condensed release notes Team:Threat Hunting:Explore 8.7 candidate labels Dec 1, 2022
@semd semd self-assigned this Dec 1, 2022
@semd semd added the Feature:Visualizations Generic visualization features (in case no more specific feature label is available) label Dec 1, 2022
@semd semd marked this pull request as ready for review December 1, 2022 17:50
@semd semd requested review from a team as code owners December 1, 2022 17:50
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-threat-hunting (Team:Threat Hunting)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

@semd semd requested review from a team as code owners December 2, 2022 11:54
@botelastic botelastic bot added Feature:Embedding Embedding content via iFrame Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) labels Dec 2, 2022
Comment on lines -78 to -91
.euiDataGridRowCell .euiDataGridRowCell__expandActions .euiDataGridRowCell__actionButtonIcon {
display: none;

&:first-child,
&:nth-child(2),
&:nth-child(3),
&:last-child {
display: inline-flex;
}

}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed in favor of visibleCellActions prop

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for cleaning this up! 👍

@semd semd changed the title [Lens] New trigger actions for chart legends and table cell actions [Security Solution][Lens] New trigger actions for chart legends and table cell actions Dec 2, 2022
@semd
Copy link
Contributor Author

semd commented Dec 12, 2022

Hi @ThomThomson , thanks a lot for taking a look at the PR.
About your comment

Is there a reason that the new trigger needs to be registered inside the embeddable plugin? Most of the triggers registered here have to do directly with an embeddable function. Mostly the triggers that have to do with the embeddable panel itself.

I have tried to follow the existing pattern that dashboard embeddable uses when it comes to registering the triggers. The triggers that are used in the embeddables, via dashboard or data actions, are registered in the embeddable plugin, some of which are also very related to visualizations (see SELECT_RANGE_TRIGGER, VALUE_CLICK_TRIGGER).
This new trigger works the same way but with lens embeddable, so I assumed it could be registered in the same place.

Other plugins can and should register UI Actions and triggers where appropriate. Is this trigger only used by Lens? If so, it might belong in the Lens plugin instead.
If this is expected to be a general purpose trigger used by multiple plugins, I'll happily approve.

For now, it is only used by Lens, but its purpose is not restricted to it, I tried to make it as generic as possible. It is not tied to Lens, visualization legends or table actions specifically. So, in the future, it can be used by other plugins to show actions for a rendered value.
The ValueHoverActions (package) component for instance, that will be created soon, could also use this trigger.

Having that said, I don't have a strong opinion about it, I registered the trigger in the embeddable as the "default" place, since the trigger can be potentially used by different entities, but I am not 100% convinced it is the correct place either. I am open to moving the trigger register to any other place that you think is more convenient.

Copy link
Contributor

@ThomThomson ThomThomson left a comment

Choose a reason for hiding this comment

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

Thank you for the explanation @semd, as long as the implementation is intended to be generic, the embeddable plugin seems like an okay home for the time being!

LGTM - code review only.

@semd
Copy link
Contributor Author

semd commented Dec 12, 2022

Hi @stephmilovic,
About your questions:

My first question may be dumb, related my unfamiliarity with Lens. My video below demonstrates the following behavior: I was able to use the Treemap visualization and see the actions in security/cases. However, on other visualizations like "Bar vertical stacked" that looks like it has the same type of legend, we do not have the actions in cases. Is this actually a different category of renderers? If so, is the plan to follow up and apply our actions to them all?
Next, I'm wondering where the filters get applied to? See in my video, I do the timeline/copy actions successfully but am confused by the filters. For filter in and out, either we should be hiding those on cases pages or apply to global kql, but not do nothing? Am i missing what these buttons are doing within security? Edit: this behavior already in main for the filters, we should fix it in follow up pr

Not dumb at all, I had to dig into the charts code to find that there's a disableTriggers flag prop in the embeddables, that cases set to true when rendering the embeddable in the comments:

EDIT:
The problem is that only a few visualization types check this flag when rendering the actions, like the stacked bar chart (XYChart), but some others don't check that flag and always show the actions if they are compatible. Even though the Filter actions do not work when the disableTriggers is true, the options are rendered anyway, that seems a bug.

I assume Cases set the disableTriggers to true to prevent Lens to show these filtering actions, it does not make much sense to have them on the Cases page.

I did not realize this flag existed, so right now the AddToTimeline and CopyToClipboard actions are inconsistent with the Filter actions, they should also be hidden inside Cases. I am fixing that.

The ideal scenario for us would probably be to display all the actions except for the Filter For/Out inside cases, but we would need more granularity to do so, the disableTriggers prop is not enough.

Since this PR is adding actions in a general way inside Security, we could keep all actions hidden in Cases by now, and discuss this topic with @paulewing and the Cases team.

What do you think?

Copy link
Contributor

@stephmilovic stephmilovic left a comment

Choose a reason for hiding this comment

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

Thank you for adding all the tests requested, LGTM!


const hasCellActions = (columnId?: string) => {
return columnId && !FIELDS_WITHOUT_CELL_ACTIONS.includes(columnId);
};

const StyledContent = styled.div<{ $isDetails: boolean }>`
Copy link
Contributor

Choose a reason for hiding this comment

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

👌🏾

Copy link
Contributor

@michaelolo24 michaelolo24 left a comment

Choose a reason for hiding this comment

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

Thanks for making this change! Everything seems to look and work fine for the tables. Investigations Codeowners LGTM!

Copy link
Contributor

@dej611 dej611 left a comment

Choose a reason for hiding this comment

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

Found only minor nitpicks here and there, nothing major.
Tested locally on Safari and found no regression.

@@ -60,6 +84,12 @@ export const getPartitionVisRenderer: (
unmountComponentAtNode(domNode);
});

const columnCellValueActions = await getColumnCellValueActions(
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we combine this with the palette async code below?

@@ -58,8 +58,10 @@ import { ExtendedDataLayerConfig, XYProps, AnnotationLayerConfigResult } from '.
import { DataLayers } from './data_layers';
import { SplitChart } from './split_chart';
import { LegendSize } from '@kbn/visualizations-plugin/common';
import { LayerCellValueActions } from '../types';
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
import { LayerCellValueActions } from '../types';
import type { LayerCellValueActions } from '../types';

@@ -1335,7 +1336,7 @@ export function isLensEditEvent<T extends LensEditSupportedActions>(

export function isLensTableRowContextMenuClickEvent(
event: ExpressionRendererEvent
): event is BrushTriggerEvent {
): event is LensTableRowContextMenuEvent {
Copy link
Contributor

Choose a reason for hiding this comment

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

❤️

@@ -104,6 +129,11 @@ export const getDatatableRenderer = (dependencies: {
}
}

const columnCellValueActions = await getColumnCellValueActions(
Copy link
Contributor

Choose a reason for hiding this comment

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

can it be combined with the columnFilterable one?

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 3387 3395 +8

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
embeddable 413 421 +8
expressions 1739 1746 +7
lens 598 599 +1
total +16

Any counts in public APIs

Total count of every any typed public API. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats any for more detailed information.

id before after diff
embeddable 6 8 +2

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
expressionPartitionVis 52.4KB 52.9KB +511.0B
expressionXY 118.8KB 119.2KB +444.0B
lens 1.3MB 1.3MB +1.4KB
securitySolution 10.1MB 12.6MB ⚠️ +2.5MB
total ⚠️ +2.5MB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
embeddable 69.8KB 70.2KB +406.0B
expressionPartitionVis 24.6KB 24.9KB +367.0B
expressions 98.5KB 98.7KB +155.0B
expressionXY 37.1KB 37.4KB +342.0B
lens 30.5KB 30.5KB +74.0B
securitySolution 50.4KB 51.0KB +575.0B
total +1.9KB
Unknown metric groups

API count

id before after diff
embeddable 514 522 +8
expressions 2198 2205 +7
lens 694 695 +1
total +16

async chunk count

id before after diff
securitySolution 37 42 +5

ESLint disabled in files

id before after diff
osquery 1 2 +1

ESLint disabled line counts

id before after diff
enterpriseSearch 19 21 +2
fleet 61 67 +6
osquery 109 115 +6
securitySolution 440 446 +6
total +20

Total ESLint disabled count

id before after diff
enterpriseSearch 20 22 +2
fleet 70 76 +6
osquery 110 117 +7
securitySolution 517 523 +6
total +21

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @semd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
8.7 candidate backport:skip This commit does not require backporting Feature:Embedding Embedding content via iFrame Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) Feature:Lens Feature:Visualizations Generic visualization features (in case no more specific feature label is available) release_note:feature Makes this part of the condensed release notes Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Threat Hunting:Explore Team:Threat Hunting Security Solution Threat Hunting Team v8.7.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Visualizations] Legends and table cells trigger actions
10 participants