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

Core: Allow linking to kind/component ID #7648

Merged
merged 10 commits into from
Oct 24, 2019
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