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

[Dashboard] [Controls] Use uiActions for control hover actions #153065

Merged
merged 18 commits into from
Mar 21, 2023

Conversation

Heenawter
Copy link
Contributor

@Heenawter Heenawter commented Mar 9, 2023

Closes #143585
Closes #151767
Closes #152609

Summary

This PR accomplishes three things, the first of which is moving the edit/delete control hover actions to use the uiActions service - this is the first step in moving existing panel actions (such as replacing the panel, opening the panel settings flyout, etc.) to this hover framework, which is outlined in this issue.

While this was the primary goal of this PR, this also made the following fixes possible:

  1. Since I was refactoring the control editor flyout code as part of this PR, I made it so that changes to the control's width/grow properties are only applied when the changes are saved rather than being automatically applied.

    Before After
    Mar-14-2023 13-05-36 Mar-14-2023 13-06-41
  2. Since the edit control button is no longer a custom component, the tooltip now responds to focus as expected.

    Before After
    Mar-14-2023 13-05-36 Mar-14-2023 13-06-41

Checklist

For maintainers

@Heenawter Heenawter added Feature:Input Control Input controls visualization Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas loe:large Large Level of Effort release_note:skip Skip the PR/issue when compiling release notes impact:medium Addressing this issue will have a medium level of impact on the quality/strength of our product. Project:Controls labels Mar 9, 2023
@Heenawter Heenawter self-assigned this Mar 9, 2023
@Heenawter Heenawter force-pushed the use-actions-framework_2023-03-06 branch 11 times, most recently from 259531d to 344bc81 Compare March 10, 2023 23:37
@Heenawter Heenawter force-pushed the use-actions-framework_2023-03-06 branch 11 times, most recently from 9545168 to 9bfa2ac Compare March 14, 2023 20:56
@@ -106,7 +106,7 @@ const SortableControlInner = forwardRef<
style={style}
>
<ControlFrame
enableActions={isEditable && draggingIndex === -1}
enableActions={draggingIndex === -1}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The available actions are now determined based on their individual compatibility + the disabled actions from the control group - so, we don't need to know if the dashboard is in edit mode for this anymore.

Comment on lines +51 to +55
// if the field name or data view id has changed in this editing session, reset all selections
newInput.selectedOptions = undefined;
newInput.existsSelected = undefined;
newInput.exclude = undefined;
newInput.sort = undefined;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before these were added, existsSelected, exclude, and sort were all remembered when the data view and/or field of a control was changed - while it doesn't cause any apparent issues (unlike selectedOptions, which was the only thing included before), it goes against expected behaviour IMO. If the data view and/or field of a control is changed, I would expect the entire state of the control to be reset.

@@ -17,7 +17,7 @@
.presentationUtil__floatingActions {
opacity: 1;
visibility: visible;
transition: visibility .1s, opacity .1s;
transition: visibility $euiAnimSpeedFast, opacity $euiAnimSpeedFast;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

cc @andreadelrio We talked about this 👍

Comment on lines 39 to 40
const viewMode = select((state) => state.explicitInput.viewMode);
const disabledActions = select((state) => state.explicitInput.disabledActions);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to pull as much logic as possible into the FloatingActions component to keep the consumers as clean as possible - this meant adding the action fetching logic to this component. However, this caused an issue where I needed things to be re-fetched when certain control group state changed - for example, view mode or the disabled actions.

To get around this, I am taking in the Redux state selector hook so that the FloatingActions component can re-fetch the compatible actions as these parts of state change... I tried a few different things, including taking each piece of state as a prop instead, but this seemed the cleanest to me? It ties the FloatingActions component to the ReduxEmbeddableState though, so I'm open to other ideas 👀

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense to me. Thanks for the explanation.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think ideally we wouldn't want the floating actions tied to any sort of redux-specific state. Most embeddable containers won't use that I think. Is there any complexity in just passing in viewMode and disabledActions as props?

@Heenawter Heenawter marked this pull request as ready for review March 15, 2023 14:43
@Heenawter Heenawter requested review from a team as code owners March 15, 2023 14:43
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-presentation (Team:Presentation)

@botelastic botelastic bot added the Feature:Embedding Embedding content via iFrame label Mar 15, 2023
Comment on lines +121 to +122
// @ts-ignore - TODO: Remove this once https://github.com/elastic/eui/pull/6645 lands in Kibana
focusTrapProps: { scrollLock: true },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refer to #153227

Copy link
Member

Choose a reason for hiding this comment

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

Just for clarification, am I correct that adding scrollLock: true in this PR does not help until #153227 is in main? Basically, we need scrollLock on the .kbnBody class, too?

Copy link
Member

@nickpeihl nickpeihl left a comment

Choose a reason for hiding this comment

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

lgtm!

code review and tested in chrome.

AFAICT, the weird flyout rendering issue should be resolved in a future EUI update.

Comment on lines +121 to +122
// @ts-ignore - TODO: Remove this once https://github.com/elastic/eui/pull/6645 lands in Kibana
focusTrapProps: { scrollLock: true },
Copy link
Member

Choose a reason for hiding this comment

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

Just for clarification, am I correct that adding scrollLock: true in this PR does not help until #153227 is in main? Basically, we need scrollLock on the .kbnBody class, too?

Comment on lines 39 to 40
const viewMode = select((state) => state.explicitInput.viewMode);
const disabledActions = select((state) => state.explicitInput.disabledActions);
Copy link
Member

Choose a reason for hiding this comment

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

Makes sense to me. Thanks for the explanation.

@Heenawter
Copy link
Contributor Author

@nickpeihl

Just for clarification, am I correct that adding scrollLock: true in this PR does not help until #153227 is in main? Basically, we need scrollLock on the .kbnBody class, too?

Yup, that's correct! And it should be in main now, so this should help reduce the frequency of the double animation we're seeing 🎉

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.

Looks like Nick beat me to it, but I figured I had enough content that it warranted a double-review. In short, everything looks good!

let reduxEmbeddablePackage: ReduxEmbeddablePackage;

beforeAll(async () => {
reduxEmbeddablePackage = await lazyLoadReduxEmbeddablePackage();
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be quicker to use a mocked version of this? I am not entirely sure if one exists yet, but if not I will be adding it in #150121

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It probably would be, yeah! We don't seem to have the mock yet, though - if you plan to add one, that would be awesome!


const onCancel = () => {
if (
isEqual(panel.explicitInput, {
Copy link
Contributor

Choose a reason for hiding this comment

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

As a follow-up in some other PR maybe we should look into fixing the bug where the confirm model is shown if you create a new control then immediately cancel.

Comment on lines 39 to 40
const viewMode = select((state) => state.explicitInput.viewMode);
const disabledActions = select((state) => state.explicitInput.disabledActions);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think ideally we wouldn't want the floating actions tied to any sort of redux-specific state. Most embeddable containers won't use that I think. Is there any complexity in just passing in viewMode and disabledActions as props?

@Heenawter
Copy link
Contributor Author

I think ideally we wouldn't want the floating actions tied to any sort of redux-specific state. Most embeddable containers won't use that I think. Is there any complexity in just passing in viewMode and disabledActions as props?

@ThomThomson Nope - if passing through props is preferred, then we can totally do that 💃 I just wasn't sure which style would be preferred, so I opted for fewest-props - but I didn't necessarily feel super strong one way or another.

Moved to props in 505924e 👍

@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #10 / security APIs - Session Idle Session POST /internal/security/session should extend the session

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
controls 150 153 +3
presentationUtil 154 155 +1
total +4

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
controls 268 270 +2
embeddable 436 441 +5
total +7

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 9 11 +2

Async chunks

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

id before after diff
controls 179.4KB 189.9KB +10.5KB
presentationUtil 129.0KB 129.1KB +2.0B
total +10.5KB

Page load bundle

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

id before after diff
controls 32.1KB 33.3KB +1.1KB
embeddable 75.3KB 75.7KB +404.0B
presentationUtil 35.2KB 36.0KB +808.0B
total +2.3KB
Unknown metric groups

API count

id before after diff
controls 272 274 +2
embeddable 539 544 +5
total +7

async chunk count

id before after diff
controls 5 7 +2

ESLint disabled line counts

id before after diff
securitySolution 433 436 +3

Total ESLint disabled count

id before after diff
securitySolution 513 516 +3

History

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

cc @Heenawter

Copy link
Contributor

@andreadelrio andreadelrio left a comment

Choose a reason for hiding this comment

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

Design changes LGTM. Amazing work @Heenawter!

@Heenawter Heenawter merged commit b6fb660 into elastic:main Mar 21, 2023
@kibanamachine kibanamachine added v8.8.0 backport:skip This commit does not require backporting labels Mar 21, 2023
@logeekal
Copy link
Contributor

logeekal commented Apr 4, 2023

Hello @Heenawter , @ThomThomson

One thought/suggestion came to me mind regarding the Actions. In addition to ACTION_EDIT_CONTROL, ACTION_DELETE_CONTROL, should we add DRAGGABLE because edit mode enabled these three things. We can make this the part of #154068.

This will help to make the control not draggable.

Let me know what you think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Embedding Embedding content via iFrame Feature:Input Control Input controls visualization impact:medium Addressing this issue will have a medium level of impact on the quality/strength of our product. loe:large Large Level of Effort Project:Controls release_note:skip Skip the PR/issue when compiling release notes Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas v8.8.0
Projects
None yet
8 participants