From 7cf7f69d221c41dc48b1a95fc242482ccbdf6b90 Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Tue, 28 Jan 2020 14:07:59 +0000 Subject: [PATCH] fix(react-tree-orgchart): crash on init when requesting undefined user The app was crashing on init when requesting users that do not exist. This adds a couple of checks to fallback to rendering a blank card instead. --- .../treeOrgChart/components/TreeOrgChart.tsx | 244 ++++++++++++------ 1 file changed, 163 insertions(+), 81 deletions(-) diff --git a/samples/react-tree-orgchart/src/webparts/treeOrgChart/components/TreeOrgChart.tsx b/samples/react-tree-orgchart/src/webparts/treeOrgChart/components/TreeOrgChart.tsx index 2325bd1f4..6ebf264dc 100644 --- a/samples/react-tree-orgchart/src/webparts/treeOrgChart/components/TreeOrgChart.tsx +++ b/samples/react-tree-orgchart/src/webparts/treeOrgChart/components/TreeOrgChart.tsx @@ -2,28 +2,38 @@ // Author: João Mendes // Fev 2019 // -import * as React from 'react'; -import styles from './TreeOrgChart.module.scss'; -import { ITreeOrgChartProps } from './ITreeOrgChartProps'; -import { ITreeOrgChartState } from './ITreeOrgChartState'; -import SortableTree from 'react-sortable-tree'; -import 'react-sortable-tree/style.css'; -import { IPersonaSharedProps, Persona, PersonaSize } from 'office-ui-fabric-react/lib/Persona'; -import { IconButton } from 'office-ui-fabric-react/lib/Button'; +import * as React from "react"; +import styles from "./TreeOrgChart.module.scss"; +import { ITreeOrgChartProps } from "./ITreeOrgChartProps"; +import { ITreeOrgChartState } from "./ITreeOrgChartState"; +import SortableTree from "react-sortable-tree"; +import "react-sortable-tree/style.css"; +import { + IPersonaSharedProps, + Persona, + PersonaSize +} from "office-ui-fabric-react/lib/Persona"; +import { IconButton } from "office-ui-fabric-react/lib/Button"; import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle"; -import spservice from '../../../services/SPServices'; -import { ITreeChildren } from './ITreeChildren'; -import { ITreeData } from './ITreeData'; -import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/components/Spinner'; +import SPService from "../../../services/SPServices"; +import { ITreeChildren } from "./ITreeChildren"; +import { ITreeData } from "./ITreeData"; +import { + Spinner, + SpinnerSize +} from "office-ui-fabric-react/lib/components/Spinner"; -export default class TreeOrgChart extends React.Component { +export default class TreeOrgChart extends React.Component< + ITreeOrgChartProps, + ITreeOrgChartState +> { private treeData: ITreeData[]; - private SPService: spservice; + private SPService: SPService; constructor(props) { super(props); - this.SPService = new spservice(this.props.context); + this.SPService = new SPService(this.props.context); this.state = { treeData: [], isLoading: true @@ -34,8 +44,14 @@ export default class TreeOrgChart extends React.Component 0) { - treeManagers = await this.getUsers(currentUserProperties.ExtendedManagers[0]); + if ( + currentUserProperties.ExtendedManagers && + currentUserProperties.ExtendedManagers.length > 0 + ) { + treeManagers = await this.getUsers( + currentUserProperties.ExtendedManagers[0] + ); } return treeManagers; } @@ -85,51 +111,73 @@ export default class TreeOrgChart extends React.Component; + person = ( + + ); // Has DirectReports - if (managerProperties.DirectReports && managerProperties.DirectReports.length > 0) { - const usersDirectReports: any[] = await this.getChildren(managerProperties.DirectReports); + if ( + managerProperties.DirectReports && + managerProperties.DirectReports.length > 0 + ) { + const usersDirectReports: any[] = await this.getChildren( + managerProperties.DirectReports + ); // return treeData - return { title: (person), expanded: true, children: usersDirectReports }; + return { title: person, expanded: true, children: usersDirectReports }; // Don't have DirectReports } else { // return treeData - return { title: (person) }; + return { title: person }; } } // Get Children (user DirectReports) private async getChildren(userDirectReports: any[]) { - let treeChildren: ITreeChildren[] = []; let spUser: IPersonaSharedProps = {}; for (const user of userDirectReports) { const managerProperties = await this.SPService.getUserProperties(user); - const imageInitials: string[] = managerProperties.DisplayName.split(' '); + const imageInitials: string[] = managerProperties.DisplayName.split(" "); spUser.imageUrl = `/_layouts/15/userphoto.aspx?size=L&username=${managerProperties.Email}`; - spUser.imageInitials = `${imageInitials[0].substring(0, 1).toUpperCase()}${imageInitials[1].substring(0, 1).toUpperCase()}`; + spUser.imageInitials = `${imageInitials[0] + .substring(0, 1) + .toUpperCase()}${imageInitials[1].substring(0, 1).toUpperCase()}`; spUser.text = managerProperties.DisplayName; spUser.tertiaryText = managerProperties.Email; spUser.secondaryText = managerProperties.Title; - const person = ; - const usersDirectReports = await this.getChildren(managerProperties.DirectReports); + const person = ( + + ); + const usersDirectReports = await this.getChildren( + managerProperties.DirectReports + ); - usersDirectReports ? treeChildren.push({ title: (person), children: usersDirectReports }) : - treeChildren.push({ title: (person) }); + usersDirectReports + ? treeChildren.push({ title: person, children: usersDirectReports }) + : treeChildren.push({ title: person }); } return treeChildren; } @@ -139,75 +187,109 @@ export default class TreeOrgChart extends React.Component; + if (myManager) { + const managerProperties = await this.SPService.getUserProperties( + myManager + ); + imageInitials = managerProperties.DisplayName?.split(" ").map(name => name[0]); + // PersonaCard Props + manager.imageUrl = `/_layouts/15/userphoto.aspx?size=L&username=${managerProperties.Email}`; + if (imageInitials) + manager.imageInitials = `${imageInitials[0]}${imageInitials[1]}`.toUpperCase(); + manager.text = managerProperties.DisplayName; + manager.tertiaryText = managerProperties.Email; + manager.secondaryText = managerProperties.Title; + // PersonaCard Component + managerCard = ( + + ); hasManager = true; } // Get my Properties - const meImageInitials: string[] = currentUserProperties.DisplayName.split(' '); + const meImageInitials: string[] = currentUserProperties.DisplayName.split( + " " + ); me.imageUrl = `/_layouts/15/userphoto.aspx?size=L&username=${currentUserProperties.Email}`; - me.imageInitials = `${meImageInitials[0].substring(0, 1).toUpperCase()}${meImageInitials[1].substring(0, 1).toUpperCase()}`; + me.imageInitials = `${meImageInitials[0] + .substring(0, 1) + .toUpperCase()}${meImageInitials[1].substring(0, 1).toUpperCase()}`; me.text = currentUserProperties.DisplayName; me.tertiaryText = currentUserProperties.Email; me.secondaryText = currentUserProperties.Title; - const meCard = ; - const usersDirectReports: any[] = await this.getChildren(currentUserProperties.DirectReports); + const meCard = ( + + ); + const usersDirectReports: any[] = await this.getChildren( + currentUserProperties.DirectReports + ); // Current USer Has Manager if (hasManager) { - treeChildren.push({ title: (meCard), expanded: true, children: usersDirectReports }); - - }else{ - treeChildren = usersDirectReports; - managerCard = meCard; + treeChildren.push({ + title: meCard, + expanded: true, + children: usersDirectReports + }); + } else { + treeChildren = usersDirectReports; + managerCard = meCard; } // Get MyPeers for (const userPeer of currentUserProperties.Peers) { const peerProperties = await this.SPService.getUserProperties(userPeer); - imageInitials = peerProperties.DisplayName.split(' '); + imageInitials = peerProperties.DisplayName.split(" "); peer.imageUrl = `/_layouts/15/userphoto.aspx?size=L&username=${peerProperties.Email}`; - peer.imageInitials = `${imageInitials[0].substring(0, 1).toUpperCase()}${imageInitials[1].substring(0, 1).toUpperCase()}`; + peer.imageInitials = `${imageInitials[0] + .substring(0, 1) + .toUpperCase()}${imageInitials[1].substring(0, 1).toUpperCase()}`; peer.text = peerProperties.DisplayName; peer.tertiaryText = peerProperties.Email; peer.secondaryText = peerProperties.Title; - const peerCard = ; - treeChildren.push({ title: (peerCard) }); + const peerCard = ( + + ); + treeChildren.push({ title: peerCard }); } // Return - return { 'person': managerCard, 'treeChildren': treeChildren }; - + return { person: managerCard, treeChildren: treeChildren }; } // Render public render(): React.ReactElement { return (
- - { - this.state.isLoading ? : null - } + updateProperty={this.props.updateProperty} + /> + {this.state.isLoading ? ( + + ) : null}
{ - window.open(`https://eur.delve.office.com/?p=${rowInfo.node.title.props.tertiaryText}&v=work`); + onClick={ev => { + window.open( + `https://eur.delve.office.com/?p=${rowInfo.node.title.props.tertiaryText}&v=work` + ); }} /> - ], + ] })} />
); } - - }