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

DataViews: add support for NOT IN operator in filter #56479

Merged
merged 16 commits into from
Dec 4, 2023

Conversation

oandregal
Copy link
Member

@oandregal oandregal commented Nov 23, 2023

Part of #55083
Related to #55100

What?

Adds support for NOT IN operator in the Author filter while leaving Status as it is (only supports IN operator).

Gravacao.do.ecra.2023-11-30.as.17.37.54.mov

Why?

It's part of the interactions we want to achieve.

How?

  • Fields API:
    • by default, any field of type: ENUMERATION gets the filter with both operator (IN, and NOT IN).
    • this can be configurable by providing the specific ones in the filterBy.operators property (see how the Author field uses it to only enable the IN operator).
  • Filter component: add support for both operators.

Testing Instructions

  • Enable the "admin views" Gutenberg experiment and visit "Appearance > Editor > Pages > Manage all pages".
  • Interact with the filters.

@oandregal oandregal self-assigned this Nov 23, 2023
@oandregal oandregal added [Type] Experimental Experimental feature or API. [Feature] DataViews Work surrounding upgrading and evolving views in the site editor and beyond labels Nov 23, 2023
Copy link

github-actions bot commented Nov 23, 2023

Size Change: +641 B (0%)

Total Size: 1.72 MB

Filename Size Change
build/edit-site/index.min.js 209 kB +641 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 964 B
build/annotations/index.min.js 2.71 kB
build/api-fetch/index.min.js 2.29 kB
build/autop/index.min.js 2.11 kB
build/blob/index.min.js 590 B
build/block-directory/index.min.js 7.25 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/content-rtl.css 4.29 kB
build/block-editor/content.css 4.28 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
build/block-editor/index.min.js 248 kB
build/block-editor/style-rtl.css 15.7 kB
build/block-editor/style.css 15.7 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 138 B
build/block-library/blocks/audio/theme.css 138 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 587 B
build/block-library/blocks/button/editor.css 587 B
build/block-library/blocks/button/style-rtl.css 633 B
build/block-library/blocks/button/style.css 632 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 421 B
build/block-library/blocks/columns/style.css 421 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 647 B
build/block-library/blocks/cover/editor.css 650 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 98 B
build/block-library/blocks/details/style.css 98 B
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 138 B
build/block-library/blocks/embed/theme.css 138 B
build/block-library/blocks/file/editor-rtl.css 316 B
build/block-library/blocks/file/editor.css 316 B
build/block-library/blocks/file/style-rtl.css 280 B
build/block-library/blocks/file/style.css 281 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/footnotes/style-rtl.css 201 B
build/block-library/blocks/footnotes/style.css 199 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 228 B
build/block-library/blocks/form-input/style-rtl.css 343 B
build/block-library/blocks/form-input/style.css 343 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 343 B
build/block-library/blocks/form-submission-notification/editor.css 342 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 452 B
build/block-library/blocks/freeform/editor-rtl.css 2.61 kB
build/block-library/blocks/freeform/editor.css 2.61 kB
build/block-library/blocks/gallery/editor-rtl.css 957 B
build/block-library/blocks/gallery/editor.css 962 B
build/block-library/blocks/gallery/style-rtl.css 1.75 kB
build/block-library/blocks/gallery/style.css 1.75 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 189 B
build/block-library/blocks/heading/style.css 189 B
build/block-library/blocks/html/editor-rtl.css 340 B
build/block-library/blocks/html/editor.css 341 B
build/block-library/blocks/image/editor-rtl.css 834 B
build/block-library/blocks/image/editor.css 833 B
build/block-library/blocks/image/style-rtl.css 1.61 kB
build/block-library/blocks/image/style.css 1.6 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/image/view.min.js 2.02 kB
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 505 B
build/block-library/blocks/media-text/style.css 503 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 671 B
build/block-library/blocks/navigation-link/editor.css 672 B
build/block-library/blocks/navigation-link/style-rtl.css 103 B
build/block-library/blocks/navigation-link/style.css 103 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation/editor-rtl.css 2.26 kB
build/block-library/blocks/navigation/editor.css 2.26 kB
build/block-library/blocks/navigation/style-rtl.css 2.27 kB
build/block-library/blocks/navigation/style.css 2.26 kB
build/block-library/blocks/navigation/view.min.js 1.04 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 401 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 235 B
build/block-library/blocks/paragraph/editor.css 235 B
build/block-library/blocks/paragraph/style-rtl.css 335 B
build/block-library/blocks/paragraph/style.css 335 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 508 B
build/block-library/blocks/post-comments-form/style.css 508 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 666 B
build/block-library/blocks/post-featured-image/editor.css 662 B
build/block-library/blocks/post-featured-image/style-rtl.css 345 B
build/block-library/blocks/post-featured-image/style.css 345 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 409 B
build/block-library/blocks/post-template/style.css 408 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 335 B
build/block-library/blocks/pullquote/style.css 335 B
build/block-library/blocks/pullquote/theme-rtl.css 168 B
build/block-library/blocks/pullquote/theme.css 168 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 486 B
build/block-library/blocks/query/editor.css 486 B
build/block-library/blocks/query/style-rtl.css 312 B
build/block-library/blocks/query/style.css 308 B
build/block-library/blocks/query/view.min.js 647 B
build/block-library/blocks/quote/style-rtl.css 237 B
build/block-library/blocks/quote/style.css 237 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 140 B
build/block-library/blocks/read-more/style.css 140 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 184 B
build/block-library/blocks/search/editor.css 184 B
build/block-library/blocks/search/style-rtl.css 613 B
build/block-library/blocks/search/style.css 613 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/search/view.min.js 475 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 329 B
build/block-library/blocks/shortcode/editor.css 329 B
build/block-library/blocks/site-logo/editor-rtl.css 760 B
build/block-library/blocks/site-logo/editor.css 760 B
build/block-library/blocks/site-logo/style-rtl.css 204 B
build/block-library/blocks/site-logo/style.css 204 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 682 B
build/block-library/blocks/social-links/editor.css 681 B
build/block-library/blocks/social-links/style-rtl.css 1.47 kB
build/block-library/blocks/social-links/style.css 1.47 kB
build/block-library/blocks/spacer/editor-rtl.css 359 B
build/block-library/blocks/spacer/editor.css 359 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 432 B
build/block-library/blocks/table/editor.css 432 B
build/block-library/blocks/table/style-rtl.css 646 B
build/block-library/blocks/table/style.css 645 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 403 B
build/block-library/blocks/template-part/editor.css 403 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/term-description/style-rtl.css 111 B
build/block-library/blocks/term-description/style.css 111 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 191 B
build/block-library/blocks/video/style.css 191 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 12.5 kB
build/block-library/editor.css 12.4 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 213 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 14.7 kB
build/block-library/style.css 14.7 kB
build/block-library/theme-rtl.css 700 B
build/block-library/theme.css 705 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 51 kB
build/commands/index.min.js 15.5 kB
build/commands/style-rtl.css 947 B
build/commands/style.css 942 B
build/components/index.min.js 256 kB
build/components/style-rtl.css 12.1 kB
build/components/style.css 12.1 kB
build/compose/index.min.js 12.7 kB
build/core-commands/index.min.js 2.73 kB
build/core-data/index.min.js 72.6 kB
build/customize-widgets/index.min.js 12.1 kB
build/customize-widgets/style-rtl.css 1.43 kB
build/customize-widgets/style.css 1.43 kB
build/data-controls/index.min.js 651 B
build/data/index.min.js 8.87 kB
build/date/index.min.js 17.9 kB
build/deprecated/index.min.js 462 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.68 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/edit-post/index.min.js 35.8 kB
build/edit-post/style-rtl.css 7.6 kB
build/edit-post/style.css 7.59 kB
build/edit-site/style-rtl.css 14.6 kB
build/edit-site/style.css 14.6 kB
build/edit-widgets/index.min.js 17.2 kB
build/edit-widgets/style-rtl.css 4.65 kB
build/edit-widgets/style.css 4.65 kB
build/editor/index.min.js 47.7 kB
build/editor/style-rtl.css 3.74 kB
build/editor/style.css 3.73 kB
build/element/index.min.js 4.87 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 7.76 kB
build/format-library/style-rtl.css 577 B
build/format-library/style.css 577 B
build/hooks/index.min.js 1.57 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.61 kB
build/interactivity/file.min.js 442 B
build/interactivity/image.min.js 2.15 kB
build/interactivity/index.min.js 12.5 kB
build/interactivity/navigation.min.js 1.16 kB
build/interactivity/query.min.js 791 B
build/interactivity/search.min.js 610 B
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.76 kB
build/keycodes/index.min.js 1.9 kB
build/list-reusable-blocks/index.min.js 2.11 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/media-utils/index.min.js 2.92 kB
build/modules/importmap-polyfill.min.js 12.2 kB
build/notices/index.min.js 964 B
build/nux/index.min.js 2.01 kB
build/nux/style-rtl.css 775 B
build/nux/style.css 771 B
build/patterns/index.min.js 5.28 kB
build/patterns/style-rtl.css 564 B
build/patterns/style.css 564 B
build/plugins/index.min.js 1.81 kB
build/preferences-persistence/index.min.js 1.85 kB
build/preferences/index.min.js 1.26 kB
build/primitives/index.min.js 994 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 994 B
build/react-i18n/index.min.js 631 B
build/react-refresh-entry/index.min.js 9.46 kB
build/react-refresh-runtime/index.min.js 6.78 kB
build/redux-routine/index.min.js 2.71 kB
build/reusable-blocks/index.min.js 2.74 kB
build/reusable-blocks/style-rtl.css 265 B
build/reusable-blocks/style.css 265 B
build/rich-text/index.min.js 9.98 kB
build/router/index.min.js 1.79 kB
build/server-side-render/index.min.js 1.96 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 1.98 kB
build/token-list/index.min.js 587 B
build/url/index.min.js 3.83 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 967 B
build/warning/index.min.js 259 B
build/widgets/index.min.js 7.18 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@oandregal oandregal mentioned this pull request Nov 23, 2023
26 tasks
@youknowriad
Copy link
Contributor

Design wise should we do something more like notion where you don't select a "value" from the "add filter" dropdown, instead, you just select the field, and then you get a modal/popover where you can do several things:

  • Choose an operator
  • Choose one or multiple values.

I think this modal will scale well to all operators and type of fields... Some fields for instance might not have a fixed list of values and you want to type something instead.

Screen.Recording.2023-11-23.at.3.06.54.PM.mov

@jameskoster
Copy link
Contributor

@youknowriad I think that might go beyond the scope of what's capable in the new DropdownMenu component and require the use of an actual modal. Cc @ciampo for confirmation.

That's not to say we should do it, but it would require a little design exploration. If we wanted to use DropdownMenu something like this might work (with finessed wording)?

Screenshot 2023-11-23 at 15 13 48

@youknowriad
Copy link
Contributor

I think the fact that we started with filters that consist of just item selection is maybe leading us to a direction that doesn't accommodate all the needs. We're trying to force some semantics to the dropdown menu that are not well suited for it. We want a form for each filter basically and a form can be shown in a dropdown or a modal, both work but not a dropdown menu.

@jameskoster
Copy link
Contributor

jameskoster commented Nov 23, 2023

That's a fair point, but it is quite well optimised for the majority of use cases – it would be a shame to make those feel more complicated unnecessarily.

Another option would be to not include operator options in these basic filters, and offer those options in a dedicated "Advanced filter" UI instead. Notion offers something similar:

Screenshot 2023-11-23 at 15 34 04

This is especially comprehensive as it even allows operations between filters.

@ciampo
Copy link
Contributor

ciampo commented Nov 23, 2023

If we wanted to use DropdownMenu something like this might work

Using nested menus with radio options could work

@oandregal
Copy link
Member Author

I've been working on refactoring a bit the existing components to be able to add this feature all at once in all of them. I'd like to land #56514 before this PR.

@jameskoster
Copy link
Contributor

jameskoster commented Nov 27, 2023

I made a quick mockup for the flow Riad proposed, where the filter UIs are forms in popovers rather than DropdownMenus.

Screenshot 2023-11-27 at 12 25 46

The main difference in design is that we lose the ability to add filters as part of the flyout, and that since the new UI is a form we should probably use form elements (checkboxes and radios). I think both concessions are okay given the benefits – more flexibility in terms of what we can place in the popovers.

There's a question about where to put focus when adding a new filter, I would assume on the first element in the popover but cc @andrewhayward for any thoughts on that. Edit: Also worth double-checking whether these UIs being forms rather than menus would impact whether or not we need a dedicated 'Apply' button.


I appreciate the mockup above doesn't include an operator UI. I'll work on that if we decide to refactor in this direction.

@oandregal oandregal force-pushed the add/not-in-operator branch 2 times, most recently from a6bd57b to bb6935b Compare November 29, 2023 09:57
@oandregal
Copy link
Member Author

I've been working on refactoring a bit the existing components to be able to add this feature all at once in all of them. I'd like to land #56514 before this PR.

I'm no longer waiting for 56514 to be merged first. This one is ready and I welcome reviews.

@andrewhayward
Copy link
Contributor

andrewhayward commented Nov 29, 2023

I know the menu foundation upon which filters are built is part of an ongoing conversation, so I wouldn't consider extending it here to be a blocker, particularly.

That being said, there are a few things I'll flag, some of which are more important than others.

Consistency

A dropdown menu from a trigger button labelled 'Author', highlighting check marks in mixed positions, and a large gap where icons might be. A dropdown menu from a trigger button labelled 'Author is admin', highlighting check marks consistently on the left.

Might feel like a minor point, but the "selected" check marks are inconsistent across menus. The menu that opens from table headers has them on the right, but then on the left when in the Settings submenu. The menu that opens from a filter button however has them consistently on the left, even for the same filter options.

Note also that there's a gap on the right of the filter options in the table menu, where icons or other markers might appear.

Focus management

Not an issue introduced here, but noting nevertheless. Sometimes, when selecting an item in a table header menu, focus is lost to the winds. This seems to be a latency issue, because I can only reproduce it with fresh filter settings. If I filter or sort by a previously requested value the data is populated immediately and focus remains on the header element.

Semantics

Different platforms have different considerations when it comes to interdependent menu options, so it's not a huge deal if we use check marks to denote selected items in a mutually exclusive group.

A menu with two mutually exclusive options, circled in red.

However, the underlying semantics should be correct, regardless of the visuals. The options in the main filter menu, for example, are (currently) single-select, but have a role of menuitemcheckbox. This should be menuitemradio, to indicate that only one item in the group can be picked.

The same is also true of options in the Settings submenu, and (although unrelated to this PR) the sorting options, which have a role of menuitem and no aria-checked attribute.

@ciampo
Copy link
Contributor

ciampo commented Nov 29, 2023

Might feel like a minor point, but the "selected" check marks are inconsistent across menus

General inconsistencies between dropdownmenus are likely caused by the fact that some menus are still using the older version of the component — that should be fixed soon, so probably we shouldn't worry about it in this PR.

@oandregal
Copy link
Member Author

oandregal commented Nov 30, 2023

@andrewhayward I pushed some changes to fix the following things:

  • Consistency for filters: all instances of filters (columns, top) show the check mark to the left. Other menus (sorting, etc.) I left as they were – it seems a left mark would not work for all of them given they have icons, but it's a separate concern from this PR anyway.
  • Semantics: all instances of filters use the role="menuitemradio". I've prepared a PR at #56676 looking at other dataview's menus.
  • Focus: this is not introduced here, so it can be investigated separately.

@jameskoster
Copy link
Contributor

Agree with @ciampo on the dropdown, let's focus on making the new component bullet-proof in separate issues / PRs.

@oandregal this is working well. The words are a little tricky, especially as we'll need to account for any/all operators down the road too. Here's a mockup to try, but I'd welcome more feedback:

Screenshot 2023-11-30 at 15 26 17

Naturally in this PR we should strip that back to:

Screenshot 2023-11-30 at 15 26 29

I noticed WooCommerce use the term "Conditions" in their product filter widget. I don't love it, but I'm assuming it has stood the test of time for them.

I'll finish up by saying these details are easy to tweak after the fact if needed, and don't need to hold up merging this PR imo.

@andrewhayward
Copy link
Contributor

Semantics: all instances of filters use the role="menuitemradio". I've prepared a PR at #56676 looking at other dataview's menus.

Thanks. Don't know if this is something to be fixed here or in #56676, but every menuitemradio also needs a corresponding aria-checked value too (either true or false).

{ filterInView.operator === OPERATOR_IN
? __( 'Is' )
: __( 'Is not' ) }
<Icon icon={ chevronRightSmall } />{ ' ' }
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we check for isRTL in all these chevronRight usage?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally this would be handled at the component level, as in RTL environments (almost) everything should be reversed, with the suffix on the left, facing the other way.

This should just work in the newer menu component.

Copy link
Contributor

Choose a reason for hiding this comment

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

I know that we have automatic inversions for CSS but so far, for icons we had to do it manually, so we should be consistent: either have the components handle this everywhere or not, because otherwise it will confuse developers

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I wasn't clear – "everything should be reversed" within the context of menu items. The newer menu component doesn't need a chevron icon passed through as a suffix at all; that bit is automatic if the the menu item has a child menu.

Otherwise, yes, RTL icons aren't always just flipped versions of their LTR equivalents, and we should leave that decision to developers.

A silhouette of a speaker pointing right with a backslash on top of it. A silhouette of a speaker pointing left with a backslash on top of it.

Copy link
Contributor

Choose a reason for hiding this comment

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

The ariakit-based version of the new DropdownMenu component already handles flipping the chevron icon in RTL environments (see storybook example), so I'd say no need to deal with it in this PR

Copy link
Contributor

Choose a reason for hiding this comment

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

Mostly unrelated, but as a side-note, it would be great if the icon system was a bit smarter, and could handle bi-directionality implicitly. So rather than developers having to explicitly think about context...

if ( isRTL() ) {
A pilcrow next to a left-pointing arrow.
<Icon icon={ icons.formatRtl } ... />
} else {
A pilcrow next to a right-pointing arrow.
<Icon icon={ icons.formatLtr } ... />
}

...they could just do something like this...

A pilcrow next to a left-pointing arrow.
<Icon icon={ icons.format } ... /> {/* RTL */}
A pilcrow next to a right-pointing arrow.
<Icon icon={ icons.format } ... /> {/* LTR */}

</brain-dump>

Copy link
Contributor

Choose a reason for hiding this comment

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

Would something like this be too rudimentary?

[dir=ltr] {
    --icon-direction: 1;
}

[dir=rtl] {
    --icon-direction: -1;
}

.icon {
    transform: scaleX(var(--icon-direction));
}

Copy link
Contributor

@andrewhayward andrewhayward Dec 1, 2023

Choose a reason for hiding this comment

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

Would something like this be too rudimentary?

Yes, because it doesn't always work.

A pilcrow next to a right-pointing arrow. A pilcrow next to a left-pointing arrow. A left-pointing arrow next to a horizontally flipped pilcrow.

We could be a bit smarter in the SVG markup though, if we wanted to keep it out of the JS...

<SVG xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24">
  <Path data-dir="ltr" d="..." />
  <Path data-dir="rtl" d="..." />
</SVG>
[dir=rtl] .icon [data-dir=ltr],
[dir=ltr] .icon [data-dir=trl] {
  display: none;
}

Copy link
Contributor

@jameskoster jameskoster left a comment

Choose a reason for hiding this comment

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

Happy to approve this for design. The implementation is good based on the component used, and it works well. The wording is easily tweaked later based on wider feedback.

@ciampo
Copy link
Contributor

ciampo commented Nov 30, 2023

Thanks. Don't know if this is something to be fixed here or in #56676, but every menuitemradio also needs a corresponding aria-checked value too (either true or false).
...
Fixed the aria-checked 250baba and updated the wording as suggested 250baba and 7ca13ce

As also commented in #56676 (review), the new DropdownMenu implementation offers specific components for implementing menu items — we should be using those, instead of manually tweaking DropdownMenuItem with extra attributes (see this comment for more details on how to perform the refactor)

@oandregal oandregal force-pushed the add/not-in-operator branch from de919f1 to f4a16d1 Compare December 1, 2023 10:21
@oandregal
Copy link
Member Author

It seems that I've addressed all feedback here, so I'm merging this one on Monday if no one else brings up anything.

@oandregal oandregal force-pushed the add/not-in-operator branch from f4a16d1 to c493dbf Compare December 4, 2023 08:19
@oandregal oandregal enabled auto-merge (squash) December 4, 2023 08:25
@oandregal oandregal merged commit 3223102 into trunk Dec 4, 2023
52 checks passed
@oandregal oandregal deleted the add/not-in-operator branch December 4, 2023 08:47
@github-actions github-actions bot added this to the Gutenberg 17.3 milestone Dec 4, 2023
Copy link
Contributor

@mcsf mcsf left a comment

Choose a reason for hiding this comment

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

I left some notes, but nice work here!

import { ENUMERATION_TYPE, OPERATOR_IN } from './constants';
import { ENUMERATION_TYPE, OPERATOR_IN, OPERATOR_NOT_IN } from './constants';

const operatorsFromField = ( field ) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Wondering if a better name might be sanitizeOperators.

Copy link
Member Author

Choose a reason for hiding this comment

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

) {
return sprintf(
/* translators: 1: Filter name. 2: Filter value. e.g.: "Author is Admin". */
__( '%1$s is %2$s' ),
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder how more synthetic languages are handled in this sort of UI (e.g. Notion). I'm not discouraging this bit of string interpolation, just pointing out that we should see how others have done this, so that later we are sure that this UI is localisable.

Copy link
Member Author

Choose a reason for hiding this comment

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

At some point, the proposal was Field: value. Though it didn't scale well when you have more operators (in, not in, starts with, etc.).

This is how notion does it (suffers from the same issue):

Gravacao.do.ecra.2023-12-14.as.10.14.24.mov

This is linear (same issue):

Gravacao.do.ecra.2023-12-14.as.10.16.52.mov

The same in other platforms (github, etc.).

I find synthetic languages difficult for this use case because the individual parts (field name, value) are translated separately, and you have no context what they are when translating this string as a whole. Happy to look at examples to improve it.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is German:

Gravacao.do.ecra.2023-12-14.as.10.25.31.mov

The gender does affect other parts of the sentence, though the general structure is the same – I'd think what we have here is fine.

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 having a look! Yeah, I think it's doable, and at worst there might be a handful of languages in which the UI reads slightly awkwardly but remains understandable.

Comment on lines +77 to +83
if ( ! columnOperators || ! Array.isArray( columnOperators ) ) {
columnOperators = [ OPERATOR_IN, OPERATOR_NOT_IN ];
}
const operators = columnOperators.filter( ( operator ) =>
[ OPERATOR_IN, OPERATOR_NOT_IN ].includes( operator )
);
if ( operators.length >= 0 ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just noticing that this is the same pattern of validation as seen in ./filters.js


Also, is this condition right? It will always evaluate to true, as it's the length of an array.

 operators.length >= 0

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a bug, thanks for catching! Fix at #57048

Copy link
Member Author

Choose a reason for hiding this comment

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

On the topic of code reuse: there's an opportunity to reuse some code between the filters.js and the view-table.js. I gave it a try at #56514 though it wasn't merged. I'm happy to pair on this and take a look at how it could be improved.

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't worry, I think premature consolidation is a danger. I was just pointing out the pattern for later. :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Prompted by this conversation, I've taken a look and consolidated little details so all the filter implementations are mostly lookalike (but still maintaining the little UI/interaction differences for each one) #57059

It's not as ambitious as 56514 was, but I've found some bugs with the column filters by doing this exercise, so it's worth having anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] DataViews Work surrounding upgrading and evolving views in the site editor and beyond [Type] Experimental Experimental feature or API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants