Problem/Motivation
Layout Builder's block listing is not filterable, which makes it hard to quickly find the block you're looking for:
Proposed resolution
We should add a filter for the block listing similar to the core one at /admin/structure/block
, like so:
Remaining tasks
- Add functionality so a categories open/closed state prior to block-filtering is maintained post-block-filtering
User interface changes
A filter will be added to the Layout Builder block listing.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#70 | 2998862-70.patch | 16.37 KB | bnjmnm |
#70 | interdiff_62-70.txt | 1.41 KB | bnjmnm |
#66 | Screen Shot 2019-01-28 at 10.28.46.png | 10.55 KB | lauriii |
#3 | 2998862-3-combined.patch | 27.87 KB | samuel.mortenson |
#3 | 2998862-3.patch | 11.38 KB | samuel.mortenson |
Comments
Comment #2
samuel.mortensonGonna work on this.
Comment #3
samuel.mortensonHere's a combined patch with #2968500: Change inline blocks workflow in Layout Builder to match mocks along with a standalone patch. This issue should be postponed on #2968500: Change inline blocks workflow in Layout Builder to match mocks.
Comment #4
samuel.mortensonComment #5
tim.plunkettComment #6
tedbowNeeded to run
yarn prettier
and 1 function could be turned into "fat arrow" functionComment #7
phenaproximaThis is a usability issue for sure, tagging as such.
Comment #8
phenaproxima#2968500: Change inline blocks workflow in Layout Builder to match mocks is in, so this needs a reroll or at least a re-upload.
Comment #9
phenaproximaMinor nits to begin with...
Should be protected.
No need to call $user->save(), drupalCreateUser() does it already.
This should be assertCount().
So should this.
Comment #10
bendeguz.csirmaz CreditAttribution: bendeguz.csirmaz at Cheppers commentedRerolled, adressed #9.
Comment #11
phenaproximaComment #12
GrandmaGlassesRopeManYou're using destructuring here, however also using `Drupal.*` further down.
This is a bit strange to declare this at the top. Why not just move the if condition higher to assign it?
I'm not generally a fan of function declarations. Can these become function expressions?
You use an arrow function for this, but also `this`, are you sure this is what you want?
What I mentioned above about destructuring.
Comment #13
phenaproximaAdding screenshots.
Also, I discovered that this patch breaks when Quick Edit is enabled. So we'll probably need to enable Quick Edit in the test.
Comment #14
bendeguz.csirmaz CreditAttribution: bendeguz.csirmaz at Cheppers commentedWhen I run
yarn run build:js -- --file modules/layout_builder/js/layout-builder.es6.js
, I get changes inlayout-builder.js
(see attached diff file).I think currently this patch is only working by accident?
this
is not set in arrow functions.I'm going to try to solve this.
Comment #15
bendeguz.csirmaz CreditAttribution: bendeguz.csirmaz at Cheppers commentedAddressed #12 and #14.
Comment #16
phenaproximaYup, that's expected. In core, you should only ever edit .es6.js files; they get transpiled down to .js files, which are ECMAScript 5 and should not be edited directly.
Comment #17
phenaproximaI, um, think we're back to needing review. @bendeguz.csirmaz tells me that the patch is not broken by Quick Edit, so I'll manually test (it may have merely been a missing file in patch #10). Removing the "Needs tests" tag until I can confirm or deny the influence of Quick Edit on this patch.
Comment #19
phenaproximaGave this a quick manual test (with Quick Edit enabled) and it worked like gangbusters. Reviewed the patch and found only some minor things, plus one accessibility question. Otherwise, I'd say this terrific UX improvement is good to go.
Accessibility question: will the placeholder be available to assistive technology?
The JavaScript condition here should check that indexOf() returns greater than 0, because if the index of "blocks are available" is zero, the message is malformed.
This seems a bit dicey to me; it could cause the assertion to be skipped, which makes the test a bit unreliable. How about using assertGreaterThan(0, count($blocks))?
assertLessThan() might be a better choice here.
This should also check that the string indexOf() is > 0.
This should verify that the message index is === 0.
Comment #20
dbungard CreditAttribution: dbungard at Tandem commentedHey There,
Per our conversation @NEDCamp:
Screen reader users are not limited to those who are visually impaired. To reduce the chance of poor UX for the user that takes in information by multiple ways simultaneously (ie. screen reader + visually) please have the non-visible form field label and the default value match. Otherwise, the misalignment of information could be perceived as confusing.
Please be sure that the default text has significant color contrast as well. Please see https://webaim.org/articles/contrast/ for additional details.
Comment #21
starshapedAddressed items in #19 and #20.
Comment #22
phenaproximaThanks, @starshaped! Interdiff looks right to me, and still works well under manual testing. RTBC once it passes Drupal CI.
Comment #23
GrandmaGlassesRopeManArrow function.
Arrow function.
Arrow function, and you will probably have to change `this`.
Additionally, I think this patch needs to have Prettier run.
Comment #24
tedbowWe are hiding the categories here but not actually testing that.
Added test for this
Comment #25
phenaproxima@tedbow, you're a hero. Changes look great, and thanks for adding the additional test.
Back to RTBC.
Comment #26
phenaproximaDemoed this for the UX team today. We found one bug, and two follow-ups:
Comment #27
tedbow@phenaproxima thanks for the update from the UX meeting.
for #26.3
Should the announce div be cleared? Not sure
Drupal.announce()
supports that. Or should it say something else like "All blocks are now ...."Comment #28
phenaproximaI think it should be something like "All available blocks are listed." Shall we open the bikeshed?
Comment #29
tim.plunkettSee also
The Views UI implementation allows searching by both the machine name and description.
Comment #30
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commented#26.2: a generic component might help, but there are some differences between the various filter implementations.
#27: don't bother trying to clear the announcement, as it would only be announced once anyway. It's a live region which is announced after it changes. You could perhaps send an empty string to it, but I don't think there's much point.
#28 is more on the right track. It's a special case where we show them all, so I think it needs a different nessage (e.g. saying it's a "modified list" diesn't make sense, it's really the default list). There may be some value in using the full count though, as it provides a sense of scale.
#29: Not all of these filters have a Drupal.announce() behaviour yet - only the module page did that when D8.0.0 was released. Since then, Drupal.announce() was added to the biock filter, and there are some open issues to add it to other filters like views UI. Note there are two places with filtering in Views UI - the main list of views, and the dialogs for add field/filter/sort etc. The module filter also responds to machine_name, I don't recall how the others behave.
Comment #31
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commented#26.3 - This could be a follow-up, since none if the other filter announcements do this either.
Comment #32
tedbowFound this problem. It is just a small optimization.
We are showing all the links and categories but right after we call
toggle()
on them depending on whether they shown or not.So we actually don't need to do the
show()
call. The only time that we need to do this is in the case wherequery.length < 2
. So moving this into an else block.It looks like we don't need to worry about #26.3
Comment #33
phenaproximaThanks, @tedbow! However...
I think we do need to worry about it. @andrewmacpherson said not to worry about clearing it...but we do need to worry about updating it. If all blocks are now visible after clearing the search query, we should announce that. Kicking this back for that, plus test coverage.
Comment #34
tedbowI notice here that we are opening all categories.
But we don't close them if the user deletes their search. Is this intentional? Maybe it doesn't matter because we know the user is looking for a block.
After #2977587: Improve block listing in Layout Builder by hiding uncommon block plugins lands most categories will be closed by default and I think will be more apparent and maybe a problem.
1 thing we could do is set a data attribute for which ones were closed before the search and close them when they cancel the search.
I think we already going to have keep track of whether the user had a query that was more than 2 letters and was querying or was just typing their first character. Otherwise when the user first types 1 character we are going to announce all blocks are available when nothing has actually changed.
Comment #35
bendeguz.csirmaz CreditAttribution: bendeguz.csirmaz at Cheppers commentedAdded the "All available blocks are listed." message.
Comment #36
tedbowWe can't actually use Destructuring for
Drupal.t
It is because PHP scans the js files for
Drupal.t
to find translation strings 😱😩I think this will also announce when you first start to search. So
Since nothing has changed in the listing at this point it seems weird to me.
Comment #37
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commentedRe #32.3 and #33
Phenaproxima is right, that's what I meant. There's no point trying to clear out the Drupal.announce DIV, but I do think it's worth making a message to say that all items are shown, when a user clears the filter.
I'm not sure how to phrase it. The message in #35 will do, but maybe it could be improved. What are we trying to convey? The essential point is that we have not hidden anything.
The Drupal.announce tag has some related issues where we are adding announcements to other filters.
Comment #38
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commentedI gathered up the various ideas into a plan, for better consistency across all our filter lists. Some already have issues in progress.
Comment #39
larowlanLooks good, needs work for #36
Comment #40
tedbowAddressing #36
Comment #42
tedbowRetesting b/c drupalci error
Comment #43
phenaproximaGreat patch. Simple, concise, useful, and well-tested. I have only a few minor questions.
This line could use a comment explaining why it's doing what it's doing.
This seems like a good place to take advantage of jQuery's has() filter. Something like:
$categories.find('.js-layout-builder-category:has(.js-layout-builder-block-link:visible)').toggle(true)
Is the title attribute useful here from an accessibility and usability standpoint? Maybe it should be a #description instead?
Comment #44
bnjmnmPatch addresses 2/3 of #43
1) Change: Added comment explaining category open call (and a few other comments explaining some nearby lines)
2) Change Refactored code responsible for category to leverage has()
3) No Change but definitely open to discussion. Using #description vs. the title attribute is interpreted identically by modern screenreaders (I qualify with modern only because I can't confirm this with old ones - there may be no difference). Regarding the UX side of it, my subjective take is the text in the title attribute is helpful for screenreader users because they're not yet aware of the list of blocks beneath - but users viewing the screen will have enough context to make that additional instruction unnecessary. Very open to feedback on this one.
While reviewing I caught to additional things that should be considered -
1 - If any block categories are collapsed prior to filtering the block list, their closed-state is not remembered if the list is filtered then returns to non-filtered. This closed-state should be remembered when returning to displaying the nonfiltered list.
2- The input placeholder does not have sufficient WCAG approved contrast. I advise switching from placeholder to label as it would address the contrast issue, and adhere to Nielsen's UX recommendations regarding placeholders https://www.nngroup.com/articles/form-design-placeholders/ (among other things, Neilsen and a few other sources mention that some older screenreaders ignore placeholder inputs.
Comment #45
bnjmnmComment #46
bnjmnmAdded revised patch to address test failures from #44 - all comments there still apply.
Forgot to mention in #44 that one additional change was made after discussing it with @tedbow: prior to this patch, category visibility was based on a data-blocks-filtered attribute on each category. To save unnecessary DOM manipulation, this was refactored to be a single bool variable declared just prior to the layoutBuilderBlockFilter, which simply indicates if filtering is taking place.
Comment #47
bnjmnmFrom discussion with @tedbow, we agreed that preserving category open/closed state should be maintained before and after filtering. Adding this to remaining tasks in the issue description.
Comment #48
bnjmnmThis is the patch from #44 tweaked to pass tests
Comment #49
bnjmnmComment #50
bnjmnmThis patch addresses closed-categories not remembering they were closed after filtering occurs. This scenario was also added to
testBlockFilter()
Comment #52
tedbowNeed to use short array syntax.
I don't(edited) think we need a wait here because this just an html element behavior and not JS but pointing it to be sure.
I think you do this with waiting on script string by using
$this->assertNotEmpty($assert_session->waitForElement('css', '#drupal-live-announce:contains("blocks are available")'));
There are couple other occurrences below.
Comment #53
bnjmnmFor #52 (2) - I can do the wait-for-element-not-exists far more elegantly if this issue were committed #2892440: Provide helper test method to wait for an element to be removed from the page (the issue reporter looks familiar). It was already RTBC once, and should be ready again. I rerolled the patch but had to make a few small changes so I can't RTBC it myself. I'd like to see if we can get that pushed through before addressing the tests here.
Comment #54
tedbowsorry for #52.2 I meant to say
Opening up a details doesn't involve JS if I am correct. If so I don't think we need the wait. Just wanted to point out we are not waiting incase we actually should be.
Comment #55
bnjmnm#52.1 , #52.3 are addressed, and confirmed #52.2 does not require waits.
Comment #56
bnjmnmAaaaand I gotta actually upload the patches
Comment #58
GrandmaGlassesRopeManThis should probably be declared inside the attach function.
Comment #59
tedbowre #58 I think we need that outside the attach function because we don't want it be reset if the a part of the page is updated via ajax when the block listing is open. This would call attach.
Comment #60
tedbowWe can also get rid of this JS evaluation
with
Comment #61
bnjmnmSomething about this ticket apparently makes me bad at uploading - the correct files in the next comment.
Comment #62
bnjmnmRefactored per the recommendation in #60
Also was inspired by #58 - although
blocksFiltered
is intentionally outside of the attach function, I renamed it to something a bit more specific:layoutBuilderBlocksFiltered
, since it has wider scope than most variables on the page.Comment #63
bnjmnmComment #65
tedbow#62 looks good!
RTBC 🎉, should pass tests but will get kicked back if not
Comment #66
lauriiiThe change itself looks good from my POV. However, we still have to open follow-ups for what has been mentioned in #26. We should open another follow-up for a problem where Umami styles are leaking to the search element:
Comment #67
tedbowCreated follow ups:
#3028972: Add category to the search for Layout Builder block listing search/filtering
#3028968: Create Javascript library for searching rendered lists on the client.
#3028977: Umami theme break Layout Builder block filtering text box.
Comment #68
lauriiiWe should still add @file documentation and document the behaviors according to our JavaScript documentation standards.
Comment #69
GrandmaGlassesRopeMan@tedbow re. #59, could you add some documentation around why this is done this way?
Comment #70
bnjmnm#68 - documented per JS coding standards
#69 - added comment explaining why
layoutBuilderBlocksFiltered
is declared outside of attach.Comment #71
tedbowSetting Needs Review for testing
Comment #72
phenaproximaI believe all feedback here is addressed. Back to RTBC.
Comment #74
lauriiiLooks all good for me now. Had to rebuild the JavaScript files but it only led into adding a few new lines. Committed 59f8c0d and pushed to 8.7.x. I will also backport this to 8.6.x after the bug release commit freeze. Thank you, everyone!
Comment #76
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commentedfixing accessibility tag