From eca88a2388862f3cbf8e33c3aeed53b0ab8be335 Mon Sep 17 00:00:00 2001 From: Sudharsan K <10280385+sudharsank@users.noreply.github.com> Date: Fri, 3 Jul 2020 15:40:22 +0800 Subject: [PATCH 1/2] Included the codetour for the solution. --- .../angularFileUpload/app/services/baseSvc.ts | 181 ------------------ .../src/common/CommonControl.module.scss | 4 +- 2 files changed, 1 insertion(+), 184 deletions(-) delete mode 100644 samples/angular-ngofficeuifabric-file-upload/src/webparts/angularFileUpload/app/services/baseSvc.ts diff --git a/samples/angular-ngofficeuifabric-file-upload/src/webparts/angularFileUpload/app/services/baseSvc.ts b/samples/angular-ngofficeuifabric-file-upload/src/webparts/angularFileUpload/app/services/baseSvc.ts deleted file mode 100644 index f0b6293f4..000000000 --- a/samples/angular-ngofficeuifabric-file-upload/src/webparts/angularFileUpload/app/services/baseSvc.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { IError } from "../../interfaces/IError"; -import * as angular from 'angular'; - - -export class BaseService { - public static $inject: string[] = ["$http", "$q"]; - public baseUrl: string; - - constructor(private $http: ng.IHttpService, private $q: ng.IQService) { - - this.baseUrl = (window)._spPageContextInfo.webAbsoluteUrl; - - } - - public getRequest(query?: string, endPoint?: string): ng.IPromise { - const deferred: ng.IDeferred = this.$q.defer(); - this.$http({ - url: endPoint || this.baseUrl + query, - method: "GET", - headers: { - "accept": "application/json;odata=verbose", - "content-Type": "application/json;odata=verbose" - } - }).then((response: any): void => { - if (response.data.d.results) { - deferred.resolve(response.data.d.results); - } else { - deferred.resolve(response.data.d); - } - }, (error: any) => { - const iError: IError = { - code: error.data.error.code, - message: error.data.error.message.value, - status: error.status, - statusText: error.statusText - }; - deferred.reject(iError); - }); - return deferred.promise; - } - - public postRequest(url: string, requestBody: any, endPoint?: string): ng.IPromise { - const deferred: ng.IDeferred = this.$q.defer(); - this.getFormDigestValue(this.baseUrl) - .then((requestDigest: string): ng.IPromise> => { - return this.$http({ - url: endPoint || this.baseUrl + url, - method: "POST", - headers: { - "accept": "application/json;odata=verbose", - "X-RequestDigest": requestDigest, - "content-Type": "application/json;odata=verbose" - }, - data: JSON.stringify(requestBody) - }); - }).then((response: ng.IHttpPromiseCallbackArg): void => { - deferred.resolve(response.data); - }, (error: any): void => { - const iError: IError = { - code: error.data.error.code, - message: error.data.error.message.value, - status: error.status, - statusText: error.statusText - }; - deferred.reject(iError); - }); - return deferred.promise; - } - - public updateRequest(url: string, requestBody: any, eTag: string, endPoint?: string): ng.IPromise<{}> { - const deferred: ng.IDeferred = this.$q.defer(); - this.getFormDigestValue(this.baseUrl) - .then((requestDigest: string): ng.IPromise> => { - return this.$http({ - url: endPoint || this.baseUrl + url, - method: "POST", - headers: { - "accept": "application/json;odata=verbose", - "X-RequestDigest": requestDigest, - "content-Type": "application/json;odata=verbose", - 'IF-MATCH': eTag, - 'X-HTTP-Method': 'MERGE' - }, - data: JSON.stringify(requestBody) - }); - }).then((response: {}): void => { - deferred.resolve(); - }, (error: any): void => { - const iError: IError = { - code: error.data.error.code, - message: error.data.error.message.value, - status: error.status, - statusText: error.statusText - }; - deferred.reject(iError); - }); - return deferred.promise; - } - - public deleteRequest(url: string, eTag: string, endPoint?: string): ng.IPromise<{}> { - const deferred: ng.IDeferred = this.$q.defer(); - this.getFormDigestValue(this.baseUrl) - .then((requestDigest: string): ng.IPromise> => { - return this.$http({ - url: endPoint || this.baseUrl + url, - method: "POST", - headers: { - 'Accept': 'application/json;odata=nometadata', - 'X-RequestDigest': requestDigest, - 'IF-MATCH': eTag, - 'X-HTTP-Method': 'DELETE' - } - }); - }).then((response: {}): void => { - deferred.resolve(); - }, (error: any): void => { - const iError: IError = { - code: error.data.error.code, - message: error.data.error.message.value, - status: error.status, - statusText: error.statusText - }; - deferred.reject(iError); - }); - return deferred.promise; - } - - public fileUploadRequest(url: string, file: ArrayBuffer, endPoint?: string): ng.IPromise { - const deferred: ng.IDeferred = this.$q.defer(); - this.getFormDigestValue(this.baseUrl) - .then((requestDigest: string): ng.IPromise> => { - return this.$http({ - url: endPoint || this.baseUrl + url, - method: "POST", - transformRequest: angular.identity, - headers: { - "accept": "application/json;odata=verbose", - "X-RequestDigest": requestDigest, - "content-Type": undefined - }, - data: ArrayBuffer - }); - }).then((response: ng.IHttpPromiseCallbackArg): void => { - deferred.resolve(response.data); - }, (error: any): void => { - const iError: IError = { - code: error.data.error.code, - message: error.data.error.message.value, - status: error.status, - statusText: error.statusText - }; - deferred.reject(iError); - }); - return deferred.promise; - } - - private getFormDigestValue(webUrl: string): ng.IPromise { - const deferred: ng.IDeferred = this.$q.defer(); - - this.$http({ - url: webUrl + '/_api/contextinfo', - method: 'POST', - headers: { - 'Accept': 'application/json;odata=nometadata' - } - }) - .then((digestResult: ng.IHttpPromiseCallbackArg<{ FormDigestValue: string }>): void => { - deferred.resolve(digestResult.data.FormDigestValue); - }, (error: any): void => { - const iError: IError = { - code: error.data.error.code, - message: error.data.error.message.value, - status: error.status, - statusText: error.statusText - }; - deferred.reject(iError); - }); - - return deferred.promise; - } -} \ No newline at end of file diff --git a/samples/react-appinsights-dashboard/src/common/CommonControl.module.scss b/samples/react-appinsights-dashboard/src/common/CommonControl.module.scss index 92126fea0..47fa80078 100644 --- a/samples/react-appinsights-dashboard/src/common/CommonControl.module.scss +++ b/samples/react-appinsights-dashboard/src/common/CommonControl.module.scss @@ -1,6 +1,3 @@ -:global{ - @import 'node_modules/office-ui-fabric-react/dist/css/fabric.css'; - } .dataLabel { padding-right: 3px; font-size: 14px; @@ -78,6 +75,7 @@ } .chartContainer { height: 350px; + width: 100%; } .chart { height: 358px !important; From b0349fc5157045255b954ae668f8aa0c938d18ce Mon Sep 17 00:00:00 2001 From: Sudharsan K <10280385+sudharsank@users.noreply.github.com> Date: Fri, 3 Jul 2020 15:40:43 +0800 Subject: [PATCH 2/2] Included the codetour for the solution. --- .../.tours/solution-overview.tour | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 samples/react-appinsights-dashboard/.tours/solution-overview.tour diff --git a/samples/react-appinsights-dashboard/.tours/solution-overview.tour b/samples/react-appinsights-dashboard/.tours/solution-overview.tour new file mode 100644 index 000000000..323986e0d --- /dev/null +++ b/samples/react-appinsights-dashboard/.tours/solution-overview.tour @@ -0,0 +1,160 @@ +{ + "title": "solution-overview", + "steps": [ + { + "file": "src/webparts/appInsightsDashboard/AppInsightsDashboardWebPart.ts", + "description": "Webpart properties declared to capture the below information\n1. **_AppId_** - Application ID of the Azure App Insights\n2. **_AppKey_** - Application key of the Azure App Insights", + "selection": { + "start": { + "line": 14, + "character": 1 + }, + "end": { + "line": 17, + "character": 2 + } + } + }, + { + "file": "src/webparts/appInsightsDashboard/components/AppInsightsDashboard.tsx", + "line": 22, + "description": "Upated the default class component to **React Functional component**.", + "selection": { + "start": { + "line": 22, + "character": 1 + }, + "end": { + "line": 22, + "character": 95 + } + } + }, + { + "file": "src/webparts/appInsightsDashboard/components/AppInsightsDashboard.tsx", + "line": 31, + "description": "Using **React Context API** feature to pass the properties using context instead of passing the properties to each component.", + "selection": { + "start": { + "line": 31, + "character": 3 + }, + "end": { + "line": 31, + "character": 44 + } + } + }, + { + "file": "src/webparts/appInsightsDashboard/components/AppInsightsDashboard.tsx", + "line": 52, + "description": "Child components for different statistics\n1. **_Page Views_**\n2. **_User statistics_**\n3. **_Performance statistics_**", + "selection": { + "start": { + "line": 44, + "character": 9 + }, + "end": { + "line": 52, + "character": 15 + } + } + }, + { + "file": "src/common/components/CustomPivot.tsx", + "line": 29, + "description": "Created a **custom Pivot component** using **Office UI Fabric Pivot control** to match the **Azure style**. All the statistics child components will use this custom pivot component for interval and timespan selection.", + "selection": { + "start": { + "line": 16, + "character": 9 + }, + "end": { + "line": 29, + "character": 15 + } + } + }, + { + "file": "src/common/components/DataList.tsx", + "line": 80, + "description": "Common **Details List** component using **Office UI Fabric Details list** control to display the data as a list for some of the statistics along with the graphical representation.", + "selection": { + "start": { + "line": 51, + "character": 9 + }, + "end": { + "line": 80, + "character": 15 + } + } + }, + { + "file": "src/common/enumHelper.ts", + "line": 28, + "description": "Enum collections for user selection\n1. **_Time Interval_**\n2. **_Time Span_**\n3. **_Segments_**", + "selection": { + "start": { + "line": 1, + "character": 1 + }, + "end": { + "line": 28, + "character": 2 + } + } + }, + { + "file": "src/common/Helper.ts", + "line": 7, + "description": "Common Helper class to define all the communications to **Azure App Insights API**." + }, + { + "file": "src/common/components/PerformanceStatistics.tsx", + "line": 61, + "description": "Using **Kusto query** to read the information from **Azure App Insights** and then to populate the data in a **Details List** or **Chart**.", + "selection": { + "start": { + "line": 49, + "character": 13 + }, + "end": { + "line": 61, + "character": 87 + } + } + }, + { + "file": "src/common/Helper.ts", + "line": 78, + "description": "Passing the **Kusto query** to the helper method along with some key parameters.", + "selection": { + "start": { + "line": 69, + "character": 5 + }, + "end": { + "line": 78, + "character": 6 + } + } + }, + { + "file": "src/common/Helper.ts", + "line": 116, + "description": "Sending the final consolidated URL with query and dynamic values to another helper method to get the actual response from **Azure App Insights**.\nBelow is the post url used\n\n**https://api.applicationinsights.io/v1/app**", + "selection": { + "start": { + "line": 113, + "character": 5 + }, + "end": { + "line": 116, + "character": 6 + } + } + } + ], + "ref": "master" +} \ No newline at end of file