Skip to content

Commit

Permalink
Add telemetry for feedback button (#1852)
Browse files Browse the repository at this point in the history
  • Loading branch information
Onokaev committed Jul 12, 2022
1 parent 5eb2074 commit b40254c
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/app/services/graph-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export const GRAPH_TOOOLKIT_EXAMPLE_URL = 'https://mgt.dev/?path=/story';
export const MOZILLA_CORS_DOCUMENTATION_LINK =
'https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS';
export const USER_ORGANIZATION_URL = `${GRAPH_URL}/v1.0/organization`;
export const NPS_FEEDBACK_URL = 'https://petrol.office.microsoft.com/v1/feedback';
16 changes: 12 additions & 4 deletions src/app/views/main-header/FeedbackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useSelector } from 'react-redux';
import FeedbackForm from '../query-runner/request/feedback/FeedbackForm';
import { IRootState } from '../../../types/root';
import { ACCOUNT_TYPE } from '../../services/graph-constants';
import { componentNames, eventTypes, telemetry } from '../../../telemetry';

export const FeedbackButton = () => {
const [enableSurvey, setEnableSurvey] = useState(false);
Expand Down Expand Up @@ -35,14 +36,21 @@ export const FeedbackButton = () => {
}
};

const toggleSurvey = () => {
setEnableSurvey(prevState => !prevState);
const activateSurvey = () => {
setEnableSurvey(true);
trackFeedbackButtonEvent();
}

const disableSurvey = () => {
setEnableSurvey(false);
}

const trackFeedbackButtonEvent = () => {
telemetry.trackEvent(eventTypes.BUTTON_CLICK_EVENT, {
ComponentName: componentNames.FEEDBACK_BUTTON
});
}

return (
<div>
{profile?.profileType !== ACCOUNT_TYPE.AAD &&
Expand All @@ -52,7 +60,7 @@ export const FeedbackButton = () => {
calloutProps={calloutProps}
styles={hostStyles}
>
<IconButton onClick={toggleSurvey}
<IconButton onClick={activateSurvey}
iconProps={feedbackIcon}
ariaDescription={feedbackTitle}
ariaLabel={feedbackTitle}
Expand All @@ -62,7 +70,7 @@ export const FeedbackButton = () => {
/>
</TooltipHost>

<FeedbackForm onDismissSurvey={toggleSurvey}
<FeedbackForm onDismissSurvey={disableSurvey}
activated={enableSurvey} onDisableSurvey={disableSurvey} />
</div>
}
Expand Down
27 changes: 24 additions & 3 deletions src/app/views/query-runner/request/feedback/FeedbackForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { translateMessage } from '../../../../utils/translate-messages';
import { getVersion } from '../../../../utils/version';
import CampaignDefinitions from './campaignDefinitions';
import { uiStringMap } from './uiStrings';
import { componentNames, telemetry } from '../../../../../telemetry';

export default function FeedbackForm({ activated, onDismissSurvey, onDisableSurvey }: any) {
const dispatch = useDispatch();
Expand Down Expand Up @@ -70,6 +71,7 @@ export default function FeedbackForm({ activated, onDismissSurvey, onDisableSurv
showCustomSurvey();
}


async function loadAndInitialize(
floodgateObject: any,
// eslint-disable-next-line no-unused-vars
Expand Down Expand Up @@ -103,14 +105,20 @@ export default function FeedbackForm({ activated, onDismissSurvey, onDisableSurv
showEmailAddress: (policies?.data?.email !== 2),
surveyEnabled: (profile?.profileType !== ACCOUNT_TYPE.AAD),
onDismiss: (campaignId: string, submitted: boolean) => {
const SecondsBeforePopup = getSecondsBeforePopup(floodgateObject.floodgate.getEngine()
.previousSurveyEventActivityStats);
const telemetryData = { SecondsBeforePopup, IsSubmitted: false };
if (submitted) {
dispatch(setQueryResponseStatus({
status: translateMessage('Submitted Successfully'),
statusText: translateMessage('Graph Explorer Feedback'),
ok: true,
messageType: MessageBarType.success
}));

trackSurveyPopup({...telemetryData, IsSubmitted: true}, campaignId);
}
else{
trackSurveyPopup(telemetryData, campaignId);
}
onDismissSurvey();
},
Expand Down Expand Up @@ -145,7 +153,6 @@ export default function FeedbackForm({ activated, onDismissSurvey, onDisableSurv
floodgateObject.floodgate.start();
floodgateObject.floodgate.getEngine().getActivityListener().logActivity('OnPageLoad');
floodgateObject.floodgate.getEngine().getActivityListener().logActivityStartTime('AppUsageTime');

}
}
window.onfocus = function () {
Expand All @@ -171,6 +178,20 @@ export default function FeedbackForm({ activated, onDismissSurvey, onDisableSurv
}
}

const trackSurveyPopup = (telemetryData: any, campaignId: string) => {
if(campaignId === process.env.REACT_APP_NPS_FEEDBACK_CAMPAIGN_ID){
telemetry.trackWindowOpenEvent(componentNames.LAUNCH_FEEDBACK_POPUP_ACTION, telemetryData);
}
}

const getSecondsBeforePopup = (previousSurveyEventActivityStats: any) : string => {
let latestCount : number = 0;
if (Object.keys(previousSurveyEventActivityStats.Surveys).length > 0) {
const surveyStats: any = Object.values(previousSurveyEventActivityStats.Surveys);
latestCount = surveyStats[0].Counts;
}
return latestCount.toString();
}

function getCampaignId(): string {
return process.env.REACT_APP_FEEDBACK_CAMPAIGN_ID || '';
Expand All @@ -185,4 +206,4 @@ export default function FeedbackForm({ activated, onDismissSurvey, onDisableSurv

}

}
}
9 changes: 5 additions & 4 deletions src/telemetry/component-names.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// Names of instrumented components

// Buttons
export const FEEDBACK_BUTTON = 'Feedback button'
export const RUN_QUERY_BUTTON = 'Run query button';
export const QUERY_COPY_BUTTON = 'Query copy button';
export const THEME_CHANGE_BUTTON = 'Theme change button';
export const SELECT_THEME_BUTTON = 'Select theme button';
export const QUERY_MORE_INFO_BUTTON = 'Query more info button';
export const JSON_SCHEMA_COPY_BUTTON = 'JSON schema copy button';
export const RUN_HISTORY_ITEM_BUTTON = 'Run history item button';
export const SHARE_QUERY_COPY_BUTTON = 'Share query copy button';
Expand All @@ -17,9 +20,6 @@ export const DELETE_HISTORY_ITEM_BUTTON = 'Delete history item button';
export const RESPONSE_HEADERS_COPY_BUTTON = 'Response headers copy button';
export const DOWNLOAD_POSTMAN_COLLECTION_BUTTON = 'Download postman collection button';
export const REMOVE_RESOURCE_FROM_COLLECTION_BUTTON = 'Remove resource from collection button';
export const QUERY_COPY_BUTTON = 'Query copy button';
export const QUERY_MORE_INFO_BUTTON = 'Query more info button';


// List items
export const HISTORY_LIST_ITEM = 'History list item';
Expand Down Expand Up @@ -82,4 +82,5 @@ export const FETCH_SAMPLES_ACTION = 'Fetch samples action';
export const AUTHENTICATION_ACTION = 'Authentication action';
export const GET_ADAPTIVE_CARD_ACTION = 'Get adaptive card action';
export const FETCH_PERMISSIONS_ACTION = 'Fetch permissions action';
export const MONACO_EDITOR_FORMAT_JSON_ACTION = 'Monaco editor format JSON action';
export const MONACO_EDITOR_FORMAT_JSON_ACTION = 'Monaco editor format JSON action';
export const LAUNCH_FEEDBACK_POPUP_ACTION = 'Launch feedback popup action';
1 change: 1 addition & 0 deletions src/telemetry/event-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export const TAB_CLICK_EVENT = 'TAB_CLICK_EVENT';
export const LINK_CLICK_EVENT = 'LINK_CLICK_EVENT';
export const LISTITEM_CLICK_EVENT = 'LISTITEM_CLICK_EVENT';
export const DROPDOWN_CHANGE_EVENT = 'DROPDOWN_CHANGE_EVENT';
export const WINDOW_OPEN_EVENT = 'WINDOW_OPEN_EVENT';
6 changes: 4 additions & 2 deletions src/telemetry/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
GRAPH_API_SANDBOX_URL,
GRAPH_TOOOLKIT_EXAMPLE_URL,
GRAPH_URL,
HOME_ACCOUNT_KEY
HOME_ACCOUNT_KEY,
NPS_FEEDBACK_URL
} from '../app/services/graph-constants';
import {
sanitizeGraphAPISandboxUrl,
Expand Down Expand Up @@ -40,7 +41,8 @@ export function filterRemoteDependencyData(envelope: ITelemetryItem): boolean {
GRAPH_API_SANDBOX_URL,
new URL(graphProxyUrl).origin,
new URL(ADAPTIVE_CARD_URL).origin,
new URL(GRAPH_TOOOLKIT_EXAMPLE_URL).origin
new URL(GRAPH_TOOOLKIT_EXAMPLE_URL).origin,
new URL(NPS_FEEDBACK_URL).origin
];
if (!targetsToInclude.includes(urlObject.origin)) {
return false;
Expand Down
11 changes: 9 additions & 2 deletions src/telemetry/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { IQuery } from '../types/query-runner';
import {
BUTTON_CLICK_EVENT,
LINK_CLICK_EVENT,
TAB_CLICK_EVENT
TAB_CLICK_EVENT,
WINDOW_OPEN_EVENT
} from './event-types';
import {
addCommonTelemetryItemProperties,
Expand All @@ -39,7 +40,7 @@ class Telemetry implements ITelemetry {
this.config = {
instrumentationKey: this.getInstrumentationKey(),
disableExceptionTracking: false, // Enables autocollection of uncaught exceptions. Used with `sanitizeStackTrace` telemetry initializer to remove any data that might be PII.
disableAjaxTracking: true,
disableAjaxTracking: false,
disableFetchTracking: false, // Enables capturing of telemetry data for outgoing requests. Used with `filterRemoteDependencyData` telemetry initializer to sanitize captured data to prevent inadvertent capture of PII.
disableTelemetry: this.getInstrumentationKey() ? false : true,
extensions: [this.reactPlugin]
Expand Down Expand Up @@ -111,6 +112,12 @@ class Telemetry implements ITelemetry {
telemetry.trackEvent(BUTTON_CLICK_EVENT, properties);
}

public trackWindowOpenEvent(windowEvent: string, properties?: any) {
properties = properties || {};
properties.ComponentName = windowEvent;
telemetry.trackEvent(WINDOW_OPEN_EVENT, properties);
}

private getInstrumentationKey() {
return (
(window as any).InstrumentationKey ||
Expand Down

0 comments on commit b40254c

Please sign in to comment.