-
Notifications
You must be signed in to change notification settings - Fork 114
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
Jamie/control menu angular ui2 #2283
Conversation
@@ -196,3 +196,49 @@ chef-loading-spinner[fixed] { | |||
input { | |||
line-height: normal; | |||
} | |||
|
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.
Angular Material requires a lot of over rides, but doesn't really seem to have a good place to target globally outside of the styles.css file. Any suggestions on a better location for something like this. Will get crowded after adding several more components.
@susanev - from a UX/style perspective, this ticket is done. I'm still trying to work through some Cypress testing issues, but I feel comfortable opening up this PR for any style and/or user |
@susanev - Major apologies! I failed to update to new spec pictured here. On that now and will retag when done |
@susanev - Ok, new colors and states are in. Sorry about that! |
} | ||
|
||
&:hover { | ||
background-color: #DEE5FD; |
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.
@susanev several of these colors here are ones that I haven't seen used in the codebase yet. Are there names you want to use for them when I make the variables?
@SEAjamieD can we increase the icon size? maybe also, we need to be able to tab to these buttons, and open them and select an option with keyboard only. you can tab to them, but there's no visible focus (maybe cause you set the outline to 0?).. and you cant open the menu with ur keyboard. flow should be..
and if you tab off the menu should close. |
8d05df1
to
f95753b
Compare
<chef-option (click)="removeMember(member)">Remove Member</chef-option> | ||
</chef-control-menu> | ||
<mat-select panelClass="chef-control-menu-x"> | ||
<mat-option (onSelectionChange)="removeMember($event, member)">Remove Member</mat-option> |
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.
mat-select requires the use of onSelectionChange
in order to be keyboard accessible. Unfortunately this will cause a double fire of connected function -> one for the selection and one for the deselection. The current workaround is running an if check for whether on not this was user input using $event.isUserInput. see: angular/components#4094 (comment)
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 material docs (https://v6.material.angular.io/components/select/overview)" indicate "mat-select
is designed to work inside of a <mat-form-field>
element." Not clear what the ramifications of that are. Any potential pitfalls using it without a <mat-form-field>
?
export interface KeyboardEvent { | ||
isUserInput: boolean; | ||
} | ||
|
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.
By default - isUserInput is not part of the KeyboardEvent interface - this extends it.
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.
Educate me: is isUserInput
something you are populating or is it actually provided by the system though not exposed...?
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.
isUserInput
is provided by Angular Material. Every time an option is selected there is an event fired for selected and an event fired for deselected. The selected event passed through isUserInput = true
and the deselection event passes through isUserInput = false
;
removeMember($event: KeyboardEvent, member: Member): void { | ||
if ($event.isUserInput) { | ||
this.store.dispatch(new RemovePolicyMembers(<PolicyMembersMgmtPayload>{ | ||
id: this.policy.id, | ||
members: [member] | ||
})); | ||
} |
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.
An example of using the $event.isUserInput
to only get the selection and not the deselection.
<chef-option (click)="notifyCopy()" data-cy="copy-token"> | ||
<chef-table-cell class="controls"> | ||
<mat-select panelClass="chef-control-menu-x" id="menu-{{token.id}}" data-cy="token-control"> | ||
<mat-option (onSelectionChange)="notifyCopy($event)" data-cy="copy-token"> |
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.
Again - instances of passing in the event to check agains isUserInput
.
export interface KeyboardEvent { | ||
isUserInput: boolean; | ||
} |
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.
Same as above - extending Keyboard Event
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.
See my earlier comment; this should only occur once in a common file.
How set are you on this flow? With angular material we get most of this built in, only change is that instead of using space bar to open, enter opens. Is this acceptable? |
@SEAjamieD that's fine, thanks for checking!! |
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.
Initial pass--some items need fixing as noted below.
components/automate-ui/src/app/components/chef-components.module.ts
Outdated
Show resolved
Hide resolved
<chef-option (click)="removeMember(member)">Remove Member</chef-option> | ||
</chef-control-menu> | ||
<mat-select panelClass="chef-control-menu-x"> | ||
<mat-option (onSelectionChange)="removeMember($event, member)">Remove Member</mat-option> |
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 material docs (https://v6.material.angular.io/components/select/overview)" indicate "mat-select
is designed to work inside of a <mat-form-field>
element." Not clear what the ramifications of that are. Any potential pitfalls using it without a <mat-form-field>
?
@@ -20,6 +20,10 @@ import { | |||
|
|||
export type PolicyTabName = 'definition' | 'members'; | |||
|
|||
export interface KeyboardEvent { |
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.
🤔 You are actually replacing the definition not extending it, and that makes it rather confusing for someone who expects a KeyboardEvent to be the original.
Would suggest rename this and really extend it:
export interface KeyboardEvent { | |
export interface ChefKeyboardEvent extends KeyboardEvent { |
Also, I notice you export KeyboardEvent
in two different files; they happen to be the same so no harm done at the moment, but that is brittle.
I would urge moving/consolidating it to a new file under src/app/types and just have a single definition that is imported in the three files that need it.
Finally, would like to add an in-code comment so folks know exactly what it is for: "isUserInput allows filtering to selection events and ignores deselection events".
components/automate-ui/src/app/modules/policy/list/policy-list.component.html
Outdated
Show resolved
Hide resolved
components/automate-ui/src/app/modules/team/team-management/team-management.component.html
Outdated
Show resolved
Hide resolved
<chef-table-cell class="three-dot-column"> | ||
<chef-control-menu id="menu-{{token.id}}" data-cy="token-control"> | ||
<chef-option (click)="notifyCopy()" data-cy="copy-token"> | ||
<chef-table-cell class="controls"> |
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.
Here is another pattern to look for--this line also needs to be reverted, and again, check for other occurrences. Be sure to check the corresponding scss entry for this, too.
export interface KeyboardEvent { | ||
isUserInput: boolean; | ||
} |
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.
See my earlier comment; this should only occur once in a common file.
export interface KeyboardEvent { | ||
isUserInput: boolean; | ||
} | ||
|
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.
Educate me: is isUserInput
something you are populating or is it actually provided by the system though not exposed...?
<chef-option (click)="startProjectDelete(project)" data-cy="delete-project">Delete Project</chef-option> | ||
</chef-control-menu> | ||
<mat-select panelClass="chef-control-menu-x"> | ||
<mat-option (onSelectionChange)="startProjectDelete(project)" data-cy="delete-project">Delete Project</mat-option> |
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.
If I am following your protocols, need to add guard if ($event.isUserInput)...
inside of the target method (startProjectDelete
).
And since a global search for .isUserInput
only shows that guard presently in 3 files, I believe there are several others to instrument 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.
Per our conversation, please add on this method and check that there are no other missing ones. Thanks!
@SEAjamieD it looks and works well.. a few more things
|
Signed-off-by: seajamied <[email protected]>
…st row, which is why the test is failing Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
3b60a2b
to
dd1d114
Compare
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.
one last super small thing, lets get the background color on selection to use the same primary blue as our buttons; thanks for all of your work on this!!
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
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 gating function we talked about (included in my comments below) is the only one of significance, I would say. The rest of my baker's dozen below are nitty-gritty cleanup. On the whole, the code looks great and it works well, so giving the thumbs up!
components/automate-ui/src/app/modules/policy/details/policy-details.component.ts
Outdated
Show resolved
Hide resolved
components/automate-ui/src/app/modules/policy/list/policy-list.component.html
Outdated
Show resolved
Hide resolved
components/automate-ui/src/app/pages/integrations/list/integrations-list.component.ts
Outdated
Show resolved
Hide resolved
components/automate-ui/src/app/pages/project/list/project-list.component.spec.ts
Show resolved
Hide resolved
} | ||
} | ||
|
||
&[aria-owns] { // hacky alternative to active |
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 comment gives me only a vague idea of justification; might you have a URL reference you could add here?
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've updated the comment so it makes a little more sense. Ultimately, I noticed "aria-owns" being applied and hooked in on it.
aria-owns
by definition tells assistive technology that another element being placed on the screen should be treated as a child element of the current element we're interacting with (https://developers.google.com/web/fundamentals/accessibility/semantics-aria/aria-labels-and-relationships#aria-owns)
I'm ultimately utilizing it out of scope because when aria-owns
is added, we know that the dropdown panel is open.
@@ -27,6 +27,7 @@ | |||
--blue-de-france: #3DA5FF; | |||
--gray: #B7BCBC; | |||
--blue: #174AF0; | |||
--palatinate-blue: #0E3DD5; |
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.
Wondering what your source is for this color?
Every reference I can find (e.g. https://encycolorpedia.com/search?q=palatinate+blue) shows palatinate blue as #273be2
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 got if from the Automate Extended Color Palette.
<chef-option (click)="startProjectDelete(project)" data-cy="delete-project">Delete Project</chef-option> | ||
</chef-control-menu> | ||
<mat-select panelClass="chef-control-menu-x"> | ||
<mat-option (onSelectionChange)="startProjectDelete(project)" data-cy="delete-project">Delete Project</mat-option> |
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.
Per our conversation, please add on this method and check that there are no other missing ones. Thanks!
components/automate-ui/src/app/pages/integrations/list/integrations-list.component.html
Outdated
Show resolved
Hide resolved
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
Signed-off-by: seajamied <[email protected]>
@SEAjamieD you're going to remove that .toml right? |
Signed-off-by: seajamied <[email protected]>
sorry thank you! |
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.deleteModalVisible = true; | ||
this.policyToDelete = policy; | ||
public startPolicyDelete($event: ChefKeyboardEvent, policy: Policy): void { | ||
if ($event.isUserInput) { |
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.
what does this conditional do? Is it necessary for any control menu item handler?
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 an effect of using Material UI's mat-select
component. When a selection is made, it fires off two events instead of just one. One of the events is the item being selected, and the other event is something being DEselected.
Unfortunately, without this gate being added, we'd fire off two events. The workaround is to check for the isUserInput
property being true, if it is - that's the selected event we want.
thanks for your attention to detail @bcmdarroch!! |
🔩 Description: What code changed, and why?
An ongoing effort to remove stencil components. The goal of this branch was to remove
chef-control-menu
from the codebase. It is replaced here with an Angular Material component, specificallymat-select
andmat-option
. In order to remain keyboard accessible, onClick functions withinmat-option
have been changed to onSelectionChange per angular material requirement.⛓️ Related Resources
#2061
👍 Definition of Done
All
chef-control-menus
have been replaced, slight styling updates to what was requested by UX.All Control menus are keyboard accessible.
👟 How to Build and Test the Change
build components/automate_ui_devproxy && start_all_services
Across the site, control menus can be found in:
Settings >
notifications
policies
projects
API Tokens
Teams
Users
Node Credentials
Node Integrations
Compliance >
Reports > Nodes Tab
Reports > Profiles Tab
Reports > Controls Tab
✅ Checklist
📷 Screenshots, if applicable