Skip to content

Commit

Permalink
Fix: add version select (microsoftgraph#215)
Browse files Browse the repository at this point in the history
* Add version select (microsoftgraph#205)

* add urlVersions type

* add version handler function

* add version dropdown

* change the version to lowerCase

* change the url version

* moves version selection to redux

* moves state properties from query runner to input

* changes to appropriate query version when query clicked

* adds tests for SELECT_VERSION_SUCCESS

* adds displayRequestComponent toggle for try it

* renames selectQueryVersion to setQueryVersion

* describes options variable as urlVersion | method

* creates and utilises a function to parse urls to sample urls

* sets the selected version when editor changed

* increases control sizes to reduce ellipsis use

* moves selectedVersion to sampleQuery property
  • Loading branch information
Charles Wahome authored and asith-w committed Nov 7, 2019
1 parent ee240f3 commit 6fd5a5e
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 50 deletions.
6 changes: 3 additions & 3 deletions src/app/services/actions/adaptive-cards-action-creator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as AdaptiveCardsTemplateAPI from 'adaptivecards-templating';
import { IAction } from '../../../types/action';
import { IQuery } from '../../../types/query-runner';
import { parseSampleUrl } from '../../utils/sample-url-generation';
import {
FETCH_ADAPTIVE_CARD_ERROR ,
FETCH_ADAPTIVE_CARD_PENDING,
Expand Down Expand Up @@ -67,9 +68,8 @@ export function getAdaptiveCard(payload: string, sampleQuery: IQuery): Function

function lookupTemplate(sampleQuery: IQuery): string {
if (sampleQuery) {
const urlObject: URL = new URL(sampleQuery.sampleUrl);
// remove the prefix i.e. beta or v1.0 and any possible extra whack character at the end'/'
const query = urlObject.pathname.substr(6).replace(/\/$/, '') + urlObject.search;
const { requestUrl, search } = parseSampleUrl(sampleQuery.sampleUrl);
const query = requestUrl + search;
return templateMap[query];
}
return '';
Expand Down
2 changes: 1 addition & 1 deletion src/app/services/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ export default combineReducers({
history,
isLoadingData,
queryRunnerError,
termsOfUse,
sampleQuery,
samples,
sidebarProperties,
snippets,
termsOfUse,
theme,
});
2 changes: 1 addition & 1 deletion src/app/services/reducers/query-input-reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export function sampleQuery(state = {}, action: IAction): any {
default:
return state;
}
}
}
19 changes: 19 additions & 0 deletions src/app/utils/sample-url-generation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { GRAPH_URL } from '../services/graph-constants';

export function parseSampleUrl(url: string, version?: string) {
let requestUrl = '';
let queryVersion = '';
let sampleUrl = '';
let search = '';

if (url !== '') {
const urlObject: URL = new URL(url);
requestUrl = urlObject.pathname.substr(6).replace(/\/$/, '');
queryVersion = (version) ? version : urlObject.pathname.substring(1, 5);
search = decodeURI(urlObject.search);
sampleUrl = `${GRAPH_URL}/${queryVersion}/${requestUrl + search}`;
}

return { queryVersion, requestUrl, sampleUrl, search };

}
42 changes: 35 additions & 7 deletions src/app/views/query-runner/QueryInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,61 @@ import SubmitButton from '../common/submit-button/SubmitButton';
export class QueryInput extends Component<IQueryInputProps, any> {
constructor(props: any) {
super(props);
this.state = {
httpMethods: [
{ key: 'GET', text: 'GET' },
{ key: 'POST', text: 'POST' },
{ key: 'PUT', text: 'PUT' },
{ key: 'PATCH', text: 'PATCH' },
{ key: 'DELETE', text: 'DELETE' }
],
urlVersions: [
{ key: 'v1.0', text: 'v1.0' },
{ key: 'beta', text: 'beta' }
],
};
}

public render() {
const { httpMethods, urlVersions } = this.state;

const {
handleOnRunQuery,
handleOnMethodChange,
handleOnUrlChange,
handleOnVersionChange,
handleOnBlur,
httpMethods,
selectedVerb,
selectedVersion,
sampleUrl,
submitting,
mode,
mode
} = this.props;

return (
<div className='row'>
<div className='col-sm-3'>
<div className='col-sm-3 col-md-2'>
<Dropdown
ariaLabel='Query sample option'
role='listbox'
selectedKey={selectedVerb}
options={httpMethods}
disabled={mode === Mode.TryIt}
styles={{ title: { paddingRight: 0 } }}
onChange={(event, method) => handleOnMethodChange(method)}
/>
</div>
<div className='col-sm-7'>

<div className='col-sm-2 col-md-2'>
<Dropdown
ariaLabel='Query sample option'
role='listbox'
selectedKey={selectedVersion || 'v1.0'}
options={urlVersions}
onChange={(event, method) => handleOnVersionChange(method)}
/>
</div>
<div className='col-sm-5 col-md-6'>
<TextField
ariaLabel='Query Sample Input'
role='textbox'
Expand All @@ -46,7 +73,7 @@ export class QueryInput extends Component<IQueryInputProps, any> {
onBlur={() => handleOnBlur()}
/>
</div>
<div className='col-sm-2 run-query-button'>
<div className='col-sm-1 col-md-2 run-query-button'>
<SubmitButton
className='run-query-button'
text='Run Query'
Expand All @@ -62,10 +89,11 @@ export class QueryInput extends Component<IQueryInputProps, any> {

function mapStateToProps(state: any) {
return {
mode: state.graphExplorerMode,
sampleUrl: state.sampleQuery.sampleUrl,
selectedVerb: state.sampleQuery.selectedVerb,
appTheme: state.theme,
mode: state.graphExplorerMode,
selectedVersion: state.sampleQuery.selectedVersion,
submitting: state.isLoadingData,
};
}
export default connect(
Expand Down
55 changes: 34 additions & 21 deletions src/app/views/query-runner/QueryRunner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,46 @@ import {
import * as queryActionCreators from '../../services/actions/query-action-creators';
import * as queryInputActionCreators from '../../services/actions/query-input-action-creators';
import { addRequestHeader } from '../../services/actions/request-headers-action-creators';
import { parseSampleUrl } from '../../utils/sample-url-generation';
import './query-runner.scss';
import QueryInput from './QueryInput';
import Request from './request/Request';

export class QueryRunner extends Component<
IQueryRunnerProps,
IQueryRunnerState
> {
> {
constructor(props: IQueryRunnerProps) {
super(props);
this.state = {
httpMethods: [
{ key: 'GET', text: 'GET' },
{ key: 'POST', text: 'POST' },
{ key: 'PUT', text: 'PUT' },
{ key: 'PATCH', text: 'PATCH' },
{ key: 'DELETE', text: 'DELETE' }
],
url: ''
url: '',
sampleBody: '',
};
}

private handleOnMethodChange = (option?: IDropdownOption) => {
private handleOnMethodChange = (method?: IDropdownOption) => {
const query = { ...this.props.sampleQuery };
const { actions } = this.props;
if (option !== undefined) {
query.selectedVerb = option.text;
if (method !== undefined) {
query.selectedVerb = method.text;
if (actions) {
actions.setSampleQuery(query);
}

// Sets selected verb in App Component
this.props.onSelectVerb(option.text);
this.props.onSelectVerb(method.text);
}
};

private handleOnUrlChange = (newQuery = '') => {
this.setState({ url: newQuery });

const { queryVersion } = parseSampleUrl(newQuery);
if (queryVersion === 'v1.0' || queryVersion === 'beta') {
const query = { ...this.props.sampleQuery };
query.selectedVersion = queryVersion;
this.props.actions!.setSampleQuery(query);
}
};

private handleOnBlur = () => {
Expand Down Expand Up @@ -85,10 +87,20 @@ export class QueryRunner extends Component<
}
};

public render() {
const { httpMethods } = this.state;
const { graphExplorerMode, isLoadingData } = this.props;
private handleOnVersionChange = (urlVersion?: IDropdownOption) => {
const { sampleQuery } = this.props;
if (urlVersion) {
const { sampleUrl, queryVersion } = parseSampleUrl(sampleQuery.sampleUrl, urlVersion.text);
this.props.actions!.setSampleQuery({
...sampleQuery,
sampleUrl,
selectedVersion: queryVersion
});
}
};

public render() {
const { graphExplorerMode } = this.props;
const displayRequestComponent = (graphExplorerMode === Mode.Complete);

return (
Expand All @@ -98,10 +110,9 @@ export class QueryRunner extends Component<
<QueryInput
handleOnRunQuery={this.handleOnRunQuery}
handleOnMethodChange={this.handleOnMethodChange}
handleOnVersionChange={this.handleOnVersionChange}
handleOnUrlChange={this.handleOnUrlChange}
handleOnBlur={this.handleOnBlur}
httpMethods={httpMethods}
submitting={isLoadingData}
/>
</div>
</div>
Expand All @@ -128,11 +139,13 @@ function mapDispatchToProps(dispatch: Dispatch): object {

function mapStateToProps(state: any) {
return {
isLoadingData: state.isLoadingData,
graphExplorerMode: state.graphExplorerMode,
headers: state.headersAdded,
sampleQuery: state.sampleQuery,
graphExplorerMode: state.graphExplorerMode,
};
}

export default connect(mapStateToProps, mapDispatchToProps)(QueryRunner);
export default connect(
mapStateToProps,
mapDispatchToProps
)(QueryRunner);
17 changes: 10 additions & 7 deletions src/app/views/sidebar/history/History.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as queryActionCreators from '../../../services/actions/query-action-cre
import * as queryInputActionCreators from '../../../services/actions/query-input-action-creators';
import * as requestHistoryActionCreators from '../../../services/actions/request-history-action-creators';
import { GRAPH_URL } from '../../../services/graph-constants';
import { parseSampleUrl } from '../../../utils/sample-url-generation';
import { classNames } from '../../classnames';
import { sidebarStyles } from '../Sidebar.styles';
import { dynamicSort } from './historyUtil';
Expand Down Expand Up @@ -232,20 +233,21 @@ export class History extends Component<IHistoryProps, any> {

private onRunQuery = (query: IHistoryItem) => {
const { actions } = this.props;

const { sampleUrl, queryVersion } = parseSampleUrl(query.url);
const sampleQuery: IQuery = {
sampleUrl: GRAPH_URL + query.url.replace(GRAPH_URL, ''),
sampleUrl,
selectedVerb: query.method,
sampleBody: query.body,
sampleHeaders: query.headers
sampleHeaders: query.headers,
selectedVersion: queryVersion,
};

if (actions) {
if (sampleQuery.selectedVerb === 'GET') {
sampleQuery.sampleBody = JSON.parse('{}');
}
actions.runQuery(sampleQuery);
actions.setSampleQuery(sampleQuery);
actions.runQuery(sampleQuery);
}
}

Expand All @@ -259,12 +261,13 @@ export class History extends Component<IHistoryProps, any> {

private onViewQuery = (query: IHistoryItem) => {
const { actions } = this.props;

const { sampleUrl, queryVersion } = parseSampleUrl(query.url);
const sampleQuery: IQuery = {
sampleUrl: GRAPH_URL + query.url.replace(GRAPH_URL, ''),
sampleUrl,
selectedVerb: query.method,
sampleBody: query.body,
sampleHeaders: query.headers
sampleHeaders: query.headers,
selectedVersion: queryVersion,
};

if (actions) {
Expand Down
4 changes: 3 additions & 1 deletion src/app/views/sidebar/sample-queries/SampleQueries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,13 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {
const selectedQuery = selection.getSelection()[0] as any;
if (!selectedQuery) { return; }

const queryVersion = selectedQuery.requestUrl.substring(1, 5);
const sampleQuery: IQuery = {
sampleUrl: GRAPH_URL + selectedQuery.requestUrl,
selectedVerb: selectedQuery.method,
sampleBody: selectedQuery.postBody,
sampleHeaders: selectedQuery.headers || []
sampleHeaders: selectedQuery.headers || [],
selectedVersion: queryVersion,
};

if (actions) {
Expand Down
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const appState = store({
selectedVerb: 'GET',
sampleBody: undefined,
sampleHeaders: {},
selectedVersion: 'v1.0',
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';

import { setSampleQuery } from '../../../app/services/actions/query-input-action-creators';
import { SET_SAMPLE_QUERY_SUCCESS } from '../../../app/services/redux-constants';
import { SELECT_VERSION_SUCCESS, SET_SAMPLE_QUERY_SUCCESS } from '../../../app/services/redux-constants';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
Expand Down Expand Up @@ -32,5 +32,4 @@ describe('actions', () => {
}));
expect(store.getActions()).toEqual(expectedActions);
});

});
Loading

0 comments on commit 6fd5a5e

Please sign in to comment.