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

Feature/multiple hierarchies #2452

Merged
merged 20 commits into from
Jan 4, 2018

Conversation

havelaer
Copy link
Contributor

@havelaer havelaer commented Dec 9, 2017

Issue: #2451

What I did

Extended the hierarchy functionality to enable multiple hierarchies next to the main (nameless hierarchy).
I added an extra rootSeparator (not sure about the name though):

setOptions({
  // ... 
  hierarchySeparator: /\./,
  rootSeparator: /\|/, // default is false
});

UPDATED: rootSeparator is renamed to hierarchyRootSeparator with default value null

Extending the API as such:

storiesOf('Addons|Addon Info.React Docgen', module)
  .add(          ^
  ...

Works backwards compatible with or without setting the hierarchySeparator.

Documentation is updated in addons/options/README.md.

Allowing multiple hierarchies, see issue #2451 for screenshot.

How to test

I added the rootSeparator to the kitchen sink example and added the "|" separator to the addon stories.

See cra-kitchen-sink for an example.

The tests are fixed and extended. Though 1 test is failing, but that it is failing on master as well:

FAIL  examples/cra-kitchen-sink/src/storyshots.test.js
  ● Test suite failed to run

    TypeError: (0 , _react3.storiesOf)(...).add(...).add(...).add(...).addWithInfo is not a function

@@ -6,7 +6,7 @@ import BaseButton from '../components/BaseButton';

const text = 'Testing the a11y addon';

storiesOf('Addon a11y', module)
storiesOf('Addons|Addon a11y', module)
Copy link
Member

Choose a reason for hiding this comment

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

Looks like now we can drop the "Addon" word everywhere:
'Addons|A11y'

@Hypnosphi
Copy link
Member

1 test is failing, but that it is failing on master as well

That's weird. Did you run yarn bootstrap --core?

@Hypnosphi
Copy link
Member

Can you please resolve the conflicts? They are mostly caused by renaming "Left panel" to "Stories panel"

@Hypnosphi Hypnosphi self-assigned this Dec 9, 2017
@havelaer havelaer force-pushed the feature/multiple-hierarchies branch from 8c5d62f to e32dfe7 Compare December 9, 2017 12:35
@codecov
Copy link

codecov bot commented Dec 9, 2017

Codecov Report

Merging #2452 into master will increase coverage by <.01%.
The diff coverage is 48.71%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2452      +/-   ##
==========================================
+ Coverage   34.33%   34.34%   +<.01%     
==========================================
  Files         388      389       +1     
  Lines        8682     8750      +68     
  Branches      901      916      +15     
==========================================
+ Hits         2981     3005      +24     
- Misses       5097     5131      +34     
- Partials      604      614      +10
Impacted Files Coverage Δ
lib/ui/src/modules/api/index.js 0% <ø> (ø) ⬆️
lib/ui/src/modules/ui/libs/filters.js 48.64% <0%> (+1.28%) ⬆️
addons/options/src/preview/index.js 0% <0%> (ø) ⬆️
.../ui/components/stories_panel/stories_tree/index.js 38.73% <0%> (-3.26%) ⬇️
...onents/stories_panel/stories_tree/index.stories.js 94.44% <100%> (ø) ⬆️
...dules/ui/components/stories_panel/index.stories.js 90.9% <100%> (ø) ⬆️
...i/src/modules/ui/components/stories_panel/index.js 20.96% <25%> (+2.44%) ⬆️
...mponents/stories_panel/stories_tree/tree_header.js 18.75% <27.27%> (ø)
lib/ui/src/modules/ui/containers/stories_panel.js 27.02% <41.66%> (+1.31%) ⬆️
lib/ui/src/modules/ui/libs/hierarchy.js 49.51% <70%> (-1.24%) ⬇️
... and 64 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 51108ef...aaff55f. Read the comment docs.

@havelaer
Copy link
Contributor Author

havelaer commented Dec 9, 2017

@Hypnosphi Thanks for reviewing!
The branch was based on master. I've rebased the branch on latest release/3.3 and fixed the conflicts.
yarn bootstrap reset everything and all tests are passing!
I've also omitted 'Addon' in the addon story names.

const headingStyle = {
...baseFonts,
textTransform: 'uppercase',
// letterSpacing: '1.5px',
Copy link
Member

Choose a reason for hiding this comment

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

Looks like it's worth uncommenting. Uppercase text is more readable when it has some letter-spacing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it to letterSpacing: '1.2px'

@Hypnosphi
Copy link
Member

Please run yarn test --core --update to update test snapshots

@Hypnosphi
Copy link
Member

Live example for reference

Looks like some of the stories still have wrong kinds:
image

@Hypnosphi
Copy link
Member

Root title is hidden when using search. Is it on purpose?
image

Copy link
Member

@igor-dv igor-dv left a comment

Choose a reason for hiding this comment

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

  1. Very like this ability. Would like to use for separating core component in my project.
  2. I didn't check the tests yet
  3. I think overloading the storyKind to have more special syntax is a bit wrong direction, but currently, we have nothing to do with it. (maybe create some kind of URI syntax for story) @ndelangen , you have plans for refactoring, WDYT?

// override the hierarchySeparator or rootSeparator if the prop is missing
const options = {
...newOptions,
...(hasOwnProp(newOptions, 'hierarchySeparator')
Copy link
Member

Choose a reason for hiding this comment

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

I think worth extracting this to a method - for readability. withProp() or something.

const option = {
  ...newOptions,
  ...withProp(newOptions, 'hierarchySeparator'),
  ...withProp(newOptions, 'rootSeparator'),
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Called it withRegexProp()

* /\|/ - split by `|`
* @type {Regex}
*/
rootSeparator: null,
Copy link
Member

Choose a reason for hiding this comment

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

Maybe better call it hierarchyRootSeparator for naming consolidation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

Copy link

Choose a reason for hiding this comment

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

Could the PR description be updated to have it in the example there? Didn't work on the first try and had to search around to discover this.

Found my way here through the 3.4.0-alpha0 changelog entry

const selectedHierarchy = resolveStoryHierarchy(selectedKind, hierarchySeparator);
const storiesHierarchies = createHierarchies(filteredStories);

const [, storyName] = resolveStoryRoots(selectedKind, rootSeparator);
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why exporting the resolveStoryRoots ? You can hide it under the resolveStoryHierarchy method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

resolveStoryRoots is exported for 2 reasons:

  1. It's also needed in the stories_panel container.
  2. It's has separate unit tests.

Btw I renamed resolveStoryRoots to resolveStoryHierarchyRoots.

@@ -46,24 +46,47 @@ function fillHierarchy(namespaces, hierarchy, story) {
fillHierarchy(namespaces.slice(1), childHierarchy, story);
}

export function createHierarchy(stories) {
const hierarchyRoot = {
export function createHierarchyRoot(name = '') {
Copy link
Member

Choose a reason for hiding this comment

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

Looks like you export this function only for tests, IMO it's not a good thing.

Copy link
Member

Choose a reason for hiding this comment

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

It's not the main js file, so I think it's Ok to have test-only exports for more granular unit tests

Copy link
Member

Choose a reason for hiding this comment

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

👌


export function resolveStoryRoots(storyName = '', rootSeparator) {
if (!rootSeparator) {
return ['', storyName];
Copy link
Member

Choose a reason for hiding this comment

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

I think in this method better return an object, instead of relying on indices in the array.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. Changed it, so it returns an object.

Btw I renamed resolveStoryRoots to resolveStoryHierarchyRoots.


fillHierarchy(namespaces, hierarchyRoot, { ...story, name });
});
}

return hierarchyRoot;
return Object.keys(rootMap).map(rootName => rootMap[rootName]);
Copy link
Member

Choose a reason for hiding this comment

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

Object.values(rootMap) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Polyfills take care of Object.values?

Code is changed a bit at those lines though: I had to make sure that the main hierarchy is always the first in the array, so I didn't have use for Object.values anymore.

Which triggers the next question:
What could we do with the sorting of the other hierarchies in the panel? Now it respects the order in which the stories are loaded.

);

SubHeader.defaultProps = {
name: '',
Copy link
Member

Choose a reason for hiding this comment

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

what do you think about changing name to children ? I think it would be nicer for use. And I think it should be required.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed! Initially copied stories_panel/header.js props interface. But I prefer children prop in such situations. So changed it.

{hierarchyContainsStories(storiesHierarchy) ? (
<Stories {...pick(this.props, storyProps)} />
) : null}
{storiesHierarchies.map(
Copy link
Member

Choose a reason for hiding this comment

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

worth extracting it to function already.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

extracted the map it to separate render method.
extracted the sub header to stories_tree/ as tree_header

@havelaer havelaer force-pushed the feature/multiple-hierarchies branch from 0a7ce0a to c82e426 Compare December 9, 2017 16:27
@havelaer
Copy link
Contributor Author

havelaer commented Dec 9, 2017

Looks like some of the stories still have wrong kinds:

Fixed!

Root title is hidden when using search. Is it on purpose?

Nice catch! Fixed!

@Hypnosphi Hypnosphi added this to the v3.4.0 milestone Dec 9, 2017
Copy link
Member

@Hypnosphi Hypnosphi left a comment

Choose a reason for hiding this comment

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

LGTM. Let's merge it right after the upcoming 3.3.0 release

Copy link
Member

@igor-dv igor-dv left a comment

Choose a reason for hiding this comment

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

Very nice tests! + tested locally.

const rootNames = Object.keys(rootMap);
const hierarchies = rootNames.map(rootName => rootMap[rootName]);

// make sure the main root is the first
Copy link
Member

Choose a reason for hiding this comment

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

Please extract this block to function - moveRootToFront / ensureRootIsFirst or something

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Extracted to ensureMainRootIsFirst and used Object.values instead of Object.keys(...).map(...)

@@ -46,24 +46,47 @@ function fillHierarchy(namespaces, hierarchy, story) {
fillHierarchy(namespaces.slice(1), childHierarchy, story);
}

export function createHierarchy(stories) {
const hierarchyRoot = {
export function createHierarchyRoot(name = '') {
Copy link
Member

Choose a reason for hiding this comment

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

👌

@havelaer havelaer force-pushed the feature/multiple-hierarchies branch from 39c0454 to df1694e Compare December 10, 2017 10:38
@ndelangen
Copy link
Member

Good to go if you ask me!

@danielduan
Copy link
Member

I think we're aiming to add this for 3.4?

I added the do not merge label because of the upcoming changes to our workflow. Feel free to merge to master after we get 3.3 out

@Hypnosphi Hypnosphi changed the base branch from release/3.3 to master December 23, 2017 23:57
@Hypnosphi
Copy link
Member

Hypnosphi commented Dec 25, 2017

We have moved some stories to examples/storybook-official. @havelaer Would you mind resolving the conflicts?

@havelaer havelaer force-pushed the feature/multiple-hierarchies branch from 630a9c9 to 05a0699 Compare December 27, 2017 09:56
@Hypnosphi
Copy link
Member

Hypnosphi commented Dec 27, 2017

@shilman after we merge this one, we won't be able to release 3.3 from master anymore. There's probably a sense in merging master into release/3.3 before that

@havelaer
Copy link
Contributor Author

I've rebased the branch on master, keeping the history nice & clean. Fixed tests, added separator config to examples/official-storybook and updated core and cli snapshots.

@ndelangen
Copy link
Member

@havelaer That's fantastic work!

@igor-dv
Copy link
Member

igor-dv commented Jan 3, 2018

@havelaer maybe you can resolve the conflicts and merge?

# Conflicts:
#	examples/official-storybook/config.js
#	lib/cli/test/snapshots/angular-cli/package.json
#	lib/cli/test/snapshots/meteor/package.json
#	lib/cli/test/snapshots/react/package.json
#	lib/cli/test/snapshots/react_native/package.json
#	lib/cli/test/snapshots/react_native_scripts/package.json
#	lib/cli/test/snapshots/react_project/package.json
#	lib/cli/test/snapshots/react_scripts/package.json
#	lib/cli/test/snapshots/sfc_vue/package.json
#	lib/cli/test/snapshots/update_package_organisations/package.json
#	lib/cli/test/snapshots/vue/package.json
#	lib/cli/test/snapshots/webpack_react/package.json
@ndelangen
Copy link
Member

I resolved merge conflicts

@igor-dv igor-dv merged commit ece503a into storybookjs:master Jan 4, 2018
@igor-dv
Copy link
Member

igor-dv commented Jan 4, 2018

👏

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.

6 participants