From c906187a567b44c2ed1a9f19132329425c2b407d Mon Sep 17 00:00:00 2001 From: Chris Bojemski Date: Fri, 21 Feb 2020 16:46:40 -0800 Subject: [PATCH] Fixes a bug wherein going to a URL for a specific tag or operation did not load the section nor scroll to the operation. Checks upon app load if the user is at the homepage. If not, decide if url is for tag or operation, then load into DOM. On componentDidUpdate, will scroll to specific operation if URL specifies it. Also, bumped debounce in search box to 1s because it was terrible to type in. --- src/components/Redoc/Redoc.tsx | 86 +++++++++++++++++++++++++- src/components/SearchBox/SearchBox.tsx | 2 +- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/components/Redoc/Redoc.tsx b/src/components/Redoc/Redoc.tsx index 2ee92915..b32bc958 100644 --- a/src/components/Redoc/Redoc.tsx +++ b/src/components/Redoc/Redoc.tsx @@ -23,6 +23,11 @@ export interface AppState { activeSelection: string | undefined; } +export interface InitializeWithSelection { + tag: IMenuItem | undefined; + operation: IMenuItem | undefined; +} + export class Redoc extends React.Component { static propTypes = { store: PropTypes.instanceOf(AppStore).isRequired, @@ -30,16 +35,95 @@ export class Redoc extends React.Component { state = { activeSelection: undefined }; + HOMEPAGE_URL = "https://admin.instagram.com/admin/api/docs"; + + getTagByName(tagName: string): IMenuItem | undefined { + const menu = this.props.store.menu; + return menu.items.find(item => item.name === tagName); + } + + getTagFromSitePath(sitePath: string): InitializeWithSelection { + const menu = this.props.store.menu + const matched: InitializeWithSelection = { tag: undefined, operation: undefined }; + menu.items.filter(item => item.type === 'tag').forEach(tag => { + tag.items.forEach(operation => { + // @ts-ignore + if (operation.operationId === sitePath.split('/#operation/')[1]) { + matched.tag = operation.parent!; + matched.operation = operation; + } + }) + }); + return matched; + } + + shouldInitializeWithActiveSelection(): Boolean { + if (this.state.activeSelection === undefined && window.location.href === this.HOMEPAGE_URL) { + return false; + }; + return true; + } + + sitePathIsTag(sitePath: string): Boolean { + return sitePath.startsWith('/#tag') && !this.sitePathIsOperation(sitePath); + } + + sitePathIsOperation(sitePath: string): Boolean { + return sitePath.includes('#operation'); + } + + parseSitePath(fullUrl: string): string { + return fullUrl.split(this.HOMEPAGE_URL)[1]; + } + + nonHomepageLocationIsTag(sitePath: string) { + const splitPath = sitePath.split('/'); + const tagIMenuItem: IMenuItem | undefined = this.getTagByName(splitPath[splitPath.length - 1]); + if (tagIMenuItem) { + this.setActiveSelection(tagIMenuItem); + } + } + + nonHomepageLocationIsOperation(sitePath: string) { + const parsed: InitializeWithSelection = this.getTagFromSitePath(sitePath); + if (parsed.tag && parsed.operation) { + this.setActiveSelection(parsed.tag); + } + } + + nonHomepageLocationSetup() { + if (this.shouldInitializeWithActiveSelection()) { + const sitePath = this.parseSitePath(window.location.href); + if (this.sitePathIsTag(sitePath)) { + this.nonHomepageLocationIsTag(sitePath); + } else { + this.nonHomepageLocationIsOperation(sitePath); + } + }; + } + componentDidMount() { this.props.store.onDidMount(); + this.nonHomepageLocationSetup(); + } + + componentDidUpdate() { + if (this.shouldInitializeWithActiveSelection && this.sitePathIsOperation) { + const sitePath = this.parseSitePath(window.location.href); + const tags = this.getTagFromSitePath(sitePath); + this.props.store.menu.activateAndScroll(tags.operation); + } } componentWillUnmount() { this.props.store.dispose(); } - setActiveSelection = (item: IMenuItem) => { + setActiveSelection = (item: IMenuItem, callback?: any) => { if (item && item.type === "tag") { + if (callback) { + this.setState({ activeSelection: item.name }, callback()); + } this.setState({ activeSelection: item.name }); } } diff --git a/src/components/SearchBox/SearchBox.tsx b/src/components/SearchBox/SearchBox.tsx index 2bb34a79..8df1df59 100644 --- a/src/components/SearchBox/SearchBox.tsx +++ b/src/components/SearchBox/SearchBox.tsx @@ -102,7 +102,7 @@ export class SearchBox extends React.PureComponent { this.setResults(res, searchTerm);