Skip to content

Commit

Permalink
Merge pull request #2450 from microsoftgraph/release/8.0.0
Browse files Browse the repository at this point in the history
Add a devcontainer to the repo (#2421)
Task: Add copy telemetry (#2419)
Fix: Enable code selection in Expand view (#2435)
Chore(deps): Bump loader-utils from 2.0.2 to 2.0.4 (#2433)
Chore(deps): Bump json5 from 1.0.1 to 1.0.2 (#2434)
Task: Handle claims challenge (#2422)
Fix: Update azure-pipelines.yml for Azure Pipelines (#2444)
Fix: Autocomplete filter (#2432)
  • Loading branch information
thewahome authored Mar 13, 2023
2 parents a6bd177 + 11177e1 commit c1282bd
Show file tree
Hide file tree
Showing 27 changed files with 358 additions and 101 deletions.
3 changes: 3 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"image": "mcr.microsoft.com/devcontainers/typescript-node:0-18"
}
9 changes: 7 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,14 @@ jobs:
- job: One
displayName: "Build and test validation"
steps:
- task: CredScan@2
- task: CredScan@3

- task: ComponentGovernanceComponentDetection@0
inputs:
toolMajorVersion: "V2"
scanType: "Register"
verbosity: "Verbose"
alertWarningLevel: "High"
ignoreDirectories: ".github,.vscode/"

- task: ComponentGovernanceComponentDetection@0
inputs:
Expand Down
33 changes: 14 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "graph-explorer-v2",
"version": "7.2.0",
"version": "8.0.0",
"private": true,
"dependencies": {
"@augloop/types-core": "file:packages/types-core-2.16.189.tgz",
Expand Down Expand Up @@ -136,4 +136,4 @@
"resolutions": {
"@types/react": "17.0.44"
}
}
}
35 changes: 35 additions & 0 deletions src/app/services/actions/query-action-creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ import {
} from './query-action-creator-util';
import { setQueryResponseStatus } from './query-status-action-creator';
import { addHistoryItem } from './request-history-action-creators';
import { authenticationWrapper } from '../../../modules/authentication';
import { BrowserAuthError } from '@azure/msal-browser';
import { ClaimsChallenge } from '../../../modules/authentication/ClaimsChallenge';
import { translateMessage } from '../../utils/translate-messages';

const MAX_NUMBER_OF_RETRIES = 3;
let CURRENT_RETRIES = 0;
export function runQuery(query: IQuery) {
return (dispatch: Function, getState: Function) => {
const tokenPresent = !!getState()?.authToken?.token;
Expand Down Expand Up @@ -80,6 +86,7 @@ export function runQuery(query: IQuery) {
}

if (response && response.ok) {
CURRENT_RETRIES = 0;
status.ok = true;
status.messageType = MessageBarType.success;

Expand All @@ -96,6 +103,11 @@ export function runQuery(query: IQuery) {
}
}

if(response && response.status === 401 && (CURRENT_RETRIES < MAX_NUMBER_OF_RETRIES)) {
const successful = await runReAuthenticatedRequest(response);
if(successful){ dispatch(runQuery(query)); }
return;
}
dispatch(setQueryResponseStatus(status));

return dispatch(
Expand All @@ -106,6 +118,20 @@ export function runQuery(query: IQuery) {
);
}

async function runReAuthenticatedRequest(response: Response): Promise<boolean>{
if (response.headers.get('www-authenticate')) {
const account = authenticationWrapper.getAccount();
if (!account) { return false; }
new ClaimsChallenge(query, account).handle(response.headers);
const authResult = await authenticationWrapper.logIn('', query);
if (authResult.accessToken) {
CURRENT_RETRIES += 1;
return true;
}
}
return false;
}

function handleError(dispatch: Function, error: any) {
let body = error;
const status: IStatus = {
Expand All @@ -128,6 +154,15 @@ export function runQuery(query: IQuery) {
};
}

if (error && error instanceof BrowserAuthError) {
if (error.errorCode === 'user_cancelled'){
status.hint = `${translateMessage('user_cancelled')}`;
}
else{
status.statusText = `${error.name}: ${error.message}`;
}
}

dispatch(
queryResponse({
body,
Expand Down
2 changes: 2 additions & 0 deletions src/app/views/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { parse } from './query-runner/util/iframe-message-parser';
import { Sidebar } from './sidebar/Sidebar';
import { MainHeader } from './main-header/MainHeader';
import { removeSpinners } from '../..';
import { KeyboardCopyEvent } from './common/copy/KeyboardCopyEvent';

export interface IAppProps {
theme?: ITheme;
Expand Down Expand Up @@ -87,6 +88,7 @@ class App extends Component<IAppProps, IAppState> {

public componentDidMount = async () => {
removeSpinners();
KeyboardCopyEvent();
this.displayToggleButton(this.mediaQueryList);
this.mediaQueryList.addListener(this.displayToggleButton);

Expand Down
40 changes: 40 additions & 0 deletions src/app/views/common/copy/KeyboardCopyEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { eventTypes, telemetry } from '../../../../telemetry';
import { KEYBOARD_COPY_TABS } from '../../../../telemetry/component-names';

interface IComponentList {
[key: string]: string;
}
export const KeyboardCopyEvent = () => {
const componentList: IComponentList = KEYBOARD_COPY_TABS;
document.addEventListener('keydown', (event: KeyboardEvent) => {
if (event && (event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'c') {
const targets = event.composedPath();
const componentName = getComponentName(targets);
trackCopyEvent(componentName);
}
});

const getComponentName = (targets: EventTarget[]): string => {
const targetIds = targets.map((target: EventTarget) => {
return getTargetId(target);
});
const filteredTargetIds = targetIds.filter((value) => value !== null)!;
const componentName = Object.keys(componentList).find(key => filteredTargetIds.includes(key));
return componentName || '';
}

const getTargetId = (target: EventTarget) => {
if(target && target instanceof Element) {
return target.getAttribute('id');
}
}

const trackCopyEvent = (componentName: string) => {
if(!componentName) { return; }
telemetry.trackEvent(eventTypes.KEYBOARD_COPY_EVENT,
{
ComponentName: (KEYBOARD_COPY_TABS as IComponentList)[componentName],
trigger: 'Keyboard'
});
}
}
1 change: 1 addition & 0 deletions src/app/views/query-response/QueryResponse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ const QueryResponse = () => {
isOpen={showModal}
onDismiss={toggleExpandResponse}
styles={modalStyles}
layerProps={{ eventBubblingEnabled: true }}
>
<IconButton
styles={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ const AdaptiveCard = (props: any) => {
'aria-controls': 'json-schema-tab'
}}
>
<div id={'json-schema-tab'}>
<div id={'JSON-schema-tab'} tabIndex={0}>
<MessageBar messageBarType={MessageBarType.info}>
<FormattedMessage id='Get started with adaptive cards on' />
<Link href={'https://learn.microsoft.com/en-us/adaptive-cards/templating/sdk'}
Expand Down
4 changes: 2 additions & 2 deletions src/app/views/query-response/headers/ResponseHeaders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ const ResponseHeaders = () => {

if (headers) {
return (
<>
<div id='response-headers-tab'>
<CopyButton
handleOnClick={handleCopy}
isIconButton={true}
style={{ float: 'right', zIndex: 1 }}
/>
<Monaco body={headers} height={height} />
</>
</div>
);
}

Expand Down
10 changes: 5 additions & 5 deletions src/app/views/query-response/pivot-items/pivot-items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const GetPivotItems = () => {
'aria-controls': 'response-tab'
}}
>
<div id={'response-tab'}><Response /></div>
<div id={'response-tab'} tabIndex={0}><Response /></div>
</PivotItem>,
<PivotItem
key='response-headers'
Expand All @@ -86,7 +86,7 @@ export const GetPivotItems = () => {
'aria-controls': 'response-headers-tab'
}}
>
<div id={'response-headers-tab'}><ResponseHeaders /></div>
<div id={'response-headers-tab'} tabIndex={0}><ResponseHeaders /></div>
</PivotItem>
];
if (mode === Mode.Complete) {
Expand All @@ -102,7 +102,7 @@ export const GetPivotItems = () => {
'aria-controls': 'code-snippets-tab'
}}
>
<div id={'code-snippets-tab'}><Snippets /></div>
<div id={'code-snippets-tab'} tabIndex={0}><Snippets /></div>
</PivotItem>,
<PivotItem
key='graph-toolkit'
Expand All @@ -116,7 +116,7 @@ export const GetPivotItems = () => {
'aria-controls': 'toolkit-tab'
}}
>
<div id={'toolkit-tab'}><GraphToolkit /></div>
<div id={'toolkit-tab'} tabIndex={0}><GraphToolkit /></div>
</PivotItem>,
<PivotItem
key='adaptive-cards'
Expand All @@ -133,7 +133,7 @@ export const GetPivotItems = () => {
<ThemeContext.Consumer >
{(theme) => (
// @ts-ignore
<div id={'adaptive-cards-tab'}>
<div id={'adaptive-cards-tab'} tabIndex={0}>
<AdaptiveCard
body={body}
hostConfig={theme === 'light' ? lightThemeHostConfig : darkThemeHostConfig}
Expand Down
2 changes: 2 additions & 0 deletions src/app/views/query-response/snippets/snippets-helper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export function renderSnippets(supportedLanguages: ISupportedLanguages) {
'aria-controls': `${language}-tab`
}}
itemKey={language}
tabIndex={0}
id={`${language}-tab`}
>
<Snippet language={language} snippetInfo={supportedLanguages} />
</PivotItem>
Expand Down
8 changes: 7 additions & 1 deletion src/app/views/query-runner/QueryRunner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useDispatch } from 'react-redux';
import { AppDispatch, useAppSelector } from '../../../store';
import { componentNames, eventTypes, telemetry } from '../../../telemetry';
import { ContentType } from '../../../types/enums';
import { IQuery } from '../../../types/query-runner';
import { runQuery } from '../../services/actions/query-action-creators';
import { setSampleQuery } from '../../services/actions/query-input-action-creators';
import { setQueryResponseStatus } from '../../services/actions/query-status-action-creator';
Expand Down Expand Up @@ -37,7 +38,7 @@ const QueryRunner = (props: any) => {
setSampleBody(value!);
};

const handleOnRunQuery = () => {
const handleOnRunQuery = (query?: IQuery) => {
if (sampleBody) {
const headers = sampleQuery.sampleHeaders;
const contentType = headers.find(k => k.name.toLowerCase() === 'content-type');
Expand All @@ -58,6 +59,11 @@ const QueryRunner = (props: any) => {
sampleQuery.sampleBody = sampleBody;
}
}
if(query) {
sampleQuery.sampleUrl = query.sampleUrl;
sampleQuery.selectedVersion = query.selectedVersion;
sampleQuery.selectedVerb = query.selectedVerb;
}

dispatch(runQuery(sampleQuery));
const sanitizedUrl = sanitizeQueryUrl(sampleQuery.sampleUrl);
Expand Down
10 changes: 7 additions & 3 deletions src/app/views/query-runner/query-input/QueryInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,15 @@ const QueryInput = (props: IQueryInputProps) => {
return query;
}

const runQuery = () => {
if (!sampleQuery.sampleUrl || sampleQuery.sampleUrl.indexOf('graph.microsoft.com') === -1) {
const runQuery = (queryUrl?: string) => {
let query: IQuery = sampleQuery;
if (queryUrl) {
query = getChangedQueryContent(queryUrl);
}
if (!query.sampleUrl || query.sampleUrl.indexOf('graph.microsoft.com') === -1) {
return;
}
handleOnRunQuery(sampleQuery);
handleOnRunQuery(query);
};

const queryInputStackTokens: IStackTokens = {
Expand Down
Loading

0 comments on commit c1282bd

Please sign in to comment.