Search code examples
reactjsspfx

SPFX - restrict properties pane with Graph API response


I'm trying to restrict a custom webparts properties pane based on whether a user is a member of a MS group

Now I have built the graph API call etc... and it simply returns true or false.

in the API request I have:-

public async checkMSGroup(){
  let groupName = "WebPartAdmin";
  return new Promise<void>((resolve: (ig: any) => any, reject: (error: any) => void): void => {
    this.context.msGraphClientFactory.getClient()
        .then((client: MSGraphClient): void => {
            client
            .api('/me/transitiveMemberOf')
            .get((error, response: any, rawResponse?: any) => {
                let msGroups = response.value;
                msGroups.forEach(   
                    (group) => {
                        //console.log(group.displayName);
                        if (group.displayName == groupName) {
                            resolve(true);
                        }
                    });
            })
        });
    }).then(resp => {return resp}); 
}

Next I want to get the response in the promise

in the PropertiesPane Config I have

    protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    let webPartOptions: IPropertyPaneField<any>[];
    const ig:any = this.checkMSGroup()

    console.log(ig) // I can see the promise results

    

this is the bit I'm trying to solve

const [inGroup, setInGroup] = useState(false);
useEffect(() => {
        ig.then(resp => {
            setInGroup(resp);
            console.log("pp"+resp)
        })
    }, []);        
 console.log("var"+inGroup)

As you can see on the image I can see the promise, I get an error on the useEffect,etc... Any advise would be great on this or if there's another way to set inGroup as the promise result.

enter image description here

the rest is easy I just need the inGroup variable to be true

    if(inGroup==true){
                        webPartOptions = [
                            PropertyPaneTextField("title", {
                                label: "Title",
                                value: this.properties.title
                            }),
                           //Adds more property fields
                        }
                    }else{
                        webPartOptions = [
                            PropertyPaneLabel("title", {
                                text: "Contact Administrator"
                            })
                        ]
                    }
             
    return {
        pages: [
            {
                groups: [
                    {
                        groupFields: webPartOptions
                    }
                ]
            }
        ]
    };
}

Solution

  • WebPart class itself is not a React component, this means You cannot use any react hooks directly in WebPart class. if You want to await Your method do it in onInit method. It could look something like this:

      protected inGroup: boolean;
      public async checkMSGroup() {
        let groupName = "WebPartAdmin";
        return new Promise<boolean>((resolve: (ig: any) => any, reject: (error: any) => void): void => {
          this.context.msGraphClientFactory.getClient()
            .then((client: MSGraphClient): void => {
              client
                .api('/me/transitiveMemberOf')
                .get((error, response: any, rawResponse?: any) => {
                  let msGroups = response.value;
                  msGroups.forEach(
                    (group) => {
                      //console.log(group.displayName);
                      if (group.displayName == groupName) {
                        resolve(true);
                      }
                    });
                })
            });
        }).then(resp => { return resp });
      }
      protected async onInit() {
        await super.onInit();
        this.inGroup = await this.checkMSGroup();
      }
      protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
        if (this.inGroup) {
          return {
            pages: [
              {
                header: {
                  description: strings.PropertyPaneDescription
                },
                groups: [
                  {
                    groupName: strings.BasicGroupName,
                    groupFields: [
                      PropertyPaneTextField('description', {
                        label: strings.DescriptionFieldLabel
                      })
                    ]
                  }
                ]
              }
            ]
          };
        }
      }
    

    Hope that helps