Added sample.json, container and fixed linting issues

This commit is contained in:
Hugo Bernier 2023-03-12 13:35:13 -04:00
parent f7d5c87c1a
commit bbdc0d7a23
8 changed files with 182 additions and 44 deletions

View File

@ -0,0 +1,39 @@
// For more information on how to run this SPFx project in a VS Code Remote Container, please visit https://aka.ms/spfx-devcontainer
{
"name": "SPFx 1.16.1",
"image": "docker.io/m365pnp/spfx:1.16.1",
// Set *default* container specific settings.json values on container create.
"settings": {},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
4321,
35729
],
"portsAttributes": {
"4321": {
"protocol": "https",
"label": "Manifest",
"onAutoForward": "silent",
"requireLocalPort": true
},
// Not needed for SPFx>= 1.12.1
// "5432": {
// "protocol": "https",
// "label": "Workbench",
// "onAutoForward": "silent"
// },
"35729": {
"protocol": "https",
"label": "LiveReload",
"onAutoForward": "silent",
"requireLocalPort": true
}
},
"postCreateCommand": "bash .devcontainer/spfx-startup.sh",
"remoteUser": "node"
}

View File

@ -0,0 +1,33 @@
echo
echo -e "\e[1;94mInstalling Node dependencies\e[0m"
npm install
## commands to create dev certificate and copy it to the root folder of the project
echo
echo -e "\e[1;94mGenerating dev certificate\e[0m"
gulp trust-dev-cert
# Convert the generated PEM certificate to a CER certificate
openssl x509 -inform PEM -in ~/.rushstack/rushstack-serve.pem -outform DER -out ./spfx-dev-cert.cer
# Copy the PEM ecrtificate for non-Windows hosts
cp ~/.rushstack/rushstack-serve.pem ./spfx-dev-cert.pem
## add *.cer to .gitignore to prevent certificates from being saved in repo
if ! grep -Fxq '*.cer' ./.gitignore
then
echo "# .CER Certificates" >> .gitignore
echo "*.cer" >> .gitignore
fi
## add *.pem to .gitignore to prevent certificates from being saved in repo
if ! grep -Fxq '*.pem' ./.gitignore
then
echo "# .PEM Certificates" >> .gitignore
echo "*.pem" >> .gitignore
fi
echo
echo -e "\e[1;92mReady!\e[0m"
echo -e "\n\e[1;94m**********\nOptional: if you plan on using gulp serve, don't forget to add the container certificate to your local machine. Please visit https://aka.ms/spfx-devcontainer for more information\n**********"

View File

@ -1,8 +1,8 @@
# Github Profile display Via API
# GitHub Profile display via API
## Summary
This webpart loads the github profile using SPHttp client in PnP v3.
This web part loads the GitHub profile using SPHttp client in PnP v3.
![Display Output](assets/OutputGithubProfile.png)
To change the profile or to use your own API follow the below path
@ -36,13 +36,9 @@ To change the profile or to use your own API follow the below path
> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram)
## Contributors
## Solution
| Solution | Author(s) |
| ----------- | ------------------------------------------------------- |
| react-pnpjs-http-client | [Divya Akula](https://github.com/divya-akula/) [@divya-akula](https://twitter.com/_divyaakula)
- [Divya Akula](https://github.com/divya-akula/) [@divya-akula](https://twitter.com/_divyaakula)
## Version history
@ -50,21 +46,16 @@ To change the profile or to use your own API follow the below path
| ------- | ---------------- | --------------- |
| 1.0 | March 07, 2023 | Initial release |
## Disclaimer
## Minimal path to awesome
**THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
---
- Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-pnpjs-http-client) then unzip it)
- From your command line, change your current directory to the directory containing this sample (`react-pnpjs-http-client`, located under `samples`)
- in the command line run:
- `npm install`
- `gulp serve`
## Minimal Path to Awesome
- Clone this repository
- Ensure that you are at the solution folder
- in the command-line run:
- **npm install**
- **gulp serve**
> Include any additional steps as needed.
> This sample can also be opened with [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview). Visit <https://aka.ms/spfx-devcontainer> for further instructions.
## Features
@ -72,11 +63,10 @@ Description of the extension that expands upon high-level summary above.
This extension illustrates the following concepts:
- invoking third party api
- invoking third party API
- PnPjs v3
- Document card layout
## References
- [Getting started with SharePoint Framework](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/set-up-your-developer-tenant)
@ -85,3 +75,25 @@ This extension illustrates the following concepts:
- [Publish SharePoint Framework applications to the Marketplace](https://docs.microsoft.com/en-us/sharepoint/dev/spfx/publish-to-marketplace-overview)
- [Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp) - Guidance, tooling, samples and open-source controls for your Microsoft 365 development
- [PnPjs Transition guide](https://pnp.github.io/pnpjs/transition-guide/) - Guidance for migrating to latest framework of pnpjs
## Help
We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
If you're having issues building the solution, please run [spfx doctor](https://pnp.github.io/cli-microsoft365/cmd/spfx/spfx-doctor/) from within the solution folder to diagnose incompatibility issues with your environment.
You can try looking at [issues related to this sample](https://github.com/pnp/sp-dev-fx-webparts/issues?q=label%3A%22sample%3A%20react-pnpjs-http-client%22) to see if anybody else is having the same issues.
You can also try looking at [discussions related to this sample](https://github.com/pnp/sp-dev-fx-webparts/discussions?discussions_q=react-pnpjs-http-client) and see what the community is saying.
If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Abug-suspected%2Csample%3A%20react-pnpjs-http-client&template=bug-report.yml&sample=react-pnpjs-http-client&authors=@divya-akula&title=react-pnpjs-http-client%20-%20).
For questions regarding this sample, [create a new question](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Aquestion%2Csample%3A%20react-pnpjs-http-client&template=question.yml&sample=react-pnpjs-http-client&authors=@divya-akula&title=react-pnpjs-http-client%20-%20).
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/sp-dev-fx-webparts/issues/new?assignees=&labels=Needs%3A+Triage+%3Amag%3A%2Ctype%3Aenhancement%2Csample%3A%20react-pnpjs-http-client&template=suggestion.yml&sample=react-pnpjs-http-client&authors=@divya-akula&title=react-pnpjs-http-client%20-%20).
## Disclaimer
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
<img src="https://pnptelemetry.azurewebsites.net/sp-dev-fx-webparts/samples/react-pnpjs-http-client" />

View File

@ -0,0 +1,50 @@
[
{
"name": "pnp-sp-dev-spfx-web-parts-react-pnpjs-http-client",
"source": "pnp",
"title": "GitHub Profile display via API",
"shortDescription": "This web part loads the GitHub profile using SPHttp client in PnP v3.",
"url": "https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-pnpjs-http-client",
"downloadUrl": "https://pnp.github.io/download-partial/?url=https://github.com/pnp/sp-dev-fx-webparts/tree/main/samples/react-pnpjs-http-client",
"longDescription": [
"This web part loads the GitHub profile using SPHttp client in PnP v3."
],
"creationDateTime": "2023-03-07",
"updateDateTime": "2023-03-07",
"products": [
"SharePoint"
],
"metadata": [
{
"key": "CLIENT-SIDE-DEV",
"value": "React"
},
{
"key": "SPFX-VERSION",
"value": "1.16.1"
}
],
"thumbnails": [
{
"type": "image",
"order": 100,
"url": "https://github.com/pnp/sp-dev-fx-webparts/raw/main/samples/react-pnpjs-http-client/assets/UpdateAPICall.png",
"alt": "Web Part Preview"
}
],
"authors": [
{
"gitHubAccount": "divya-akula",
"pictureUrl": "https://github.com/divya-akula.png",
"name": "Divya Akula"
}
],
"references": [
{
"name": "Build your first SharePoint client-side web part",
"description": "Client-side web parts are client-side components that run in the context of a SharePoint page. Client-side web parts can be deployed to SharePoint environments that support the SharePoint Framework. You can also use modern JavaScript web frameworks, tools, and libraries to build them.",
"url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/get-started/build-a-hello-world-web-part"
}
]
}
]

View File

@ -13,11 +13,11 @@ import { AdalClient } from "@pnp/adaljsclient";
import "@microsoft/sp-http";
import { spfi, SPFx as spSPFx } from "@pnp/sp";
import { graphfi, SPFx as graphSPFx} from "@pnp/graph";
// eslint-disable-next-line no-var
var _sp: SPFI = null;
var _graph:GraphFI=null;
var _SpHttpClient:SPHttpClient = null;
var _adalClient: any = null;
let _sp: SPFI = null;
let _graph:GraphFI=null;
let _SpHttpClient:SPHttpClient = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let _adalClient: any = null;
export const getSP = (context?: WebPartContext): SPFI => {
if (context != null) { // eslint-disable-line eqeqeq
@ -41,21 +41,22 @@ export const getGraph = (context?: WebPartContext): GraphFI => {
// _sp = spfi().using(SPFx(context)).using(PnPLogging(LogLevel.Warning));
// _sp = spfi().using(SPFx(context)).using(PnPLogging(LogLevel.Warning));
// _sp = spfi().using(SPFx(context)).using(PnPLogging(LogLevel.Warning));
if (context != null) {
if (context !== null) {
_graph = graphfi().using(graphSPFx(context)).using(DefaultHeaders());
}
return _graph;
};
export const getSPHttpClient =(context?: WebPartContext):SPHttpClient=>{
if (context != null) {
if (context !== null) {
_SpHttpClient = context.spHttpClient;
}
return _SpHttpClient;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const getAdalClient =(context?: WebPartContext):any=>{
if (context != null) {
if (context !== null) {
_adalClient = AdalClient.fromSPFxContext(context);
}

View File

@ -28,7 +28,7 @@ export default class ApimsalWebPart extends BaseClientSideWebPart<IApimsalWebPar
protected get isRenderAsync(): boolean {
return true;
}
public async render() {
public async render(): Promise<void> {
const element: React.ReactElement<IApimsalProps> = React.createElement(
Apimsal,
{

View File

@ -24,8 +24,10 @@ export class UserServics implements IUserService {
this._httpClient = serviceScope.consume(HttpClient.serviceKey);
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async getUserDetails(upn: string,url:string): Promise<any> {
const _client: HttpClient = await this._httpClient;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const httpClientOptions:any = {
headers: { "Content-Type": "application/json" },
method:"GET"
@ -33,10 +35,12 @@ export class UserServics implements IUserService {
};
let userDets= null;
await _client.fetch("https://api.github.com/users/divya-akula",HttpClient.configurations.v1,httpClientOptions).
// eslint-disable-next-line @typescript-eslint/no-explicit-any
then((res:any): Promise<any>=>{
userDets= res.json();
return userDets;
}).
// eslint-disable-next-line @typescript-eslint/no-explicit-any
catch((err:any)=>{
console.warn(err);
});

View File

@ -24,21 +24,23 @@ export default class Apimsal extends React.Component<IApimsalProps,GitUser, {}>
// public async componentDidMount() {
public componentDidMount(): void {
public async componentDidMount(): Promise<void> {
// read all file sizes from Documents library
console.log("loadedx");
this.state={
this.setState({
"name": "",
"blog": "",
"followers":9,
"imageUrl":""
}
});
this.fetchUserDetails();
await this.fetchUserDetails();
}
private fetchUserDetails= async (): Promise<void> => {
this.props.userService.getUserDetails("divya-akula","name").then((result:any)=>{
// @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await this.props.userService.getUserDetails("divya-akula","name").then((result:any)=>{
this.setState({name: result.name,followers:result.followers,blog:result.blog,imageUrl:result.
avatar_url}
);
@ -54,15 +56,14 @@ private fetchUserDetails= async (): Promise<void> => {
isDarkTheme,
hasTeamsContext,
} = this.props;
if(this.state != null)
if(this.state !== null)
{
return (
<section className={`${styles.apimsal} ${hasTeamsContext ? styles.teams : ''}`}>
<div>
{/* <h3>{this.state.user.name}</h3> */}
<this.UserElement blog={this.state.blog} followers={this.state.followers} name={this.state.name} imageUrl={this.state.imageUrl}/>
<div >
</div>
<div />
</div>
</section>);
}
@ -71,14 +72,14 @@ private fetchUserDetails= async (): Promise<void> => {
<div className={styles.welcome}>
<img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className={styles.welcomeImage} />
<h2>Well done, !</h2>
<div></div>
<div/>
<div>Web part property value: </div>
</div>
<div>
<div className="ms-Grid">
<div className="ms-Grid-row">
<div className="ms-Grid-col">
I am empty <i className="ms-Icon ms-Icon--Sad" aria-hidden="true"></i>
I am empty <i className="ms-Icon ms-Icon--Sad" aria-hidden="true"/>
</div>
</div>
</div>
@ -109,9 +110,7 @@ private fetchUserDetails= async (): Promise<void> => {
title={currentUser.name}
shouldTruncate={true}
/>
<DocumentCardActivity people={[{ name: String( currentUser.followers), profileImageSrc: currentUser.imageUrl }]} activity={currentUser.blog}>
</DocumentCardActivity>
<DocumentCardActivity people={[{ name: String( currentUser.followers), profileImageSrc: currentUser.imageUrl }]} activity={currentUser.blog}/>
</DocumentCardDetails>
</DocumentCard>