Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Ejaz Hussain committed Oct 10, 2024
2 parents 456dff3 + b647ec7 commit 40a9437
Show file tree
Hide file tree
Showing 9 changed files with 21,903 additions and 17,833 deletions.
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
import { MSGraphClientV3 } from "@microsoft/sp-http";
import { AdaptiveCardExtensionContext } from '@microsoft/sp-adaptive-card-extension-base';
import { GraphFiles } from './types';


export interface IFileService {
_getFiles(siteAddress: string, listTitle: string): Promise<GraphFiles>;
}

export class FileService implements IFileService {
public context: AdaptiveCardExtensionContext;
private MSGraphClient: MSGraphClientV3;

constructor(context: AdaptiveCardExtensionContext) {
this.context = context;
}

public async _getFiles(siteAddress: string, listTitle: string): Promise<GraphFiles> {
let files: GraphFiles;
try{
const client = await this._getClient();
const siteId = await this._getSiteId(client, siteAddress);
const listId = await this._getListId(client, siteId, listTitle);
files = await client.api("sites/"+siteId+"/lists/"+listId+"/items").select("contentType").version('beta').get();
} catch{
files = {value:[]};
}
return files;
}

private async _getSiteId (client:MSGraphClientV3, siteAddress: string): Promise<string> {
const hostname = siteAddress.split('/')[2];
const serverRelativeUrl = siteAddress.split(hostname)[1];
const siteId = await client.api("sites/"+hostname+":"+serverRelativeUrl).version('beta').get();
return siteId.id;
}

private async _getListId (client:MSGraphClientV3, siteId: string, listTitle: string): Promise<string> {
const list = await client.api("sites/"+siteId+"/lists").version('beta').filter("displayName eq '"+listTitle+"'").get();
return list.value[0].id;
}

private async _getClient(): Promise<MSGraphClientV3> {
if (this.MSGraphClient === undefined)
this.MSGraphClient = await this.context.msGraphClientFactory.getClient("3");
return this.MSGraphClient;
}
import { MSGraphClientV3 } from "@microsoft/sp-http";
import { AdaptiveCardExtensionContext } from '@microsoft/sp-adaptive-card-extension-base';
import { GraphFiles } from './types';


export interface IFileService {
_getFiles(siteAddress: string, listTitle: string): Promise<GraphFiles>;
}

export class FileService implements IFileService {
public context: AdaptiveCardExtensionContext;
private MSGraphClient: MSGraphClientV3;

constructor(context: AdaptiveCardExtensionContext) {
this.context = context;
}

public async _getFiles(siteAddress: string, listTitle: string): Promise<GraphFiles> {
let files: GraphFiles;
try{
const client = await this._getClient();
const siteId = await this._getSiteId(client, siteAddress);
const listId = await this._getListId(client, siteId, listTitle);
files = await client.api("sites/"+siteId+"/lists/"+listId+"/items").select("contentType").version('beta').get();
} catch{
files = {value:[]};
}
return files;
}

private async _getSiteId (client:MSGraphClientV3, siteAddress: string): Promise<string> {
const hostname = siteAddress.split('/')[2];
const serverRelativeUrl = siteAddress.split(hostname)[1];
const siteId = await client.api("sites/"+hostname+":"+serverRelativeUrl).version('beta').get();
return siteId.id;
}

private async _getListId (client:MSGraphClientV3, siteId: string, listTitle: string): Promise<string> {
const list = await client.api("sites/"+siteId+"/lists").version('beta').filter("displayName eq '"+listTitle+"'").get();
return list.value[0].id;
}

private async _getClient(): Promise<MSGraphClientV3> {
if (this.MSGraphClient === undefined)
this.MSGraphClient = await this.context.msGraphClientFactory.getClient("3");
return this.MSGraphClient;
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { IPropertyPaneConfiguration } from '@microsoft/sp-property-pane';
import { BaseAdaptiveCardExtension } from '@microsoft/sp-adaptive-card-extension-base';
import { BaseAdaptiveCardExtension, IPieDataPoint } from '@microsoft/sp-adaptive-card-extension-base';
import { CardView } from './cardView/CardView';
import { FilesByContentTypePropertyPane } from './FilesByContentTypePropertyPane';
import { QuickView } from './quickView/QuickView';
import { FileService, IFileService } from '../FileService';
import { GraphFiles, PieFileData } from '../types';
import { GraphFiles } from '../types';

export interface IFilesByContentTypeAdaptiveCardExtensionProps {
title: string;
siteAddress: string;
listTitle: string;
filesNumberByCtP: PieFileData[]
}

export interface IFilesByContentTypeAdaptiveCardExtensionState {
filesNumberByCtP: IPieDataPoint[];
}

const CARD_VIEW_REGISTRY_ID: string = 'FilesByContentType_CARD_VIEW';
Expand All @@ -27,7 +27,9 @@ export default class FilesByContentTypeAdaptiveCardExtension extends BaseAdaptiv
private _deferredPropertyPane: FilesByContentTypePropertyPane;

public async onInit(): Promise<void> {
this.state = {};
this.state = {
filesNumberByCtP: []
};
// registers the card view to be shown in a dashboard
this.cardNavigator.register(CARD_VIEW_REGISTRY_ID, () => new CardView());
// registers the quick view to open via QuickView action
Expand All @@ -37,16 +39,20 @@ export default class FilesByContentTypeAdaptiveCardExtension extends BaseAdaptiv
}

private async retrieveFiles(): Promise<void> {
let filesData: PieFileData[] = [];

const service: IFileService = new FileService(this.context);
const allFiles: GraphFiles = await service._getFiles(this.properties.siteAddress, this.properties.listTitle);
const ctNames: string[] = allFiles.value.map((file) => file.contentType.name);

let filesData: IPieDataPoint[] = [];
let uniqueNames = [...new Set(ctNames)];
uniqueNames.forEach(ctName => {
let currentCtCount = allFiles.value.filter(file => file.contentType.name === ctName);
filesData.push({ name: ctName, total: currentCtCount.length });
filesData.push({ x: ctName, y: currentCtCount.length });
})
this.setState({
filesNumberByCtP: filesData
})
this.properties.filesNumberByCtP = filesData;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
IDataVisualizationCardViewParameters,
IExternalLinkCardAction,
IQuickViewCardAction,
IPieDataPoint,
PieChartCardView,
} from '@microsoft/sp-adaptive-card-extension-base';
import {
Expand All @@ -12,31 +11,39 @@ import {
QUICK_VIEW_REGISTRY_ID,
} from '../FilesByContentTypeAdaptiveCardExtension';

let fileSeries: IPieDataPoint[]= [];

export class CardView extends BaseComponentsCardView<
IFilesByContentTypeAdaptiveCardExtensionProps,
IFilesByContentTypeAdaptiveCardExtensionState,
IDataVisualizationCardViewParameters
> {

public get cardViewParameters(): IDataVisualizationCardViewParameters {
fileSeries = [];
this.properties.filesNumberByCtP.forEach(contentType =>{
fileSeries.push({x: contentType.name, y: contentType.total});
});
this.properties.filesNumberByCtP = [];
return PieChartCardView({
cardBar: {
componentName: 'cardBar',
title: this.properties.title
},
header: {
componentName: 'text',
text: this.properties.listTitle
},
body: {
componentName: 'dataVisualization',
dataVisualizationKind: 'pie',
isDonut: false,
series: [{
data: fileSeries,
data: this.state.filesNumberByCtP
}]
},
footer: {
componentName: 'cardButton',
title: 'View Details',
action: {
type: 'QuickView',
parameters: {
view: QUICK_VIEW_REGISTRY_ID
}
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
export type File = {
"@odata.etag"?: string;
contentType: {
id: string;
name: string;
}
};


export type GraphFiles = {
"@odata.context"?: string;
value: File[];
};

export type PieFileData ={
name: string;
total: number;
}
export type File = {
"@odata.etag"?: string;
contentType: {
id: string;
name: string;
}
};


export type GraphFiles = {
"@odata.context"?: string;
value: File[];
};
33 changes: 0 additions & 33 deletions samples/ImageCard-HTML-React-FAQs/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,6 @@ module.exports = {
'@rushstack/security/no-unsafe-regexp': 1,
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
'@typescript-eslint/adjacent-overload-signatures': 1,
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
//
// CONFIGURATION: By default, these are banned: String, Boolean, Number, Object, Symbol
'@typescript-eslint/ban-types': [
1,
{
'extendDefaults': false,
'types': {
'String': {
'message': 'Use \'string\' instead',
'fixWith': 'string'
},
'Boolean': {
'message': 'Use \'boolean\' instead',
'fixWith': 'boolean'
},
'Number': {
'message': 'Use \'number\' instead',
'fixWith': 'number'
},
'Object': {
'message': 'Use \'object\' instead, or else define a proper TypeScript type:'
},
'Symbol': {
'message': 'Use \'symbol\' instead',
'fixWith': 'symbol'
},
'Function': {
'message': 'The \'Function\' type accepts any function-like value.\nIt provides no type safety when calling the function, which can be a common source of bugs.\nIt also accepts things like class declarations, which will throw at runtime as they will not be called with \'new\'.\nIf you are expecting the function to accept certain arguments, you should explicitly define the function shape.'
}
}
}
],
// RATIONALE: Code is more readable when the type of every variable is immediately obvious.
// Even if the compiler may be able to infer a type, this inference will be unavailable
// to a person who is reviewing a GitHub diff. This rule makes writing code harder,
Expand Down
3 changes: 2 additions & 1 deletion samples/ImageCard-HTML-React-FAQs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This ACE allows you to display a list of FAQs. The FAQs are stored in the proper

## Used SharePoint Framework Version

![version](https://img.shields.io/badge/version-1.20.0--rc.1-yellow.svg)
![version](https://img.shields.io/badge/version-1.20.0-yellow.svg)

## Applies to

Expand All @@ -41,6 +41,7 @@ This ACE allows you to display a list of FAQs. The FAQs are stored in the proper
| Version | Date | Comments |
| ------- | ---------------- | --------------- |
| 1.0 | September 13, 2024 | Initial release |
| 1.1 | October 04, 2024 | Updated to SPFx 1.20 |

## Disclaimer

Expand Down
6 changes: 6 additions & 0 deletions samples/ImageCard-HTML-React-FAQs/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@ build.rig.getTasks = function () {
return result;
};

/* fast-serve */
const { addFastServe } = require("spfx-fast-serve-helpers");
addFastServe(build);
/* end of fast-serve */

build.initialize(require('gulp'));

Loading

0 comments on commit 40a9437

Please sign in to comment.