Merge pull request #1369 from sudharsank/react-appinsights-dashboard
This commit is contained in:
commit
11c471c199
|
@ -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 = (<any>window)._spPageContextInfo.webAbsoluteUrl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public getRequest(query?: string, endPoint?: string): ng.IPromise<any> {
|
|
||||||
const deferred: ng.IDeferred<any> = 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<any> {
|
|
||||||
const deferred: ng.IDeferred<any> = this.$q.defer();
|
|
||||||
this.getFormDigestValue(this.baseUrl)
|
|
||||||
.then((requestDigest: string): ng.IPromise<ng.IHttpPromiseCallbackArg<any>> => {
|
|
||||||
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<any>): 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<any> = this.$q.defer();
|
|
||||||
this.getFormDigestValue(this.baseUrl)
|
|
||||||
.then((requestDigest: string): ng.IPromise<ng.IHttpPromiseCallbackArg<any>> => {
|
|
||||||
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<any> = this.$q.defer();
|
|
||||||
this.getFormDigestValue(this.baseUrl)
|
|
||||||
.then((requestDigest: string): ng.IPromise<ng.IHttpPromiseCallbackArg<any>> => {
|
|
||||||
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<any> {
|
|
||||||
const deferred: ng.IDeferred<any> = this.$q.defer();
|
|
||||||
this.getFormDigestValue(this.baseUrl)
|
|
||||||
.then((requestDigest: string): ng.IPromise<ng.IHttpPromiseCallbackArg<any>> => {
|
|
||||||
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<any>): 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<string> {
|
|
||||||
const deferred: ng.IDeferred<string> = 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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"
|
||||||
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
:global{
|
|
||||||
@import 'node_modules/office-ui-fabric-react/dist/css/fabric.css';
|
|
||||||
}
|
|
||||||
.dataLabel {
|
.dataLabel {
|
||||||
padding-right: 3px;
|
padding-right: 3px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -78,6 +75,7 @@
|
||||||
}
|
}
|
||||||
.chartContainer {
|
.chartContainer {
|
||||||
height: 350px;
|
height: 350px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.chart {
|
.chart {
|
||||||
height: 358px !important;
|
height: 358px !important;
|
||||||
|
|
Loading…
Reference in New Issue