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

UI: Add an experimental API for adding sidebar filter functions at runtime #23722

Merged
merged 16 commits into from Aug 21, 2023

Conversation

ndelangen
Copy link
Member

@ndelangen ndelangen commented Aug 4, 2023

Telescoped off: #23802

What I did

I introduced a new manager API!
It's marked as experimental for now.

The purpose is to allow users and addon-creators to inject (dynamically at runtime) filter functions that filter the list of stories in the sidebar. I know this has been a feature that has been requested many times for a varied use-cases.

I've implemented the actual filtering in the sidebar, but this code will likely need optimization.
And with this optimization there will be assumptions in when the filters are re-evaluated.

A FilterFunction receives an (with status extended) IndexHash_Item and returns a boolean.
Storybook will only ask to filter leaf-items (story and docs).
Storybook will filter out empty components/groups/roots for you.

How to test

This API can be used via from manager.ts:

import { addons } from '@storybook/manager-api';
import startCase from 'lodash/startCase.js';

addons.setConfig({
  sidebar: {
    filters: {
      a: (item) => item.depth === 2,
    },
  },
});

The expected result is that the sidebar stories are filtered.

Checklist

  • Make sure your changes are tested (stories and/or unit, integration, or end-to-end tests)
  • Make sure to add/update documentation regarding your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli/src/sandbox-templates.ts
  • Make sure this PR contains one of the labels below.

["cleanup", "BREAKING CHANGE", "feature request", "bug", "build", "documentation", "maintenance", "dependencies", "other"]

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>

@ndelangen ndelangen self-assigned this Aug 4, 2023
@ndelangen ndelangen changed the title UI: Add a experimental API for adding sidebar filter functions at runtime UI: Add an experimental API for adding sidebar filter functions at runtime Aug 4, 2023
Copy link
Member

@tmeasday tmeasday left a comment

Choose a reason for hiding this comment

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

Can we have some tests please!

Some questions:

  1. How do you remove a filter?
  2. What do you do when some external variable that affects the filter changes? Should you remove the filter and re-add it?

*
* @param {string} addonId - The ID of the addon to update.
* @param {API_FilterFunction} filterFunction - A function that returns a boolean based on the story, index and status.
* @returns {Promise<void>} A promise that resolves when the state has been updated.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe it should return an off function.

@ndelangen
Copy link
Member Author

I had imagined you cannot remove the filter, I figured that you'd set a new filter that just always return true.
I did this to minimize the amount & complexity of APIs being added as experimental.

I added tests!

@ndelangen ndelangen requested a review from tmeasday August 9, 2023 17:19
@tmeasday
Copy link
Member

tmeasday commented Aug 9, 2023

I had imagined you cannot remove the filter, I figured that you'd set a new filter that just always return true.
I did this to minimize the amount & complexity of APIs being added as experimental.

I don't really understand though. If you set >1 filter, don't they both apply? So wouldn't adding a ()=>true filter have no effect?

When adding the API to set this from manager.ts I discovered the setConfig API seems broken due to a race condition between the manager UI rendering async and the manager being initiated before the manager.ts file is executed.

Can we split the PR up and just do this bit first?


I'd like to go over this one together in more detail because as I said elsewhere, I think the approach of doing the filtering in the nodes isn't the right approach, we should filter right at the top in the store. Otherwise we'll constantly be having to refilter everytime we interact with the stories hash, eg in keyboard shortcuts or when addons get the story list, etc.

@tmeasday
Copy link
Member

tmeasday commented Aug 9, 2023

I added tests!

Did you forget to push this bit?

@ndelangen ndelangen changed the base branch from next to norbert/fix-setConfig-execution-order August 11, 2023 10:14
@ndelangen
Copy link
Member Author

I split the PRs apart @tmeasday

const filtered = new Set();
Object.values(originalIndex).forEach((item) => {
if (item.type === 'story' || item.type === 'docs') {
let result = true;
Copy link
Member

Choose a reason for hiding this comment

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

Can result be called something more explicit?

Co-authored-by: Yann Braga <yannbf@gmail.com>
Base automatically changed from norbert/fix-setConfig-execution-order to next August 21, 2023 07:55
@ndelangen ndelangen merged commit 592c32f into next Aug 21, 2023
53 checks passed
@ndelangen ndelangen deleted the norbert/sidebar-filter-api branch August 21, 2023 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants