@@ -11,17 +11,34 @@ import { IconButton } from "@fluentui/react/lib/Button";
1111import { Text } from "@fluentui/react/lib/Text" ;
1212import { ECommentAction } from "../../common/ECommentAction" ;
1313import { IAddCommentPayload } from "../../models/IAddCommentPayload" ;
14- import { useMsGraphAPI } from "../.." ;
14+ import { AppContext , useMsGraphAPI } from "../.." ;
15+ import SPPeopleSearchService from "../../../../services/PeopleSearchService" ;
16+ import { MSGraphClientFactory , SPHttpClient } from "@microsoft/sp-http" ;
17+ import { PageContext } from "@microsoft/sp-page-context" ;
18+ import { PrincipalType } from "../../../peoplepicker" ;
19+ import * as strings from "ControlStrings" ;
1520
1621export interface IAddCommentProps { }
1722
1823export const AddComment : React . FunctionComponent < IAddCommentProps > = ( props : IAddCommentProps ) => {
1924 const [ commentText , setCommentText ] = useState < string > ( "" ) ;
25+ const [ disableCallingGraph , setDisableCallingGraph ] = useState < boolean > ( false ) ;
2026 const { getUsers, getSuggestions } = useMsGraphAPI ( ) ;
2127 const { reactMentionStyles, mentionsClasses, componentClasses } = useAddCommentStyles ( ) ;
2228 const [ singleLine , setSingleLine ] = useState < boolean > ( true ) ;
2329 const { setlistItemCommentsState } = useContext ( ListItemCommentsStateContext ) ;
2430 const _addCommentText = useRef < IAddCommentPayload > ( { mentions : [ ] , text : "" } ) ;
31+ const { serviceScope } = useContext ( AppContext ) ;
32+ let _msGraphClientFactory : MSGraphClientFactory = undefined ;
33+ let _sPHttpClient : SPHttpClient = undefined ;
34+ let _pageContext : PageContext = undefined ;
35+ let _peopleSearchService : SPPeopleSearchService = undefined ;
36+ serviceScope . whenFinished ( async ( ) => {
37+ _msGraphClientFactory = serviceScope . consume ( MSGraphClientFactory . serviceKey ) ;
38+ _sPHttpClient = serviceScope . consume ( SPHttpClient . serviceKey ) ;
39+ _pageContext = serviceScope . consume ( PageContext . serviceKey ) ;
40+ _peopleSearchService = new SPPeopleSearchService ( { absoluteUrl : _pageContext . web . absoluteUrl , msGraphClientFactory : _msGraphClientFactory , spHttpClient : _sPHttpClient } , false ) ;
41+ } ) ;
2542
2643 const sugestionsContainer = useRef < HTMLDivElement > ( ) ;
2744 let _reactMentionStyles = reactMentionStyles ;
@@ -54,17 +71,47 @@ export const AddComment: React.FunctionComponent<IAddCommentProps> = (props: IAd
5471 } , [ ] ) ;
5572
5673 const _searchData = ( search : string , callback : ( users : SuggestionDataItem [ ] ) => void ) : void => {
74+ const _searchPeople = ( ) : void => {
75+ _peopleSearchService . searchPeople ( search , 5 , [ PrincipalType . User ] )
76+ . then ( ( res ) => res . map ( ( user ) => ( { display : user . text , id : user . secondaryText } ) ) )
77+ . then ( callback )
78+ . catch ( ( ) => { /* no-op; */ } ) ;
79+ } ;
80+
81+ if ( disableCallingGraph ) {
82+ _searchPeople ( ) ;
83+ return ;
84+ }
85+
5786 // Try to get sugested users when user type '@'
5887 if ( ! search ) {
5988 getSuggestions ( )
6089 . then ( ( res ) => res . users . map ( ( user ) => ( { display : user . displayName , id : user . mail } ) ) )
6190 . then ( callback )
62- . catch ( ( ) => { /* no-op; */ } ) ;
91+ . catch ( ( error ) => {
92+ switch ( error . statusCode ) {
93+ case 403 :
94+ case 404 :
95+ // If the user is not allowed to call graph API (e.g. guest users), we need to use the People Search API
96+ setDisableCallingGraph ( true ) ;
97+ break ;
98+ default :
99+ }
100+ } ) ;
63101 } else {
64102 getUsers ( search )
65103 . then ( ( res ) => res . users . map ( ( user ) => ( { display : user . displayName , id : user . mail } ) ) )
66104 . then ( callback )
67- . catch ( ( ) => { /* no-op; */ } ) ;
105+ . catch ( ( error ) => {
106+ switch ( error . statusCode ) {
107+ case 403 :
108+ // If the user is not allowed to call graph API (e.g. guest users), we need to use the People Search API
109+ setDisableCallingGraph ( true ) ;
110+ _searchPeople ( ) ;
111+ break ;
112+ default :
113+ }
114+ } ) ;
68115 }
69116 } ;
70117
@@ -78,8 +125,8 @@ export const AddComment: React.FunctionComponent<IAddCommentProps> = (props: IAd
78125 < >
79126 < Stack tokens = { { padding : 5 } } styles = { { root : { width : 260 } } } >
80127 < Stack horizontal horizontalAlign = "start" tokens = { { childrenGap : 10 } } >
81- < img src = { `${ PHOTO_URL } ${ _user . mail } ` } width = { 30 } height = { 30 } style = { { borderRadius : "50%" } } />
82- < Stack >
128+ < img src = { `${ PHOTO_URL } ${ _user . mail } ` } width = { 30 } height = { 30 } style = { { borderRadius : "50%" } } alt = { _user . displayName } />
129+ < Stack styles = { { root : { overflow : "hidden" } } } >
83130 < Text styles = { { root : { fontWeight : 700 } } } variant = "smallPlus" nowrap >
84131 { _user . displayName }
85132 </ Text >
@@ -106,7 +153,7 @@ export const AddComment: React.FunctionComponent<IAddCommentProps> = (props: IAd
106153 < MentionsInput
107154 value = { commentText }
108155 onChange = { _onChange }
109- placeholder = "@mention or comment"
156+ placeholder = { strings . ListItemCommentsPlaceholder }
110157 style = { _reactMentionStyles }
111158 suggestionsPortalHost = { sugestionsContainer . current }
112159 >
0 commit comments