Updated sample, container, linting issues
This commit is contained in:
parent
643bf996f9
commit
e31c94ac76
|
@ -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"
|
||||
}
|
|
@ -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**********"
|
|
@ -9,7 +9,7 @@
|
|||
"This is sample web part using SPFx and MSGraph to fetch the users information based on First Name, Last Name and Email Address. web part will fetch data from directory using Graph API and display in details list."
|
||||
],
|
||||
"creationDateTime": "2020-11-07",
|
||||
"updateDateTime": "2021-08-07",
|
||||
"updateDateTime": "2023-03-10",
|
||||
"products": [
|
||||
"SharePoint"
|
||||
],
|
||||
|
@ -20,7 +20,7 @@
|
|||
},
|
||||
{
|
||||
"key": "SPFX-VERSION",
|
||||
"value": "1.11.0"
|
||||
"value": "1.16.1"
|
||||
}
|
||||
],
|
||||
"thumbnails": [
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,16 @@
|
|||
import { IMSGraphService } from "./IMSGraphService";
|
||||
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
||||
import { IUserProperties } from "./IUserProperties";
|
||||
import { MSGraphClient,MSGraphClientFactory } from "@microsoft/sp-http";
|
||||
import { MSGraphClient } from "@microsoft/sp-http";
|
||||
import { Log } from "@microsoft/sp-core-library";
|
||||
const LOG_SOURCE = "MSGraphService";
|
||||
export class MSGraphService implements IMSGraphService{
|
||||
|
||||
public async getUserProperties(email:string,client:MSGraphClient):Promise<IUserProperties[]>{
|
||||
let userProperties:IUserProperties[] = [];
|
||||
const userProperties:IUserProperties[] = [];
|
||||
try {
|
||||
//let client:MSGraphClient = await context.msGraphClientFactory.getClient().then();
|
||||
let endPoint:string = `/Users/${email}`;
|
||||
let response = await client.api(`${endPoint}`).version("v1.0").get();
|
||||
const endPoint = `/Users/${email}`;
|
||||
const response = await client.api(`${endPoint}`).version("v1.0").get();
|
||||
if(response){
|
||||
userProperties.push({
|
||||
businessPhone:response.businessPhones[0],
|
||||
|
@ -31,12 +30,13 @@ export class MSGraphService implements IMSGraphService{
|
|||
}
|
||||
|
||||
public async getUserPropertiesByLastName(searchFor:string,client:MSGraphClient):Promise<IUserProperties[]>{
|
||||
let userProperties:IUserProperties[] = [];
|
||||
const userProperties:IUserProperties[] = [];
|
||||
try {
|
||||
let res = await client.api("users")
|
||||
const res = await client.api("users")
|
||||
.version("v1.0")
|
||||
.filter(`(startswith(surname,'${escape(searchFor)}'))`).get();
|
||||
if(res.value.length !== 0){
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
||||
res.value.map((_userProperty:any,_index:any)=>{
|
||||
if(_userProperty.mail !== null){
|
||||
userProperties.push({
|
||||
|
@ -60,12 +60,13 @@ export class MSGraphService implements IMSGraphService{
|
|||
}
|
||||
|
||||
public async getUserPropertiesByFirstName(searchFor:string,client:MSGraphClient):Promise<IUserProperties[]>{
|
||||
let userProperties:IUserProperties[] = [];
|
||||
const userProperties:IUserProperties[] = [];
|
||||
try {
|
||||
let res = await client.api("users")
|
||||
const res = await client.api("users")
|
||||
.version("v1.0")
|
||||
.filter(`(startswith(givenName,'${escape(searchFor)}'))`).get();
|
||||
if(res.value.length !== 0){
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
||||
res.value.map((_userProperty:any,_index:any)=>{
|
||||
if(_userProperty.mail !== null){
|
||||
userProperties.push({
|
||||
|
@ -88,12 +89,13 @@ export class MSGraphService implements IMSGraphService{
|
|||
|
||||
}
|
||||
public async getUserPropertiesBySearch(searchFor:string,client:MSGraphClient):Promise<IUserProperties[]>{
|
||||
let userProperties:IUserProperties[] = [];
|
||||
const userProperties:IUserProperties[] = [];
|
||||
try {
|
||||
let res = await client.api("users")
|
||||
const res = await client.api("users")
|
||||
.version("v1.0")
|
||||
.filter(`(startswith(displayName,'${escape(searchFor)}'))`).get();
|
||||
if(res.value.length !== 0){
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
||||
res.value.map((_userProperty:any,_index:any)=>{
|
||||
userProperties.push({
|
||||
businessPhone:_userProperty.businessPhones[0],
|
||||
|
@ -113,4 +115,4 @@ export class MSGraphService implements IMSGraphService{
|
|||
return userProperties;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,8 @@ import { autobind } from "office-ui-fabric-react/lib/Utilities";
|
|||
import { PeoplePicker, PrincipalType } from '@pnp/spfx-controls-react/lib/PeoplePicker';
|
||||
import { } from "@pnp/spfx-controls-react/";
|
||||
import { Stack, IStackProps, IStackStyles } from 'office-ui-fabric-react/lib/Stack';
|
||||
import { DetailsList, DetailsListLayoutMode, IColumn, SelectionMode } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
const LOG_SOURCE = "ByFirstName";
|
||||
import { DetailsList, DetailsListLayoutMode } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
const stackTokens = { childrenGap: 50 };
|
||||
const iconProps = { iconName: 'Calendar' };
|
||||
const stackStyles: Partial<IStackStyles> = { root: { width: 650 } };
|
||||
const columnProps: Partial<IStackProps> = {
|
||||
tokens: { childrenGap: 15 },
|
||||
|
@ -28,20 +26,9 @@ export class ByEmail extends React.Component<ByEmailProps,ByEmailState>{
|
|||
};
|
||||
}
|
||||
|
||||
@autobind
|
||||
private _getPeoplePickerItems(items: any[]) {
|
||||
if(items.length == 1){
|
||||
this.getUsers(items[0].secondaryText !== ""?items[0].secondaryText:items[0].id.split('|').pop());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setState({
|
||||
userProperties:[]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private async getUsers(email:string) : Promise<any>{
|
||||
this.setState({loading:true},async()=>{
|
||||
await this.props.MSGraphServiceInstance
|
||||
|
@ -67,7 +54,7 @@ export class ByEmail extends React.Component<ByEmailProps,ByEmailState>{
|
|||
|
||||
public render(): React.ReactElement<ByEmailProps> {
|
||||
return (
|
||||
<div className={styles.telephonedirectory}>
|
||||
<div className={styles.telephonedirectory}>
|
||||
<div>
|
||||
<Stack horizontal tokens={stackTokens} styles={stackStyles}>
|
||||
<Stack {...columnProps}>
|
||||
|
@ -82,10 +69,9 @@ export class ByEmail extends React.Component<ByEmailProps,ByEmailState>{
|
|||
resolveDelay={1000} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
<div>
|
||||
</div>
|
||||
<div/>
|
||||
<div id='detailedList'>
|
||||
{this.state.userProperties.length !== 0 &&
|
||||
{this.state.userProperties.length !== 0 &&
|
||||
<DetailsList
|
||||
items={this.state.userProperties}
|
||||
columns={this.props.columns}
|
||||
|
@ -98,4 +84,4 @@ export class ByEmail extends React.Component<ByEmailProps,ByEmailState>{
|
|||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { IUserProperties } from "../../../../Services/IUserProperties";
|
||||
import { IColumn } from "office-ui-fabric-react/lib/DetailsList";
|
||||
|
||||
|
||||
export interface ByEmailState{
|
||||
|
@ -7,4 +6,4 @@ export interface ByEmailState{
|
|||
userProperties:IUserProperties[];
|
||||
searchFor: string;
|
||||
isDataFound:boolean;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as strings from 'TelephonedirectoryWebPartStrings';
|
|||
import { Log } from "@microsoft/sp-core-library";
|
||||
import { Stack, IStackProps, IStackStyles } from 'office-ui-fabric-react/lib/Stack';
|
||||
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
||||
import { DetailsList, DetailsListLayoutMode, IColumn, SelectionMode } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
import { DetailsList, DetailsListLayoutMode } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
const LOG_SOURCE = "ByFirstName";
|
||||
const stackTokens = { childrenGap: 50 };
|
||||
const stackStyles: Partial<IStackStyles> = { root: { width: 650 } };
|
||||
|
@ -39,6 +39,7 @@ export class ByFirstName extends React.Component<ByFirstNameProps,ByFirstNameSta
|
|||
}
|
||||
|
||||
@autobind
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private async getUsers(email:string) : Promise<any>{
|
||||
this.setState({loading:true},async()=>{
|
||||
await this.props.MSGraphServiceInstance
|
||||
|
@ -72,7 +73,7 @@ export class ByFirstName extends React.Component<ByFirstNameProps,ByFirstNameSta
|
|||
|
||||
public render(): React.ReactElement<ByFirstNameProps> {
|
||||
return (
|
||||
<div className={styles.telephonedirectory}>
|
||||
<div className={styles.telephonedirectory}>
|
||||
<div>
|
||||
<Stack horizontal tokens={stackTokens} styles={stackStyles}>
|
||||
<Stack {...columnProps}>
|
||||
|
@ -85,10 +86,10 @@ export class ByFirstName extends React.Component<ByFirstNameProps,ByFirstNameSta
|
|||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<div>
|
||||
</div>
|
||||
<div/>
|
||||
|
||||
<div id='detailedList'>
|
||||
{this.state.userProperties.length !== 0 &&
|
||||
{this.state.userProperties.length !== 0 &&
|
||||
<DetailsList
|
||||
items={this.state.userProperties}
|
||||
columns={this.props.Columns}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { IUserProperties } from "../../../../Services/IUserProperties";
|
||||
import { IColumn } from "office-ui-fabric-react/lib/DetailsList";
|
||||
|
||||
|
||||
export interface ByFirstNameState{
|
||||
|
@ -7,4 +6,4 @@ export interface ByFirstNameState{
|
|||
userProperties:IUserProperties[];
|
||||
searchFor: string;
|
||||
isDataFound:boolean;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,9 @@ import * as strings from 'TelephonedirectoryWebPartStrings';
|
|||
import { Log } from "@microsoft/sp-core-library";
|
||||
import { Stack, IStackProps, IStackStyles } from 'office-ui-fabric-react/lib/Stack';
|
||||
import { TextField } from "office-ui-fabric-react/lib/TextField";
|
||||
import { DetailsList, DetailsListLayoutMode, IColumn, SelectionMode } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
import { DetailsList, DetailsListLayoutMode } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
const LOG_SOURCE = "ByFirstName";
|
||||
const stackTokens = { childrenGap: 50 };
|
||||
const iconProps = { iconName: 'Calendar' };
|
||||
const stackStyles: Partial<IStackStyles> = { root: { width: 650 } };
|
||||
const columnProps: Partial<IStackProps> = {
|
||||
tokens: { childrenGap: 15 },
|
||||
|
@ -42,6 +41,7 @@ export class ByLastName extends React.Component<ByLastNameProps,ByLastNameState>
|
|||
}
|
||||
|
||||
@autobind
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private async getUsers(email:string) : Promise<any>{
|
||||
this.setState({loading:true},async()=>{
|
||||
await this.props.MSGraphServiceInstance
|
||||
|
@ -75,7 +75,7 @@ export class ByLastName extends React.Component<ByLastNameProps,ByLastNameState>
|
|||
|
||||
public render(): React.ReactElement<ByLastNameProps> {
|
||||
return (
|
||||
<div className={styles.telephonedirectory}>
|
||||
<div className={styles.telephonedirectory}>
|
||||
<div>
|
||||
<Stack horizontal tokens={stackTokens} styles={stackStyles}>
|
||||
<Stack {...columnProps}>
|
||||
|
@ -88,10 +88,9 @@ export class ByLastName extends React.Component<ByLastNameProps,ByLastNameState>
|
|||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<div>
|
||||
</div>
|
||||
<div/>
|
||||
<div id='detailedList'>
|
||||
{this.state.userProperties.length !== 0 &&
|
||||
{this.state.userProperties.length !== 0 &&
|
||||
<DetailsList
|
||||
items={this.state.userProperties}
|
||||
columns={this.props.columns}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { IUserProperties } from "../../../../Services/IUserProperties";
|
||||
import { IColumn } from "office-ui-fabric-react/lib/DetailsList";
|
||||
export interface ByLastNameState{
|
||||
loading:boolean;
|
||||
userProperties:IUserProperties[];
|
||||
searchFor: string;
|
||||
isDataFound:boolean;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { IUserProperties } from "../../../Services/IUserProperties";
|
||||
import { IColumn } from "office-ui-fabric-react/lib/DetailsList";
|
||||
|
||||
export interface ITelephoneDirectoryState{
|
||||
loading:boolean;
|
||||
columns:IColumn[];
|
||||
selectedKey:string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import { ByLastName } from "./ByLastName/ByLastName";
|
|||
import { ByEmail } from "./ByEmail/ByEmail";
|
||||
import { Pivot, PivotItem,PivotLinkFormat, PivotLinkSize } from 'office-ui-fabric-react/lib/Pivot';
|
||||
import { IColumn } from 'office-ui-fabric-react/lib/DetailsList';
|
||||
const LOG_SOURCE = "TelephoneDirectory";
|
||||
export default class Telephonedirectory extends React.Component<ITelephoneDirectoryProps, ITelephoneDirectoryState> {
|
||||
private headers = [
|
||||
{ label: 'Name', key: 'displayName' },
|
||||
|
@ -88,7 +87,7 @@ export default class Telephonedirectory extends React.Component<ITelephoneDirect
|
|||
isResizable: true
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
this.state={
|
||||
loading:false,
|
||||
selectedKey:"byFirstName",
|
||||
|
@ -112,7 +111,7 @@ export default class Telephonedirectory extends React.Component<ITelephoneDirect
|
|||
<WebPartTitle displayMode={this.props.DisplayMode}
|
||||
title={this.props.WebpartTitle}
|
||||
updateProperty={this.props.updateProperty} />
|
||||
|
||||
|
||||
<Pivot headersOnly={true}
|
||||
selectedKey ={this.state.selectedKey}
|
||||
onLinkClick = {this._handleLinkClick}
|
||||
|
@ -121,36 +120,36 @@ export default class Telephonedirectory extends React.Component<ITelephoneDirect
|
|||
<PivotItem
|
||||
headerText='Search User By First Name'
|
||||
itemKey='byFirstName'
|
||||
itemIcon="Group" ></PivotItem>
|
||||
itemIcon="Group" />
|
||||
<PivotItem
|
||||
headerText='Search User By Last Name'
|
||||
itemKey='byLastName'
|
||||
itemIcon="Group"></PivotItem>
|
||||
itemIcon="Group"/>
|
||||
<PivotItem
|
||||
headerText='Search User By Email'
|
||||
itemKey="byEmail"
|
||||
itemIcon="Group"></PivotItem>
|
||||
itemIcon="Group"/>
|
||||
</Pivot><br/>
|
||||
{this.state.selectedKey === "byFirstName" &&
|
||||
<ByFirstName
|
||||
MSGraphClient={this.props.MsGraphClient}
|
||||
<ByFirstName
|
||||
MSGraphClient={this.props.MsGraphClient}
|
||||
MSGraphServiceInstance={this.props.MSGraphServiceInstance}
|
||||
context={this.props.context}
|
||||
Columns={this.state.columns}></ByFirstName>
|
||||
Columns={this.state.columns}/>
|
||||
}
|
||||
{this.state.selectedKey === "byLastName" &&
|
||||
<ByLastName
|
||||
MSGraphClient = {this.props.MsGraphClient}
|
||||
MSGraphServiceInstance= {this.props.MSGraphServiceInstance}
|
||||
context={this.props.context}
|
||||
columns={this.state.columns}></ByLastName>
|
||||
columns={this.state.columns}/>
|
||||
}
|
||||
{this.state.selectedKey === "byEmail" &&
|
||||
<ByEmail
|
||||
MSGraphClient = {this.props.MsGraphClient}
|
||||
MSGraphServiceInstance= {this.props.MSGraphServiceInstance}
|
||||
context={this.props.context}
|
||||
columns={this.state.columns}></ByEmail>
|
||||
columns={this.state.columns}/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue