@@ -19,6 +19,11 @@ | |||
*/ | |||
import { getJSON } from '../helpers/request'; | |||
export interface Changelog { | |||
description: string; | |||
version: string; | |||
} | |||
export interface Param { | |||
key: string; | |||
defaultValue?: string; | |||
@@ -28,20 +33,22 @@ export interface Param { | |||
deprecatedSince?: string; | |||
exampleValue?: string; | |||
internal: boolean; | |||
maxValuesAllowed?: number; | |||
possibleValues?: string[]; | |||
required: boolean; | |||
since?: string; | |||
} | |||
export interface Action { | |||
key: string; | |||
changelog: Changelog[]; | |||
description: string; | |||
deprecatedSince?: string; | |||
since?: string; | |||
internal: boolean; | |||
post: boolean; | |||
hasResponseExample: boolean; | |||
changelog: Array<{ version: string; description: string }>; | |||
internal: boolean; | |||
params?: Param[]; | |||
post: boolean; | |||
since?: string; | |||
} | |||
export interface Domain { | |||
@@ -50,6 +57,12 @@ export interface Domain { | |||
deprecated: boolean; | |||
internal: boolean; | |||
path: string; | |||
since?: string; | |||
} | |||
export interface Example { | |||
example: string; | |||
format: string; | |||
} | |||
export function fetchWebApi(showInternal: boolean = true): Promise<Array<Domain>> { | |||
@@ -62,6 +75,6 @@ export function fetchWebApi(showInternal: boolean = true): Promise<Array<Domain> | |||
); | |||
} | |||
export function fetchResponseExample(domain: string, action: string): Promise<{ example: string }> { | |||
export function fetchResponseExample(domain: string, action: string): Promise<Example> { | |||
return getJSON('/api/webservices/response_example', { controller: domain, action }); | |||
} |
@@ -1,178 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import { Link } from 'react-router'; | |||
import classNames from 'classnames'; | |||
import { getActionKey } from '../utils'; | |||
import Params from './Params'; | |||
import ResponseExample from './ResponseExample'; | |||
import ActionChangelog from './ActionChangelog'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
import InternalBadge from './InternalBadge'; | |||
import LinkIcon from '../../../components/icons-components/LinkIcon'; | |||
import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin'; | |||
/*:: import type { Action as ActionType, Domain as DomainType } from '../../../api/web-api'; */ | |||
/*:: | |||
type Props = { | |||
action: ActionType, | |||
domain: DomainType, | |||
showDeprecated: boolean, | |||
showInternal: boolean | |||
}; | |||
*/ | |||
/*:: | |||
type State = { | |||
showChangelog: boolean, | |||
showParams: boolean, | |||
showResponse: boolean | |||
}; | |||
*/ | |||
export default class Action extends React.PureComponent { | |||
/*:: props: Props; */ | |||
state /*: State */ = { | |||
showChangelog: false, | |||
showParams: false, | |||
showResponse: false | |||
}; | |||
handleShowParamsClick = (e /*: SyntheticInputEvent */) => { | |||
e.preventDefault(); | |||
this.setState({ | |||
showChangelog: false, | |||
showResponse: false, | |||
showParams: !this.state.showParams | |||
}); | |||
}; | |||
handleShowResponseClick = (e /*: SyntheticInputEvent */) => { | |||
e.preventDefault(); | |||
this.setState({ | |||
showChangelog: false, | |||
showParams: false, | |||
showResponse: !this.state.showResponse | |||
}); | |||
}; | |||
handleChangelogClick = (e /*: SyntheticInputEvent */) => { | |||
e.preventDefault(); | |||
this.setState({ | |||
showChangelog: !this.state.showChangelog, | |||
showParams: false, | |||
showResponse: false | |||
}); | |||
}; | |||
render() { | |||
const { action, domain } = this.props; | |||
const { showChangelog, showParams, showResponse } = this.state; | |||
const verb = action.post ? 'POST' : 'GET'; | |||
const actionKey = getActionKey(domain.path, action.key); | |||
return ( | |||
<div id={actionKey} className="web-api-action"> | |||
<TooltipsContainer> | |||
<header className="web-api-action-header"> | |||
<Link | |||
to={{ pathname: '/web_api/' + actionKey }} | |||
className="spacer-right link-no-underline"> | |||
<LinkIcon /> | |||
</Link> | |||
<h3 className="web-api-action-title"> | |||
{verb} {actionKey} | |||
</h3> | |||
{action.internal && | |||
<span className="spacer-left"> | |||
<InternalBadge /> | |||
</span>} | |||
{action.since && | |||
<span className="spacer-left badge"> | |||
since {action.since} | |||
</span>} | |||
{action.deprecatedSince && | |||
<span className="spacer-left"> | |||
<DeprecatedBadge since={action.deprecatedSince} /> | |||
</span>} | |||
</header> | |||
</TooltipsContainer> | |||
<div | |||
className="web-api-action-description markdown" | |||
dangerouslySetInnerHTML={{ __html: action.description }} | |||
/> | |||
{(action.params || action.hasResponseExample) && | |||
<ul className="web-api-action-actions tabs"> | |||
{action.params && | |||
<li> | |||
<a | |||
className={classNames({ selected: showParams })} | |||
href="#" | |||
onClick={this.handleShowParamsClick}> | |||
Parameters | |||
</a> | |||
</li>} | |||
{action.hasResponseExample && | |||
<li> | |||
<a | |||
className={classNames({ selected: showResponse })} | |||
href="#" | |||
onClick={this.handleShowResponseClick}> | |||
Response Example | |||
</a> | |||
</li>} | |||
{action.changelog.length > 0 && | |||
<li> | |||
<a | |||
className={classNames({ selected: showChangelog })} | |||
href="#" | |||
onClick={this.handleChangelogClick}> | |||
Changelog | |||
</a> | |||
</li>} | |||
</ul>} | |||
{showParams && | |||
action.params && | |||
<Params | |||
params={action.params} | |||
showDeprecated={this.props.showDeprecated} | |||
showInternal={this.props.showInternal} | |||
/>} | |||
{showResponse && | |||
action.hasResponseExample && | |||
<ResponseExample domain={domain} action={action} />} | |||
{showChangelog && <ActionChangelog changelog={action.changelog} />} | |||
</div> | |||
); | |||
} | |||
} |
@@ -0,0 +1,181 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { Link } from 'react-router'; | |||
import * as classNames from 'classnames'; | |||
import { getActionKey } from '../utils'; | |||
import Params from './Params'; | |||
import ResponseExample from './ResponseExample'; | |||
import ActionChangelog from './ActionChangelog'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
import InternalBadge from './InternalBadge'; | |||
import LinkIcon from '../../../components/icons-components/LinkIcon'; | |||
import { Action as ActionType, Domain as DomainType } from '../../../api/web-api'; | |||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
interface Props { | |||
action: ActionType; | |||
domain: DomainType; | |||
showDeprecated: boolean; | |||
showInternal: boolean; | |||
} | |||
interface State { | |||
showChangelog: boolean; | |||
showParams: boolean; | |||
showResponse: boolean; | |||
} | |||
export default class Action extends React.PureComponent<Props, State> { | |||
state: State = { | |||
showChangelog: false, | |||
showParams: false, | |||
showResponse: false | |||
}; | |||
handleShowParamsClick = (e: React.SyntheticEvent<HTMLElement>) => { | |||
e.preventDefault(); | |||
this.setState({ | |||
showChangelog: false, | |||
showResponse: false, | |||
showParams: !this.state.showParams | |||
}); | |||
}; | |||
handleShowResponseClick = (e: React.SyntheticEvent<HTMLElement>) => { | |||
e.preventDefault(); | |||
this.setState({ | |||
showChangelog: false, | |||
showParams: false, | |||
showResponse: !this.state.showResponse | |||
}); | |||
}; | |||
handleChangelogClick = (e: React.SyntheticEvent<HTMLElement>) => { | |||
e.preventDefault(); | |||
this.setState({ | |||
showChangelog: !this.state.showChangelog, | |||
showParams: false, | |||
showResponse: false | |||
}); | |||
}; | |||
renderTabs() { | |||
const { action } = this.props; | |||
const { showChangelog, showParams, showResponse } = this.state; | |||
if (action.params || action.hasResponseExample || action.changelog.length > 0) { | |||
return ( | |||
<ul className="web-api-action-actions tabs"> | |||
{action.params && | |||
<li> | |||
<a | |||
className={classNames({ selected: showParams })} | |||
href="#" | |||
onClick={this.handleShowParamsClick}> | |||
{translate('api_documentation.parameters')} | |||
</a> | |||
</li>} | |||
{action.hasResponseExample && | |||
<li> | |||
<a | |||
className={classNames({ selected: showResponse })} | |||
href="#" | |||
onClick={this.handleShowResponseClick}> | |||
{translate('api_documentation.response_example')} | |||
</a> | |||
</li>} | |||
{action.changelog.length > 0 && | |||
<li> | |||
<a | |||
className={classNames({ selected: showChangelog })} | |||
href="#" | |||
onClick={this.handleChangelogClick}> | |||
{translate('api_documentation.changelog')} | |||
</a> | |||
</li>} | |||
</ul> | |||
); | |||
} | |||
return <hr />; | |||
} | |||
render() { | |||
const { action, domain } = this.props; | |||
const { showChangelog, showParams, showResponse } = this.state; | |||
const verb = action.post ? 'POST' : 'GET'; | |||
const actionKey = getActionKey(domain.path, action.key); | |||
return ( | |||
<div id={actionKey} className="web-api-action"> | |||
<header className="web-api-action-header"> | |||
<Link | |||
to={{ pathname: '/web_api/' + actionKey }} | |||
className="spacer-right link-no-underline"> | |||
<LinkIcon /> | |||
</Link> | |||
<h3 className="web-api-action-title"> | |||
{verb} {actionKey} | |||
</h3> | |||
{action.internal && | |||
<span className="spacer-left"> | |||
<InternalBadge /> | |||
</span>} | |||
{action.since && | |||
<span className="spacer-left badge"> | |||
{translateWithParameters('since_x', action.since)} | |||
</span>} | |||
{action.deprecatedSince && | |||
<span className="spacer-left"> | |||
<DeprecatedBadge since={action.deprecatedSince} /> | |||
</span>} | |||
</header> | |||
<div | |||
className="web-api-action-description markdown" | |||
dangerouslySetInnerHTML={{ __html: action.description }} | |||
/> | |||
{this.renderTabs()} | |||
{showParams && | |||
action.params && | |||
<Params | |||
params={action.params} | |||
showDeprecated={this.props.showDeprecated} | |||
showInternal={this.props.showInternal} | |||
/>} | |||
{showResponse && | |||
action.hasResponseExample && | |||
<ResponseExample domain={domain} action={action} />} | |||
{showChangelog && <ActionChangelog changelog={action.changelog} />} | |||
</div> | |||
); | |||
} | |||
} |
@@ -17,33 +17,24 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import * as React from 'react'; | |||
import { Changelog } from '../../../api/web-api'; | |||
/*:: | |||
type Props = { | |||
changelog: Array<{ | |||
description: string, | |||
version: string | |||
}> | |||
}; | |||
*/ | |||
export default class ActionChangelog extends React.PureComponent { | |||
/*:: props: Props; */ | |||
interface Props { | |||
changelog: Changelog[]; | |||
} | |||
render() { | |||
return ( | |||
<ul className="big-spacer-top"> | |||
{this.props.changelog.map((item, index) => | |||
<li key={index} className="spacer-top"> | |||
<span className="spacer-right badge"> | |||
{item.version} | |||
</span> | |||
{item.description} | |||
</li> | |||
)} | |||
</ul> | |||
); | |||
} | |||
export default function ActionChangelog({ changelog }: Props) { | |||
return ( | |||
<ul className="big-spacer-top"> | |||
{changelog.map((item, index) => | |||
<li key={index} className="spacer-top"> | |||
<span className="spacer-right badge"> | |||
{item.version} | |||
</span> | |||
{item.description} | |||
</li> | |||
)} | |||
</ul> | |||
); | |||
} |
@@ -0,0 +1,35 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import Tooltip from '../../../components/controls/Tooltip'; | |||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
export default function DeprecatedBadge({ since }: { since?: string }) { | |||
const label = since | |||
? translateWithParameters('api_documentation.depracated_since_x', since) | |||
: translate('api_documentation.depracated'); | |||
return ( | |||
<Tooltip overlay={translate('api_documentation.deprecation_tooltip')}> | |||
<span className="badge badge-warning"> | |||
{label} | |||
</span> | |||
</Tooltip> | |||
); | |||
} |
@@ -1,84 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import Action from './Action'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
import InternalBadge from './InternalBadge'; | |||
import { getActionKey, actionsFilter } from '../utils'; | |||
/*:: import type { Domain as DomainType } from '../../../api/web-api'; */ | |||
/*:: | |||
type Props = { | |||
domain: DomainType, | |||
showDeprecated: boolean, | |||
showInternal: boolean, | |||
searchQuery: string | |||
}; | |||
*/ | |||
export default class Domain extends React.PureComponent { | |||
/*:: props: Props; */ | |||
render() { | |||
const { domain, showInternal, showDeprecated, searchQuery } = this.props; | |||
const filteredActions = domain.actions.filter(action => | |||
actionsFilter(showDeprecated, showInternal, searchQuery, domain, action) | |||
); | |||
return ( | |||
<div className="web-api-domain"> | |||
<header className="web-api-domain-header"> | |||
<h2 className="web-api-domain-title"> | |||
{domain.path} | |||
</h2> | |||
{domain.deprecated && | |||
<span className="spacer-left"> | |||
<DeprecatedBadge /> | |||
</span>} | |||
{domain.internal && | |||
<span className="spacer-left"> | |||
<InternalBadge /> | |||
</span>} | |||
</header> | |||
{domain.description && | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={{ __html: domain.description }} | |||
/>} | |||
<div className="web-api-domain-actions"> | |||
{filteredActions.map(action => | |||
<Action | |||
key={getActionKey(domain.path, action.key)} | |||
action={action} | |||
domain={domain} | |||
showDeprecated={showDeprecated} | |||
showInternal={showInternal} | |||
/> | |||
)} | |||
</div> | |||
</div> | |||
); | |||
} | |||
} |
@@ -0,0 +1,76 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import Action from './Action'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
import InternalBadge from './InternalBadge'; | |||
import { getActionKey, actionsFilter } from '../utils'; | |||
import { Domain as DomainType } from '../../../api/web-api'; | |||
interface Props { | |||
domain: DomainType; | |||
showDeprecated: boolean; | |||
showInternal: boolean; | |||
searchQuery: string; | |||
} | |||
export default function Domain({ domain, showInternal, showDeprecated, searchQuery }: Props) { | |||
const filteredActions = domain.actions.filter(action => | |||
actionsFilter(showDeprecated, showInternal, searchQuery, domain, action) | |||
); | |||
return ( | |||
<div className="web-api-domain"> | |||
<header className="web-api-domain-header"> | |||
<h2 className="web-api-domain-title"> | |||
{domain.path} | |||
</h2> | |||
{domain.deprecated && | |||
<span className="spacer-left"> | |||
<DeprecatedBadge /> | |||
</span>} | |||
{domain.internal && | |||
<span className="spacer-left"> | |||
<InternalBadge /> | |||
</span>} | |||
</header> | |||
{domain.description && | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={{ __html: domain.description }} | |||
/>} | |||
<div className="web-api-domain-actions"> | |||
{filteredActions.map(action => | |||
<Action | |||
key={getActionKey(domain.path, action.key)} | |||
action={action} | |||
domain={domain} | |||
showDeprecated={showDeprecated} | |||
showInternal={showInternal} | |||
/> | |||
)} | |||
</div> | |||
</div> | |||
); | |||
} |
@@ -17,16 +17,16 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import React from 'react'; | |||
import * as React from 'react'; | |||
import Tooltip from '../../../components/controls/Tooltip'; | |||
import { translate } from '../../../helpers/l10n'; | |||
export default function InternalBadge() { | |||
return ( | |||
<span | |||
className="badge badge-danger" | |||
title={translate('api_documentation.internal_tooltip')} | |||
data-toggle="tooltip"> | |||
internal | |||
</span> | |||
<Tooltip overlay={translate('api_documentation.internal_tooltip')}> | |||
<span className="badge badge-danger"> | |||
{translate('internal')} | |||
</span> | |||
</Tooltip> | |||
); | |||
} |
@@ -1,82 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import { Link } from 'react-router'; | |||
import classNames from 'classnames'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
import InternalBadge from './InternalBadge'; | |||
import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin'; | |||
import { isDomainPathActive, actionsFilter } from '../utils'; | |||
/*:: import type { Domain as DomainType } from '../../../api/web-api'; */ | |||
/*:: | |||
type Props = { | |||
domains: Array<DomainType>, | |||
showDeprecated: boolean, | |||
showInternal: boolean, | |||
searchQuery: string, | |||
splat: string | |||
}; | |||
*/ | |||
export default class Menu extends React.PureComponent { | |||
/*:: props: Props; */ | |||
render() { | |||
const { domains, showInternal, showDeprecated, searchQuery, splat } = this.props; | |||
const filteredDomains = (domains || []) | |||
.map(domain => { | |||
const filteredActions = domain.actions.filter(action => | |||
actionsFilter(showDeprecated, showInternal, searchQuery, domain, action) | |||
); | |||
return { ...domain, filteredActions }; | |||
}) | |||
.filter(domain => domain.filteredActions.length); | |||
return ( | |||
<div className="api-documentation-results panel"> | |||
<TooltipsContainer> | |||
<div className="list-group"> | |||
{filteredDomains.map(domain => | |||
<Link | |||
key={domain.path} | |||
className={classNames('list-group-item', { | |||
active: isDomainPathActive(domain.path, splat) | |||
})} | |||
to={'/web_api/' + domain.path}> | |||
<h3 className="list-group-item-heading"> | |||
{domain.path} | |||
{domain.deprecated && <DeprecatedBadge />} | |||
{domain.internal && <InternalBadge />} | |||
</h3> | |||
{domain.description && | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={{ __html: domain.description }} | |||
/>} | |||
</Link> | |||
)} | |||
</div> | |||
</TooltipsContainer> | |||
</div> | |||
); | |||
} | |||
} |
@@ -0,0 +1,72 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { Link } from 'react-router'; | |||
import * as classNames from 'classnames'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
import InternalBadge from './InternalBadge'; | |||
import { isDomainPathActive, actionsFilter } from '../utils'; | |||
import { Domain } from '../../../api/web-api'; | |||
interface Props { | |||
domains: Domain[]; | |||
showDeprecated: boolean; | |||
showInternal: boolean; | |||
searchQuery: string; | |||
splat: string; | |||
} | |||
export default function Menu(props: Props) { | |||
const { domains, showInternal, showDeprecated, searchQuery, splat } = props; | |||
const filteredDomains = (domains || []) | |||
.map(domain => { | |||
const filteredActions = domain.actions.filter(action => | |||
actionsFilter(showDeprecated, showInternal, searchQuery, domain, action) | |||
); | |||
return { ...domain, filteredActions }; | |||
}) | |||
.filter(domain => domain.filteredActions.length); | |||
return ( | |||
<div className="api-documentation-results panel"> | |||
<div className="list-group"> | |||
{filteredDomains.map(domain => | |||
<Link | |||
key={domain.path} | |||
className={classNames('list-group-item', { | |||
active: isDomainPathActive(domain.path, splat) | |||
})} | |||
to={'/web_api/' + domain.path}> | |||
<h3 className="list-group-item-heading"> | |||
{domain.path} | |||
{domain.deprecated && <DeprecatedBadge />} | |||
{domain.internal && <InternalBadge />} | |||
</h3> | |||
{domain.description && | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={{ __html: domain.description }} | |||
/>} | |||
</Link> | |||
)} | |||
</div> | |||
</div> | |||
); | |||
} |
@@ -1,138 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import InternalBadge from './InternalBadge'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
/*:: import type { Param } from '../../../api/web-api'; */ | |||
export default class Params extends React.PureComponent { | |||
/*:: props: { | |||
showDeprecated: boolean, | |||
showInternal: boolean, | |||
params: Array<Param> | |||
}; | |||
*/ | |||
render() { | |||
const { showDeprecated, showInternal, params } = this.props; | |||
const displayedParameters = params | |||
.filter(p => showDeprecated || !p.deprecatedSince) | |||
.filter(p => showInternal || !p.internal); | |||
return ( | |||
<div className="web-api-params"> | |||
<table> | |||
<tbody> | |||
{displayedParameters.map(param => | |||
<tr key={param.key}> | |||
<td className="markdown" style={{ width: 180 }}> | |||
<code> | |||
{param.key} | |||
</code> | |||
{param.internal && | |||
<div className="little-spacer-top"> | |||
<InternalBadge /> | |||
</div>} | |||
{param.deprecatedSince && | |||
<div className="little-spacer-top"> | |||
<DeprecatedBadge since={param.deprecatedSince} /> | |||
</div>} | |||
{showDeprecated && | |||
param.deprecatedKey && | |||
<div className="little-spacer-top"> | |||
<code> | |||
{param.deprecatedKey} | |||
</code> | |||
</div>} | |||
{showDeprecated && | |||
param.deprecatedKey && | |||
param.deprecatedKeySince && | |||
<div className="little-spacer-top"> | |||
<DeprecatedBadge since={param.deprecatedKeySince} /> | |||
</div>} | |||
<div className="note little-spacer-top"> | |||
{param.required ? 'required' : 'optional'} | |||
</div> | |||
{param.since && | |||
<div className="note little-spacer-top"> | |||
since {param.since} | |||
</div>} | |||
</td> | |||
<td> | |||
<div | |||
className="markdown" | |||
dangerouslySetInnerHTML={{ __html: param.description }} | |||
/> | |||
</td> | |||
<td style={{ width: 250 }}> | |||
{param.possibleValues && | |||
<div> | |||
<h4>Possible values</h4> | |||
<ul className="list-styled"> | |||
{param.possibleValues.map(value => | |||
<li key={value} className="little-spacer-top"> | |||
<code> | |||
{value} | |||
</code> | |||
</li> | |||
)} | |||
</ul> | |||
</div>} | |||
{param.defaultValue && | |||
<div className="little-spacer-top"> | |||
<h4>Default value</h4> | |||
<code> | |||
{param.defaultValue} | |||
</code> | |||
</div>} | |||
{param.exampleValue && | |||
<div className="little-spacer-top"> | |||
<h4>Example value</h4> | |||
<code> | |||
{param.exampleValue} | |||
</code> | |||
</div>} | |||
{param.maxValuesAllowed != null && | |||
<div className="little-spacer-top"> | |||
<h4>Maximum allowed values</h4> | |||
<code> | |||
{param.maxValuesAllowed} | |||
</code> | |||
</div>} | |||
</td> | |||
</tr> | |||
)} | |||
</tbody> | |||
</table> | |||
</div> | |||
); | |||
} | |||
} |
@@ -0,0 +1,139 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import InternalBadge from './InternalBadge'; | |||
import DeprecatedBadge from './DeprecatedBadge'; | |||
import { Param } from '../../../api/web-api'; | |||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
interface Props { | |||
params: Param[]; | |||
showDeprecated: boolean; | |||
showInternal: boolean; | |||
} | |||
export default function Params({ params, showDeprecated, showInternal }: Props) { | |||
const displayedParameters = params | |||
.filter(p => showDeprecated || !p.deprecatedSince) | |||
.filter(p => showInternal || !p.internal); | |||
return ( | |||
<div className="web-api-params"> | |||
<table> | |||
<tbody> | |||
{displayedParameters.map(param => | |||
<tr key={param.key}> | |||
<td className="markdown" style={{ width: 180 }}> | |||
<code> | |||
{param.key} | |||
</code> | |||
{param.internal && | |||
<div className="little-spacer-top"> | |||
<InternalBadge /> | |||
</div>} | |||
{param.deprecatedSince && | |||
<div className="little-spacer-top"> | |||
<DeprecatedBadge since={param.deprecatedSince} /> | |||
</div>} | |||
{showDeprecated && | |||
param.deprecatedKey && | |||
<div className="little-spacer-top"> | |||
<code> | |||
{param.deprecatedKey} | |||
</code> | |||
</div>} | |||
{showDeprecated && | |||
param.deprecatedKey && | |||
param.deprecatedKeySince && | |||
<div className="little-spacer-top"> | |||
<DeprecatedBadge since={param.deprecatedKeySince} /> | |||
</div>} | |||
<div className="note little-spacer-top"> | |||
{param.required ? 'required' : 'optional'} | |||
</div> | |||
{param.since && | |||
<div className="note little-spacer-top"> | |||
{translateWithParameters('since_x', param.since)} | |||
</div>} | |||
</td> | |||
<td> | |||
<div className="markdown" dangerouslySetInnerHTML={{ __html: param.description }} /> | |||
</td> | |||
<td style={{ width: 250 }}> | |||
{param.possibleValues && | |||
<div> | |||
<h4> | |||
{translate('api_documentation.possible_values')} | |||
</h4> | |||
<ul className="list-styled"> | |||
{param.possibleValues.map(value => | |||
<li key={value} className="little-spacer-top"> | |||
<code> | |||
{value} | |||
</code> | |||
</li> | |||
)} | |||
</ul> | |||
</div>} | |||
{param.defaultValue && | |||
<div className="little-spacer-top"> | |||
<h4> | |||
{translate('api_documentation.default_values')} | |||
</h4> | |||
<code> | |||
{param.defaultValue} | |||
</code> | |||
</div>} | |||
{param.exampleValue && | |||
<div className="little-spacer-top"> | |||
<h4> | |||
{translate('api_documentation.example_values')} | |||
</h4> | |||
<code> | |||
{param.exampleValue} | |||
</code> | |||
</div>} | |||
{param.maxValuesAllowed != null && | |||
<div className="little-spacer-top"> | |||
<h4> | |||
{translate('api_documentation.max_values')} | |||
</h4> | |||
<code> | |||
{param.maxValuesAllowed} | |||
</code> | |||
</div>} | |||
</td> | |||
</tr> | |||
)} | |||
</tbody> | |||
</table> | |||
</div> | |||
); | |||
} |
@@ -17,18 +17,33 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import React from 'react'; | |||
import { fetchResponseExample as fetchResponseExampleApi } from '../../../api/web-api'; | |||
import * as React from 'react'; | |||
import { | |||
Action, | |||
Domain, | |||
Example, | |||
fetchResponseExample as fetchResponseExampleApi | |||
} from '../../../api/web-api'; | |||
export default class ResponseExample extends React.PureComponent { | |||
state = {}; | |||
interface Props { | |||
action: Action; | |||
domain: Domain; | |||
} | |||
interface State { | |||
responseExample?: Example; | |||
} | |||
export default class ResponseExample extends React.PureComponent<Props, State> { | |||
mounted: boolean; | |||
state: State = {}; | |||
componentDidMount() { | |||
this.mounted = true; | |||
this.fetchResponseExample(); | |||
} | |||
componentDidUpdate(nextProps) { | |||
componentDidUpdate(nextProps: Props) { | |||
if (nextProps.action !== this.props.action) { | |||
this.fetchResponseExample(); | |||
} |
@@ -17,51 +17,38 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import * as React from 'react'; | |||
import { debounce } from 'lodash'; | |||
import Checkbox from '../../../components/controls/Checkbox'; | |||
import HelpIcon from '../../../components/icons-components/HelpIcon'; | |||
import Tooltip from '../../../components/controls/Tooltip'; | |||
import { translate } from '../../../helpers/l10n'; | |||
/*:: | |||
type Props = { | |||
showDeprecated: boolean, | |||
showInternal: boolean, | |||
onSearch: string => void, | |||
onToggleInternal: () => void, | |||
onToggleDeprecated: () => void | |||
}; | |||
*/ | |||
/*:: | |||
type State = { | |||
query: string | |||
}; | |||
*/ | |||
interface Props { | |||
showDeprecated: boolean; | |||
showInternal: boolean; | |||
onSearch: (search: string) => void; | |||
onToggleInternal: () => void; | |||
onToggleDeprecated: () => void; | |||
} | |||
export default class Search extends React.PureComponent { | |||
/*:: actuallySearch: () => void; */ | |||
/*:: props: Props; */ | |||
/*:: state: State; */ | |||
interface State { | |||
query: string; | |||
} | |||
constructor(props /*: Props */) { | |||
export default class Search extends React.PureComponent<Props, State> { | |||
constructor(props: Props) { | |||
super(props); | |||
this.state = { query: '' }; | |||
this.actuallySearch = debounce(this.actuallySearch, 250); | |||
} | |||
handleSearch = (e /*: SyntheticInputEvent */) => { | |||
const { value } = e.target; | |||
this.setState({ query: value }); | |||
handleSearch = (e: React.SyntheticEvent<HTMLInputElement>) => { | |||
this.setState({ query: e.currentTarget.value }); | |||
this.actuallySearch(); | |||
}; | |||
actuallySearch = () => { | |||
const { onSearch } = this.props; | |||
onSearch(this.state.query); | |||
}; | |||
actuallySearch = () => this.props.onSearch(this.state.query); | |||
render() { | |||
const { showInternal, showDeprecated, onToggleInternal, onToggleDeprecated } = this.props; | |||
@@ -82,7 +69,7 @@ export default class Search extends React.PureComponent { | |||
<div className="big-spacer-top"> | |||
<Checkbox checked={showInternal} onCheck={onToggleInternal}> | |||
<span className="little-spacer-left"> | |||
{translate('api_documentation.show_deprecated')} | |||
{translate('api_documentation.show_internal')} | |||
</span> | |||
</Checkbox> | |||
<Tooltip overlay={translate('api_documentation.internal_tooltip')} placement="right"> | |||
@@ -95,7 +82,7 @@ export default class Search extends React.PureComponent { | |||
<div className="spacer-top"> | |||
<Checkbox checked={showDeprecated} onCheck={onToggleDeprecated}> | |||
<span className="little-spacer-left"> | |||
{translate('api_documentation.show_internal')} | |||
{translate('api_documentation.show_deprecated')} | |||
</span> | |||
</Checkbox> | |||
<Tooltip overlay={translate('api_documentation.deprecation_tooltip')} placement="right"> |
@@ -17,39 +17,43 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import PropTypes from 'prop-types'; | |||
import * as React from 'react'; | |||
import * as PropTypes from 'prop-types'; | |||
import Helmet from 'react-helmet'; | |||
import { Link } from 'react-router'; | |||
import { fetchWebApi } from '../../../api/web-api'; | |||
import { Domain as DomainType, fetchWebApi } from '../../../api/web-api'; | |||
import Menu from './Menu'; | |||
import Search from './Search'; | |||
import Domain from './Domain'; | |||
import { getActionKey, isDomainPathActive } from '../utils'; | |||
import { scrollToElement } from '../../../helpers/scrolling'; | |||
import { translate } from '../../../helpers/l10n'; | |||
/*:: import type { Domain as DomainType } from '../../../api/web-api'; */ | |||
import '../styles/web-api.css'; | |||
/*:: | |||
type State = { | |||
domains: Array<DomainType>, | |||
searchQuery: string, | |||
showDeprecated: boolean, | |||
showInternal: boolean | |||
}; | |||
*/ | |||
export default class WebApiApp extends React.PureComponent { | |||
/*:: mounted: boolean; */ | |||
/*:: scrollToAction: () => void; */ | |||
state /*: State */ = { | |||
interface Props { | |||
params: { splat?: string }; | |||
} | |||
interface State { | |||
domains: DomainType[]; | |||
searchQuery: string; | |||
showDeprecated: boolean; | |||
showInternal: boolean; | |||
} | |||
export default class WebApiApp extends React.PureComponent<Props, State> { | |||
mounted: boolean; | |||
state: State = { | |||
domains: [], | |||
searchQuery: '', | |||
showDeprecated: false, | |||
showInternal: false | |||
}; | |||
static contextTypes = { | |||
router: PropTypes.object.isRequired | |||
}; | |||
componentDidMount() { | |||
this.mounted = true; | |||
this.fetchList(); | |||
@@ -72,7 +76,7 @@ export default class WebApiApp extends React.PureComponent { | |||
} | |||
} | |||
fetchList(cb /*: void | () => void */) { | |||
fetchList(cb?: () => void) { | |||
fetchWebApi().then(domains => { | |||
if (this.mounted) { | |||
this.setState({ domains }, cb); | |||
@@ -82,21 +86,13 @@ export default class WebApiApp extends React.PureComponent { | |||
scrollToAction = () => { | |||
const splat = this.props.params.splat || ''; | |||
this.scrollToElement(splat); | |||
}; | |||
scrollToElement(id /*: string */) { | |||
const element = document.getElementById(id); | |||
if (element) { | |||
const rect = element.getBoundingClientRect(); | |||
const top = rect.top + window.pageYOffset - 20; | |||
window.scrollTo(0, top); | |||
const action = document.getElementById(splat); | |||
if (action) { | |||
scrollToElement(action, { topOffset: 20, bottomOffset: 20 }); | |||
} else { | |||
window.scrollTo(0, 0); | |||
} | |||
} | |||
}; | |||
toggleInternalInitially() { | |||
const splat = this.props.params.splat || ''; | |||
@@ -117,9 +113,7 @@ export default class WebApiApp extends React.PureComponent { | |||
} | |||
} | |||
handleSearch = (searchQuery /*: string */) => { | |||
this.setState({ searchQuery }); | |||
}; | |||
handleSearch = (searchQuery: string) => this.setState({ searchQuery }); | |||
handleToggleInternal = () => { | |||
const splat = this.props.params.splat || ''; | |||
@@ -135,9 +129,8 @@ export default class WebApiApp extends React.PureComponent { | |||
this.setState({ showInternal }); | |||
}; | |||
handleToggleDeprecated = () => { | |||
handleToggleDeprecated = () => | |||
this.setState(state => ({ showDeprecated: !state.showDeprecated })); | |||
}; | |||
render() { | |||
const splat = this.props.params.splat || ''; | |||
@@ -196,7 +189,3 @@ export default class WebApiApp extends React.PureComponent { | |||
); | |||
} | |||
} | |||
WebApiApp.contextTypes = { | |||
router: PropTypes.object.isRequired | |||
}; |
@@ -0,0 +1,75 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import Action from '../Action'; | |||
const ACTION = { | |||
key: 'foo', | |||
changelog: [{ description: 'Changelog desc', version: '5.0' }], | |||
description: 'Foo Desc', | |||
hasResponseExample: true, | |||
internal: false, | |||
params: [ | |||
{ | |||
key: 'param', | |||
description: 'Param desc', | |||
internal: true, | |||
required: true | |||
} | |||
], | |||
post: false | |||
}; | |||
const DOMAIN = { | |||
actions: [ACTION], | |||
path: 'foo', | |||
description: 'API Foo', | |||
deprecated: false, | |||
internal: false | |||
}; | |||
const PROPS = { | |||
action: ACTION, | |||
domain: DOMAIN, | |||
showDeprecated: false, | |||
showInternal: false | |||
}; | |||
it('should render correctly', () => { | |||
expect(shallow(<Action {...PROPS} />)).toMatchSnapshot(); | |||
}); | |||
it('should display the params', () => { | |||
const wrapper = shallow(<Action {...PROPS} />); | |||
wrapper.setState({ showParams: true }); | |||
expect(wrapper.find('Params')).toMatchSnapshot(); | |||
}); | |||
it('should display the response example', () => { | |||
const wrapper = shallow(<Action {...PROPS} />); | |||
wrapper.setState({ showResponse: true }); | |||
expect(wrapper.find('ResponseExample')).toMatchSnapshot(); | |||
}); | |||
it('should display the changelog', () => { | |||
const wrapper = shallow(<Action {...PROPS} />); | |||
wrapper.setState({ showChangelog: true }); | |||
expect(wrapper.find('ActionChangelog')).toMatchSnapshot(); | |||
}); |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import React from 'react'; | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import ActionChangelog from '../ActionChangelog'; | |||
@@ -1,64 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import Domain from '../Domain'; | |||
it('should render deprecated actions', () => { | |||
const actions = [{ key: 'foo', deprecatedSince: '5.0' }]; | |||
const domain = { actions, path: 'api' }; | |||
expect( | |||
shallow(<Domain domain={domain} searchQuery="" showDeprecated={true} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should not render deprecated actions', () => { | |||
const actions = [{ key: 'foo', deprecatedSince: '5.0' }]; | |||
const domain = { actions, path: 'api' }; | |||
expect( | |||
shallow(<Domain domain={domain} searchQuery="" showDeprecated={false} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should render internal actions', () => { | |||
const actions = [{ key: 'foo', internal: true }]; | |||
const domain = { actions, path: 'api' }; | |||
expect(shallow(<Domain domain={domain} searchQuery="" showInternal={true} />)).toMatchSnapshot(); | |||
}); | |||
it('should not render internal actions', () => { | |||
const actions = [{ key: 'foo', internal: true }]; | |||
const domain = { actions, path: 'api' }; | |||
expect(shallow(<Domain domain={domain} searchQuery="" showInternal={false} />)).toMatchSnapshot(); | |||
}); | |||
it('should render only actions matching the query', () => { | |||
const actions = [{ key: 'foo' }, { key: 'bar' }]; | |||
const domain = { actions, path: 'api' }; | |||
expect(shallow(<Domain domain={domain} searchQuery="Foo" />)).toMatchSnapshot(); | |||
}); | |||
it('should also render actions with a description matching the query', () => { | |||
const actions = [{ key: 'foo', description: 'foobar' }, { key: 'bar' }, { key: 'baz' }]; | |||
const domain = { actions, path: 'api' }; | |||
expect( | |||
shallow(<Domain domain={domain} searchQuery="bar" showDeprecated={false} />) | |||
).toMatchSnapshot(); | |||
}); |
@@ -0,0 +1,96 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import Domain from '../Domain'; | |||
const ACTION = { | |||
key: 'foo', | |||
changelog: [], | |||
description: 'Foo Desc', | |||
hasResponseExample: false, | |||
internal: false, | |||
post: false | |||
}; | |||
const DOMAIN = { | |||
actions: [ACTION], | |||
path: 'api', | |||
description: 'API Desc', | |||
deprecated: false, | |||
internal: false | |||
}; | |||
const DEFAULT_PROPS = { | |||
domain: DOMAIN, | |||
showDeprecated: false, | |||
showInternal: false, | |||
searchQuery: '' | |||
}; | |||
it('should render deprecated actions', () => { | |||
const action = { ...ACTION, deprecatedSince: '5.0' }; | |||
const domain = { ...DOMAIN, actions: [action] }; | |||
expect( | |||
shallow(<Domain {...DEFAULT_PROPS} domain={domain} showDeprecated={true} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should not render deprecated actions', () => { | |||
const action = { ...ACTION, deprecatedSince: '5.0' }; | |||
const domain = { ...DOMAIN, actions: [action] }; | |||
expect( | |||
shallow(<Domain {...DEFAULT_PROPS} domain={domain} showDeprecated={false} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should render internal actions', () => { | |||
const action = { ...ACTION, internal: true }; | |||
const domain = { ...DOMAIN, actions: [action] }; | |||
expect( | |||
shallow(<Domain {...DEFAULT_PROPS} domain={domain} showInternal={true} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should not render internal actions', () => { | |||
const action = { ...ACTION, internal: true }; | |||
const domain = { ...DOMAIN, actions: [action] }; | |||
expect( | |||
shallow(<Domain {...DEFAULT_PROPS} domain={domain} showInternal={false} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should render only actions matching the query', () => { | |||
const actions = [ACTION, { ...ACTION, key: 'bar', description: 'Bar desc' }]; | |||
const domain = { ...DOMAIN, actions: actions }; | |||
expect( | |||
shallow(<Domain {...DEFAULT_PROPS} domain={domain} searchQuery="Foo" />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should also render actions with a description matching the query', () => { | |||
const actions = [ | |||
ACTION, | |||
{ ...ACTION, key: 'bar', description: 'Bar desc' }, | |||
{ ...ACTION, key: 'baz', description: 'foobar' } | |||
]; | |||
const domain = { ...DOMAIN, actions: actions }; | |||
expect( | |||
shallow(<Domain {...DEFAULT_PROPS} domain={domain} searchQuery="Foo" />) | |||
).toMatchSnapshot(); | |||
}); |
@@ -0,0 +1,104 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import Menu from '../Menu'; | |||
const ACTION = { | |||
key: 'foo', | |||
changelog: [], | |||
description: 'Foo Desc', | |||
hasResponseExample: false, | |||
internal: false, | |||
post: false | |||
}; | |||
const DOMAIN1 = { | |||
actions: [ACTION], | |||
path: 'foo', | |||
description: 'API Foo', | |||
deprecated: false, | |||
internal: false | |||
}; | |||
const DOMAIN2 = { | |||
actions: [ACTION], | |||
path: 'bar', | |||
description: 'API Bar', | |||
deprecated: false, | |||
internal: false | |||
}; | |||
const PROPS = { | |||
domains: [DOMAIN1, DOMAIN2], | |||
showDeprecated: false, | |||
showInternal: false, | |||
searchQuery: '', | |||
splat: '' | |||
}; | |||
it('should render deprecated domains', () => { | |||
const domain = { | |||
...DOMAIN2, | |||
deprecatedSince: '5.0', | |||
actions: [{ ...ACTION, deprecatedSince: '5.0' }] | |||
}; | |||
const domains = [DOMAIN1, domain]; | |||
expect(shallow(<Menu {...PROPS} domains={domains} showDeprecated={true} />)).toMatchSnapshot(); | |||
}); | |||
it('should not render deprecated domains', () => { | |||
const domain = { | |||
...DOMAIN2, | |||
deprecatedSince: '5.0', | |||
actions: [{ ...ACTION, deprecatedSince: '5.0' }] | |||
}; | |||
const domains = [DOMAIN1, domain]; | |||
expect(shallow(<Menu {...PROPS} domains={domains} showDeprecated={false} />)).toMatchSnapshot(); | |||
}); | |||
it('should render internal domains', () => { | |||
const domain = { ...DOMAIN2, internal: true, actions: [{ ...ACTION, internal: true }] }; | |||
const domains = [DOMAIN1, domain]; | |||
expect(shallow(<Menu {...PROPS} domains={domains} showInternal={true} />)).toMatchSnapshot(); | |||
}); | |||
it('should not render internal domains', () => { | |||
const domain = { ...DOMAIN2, internal: true, actions: [{ ...ACTION, internal: true }] }; | |||
const domains = [DOMAIN1, domain]; | |||
expect(shallow(<Menu {...PROPS} domains={domains} showInternal={false} />)).toMatchSnapshot(); | |||
}); | |||
it('should render only domains with an action matching the query', () => { | |||
const domain = { | |||
...DOMAIN2, | |||
actions: [{ ...ACTION, key: 'bar', path: 'bar', description: 'Bar Desc' }] | |||
}; | |||
const domains = [DOMAIN1, domain]; | |||
expect(shallow(<Menu {...PROPS} domains={domains} searchQuery="Foo" />)).toMatchSnapshot(); | |||
}); | |||
it('should also render domains with an actions description matching the query', () => { | |||
const domain = { | |||
...DOMAIN1, | |||
path: 'baz', | |||
description: 'API Baz', | |||
actions: [{ ...ACTION, key: 'baz', path: 'baz', description: 'barbaz' }] | |||
}; | |||
const domains = [DOMAIN1, DOMAIN2, domain]; | |||
expect(shallow(<Menu {...PROPS} domains={domains} searchQuery="Bar" />)).toMatchSnapshot(); | |||
}); |
@@ -17,37 +17,40 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import React from 'react'; | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import Params from '../Params'; | |||
it('should render deprecated parameters', () => { | |||
const DEFAULT_PARAM = { | |||
key: 'foo', | |||
description: 'Foo desc', | |||
internal: false, | |||
required: false | |||
}; | |||
it('should render deprecated and internal parameters', () => { | |||
const params = [ | |||
{ | |||
key: 'foo', | |||
deprecatedSince: '5.0' | |||
} | |||
{ ...DEFAULT_PARAM, deprecatedSince: '5.0' }, | |||
{ ...DEFAULT_PARAM, deprecatedSince: '5.0', internal: true } | |||
]; | |||
expect(shallow(<Params params={params} showDeprecated={true} />)).toMatchSnapshot(); | |||
expect( | |||
shallow(<Params params={params} showDeprecated={true} showInternal={true} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should not render deprecated parameters', () => { | |||
const params = [ | |||
{ | |||
key: 'foo', | |||
deprecatedSince: '5.0' | |||
} | |||
]; | |||
expect(shallow(<Params params={params} showDeprecated={false} />)).toMatchSnapshot(); | |||
const params = [{ ...DEFAULT_PARAM, deprecatedSince: '5.0' }]; | |||
expect( | |||
shallow(<Params params={params} showDeprecated={false} showInternal={false} />) | |||
).toMatchSnapshot(); | |||
}); | |||
it('should render deprecated key', () => { | |||
const params = [ | |||
{ | |||
key: 'foo', | |||
deprecatedKey: 'foo-deprecated', | |||
deprecatedKeySince: '5.0' | |||
} | |||
{ ...DEFAULT_PARAM, deprecatedKey: 'foo-deprecated', deprecatedSince: '5.0' }, | |||
{ ...DEFAULT_PARAM, deprecatedSince: '5.0', internal: true } | |||
]; | |||
expect(shallow(<Params params={params} showDeprecated={true} />)).toMatchSnapshot(); | |||
expect( | |||
shallow(<Params params={params} showDeprecated={true} showInternal={false} />) | |||
).toMatchSnapshot(); | |||
}); |
@@ -0,0 +1,50 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2017 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import ResponseExample from '../ResponseExample'; | |||
const ACTION = { | |||
key: 'foo', | |||
changelog: [], | |||
description: 'Foo Desc', | |||
hasResponseExample: false, | |||
internal: false, | |||
post: false | |||
}; | |||
const DOMAIN = { | |||
actions: [ACTION], | |||
path: 'foo', | |||
description: 'API Foo', | |||
deprecated: false, | |||
internal: false | |||
}; | |||
const PROPS = { | |||
action: ACTION, | |||
domain: DOMAIN | |||
}; | |||
it('should render correctly after fetching an example', () => { | |||
const wrapper = shallow(<ResponseExample {...PROPS} />); | |||
expect(wrapper).toMatchSnapshot(); | |||
wrapper.setState({ responseExample: { format: 'json', example: 'my example' } }); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); |
@@ -17,18 +17,18 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import React from 'react'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import * as React from 'react'; | |||
import { shallow } from 'enzyme'; | |||
import Search from '../Search'; | |||
export default function DeprecatedBadge({ since }) { | |||
const label = since ? `deprecated since ${since}` : 'deprecated'; | |||
const PROPS = { | |||
showDeprecated: false, | |||
showInternal: false, | |||
onSearch: () => {}, | |||
onToggleInternal: () => {}, | |||
onToggleDeprecated: () => {} | |||
}; | |||
return ( | |||
<span | |||
className="badge badge-warning" | |||
title={translate('api_documentation.deprecation_tooltip')} | |||
data-toggle="tooltip"> | |||
{label} | |||
</span> | |||
); | |||
} | |||
it('should render correctly', () => { | |||
expect(shallow(<Search {...PROPS} />)).toMatchSnapshot(); | |||
}); |
@@ -0,0 +1,160 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should display the changelog 1`] = ` | |||
<ActionChangelog | |||
changelog={ | |||
Array [ | |||
Object { | |||
"description": "Changelog desc", | |||
"version": "5.0", | |||
}, | |||
] | |||
} | |||
/> | |||
`; | |||
exports[`should display the params 1`] = ` | |||
<Params | |||
params={ | |||
Array [ | |||
Object { | |||
"description": "Param desc", | |||
"internal": true, | |||
"key": "param", | |||
"required": true, | |||
}, | |||
] | |||
} | |||
showDeprecated={false} | |||
showInternal={false} | |||
/> | |||
`; | |||
exports[`should display the response example 1`] = ` | |||
<ResponseExample | |||
action={ | |||
Object { | |||
"changelog": Array [ | |||
Object { | |||
"description": "Changelog desc", | |||
"version": "5.0", | |||
}, | |||
], | |||
"description": "Foo Desc", | |||
"hasResponseExample": true, | |||
"internal": false, | |||
"key": "foo", | |||
"params": Array [ | |||
Object { | |||
"description": "Param desc", | |||
"internal": true, | |||
"key": "param", | |||
"required": true, | |||
}, | |||
], | |||
"post": false, | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"changelog": Array [ | |||
Object { | |||
"description": "Changelog desc", | |||
"version": "5.0", | |||
}, | |||
], | |||
"description": "Foo Desc", | |||
"hasResponseExample": true, | |||
"internal": false, | |||
"key": "foo", | |||
"params": Array [ | |||
Object { | |||
"description": "Param desc", | |||
"internal": true, | |||
"key": "param", | |||
"required": true, | |||
}, | |||
], | |||
"post": false, | |||
}, | |||
], | |||
"deprecated": false, | |||
"description": "API Foo", | |||
"internal": false, | |||
"path": "foo", | |||
} | |||
} | |||
/> | |||
`; | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="web-api-action" | |||
id="foo/foo" | |||
> | |||
<header | |||
className="web-api-action-header" | |||
> | |||
<Link | |||
className="spacer-right link-no-underline" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/web_api/foo/foo", | |||
} | |||
} | |||
> | |||
<LinkIcon /> | |||
</Link> | |||
<h3 | |||
className="web-api-action-title" | |||
> | |||
GET | |||
foo/foo | |||
</h3> | |||
</header> | |||
<div | |||
className="web-api-action-description markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "Foo Desc", | |||
} | |||
} | |||
/> | |||
<ul | |||
className="web-api-action-actions tabs" | |||
> | |||
<li> | |||
<a | |||
className="" | |||
href="#" | |||
onClick={[Function]} | |||
> | |||
api_documentation.parameters | |||
</a> | |||
</li> | |||
<li> | |||
<a | |||
className="" | |||
href="#" | |||
onClick={[Function]} | |||
> | |||
api_documentation.response_example | |||
</a> | |||
</li> | |||
<li> | |||
<a | |||
className="" | |||
href="#" | |||
onClick={[Function]} | |||
> | |||
api_documentation.changelog | |||
</a> | |||
</li> | |||
</ul> | |||
</div> | |||
`; |
@@ -1,230 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should also render actions with a description matching the query 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"description": "foobar", | |||
"key": "foo", | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"description": "foobar", | |||
"key": "foo", | |||
}, | |||
Object { | |||
"key": "bar", | |||
}, | |||
Object { | |||
"key": "baz", | |||
}, | |||
], | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={false} | |||
/> | |||
<Action | |||
action={ | |||
Object { | |||
"key": "bar", | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"description": "foobar", | |||
"key": "foo", | |||
}, | |||
Object { | |||
"key": "bar", | |||
}, | |||
Object { | |||
"key": "baz", | |||
}, | |||
], | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={false} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should not render deprecated actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-actions" | |||
/> | |||
</div> | |||
`; | |||
exports[`should not render internal actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-actions" | |||
/> | |||
</div> | |||
`; | |||
exports[`should render deprecated actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"deprecatedSince": "5.0", | |||
"key": "foo", | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"deprecatedSince": "5.0", | |||
"key": "foo", | |||
}, | |||
], | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={true} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render internal actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"internal": true, | |||
"key": "foo", | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"internal": true, | |||
"key": "foo", | |||
}, | |||
], | |||
"path": "api", | |||
} | |||
} | |||
showInternal={true} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render only actions matching the query 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"key": "foo", | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"key": "foo", | |||
}, | |||
Object { | |||
"key": "bar", | |||
}, | |||
], | |||
"path": "api", | |||
} | |||
} | |||
/> | |||
</div> | |||
</div> | |||
`; |
@@ -0,0 +1,369 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should also render actions with a description matching the query 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Desc", | |||
} | |||
} | |||
/> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"changelog": Array [], | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "foo", | |||
"post": false, | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"changelog": Array [], | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "foo", | |||
"post": false, | |||
}, | |||
Object { | |||
"changelog": Array [], | |||
"description": "Bar desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "bar", | |||
"post": false, | |||
}, | |||
Object { | |||
"changelog": Array [], | |||
"description": "foobar", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "baz", | |||
"post": false, | |||
}, | |||
], | |||
"deprecated": false, | |||
"description": "API Desc", | |||
"internal": false, | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={false} | |||
showInternal={false} | |||
/> | |||
<Action | |||
action={ | |||
Object { | |||
"changelog": Array [], | |||
"description": "foobar", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "baz", | |||
"post": false, | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"changelog": Array [], | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "foo", | |||
"post": false, | |||
}, | |||
Object { | |||
"changelog": Array [], | |||
"description": "Bar desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "bar", | |||
"post": false, | |||
}, | |||
Object { | |||
"changelog": Array [], | |||
"description": "foobar", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "baz", | |||
"post": false, | |||
}, | |||
], | |||
"deprecated": false, | |||
"description": "API Desc", | |||
"internal": false, | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={false} | |||
showInternal={false} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should not render deprecated actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Desc", | |||
} | |||
} | |||
/> | |||
<div | |||
className="web-api-domain-actions" | |||
/> | |||
</div> | |||
`; | |||
exports[`should not render internal actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Desc", | |||
} | |||
} | |||
/> | |||
<div | |||
className="web-api-domain-actions" | |||
/> | |||
</div> | |||
`; | |||
exports[`should render deprecated actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Desc", | |||
} | |||
} | |||
/> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"changelog": Array [], | |||
"deprecatedSince": "5.0", | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "foo", | |||
"post": false, | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"changelog": Array [], | |||
"deprecatedSince": "5.0", | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "foo", | |||
"post": false, | |||
}, | |||
], | |||
"deprecated": false, | |||
"description": "API Desc", | |||
"internal": false, | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={true} | |||
showInternal={false} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render internal actions 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Desc", | |||
} | |||
} | |||
/> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"changelog": Array [], | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": true, | |||
"key": "foo", | |||
"post": false, | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"changelog": Array [], | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": true, | |||
"key": "foo", | |||
"post": false, | |||
}, | |||
], | |||
"deprecated": false, | |||
"description": "API Desc", | |||
"internal": false, | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={false} | |||
showInternal={true} | |||
/> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render only actions matching the query 1`] = ` | |||
<div | |||
className="web-api-domain" | |||
> | |||
<header | |||
className="web-api-domain-header" | |||
> | |||
<h2 | |||
className="web-api-domain-title" | |||
> | |||
api | |||
</h2> | |||
</header> | |||
<div | |||
className="web-api-domain-description markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Desc", | |||
} | |||
} | |||
/> | |||
<div | |||
className="web-api-domain-actions" | |||
> | |||
<Action | |||
action={ | |||
Object { | |||
"changelog": Array [], | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "foo", | |||
"post": false, | |||
} | |||
} | |||
domain={ | |||
Object { | |||
"actions": Array [ | |||
Object { | |||
"changelog": Array [], | |||
"description": "Foo Desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "foo", | |||
"post": false, | |||
}, | |||
Object { | |||
"changelog": Array [], | |||
"description": "Bar desc", | |||
"hasResponseExample": false, | |||
"internal": false, | |||
"key": "bar", | |||
"post": false, | |||
}, | |||
], | |||
"deprecated": false, | |||
"description": "API Desc", | |||
"internal": false, | |||
"path": "api", | |||
} | |||
} | |||
showDeprecated={false} | |||
showInternal={false} | |||
/> | |||
</div> | |||
</div> | |||
`; |
@@ -0,0 +1,248 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should also render domains with an actions description matching the query 1`] = ` | |||
<div | |||
className="api-documentation-results panel" | |||
> | |||
<div | |||
className="list-group" | |||
> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/bar" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
bar | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Bar", | |||
} | |||
} | |||
/> | |||
</Link> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/baz" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
baz | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Baz", | |||
} | |||
} | |||
/> | |||
</Link> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should not render deprecated domains 1`] = ` | |||
<div | |||
className="api-documentation-results panel" | |||
> | |||
<div | |||
className="list-group" | |||
> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/foo" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
foo | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Foo", | |||
} | |||
} | |||
/> | |||
</Link> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should not render internal domains 1`] = ` | |||
<div | |||
className="api-documentation-results panel" | |||
> | |||
<div | |||
className="list-group" | |||
> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/foo" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
foo | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Foo", | |||
} | |||
} | |||
/> | |||
</Link> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render deprecated domains 1`] = ` | |||
<div | |||
className="api-documentation-results panel" | |||
> | |||
<div | |||
className="list-group" | |||
> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/foo" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
foo | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Foo", | |||
} | |||
} | |||
/> | |||
</Link> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/bar" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
bar | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Bar", | |||
} | |||
} | |||
/> | |||
</Link> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render internal domains 1`] = ` | |||
<div | |||
className="api-documentation-results panel" | |||
> | |||
<div | |||
className="list-group" | |||
> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/foo" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
foo | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Foo", | |||
} | |||
} | |||
/> | |||
</Link> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/bar" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
bar | |||
<InternalBadge /> | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Bar", | |||
} | |||
} | |||
/> | |||
</Link> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render only domains with an action matching the query 1`] = ` | |||
<div | |||
className="api-documentation-results panel" | |||
> | |||
<div | |||
className="list-group" | |||
> | |||
<Link | |||
className="list-group-item" | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
to="/web_api/foo" | |||
> | |||
<h3 | |||
className="list-group-item-heading" | |||
> | |||
foo | |||
</h3> | |||
<div | |||
className="list-group-item-text markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "API Foo", | |||
} | |||
} | |||
/> | |||
</Link> | |||
</div> | |||
</div> | |||
`; |
@@ -10,7 +10,7 @@ exports[`should not render deprecated parameters 1`] = ` | |||
</div> | |||
`; | |||
exports[`should render deprecated key 1`] = ` | |||
exports[`should render deprecated and internal parameters 1`] = ` | |||
<div | |||
className="web-api-params" | |||
> | |||
@@ -31,9 +31,50 @@ exports[`should render deprecated key 1`] = ` | |||
<div | |||
className="little-spacer-top" | |||
> | |||
<code> | |||
foo-deprecated | |||
</code> | |||
<DeprecatedBadge | |||
since="5.0" | |||
/> | |||
</div> | |||
<div | |||
className="note little-spacer-top" | |||
> | |||
optional | |||
</div> | |||
</td> | |||
<td> | |||
<div | |||
className="markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "Foo desc", | |||
} | |||
} | |||
/> | |||
</td> | |||
<td | |||
style={ | |||
Object { | |||
"width": 250, | |||
} | |||
} | |||
/> | |||
</tr> | |||
<tr> | |||
<td | |||
className="markdown" | |||
style={ | |||
Object { | |||
"width": 180, | |||
} | |||
} | |||
> | |||
<code> | |||
foo | |||
</code> | |||
<div | |||
className="little-spacer-top" | |||
> | |||
<InternalBadge /> | |||
</div> | |||
<div | |||
className="little-spacer-top" | |||
@@ -53,7 +94,7 @@ exports[`should render deprecated key 1`] = ` | |||
className="markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": undefined, | |||
"__html": "Foo desc", | |||
} | |||
} | |||
/> | |||
@@ -71,7 +112,7 @@ exports[`should render deprecated key 1`] = ` | |||
</div> | |||
`; | |||
exports[`should render deprecated parameters 1`] = ` | |||
exports[`should render deprecated key 1`] = ` | |||
<div | |||
className="web-api-params" | |||
> | |||
@@ -96,6 +137,13 @@ exports[`should render deprecated parameters 1`] = ` | |||
since="5.0" | |||
/> | |||
</div> | |||
<div | |||
className="little-spacer-top" | |||
> | |||
<code> | |||
foo-deprecated | |||
</code> | |||
</div> | |||
<div | |||
className="note little-spacer-top" | |||
> | |||
@@ -107,7 +155,7 @@ exports[`should render deprecated parameters 1`] = ` | |||
className="markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": undefined, | |||
"__html": "Foo desc", | |||
} | |||
} | |||
/> |
@@ -0,0 +1,23 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly after fetching an example 1`] = ` | |||
<div | |||
className="web-api-response" | |||
/> | |||
`; | |||
exports[`should render correctly after fetching an example 2`] = ` | |||
<div | |||
className="web-api-response" | |||
> | |||
<pre | |||
style={ | |||
Object { | |||
"whiteSpace": "pre-wrap", | |||
} | |||
} | |||
> | |||
my example | |||
</pre> | |||
</div> | |||
`; |
@@ -0,0 +1,70 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="web-api-search" | |||
> | |||
<div> | |||
<i | |||
className="icon-search" | |||
/> | |||
<input | |||
className="spacer-left input-large" | |||
onChange={[Function]} | |||
placeholder="search_verb" | |||
type="search" | |||
value="" | |||
/> | |||
</div> | |||
<div | |||
className="big-spacer-top" | |||
> | |||
<Checkbox | |||
checked={false} | |||
onCheck={[Function]} | |||
thirdState={false} | |||
> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
api_documentation.show_internal | |||
</span> | |||
</Checkbox> | |||
<Tooltip | |||
overlay="api_documentation.internal_tooltip" | |||
placement="right" | |||
> | |||
<span> | |||
<HelpIcon | |||
className="spacer-left text-info" | |||
/> | |||
</span> | |||
</Tooltip> | |||
</div> | |||
<div | |||
className="spacer-top" | |||
> | |||
<Checkbox | |||
checked={false} | |||
onCheck={[Function]} | |||
thirdState={false} | |||
> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
api_documentation.show_deprecated | |||
</span> | |||
</Checkbox> | |||
<Tooltip | |||
overlay="api_documentation.deprecation_tooltip" | |||
placement="right" | |||
> | |||
<span> | |||
<HelpIcon | |||
className="spacer-left text-info" | |||
/> | |||
</span> | |||
</Tooltip> | |||
</div> | |||
</div> | |||
`; |
@@ -48,6 +48,11 @@ | |||
margin-top: 10px; | |||
} | |||
.web-api-action hr { | |||
margin: 10px 0 0; | |||
background-color: #ddd; | |||
} | |||
.web-api-params, | |||
.web-api-response { | |||
margin-top: 10px; |
@@ -17,15 +17,14 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
//@flow | |||
/*:: import type { Domain, Action } from '../../api/web-api'; */ | |||
import { Domain, Action } from '../../api/web-api'; | |||
export function actionsFilter( | |||
showDeprecated /*: boolean */, | |||
showInternal /*: boolean */, | |||
searchQuery /*: string */, | |||
domain /*: Domain */, | |||
action /*: Action */ | |||
showDeprecated: boolean, | |||
showInternal: boolean, | |||
searchQuery: string, | |||
domain: Domain, | |||
action: Action | |||
) { | |||
const lowSearchQuery = searchQuery.toLowerCase(); | |||
return ( | |||
@@ -36,11 +35,11 @@ export function actionsFilter( | |||
); | |||
} | |||
export function getActionKey(domainPath /*: string */, actionKey /*: string */) { | |||
export function getActionKey(domainPath: string, actionKey: string) { | |||
return domainPath + '/' + actionKey; | |||
} | |||
export const isDomainPathActive = (path /*: string */, splat /*: string */) => { | |||
export const isDomainPathActive = (path: string, splat: string) => { | |||
const pathTokens = path.split('/'); | |||
const splatTokens = splat.split('/'); | |||
@@ -17,12 +17,14 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
// @flow | |||
import React from 'react'; | |||
import * as React from 'react'; | |||
/*:: type Props = { className?: string, size?: number }; */ | |||
interface Props { | |||
className?: string; | |||
size?: number; | |||
} | |||
export default function LinkIcon({ className, size = 14 } /*: Props */) { | |||
export default function LinkIcon({ className, size = 14 }: Props) { | |||
/* eslint-disable max-len */ | |||
return ( | |||
<svg |
@@ -2875,6 +2875,17 @@ api_documentation.internal_tooltip=Use at your own risk; internal services are s | |||
api_documentation.page=Web API | |||
api_documentation.show_deprecated=Show Deprecated API | |||
api_documentation.show_internal=Show Internal API | |||
api_documentation.possible_values=Possible values | |||
api_documentation.default_values=Default value | |||
api_documentation.example_values=Example value | |||
api_documentation.max_values=Maximum allowed values | |||
api_documentation.internal=internal | |||
api_documentation.deprecated=deprecated | |||
api_documentation.depracated_since_x=deprecated since {0} | |||
api_documentation.parameters=Parameters | |||
api_documentation.response_example=Response Example | |||
api_documentation.changelog=Changelog | |||
#------------------------------------------------------------------------------ | |||
# |