Skip to content

Commit

Permalink
Merge branch 'a1mery-ChartCard-FilesByContentType_Improvements' into …
Browse files Browse the repository at this point in the history
…'main'
  • Loading branch information
anoopt committed Oct 4, 2024
2 parents f55b1bb + d02729c commit e58f647
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 94 deletions.
4 changes: 2 additions & 2 deletions samples/ChartCard-FilesByContentType/assets/sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
],
"authors": [
{
"gitHubAccount": "aimery_thomas",
"pictureUrl": "https://github.com/aimery_thomas.png",
"gitHubAccount": "a1mery",
"pictureUrl": "https://github.com/a1mery.png",
"name": "Aimery Thomas"
}
],
Expand Down
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[];
};
2 changes: 1 addition & 1 deletion samples/ImageCard-HTML-React-FAQs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ This ACE allows you to display a list of FAQs. The FAQs are stored in the proper
- in the command-line run:
- **npm install**
- **gulp serve**
- Add the "Fequently Asked Quesiotns" ACE to the dashboard page
- Add the "Fequently Asked Questions" ACE to the dashboard page
- Edit the properties of the ACE as needed

## References
Expand Down
34 changes: 24 additions & 10 deletions samples/ImageCard-HTML-React-FAQs/assets/sample.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[{
"name": "pnp-sp-fx-aces-imagecard-html-react-faqs",
"source": "pnp",
"title": "Frequently Asked Questions",
"shortDescription": "Displays a list of frequently asked questions.",
"title": "Frequently Asked Questions - Adaptive Card Extension",
"shortDescription": "This Adaptive Card Extension (ACE) sample shows how to use HTML and React in an ACEs which was introduced in SPFx 1.20.0. This ACE allows you to display a list of FAQs. The FAQs are stored in the properties of ACE and are displayed as an accordion in the QuickView.",
"url": "https://github.com/pnp/sp-dev-fx-aces/tree/main/samples/ImageCard-HTML-React-FAQs",
"longDescription": [
"This sample demonstrates how to create an Adaptive Card Extension that displays a list of frequently asked questions. The sample uses React to render the FAQs in the QuickView."
"This Adaptive Card extension (ACE) sample shows how to use HTML and React in an ACEs which was introduced in SPFx 1.20.0. This ACE allows you to display a list of FAQs. The FAQs are stored in the properties of ACE and are displayed as an accordion in the QuickView."
],
"creationDateTime": "2024-09-13",
"updateDateTime": "2024-09-13",
Expand All @@ -22,12 +22,26 @@
"value": "1.20.0-rc1"
}
],
"thumbnails": [{
"type": "image",
"order": 100,
"url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/ImageCard-HTML-React-FAQs/assets/demo.gif",
"alt": "Preview"
}],
"thumbnails": [
{
"type": "image",
"order": 100,
"url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/ImageCard-HTML-React-FAQs/assets/demo.gif",
"alt": "Preview"
},
{
"type": "image",
"order": 200,
"url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/ImageCard-HTML-React-FAQs/assets/medium.png",
"alt": "Preview"
},
{
"type": "image",
"order": 300,
"url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/ImageCard-HTML-React-FAQs/assets/large.png",
"alt": "Preview"
}
],
"authors": [{
"gitHubAccount": "anoopt",
"pictureUrl": "https://github.com/anoopt.png",
Expand All @@ -48,4 +62,4 @@
"url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/viva/design/design-intro"
}
]
}]
}]

0 comments on commit e58f647

Please sign in to comment.