Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Adaptive cards changes #873

Merged
merged 6 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 32 additions & 33 deletions src/app/services/actions/adaptive-cards-action-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
FETCH_ADAPTIVE_CARD_SUCCESS,
} from '../redux-constants';

export function getAdaptiveCardSuccess(result: string = ''): IAction {
export function getAdaptiveCardSuccess(result: object): IAction {
return {
type: FETCH_ADAPTIVE_CARD_SUCCESS,
response: result,
Expand Down Expand Up @@ -39,7 +39,7 @@ export function getAdaptiveCard(
return async (dispatch: Function) => {
if (!payload) {
// no payload so return empty result
return dispatch(getAdaptiveCardSuccess());
return dispatch(getAdaptiveCardSuccess({}));
}

if (Object.keys(payload).length === 0) {
Expand All @@ -54,38 +54,37 @@ export function getAdaptiveCard(
}

dispatch(getAdaptiveCardPending());
try {
const response = await fetch(`https://templates.adaptivecards.io/graph.microsoft.com/${templateFileName}`);
const templatePayload = await response.json();
const card = createCardFromTemplate(templatePayload, payload);
return dispatch(getAdaptiveCardSuccess({ card, template: templatePayload }));

return fetch(`https://templates.adaptivecards.io/graph.microsoft.com/${templateFileName}`)
.then((resp) => resp.json())
.then((fetchResult) => {
if (fetchResult.error) {
throw fetchResult.error;
} catch (error) {
// something wrong happened
const sanitizedUrl = sanitizeQueryUrl(sampleQuery.sampleUrl);
telemetry.trackException(
new Error(errorTypes.NETWORK_ERROR),
SeverityLevel.Error,
{
ComponentName: componentNames.GET_ADAPTIVE_CARD_ACTION,
QuerySignature: `${sampleQuery.selectedVerb} ${sanitizedUrl}`,
Message: `${error}`
}
// create a card from the template
const template = new AdaptiveCardsTemplateAPI.Template(fetchResult);
const context: AdaptiveCardsTemplateAPI.IEvaluationContext = {
$root: payload,
};
AdaptiveCardsTemplateAPI.GlobalSettings.getUndefinedFieldValueSubstitutionString = (
path: string
) => ' ';
const card = template.expand(context);
// give back the result of the card
return dispatch(getAdaptiveCardSuccess(card));
})
.catch((error) => {
// something wrong happened
const sanitizedUrl = sanitizeQueryUrl(sampleQuery.sampleUrl);
telemetry.trackException(
new Error(errorTypes.NETWORK_ERROR),
SeverityLevel.Error,
{
ComponentName: componentNames.GET_ADAPTIVE_CARD_ACTION,
QuerySignature: `${sampleQuery.selectedVerb} ${sanitizedUrl}`,
Message: `${error}`
}
);
return dispatch(getAdaptiveCardError(error));
});
);
return dispatch(getAdaptiveCardError(error));
}
};
}

function createCardFromTemplate(templatePayload: any, payload: string) {
const template = new AdaptiveCardsTemplateAPI.Template(templatePayload);
const context: AdaptiveCardsTemplateAPI.IEvaluationContext = {
$root: payload,
};
AdaptiveCardsTemplateAPI.GlobalSettings.getUndefinedFieldValueSubstitutionString = (
path: string
) => ' ';
return template.expand(context);
}

125 changes: 67 additions & 58 deletions src/app/views/query-response/adaptive-cards/AdaptiveCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,66 +95,75 @@ class AdaptiveCard extends Component<IAdaptiveCardProps> {
</Label>
);
}
}

try {
this.adaptiveCard!.parse(data);
const renderedCard = this.adaptiveCard!.render();
return (
<Pivot className='pivot-response' onLinkClick={(pivotItem) => onPivotItemClick(sampleQuery, pivotItem)}>
<PivotItem
itemKey='card'
ariaLabel={translateMessage('card')}
headerText={'Card'}
className={classes.cardStyles}
>
<div
ref={(n) => {
if (n && !n.firstChild) {
n.appendChild(renderedCard);
} else {
if (n && n.firstChild) {
n.replaceChild(renderedCard, n.firstChild);
try {
this.adaptiveCard!.parse(data.card);
const renderedCard = this.adaptiveCard!.render();
return (
<Pivot className='pivot-response' onLinkClick={(pivotItem) => onPivotItemClick(sampleQuery, pivotItem)}>
<PivotItem
itemKey='card'
ariaLabel={translateMessage('card')}
headerText={translateMessage('card')}
className={classes.card}
>
<div
ref={(n) => {
if (n && !n.firstChild) {
n.appendChild(renderedCard);
} else {
if (n && n.firstChild) {
n.replaceChild(renderedCard, n.firstChild);
}
}
}
}}
/>
</PivotItem>
<PivotItem
itemKey='JSON-schema'
ariaLabel={translateMessage('JSON Schema')}
headerText={'JSON Schema'}
>
<MessageBar messageBarType={MessageBarType.info}>
<FormattedMessage id='Get started with adaptive cards on' />
<a href={'https://docs.microsoft.com/en-us/adaptive-cards/templating/sdk'}
target='_blank'
rel='noopener noreferrer'
tabIndex={0}
className={classes.link}
>
<FormattedMessage id='Adaptive Cards Templating SDK' />
</a>
</MessageBar>
<IconButton className={classes.copyIcon}
iconProps={{
iconName: 'copy',
}}
onClick={async () => {
genericCopy(JSON.stringify(data, null, 4));
trackJsonSchemaCopyEvent(sampleQuery)
}}
/>
<Monaco
language='json'
body={data}
height={'800px'}
/>
</PivotItem>
</Pivot>
);
} catch (err) {
return <div style={{ color: 'red' }}>{err.message}</div>;
}}
/>
</PivotItem>
<PivotItem
itemKey='JSON-schema'
ariaLabel={translateMessage('JSON Schema')}
headerText={translateMessage('JSON Schema')}
>
<MessageBar messageBarType={MessageBarType.info}>
<FormattedMessage id='Get started with adaptive cards on' />
<a href={'https://docs.microsoft.com/en-us/adaptive-cards/templating/sdk'}
target='_blank'
rel='noopener noreferrer'
tabIndex={0}
className={classes.link}
>
<FormattedMessage id='Adaptive Cards Templating SDK' />
</a>
<FormattedMessage id='and experiment on' />
<a href={'https://adaptivecards.io/designer/'}
target='_blank'
rel='noopener noreferrer'
tabIndex={0}
className={classes.link}
>
<FormattedMessage id='Adaptive Cards designer' />
</a>
</MessageBar>
<IconButton className={classes.copyIcon}
iconProps={{
iconName: 'copy',
}}
onClick={async () => {
genericCopy(JSON.stringify(data.template, null, 4));
trackJsonSchemaCopyEvent(sampleQuery)
}}
/>
<Monaco
language='json'
body={data.template}
height={'800px'}
/>
</PivotItem>
</Pivot>
);
} catch (err) {
return <div style={{ color: 'red' }}>{err.message}</div>;
}
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/app/views/query-response/queryResponse.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ export const queryResponseStyles = (theme: ITheme) => {
alignItems: 'center',
},
link: {
color: theme.palette.blueMid,
color: `${theme.palette.blueMid} !important`,
},
card: {
minHeight: '500px',
maxHeight: '800px',
overflowY: 'auto',
height: '450px',
overflowY: 'auto'
},
copyIcon: {
float: 'right',
Expand Down
5 changes: 3 additions & 2 deletions src/messages/GE.json
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,11 @@
"Get started with adaptive cards on": "Get started with adaptive cards on",
"Adaptive Cards Templating SDK": "Adaptive Cards Templating SDK",
"card": "Card",
"JSON Schema": "JSON Schema",
"JSON Schema": "JSON template",
"Report an Issue": "Report an Issue",
"Maximize sidebar": "Maximize sidebar",
"Getting your access token": "Getting your access token",
"This response contains an @odata.nextLink property.": "This response contains an @odata.nextLink property.",
"Click here to go to the next page": "Click here to go to the next page"
"Click here to go to the next page": "Click here to go to the next page",
"and experiment on": " and experiment on"
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('Graph Explorer Adaptive Cards Action Creators\'', () => {

it('creates ADAPTIVE_FETCH_SUCCESS when getAdaptiveCardSuccess is called', () => {

const result = 'sample response';
const result = { sample: 'response' };
const expectedAction = {
type: FETCH_ADAPTIVE_CARD_SUCCESS,
response: result
Expand Down
5 changes: 4 additions & 1 deletion src/types/adaptivecard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ export interface IAdaptiveCardProps {
body: any;
card: {
pending: boolean;
data?: any;
data?: {
card: object;
template: object;
}
};
intl: {
message: object;
Expand Down