-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Add tag bulk action context menu #82816
Add tag bulk action context menu #82816
Conversation
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.
Self review
if (this.changeListener) { | ||
tagIds.forEach((tagId) => { | ||
this.changeListener!.onDelete(tagId); | ||
}); | ||
} | ||
}); |
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.
I wanted to avoid adding more hooks on the TagCache class. Doing a loop for each delete tag felt good enough.
for (const tagId of tagIds) { | ||
await client.delete(tagId); | ||
} |
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.
We don't have a SoClient.bulkDelete
API, and I need to use the TagClient
instance anyway to perform the references cleanup, which is why there is a loop here.
Note that is there is an error during any tag removal (or associated references cleanup), we will fail fast and do not attempt to delete the next tags in the list. I did that because the most likely cause of failure would be an RBAC related failure, and in that case, it will be thrown for the first tag, and attempting to remove the next tags felt unnecessary.
I did not create a bulkDelete
API on the TagClient
as I thought the logic was simple enough to be kept in the handler (and to avoid increase API surface, as bulkDelete
is supposed to be internal), but I can if we think this is better.
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.
The performance of this is probably going to be fine in 99% of cases, but it is certainly possible for this to partially fail in cases where 1000s of tags are being deleted at once. The reason I think this is acceptable for now is that failing part of the way through (most likely b/c of a timeout) doesn't corrupt the data and the user can easily refresh & try again to delete any remaining tags.
.tagMgt__actionBar + .euiSpacer { | ||
display: none; | ||
} |
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.
elastic/eui#4103 unblocked us by allowing to inject arbitrary content between the InMemoryTable
's searchbar and table. However the EuiSpace
added when using childrenBetween
conflicts with the expected design, so I have to hack it into display: none;
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.
Unfortunately, this whole file goes against our policies for custom styles on top of EUI. There are a couple of issues:
- Don't target
.eui
classes. All our component accept aclassName
prop which you can use to create your own class instance and append to the EUI component class list. Then target this class name so that, in case EUI ever changes it's naming structure (most likely to happen within the next year), your styles won't break. - Don't use hard-coded pixel values. Always use our SASS variables for sizing and font sizes. Most likely a prop exists on the component to help this as well.
If you're having trouble affecting change on an EUI component, please let us know before targeting the .eui
classes directly. Most likely we can get a fix in pretty quickly, or if there's a long-term solution being worked on, for instances like these, it's better to be consistent with the EUI components than to override them.
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.
Don't target .eui classes. All our component accept a className
Unfortunately I can't here. I'm targeting the EuiSpacer
that is inside the EuiInMemoryTable
, between the childrenBetween
node and the table. See elastic/eui#4103 / https://github.com/elastic/eui/blob/master/src/components/basic_table/in_memory_table.tsx#L695.
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.
Yep. Mostly my comment for that specifically is to say, please ask us or create a PR on the EUI side so we can support your needs without needing hacks. I see this as a valid request that we shouldn't really be introducing a hard-coded spacer here and leave it up to the consumer to provide one.
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.
Created elastic/eui#4246
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.
Thanks @pgayvallet ! I've already got a PR up for you to fix this elastic/eui#4246
I'll let it slide for now 😉 because at least when the fix merges into Kibana, your hack won't have any ill effect. I'd def then appreciate a follow-up.
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.
Created #83161. Will do it as soon as elastic/eui#4246 get shipped in next Kibana EUI update.
Thanks again for the quick fix btw
x-pack/plugins/saved_objects_tagging/public/management/components/_action_bar.scss
Outdated
Show resolved
Hide resolved
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.
This is looking great, @pgayvallet! Excellent work all around. I left a handful of minor comments for your review.
And one final nit: I was wondering if it would also be possible to change the delete modals' max width from the current 768px to 560px. Doing so would better match the design and make the line lengths a little easier on the eyes. Thanks!
x-pack/plugins/saved_objects_tagging/public/management/components/_action_bar.scss
Outdated
Show resolved
Hide resolved
confirmButtonText: i18n.translate( | ||
'xpack.savedObjectsTagging.management.actions.bulkDelete.confirm.confirmButtonText', | ||
{ | ||
defaultMessage: 'Delete {count, plural, one {tag} other {tags}}', | ||
values: { | ||
count: tagIds.length, | ||
}, | ||
} | ||
), | ||
buttonColor: 'danger', |
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.
In addition to delete button text and color, would it be possible to also specify an icon (trash
) to precede the button text, as shown in the design? This would also apply to the non-bulk, individual delete tag modals as well.
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.
Not right now unfortunately. We had the same issue in the MVP for the single 'delete' action. I created #81482 at this time.
x-pack/plugins/saved_objects_tagging/public/management/components/action_bar.tsx
Outdated
Show resolved
Hide resolved
x-pack/plugins/saved_objects_tagging/public/management/components/action_bar.tsx
Outdated
Show resolved
Hide resolved
x-pack/plugins/saved_objects_tagging/public/management/tag_management_page.tsx
Outdated
Show resolved
Hide resolved
export { | ||
OverlayStart, | ||
OverlayBannersStart, | ||
OverlayRef, | ||
OverlayFlyoutStart, | ||
OverlayFlyoutOpenOptions, | ||
OverlayModalOpenOptions, | ||
OverlayModalConfirmOptions, | ||
OverlayModalStart, | ||
} from './overlays'; |
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.
There was a lot of missing exports from the overlays
package (and a lot of missing associated generated doc files) I saw that when adding the maxWidth
option did not update any file from the generated doc, so I fixed it in this PR.
Pinging @elastic/apm-ui (Team:apm) |
Pinging @elastic/ingest-management (Team:Ingest Management) |
8f8f1b8
to
71236d5
Compare
Sorry for the noise, teams. Messed up my rebase. |
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.
A few small issues for robustness, but otherwise LGTM
x-pack/plugins/saved_objects_tagging/public/management/tag_management_page.tsx
Outdated
Show resolved
Hide resolved
for (const tagId of tagIds) { | ||
await client.delete(tagId); | ||
} |
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.
The performance of this is probably going to be fine in 99% of cases, but it is certainly possible for this to partially fail in cases where 1000s of tags are being deleted at once. The reason I think this is acceptable for now is that failing part of the way through (most likely b/c of a timeout) doesn't corrupt the data and the user can easily refresh & try again to delete any remaining tags.
if (action.refreshAfterExecute) { | ||
await fetchTags(); | ||
} |
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.
Given that bulk delete could fail part of the way through the list of tags, I think it would make sense to also refresh the tags after a failure, not just in the success case.
💚 Build SucceededMetrics [docs]Module Count
Async chunks
Distributable file count
Page load bundle
History
To update your PR or re-run it, just comment with: |
* add the delete tag bulk action * add unit tests for bulk delete * fix duplicate i18n key * add RBAC test on bulk delete * add functional tests * self review * design nits * add maxWidth option for confirm modal and add missing doc * change bulk delete confirm modal max width * add more missing doc * only show loading state when performing the bulk delete * use spacer instead of custom margin on horizontal rule * use link instead of button to remove custom styles * remove spacers, just use styles * add divider when action menu is displayed * set max-width for single delete confirm * a11y fixes * address nits * add aria-label to delete action Co-authored-by: Michail Yasonik <michail.yasonik@elastic.co>
* add the delete tag bulk action * add unit tests for bulk delete * fix duplicate i18n key * add RBAC test on bulk delete * add functional tests * self review * design nits * add maxWidth option for confirm modal and add missing doc * change bulk delete confirm modal max width * add more missing doc * only show loading state when performing the bulk delete * use spacer instead of custom margin on horizontal rule * use link instead of button to remove custom styles * remove spacers, just use styles * add divider when action menu is displayed * set max-width for single delete confirm * a11y fixes * address nits * add aria-label to delete action Co-authored-by: Michail Yasonik <michail.yasonik@elastic.co> Co-authored-by: Michail Yasonik <michail.yasonik@elastic.co>
…o-node-details * 'master' of github.com:elastic/kibana: (65 commits) update chromedriver dependency to 87 (elastic#83624) [TSVB] use new Search API for rollup search (elastic#83275) [TSVB] Y-axis has number formatting not considering all series formatters in the group (elastic#83438) [Logs UI] Update <LogStream /> internal state when its props change (elastic#83302) Add tag bulk action context menu (elastic#82816) [code coverage] adding plugin to flush coverage data (elastic#83447) [UsageCollection] Expose `KibanaRequest` to explicitly opted-in collectors (elastic#83413) Added eventBus to trigger and listen plotHandler event (elastic#83435) [Runtime fields] Editor phase 1 (elastic#81472) [Maps] Fix threshold alert issue resolving nested fields (elastic#83577) chore(NA): remove usage of unverified es snapshots (elastic#83589) [DOCS] Adds Elastic Contributor Program link (elastic#83561) Upgrade EUI to v30.2.0 (elastic#82730) Don't show loading screen during auto-reload (elastic#83376) Functional tests - fix esArchive mappings with runtime fields (elastic#83530) [deb/rpm] Create keystore after installation (elastic#76465) [rpm] Create default environment file at "/etc/sysconfig/kibana" (elastic#82144) [docker] removes workaround for missing crypto-policies-scripts subpackage (elastic#83455) [ML] Persisted URL state for the Data frame analytics jobs and models pages (elastic#83439) adds xpack.security.authc.selector.enabled setting (elastic#83551) ...
Summary
Part of #81980
Required for #81970
maxWidth
option toOverlayModalConfirmOptions
and add missing exports fromcore/public/index
bulk delete
actionclear selection
actionScreenshots
Checklist
Delete any items that are not applicable to this PR.