Skip to content

Commit

Permalink
Core: Allow linking to kind/component ID (#7648)
Browse files Browse the repository at this point in the history
Core: Allow linking to kind/component ID
  • Loading branch information
shilman authored Oct 24, 2019
2 parents d57dd04 + 68ee7ce commit ef1d964
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 6 deletions.
16 changes: 16 additions & 0 deletions lib/api/src/modules/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,17 @@ const initStoriesApi = ({
id: toKey(name),
});

// Recursively traverse storiesHash from the initial storyId until finding
// the leaf story.
const findLeafStoryId = (storiesHash: StoriesHash, storyId: string): string => {
if (storiesHash[storyId].isLeaf) {
return storyId;
}

const childStoryId = storiesHash[storyId].children[0];
return findLeafStoryId(storiesHash, childStoryId);
};

const setStories = (input: StoriesRaw) => {
const hash: StoriesHash = {};
const storiesHashOutOfOrder = Object.values(input).reduce((acc, item) => {
Expand Down Expand Up @@ -286,6 +297,11 @@ Did you create a path that uses the separator char accidentally, such as 'Vue <d
} else if (viewMode && firstLeaf) {
navigate(`/${viewMode}/${firstLeaf.id}`);
}
} else if (storiesHash[storyId] && !storiesHash[storyId].isLeaf) {
// When story exists but if it is not the leaf story, it finds the proper
// leaf story from any depth.
const firstLeafStoryId = findLeafStoryId(storiesHash, storyId);
navigate(`/${viewMode}/${firstLeafStoryId}`);
}

store.setState({
Expand Down
130 changes: 124 additions & 6 deletions lib/api/src/tests/stories.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ describe('stories API', () => {
path: 'b-c--1',
id: 'b-c--1',
},
'b-d--1': {
kind: 'b/d',
name: '1',
parameters,
path: 'b-d--1',
id: 'b-d--1',
},
'b-d--2': {
kind: 'b/d',
name: '2',
parameters,
path: 'b-d--2',
id: 'b-d--2',
},
};
describe('setStories', () => {
it('stores basic kinds and stories w/ correct keys', () => {
Expand All @@ -50,7 +64,17 @@ describe('stories API', () => {
const { storiesHash: storedStoriesHash } = store.getState();

// We need exact key ordering, even if in theory JS doens't guarantee it
expect(Object.keys(storedStoriesHash)).toEqual(['a', 'a--1', 'a--2', 'b', 'b-c', 'b-c--1']);
expect(Object.keys(storedStoriesHash)).toEqual([
'a',
'a--1',
'a--2',
'b',
'b-c',
'b-c--1',
'b-d',
'b-d--1',
'b-d--2',
]);
expect(storedStoriesHash.a).toMatchObject({
id: 'a',
children: ['a--1', 'a--2'],
Expand All @@ -76,7 +100,7 @@ describe('stories API', () => {

expect(storedStoriesHash.b).toMatchObject({
id: 'b',
children: ['b-c'],
children: ['b-c', 'b-d'],
isRoot: false,
isComponent: false,
});
Expand All @@ -96,6 +120,30 @@ describe('stories API', () => {
name: '1',
parameters,
});

expect(storedStoriesHash['b-d']).toMatchObject({
id: 'b-d',
parent: 'b',
children: ['b-d--1', 'b-d--2'],
isRoot: false,
isComponent: true,
});

expect(storedStoriesHash['b-d--1']).toMatchObject({
id: 'b-d--1',
parent: 'b-d',
kind: 'b/d',
name: '1',
parameters,
});

expect(storedStoriesHash['b-d--2']).toMatchObject({
id: 'b-d--2',
parent: 'b-d',
kind: 'b/d',
name: '2',
parameters,
});
});

it('handles roots also', () => {
Expand All @@ -116,14 +164,38 @@ describe('stories API', () => {
path: 'b-c--1',
id: 'b-c--1',
},
'b-d--1': {
kind: 'b|d',
name: '1',
parameters,
path: 'b-d--1',
id: 'b-d--1',
},
'b-d--2': {
kind: 'b|d',
name: '2',
parameters,
path: 'b-d--2',
id: 'b-d--2',
},
});
const { storiesHash: storedStoriesHash } = store.getState();

// We need exact key ordering, even if in theory JS doens't guarantee it
expect(Object.keys(storedStoriesHash)).toEqual(['a', 'a--1', 'a--2', 'b', 'b-c', 'b-c--1']);
expect(Object.keys(storedStoriesHash)).toEqual([
'a',
'a--1',
'a--2',
'b',
'b-c',
'b-c--1',
'b-d',
'b-d--1',
'b-d--2',
]);
expect(storedStoriesHash.b).toMatchObject({
id: 'b',
children: ['b-c'],
children: ['b-c', 'b-d'],
isRoot: true,
isComponent: false,
});
Expand All @@ -143,6 +215,22 @@ describe('stories API', () => {
name: '1',
parameters,
});

expect(storedStoriesHash['b-d--1']).toMatchObject({
id: 'b-d--1',
parent: 'b-d',
kind: 'b|d',
name: '1',
parameters,
});

expect(storedStoriesHash['b-d--2']).toMatchObject({
id: 'b-d--2',
parent: 'b-d',
kind: 'b|d',
name: '2',
parameters,
});
});

// Stories can get out of order for a few reasons -- see reproductions on
Expand Down Expand Up @@ -207,6 +295,36 @@ describe('stories API', () => {
expect(navigate).toHaveBeenCalledWith('/story/a--1');
});

it('navigates to the first leaf story if a story exsits but it is not a leaf story(1)', () => {
const navigate = jest.fn();
const store = {
getState: () => ({ viewMode: 'story', storyId: 'b' }),
setState: jest.fn(),
};

const {
api: { setStories },
} = initStories({ store, navigate });

setStories(storiesHash);
expect(navigate).toHaveBeenCalledWith('/story/b-c--1');
});

it('navigates to the first leaf story if a story exsits but it is not a leaf story(2)', () => {
const navigate = jest.fn();
const store = {
getState: () => ({ viewMode: 'story', storyId: 'b-d' }),
setState: jest.fn(),
};

const {
api: { setStories },
} = initStories({ store, navigate });

setStories(storiesHash);
expect(navigate).toHaveBeenCalledWith('/story/b-d--1');
});

it('does not navigate if a existing story was selected', () => {
const navigate = jest.fn();
const store = {
Expand Down Expand Up @@ -295,7 +413,7 @@ describe('stories API', () => {
const {
api: { setStories, jumpToStory },
state,
} = initStories({ store, navigate, storyId: 'b-c--1', viewMode: 'story' });
} = initStories({ store, navigate, storyId: 'b-d--2', viewMode: 'story' });
store.setState(state);
setStories(storiesHash);

Expand Down Expand Up @@ -369,7 +487,7 @@ describe('stories API', () => {
const {
api: { setStories, jumpToComponent },
state,
} = initStories({ store, navigate, storyId: 'b-c--1', viewMode: 'story' });
} = initStories({ store, navigate, storyId: 'b-d--2', viewMode: 'story' });
store.setState(state);
setStories(storiesHash);

Expand Down

0 comments on commit ef1d964

Please sign in to comment.