11import * as React from 'react' ;
2+ import { useIntl } from 'react-intl' ;
23import isEmpty from 'lodash/isEmpty' ;
3-
4+ import { useNotification } from '@box/blueprint-web' ;
45import { UnifiedShareModal } from '@box/unified-share-modal' ;
56import type { CollaborationRole , Collaborator , Item , SharedLink , User } from '@box/unified-share-modal' ;
67
78import API from '../../api' ;
8- import Internationalize from '../common/Internationalize' ;
9- import Providers from '../common/Providers' ;
109import { withBlueprintModernization } from '../common/withBlueprintModernization' ;
1110import { fetchAvatars , fetchCollaborators , fetchCurrentUser , fetchItem } from './apis' ;
11+ import { CONTENT_SHARING_ERRORS } from './constants' ;
1212import { useContactService , useSharingService } from './hooks' ;
1313import { convertCollabsResponse , convertItemResponse } from './utils' ;
1414
15- import type { Collaborations , ItemType , StringMap } from '../../common/types/core' ;
15+ import type { Collaborations , ItemType } from '../../common/types/core' ;
16+ import type { ElementsXhrError } from '../../common/types/api' ;
1617import type { AvatarURLMap } from './types' ;
1718
19+ import messages from './messages' ;
20+
1821export interface ContentSharingV2Props {
1922 /** api - API instance */
2023 api : API ;
@@ -24,25 +27,12 @@ export interface ContentSharingV2Props {
2427 itemId : string ;
2528 /** itemType - "file" or "folder" */
2629 itemType : ItemType ;
27- /** hasProviders - Whether the element has providers for USM already */
28- hasProviders ?: boolean ;
29- /** language - Language used for the element */
30- language ?: string ;
31- /** messages - Localized strings used by the element */
32- messages ?: StringMap ;
3330}
3431
35- function ContentSharingV2 ( {
36- api,
37- children,
38- itemId,
39- itemType,
40- hasProviders,
41- language,
42- messages,
43- } : ContentSharingV2Props ) {
32+ function ContentSharingV2 ( { api, children, itemId, itemType } : ContentSharingV2Props ) {
4433 const [ avatarUrlMap , setAvatarUrlMap ] = React . useState < AvatarURLMap | null > ( null ) ;
4534 const [ item , setItem ] = React . useState < Item | null > ( null ) ;
35+ const [ hasError , setHasError ] = React . useState < boolean > ( false ) ;
4636 const [ sharedLink , setSharedLink ] = React . useState < SharedLink | null > ( null ) ;
4737 const [ sharingServiceProps , setSharingServiceProps ] = React . useState ( null ) ;
4838 const [ currentUser , setCurrentUser ] = React . useState < User | null > ( null ) ;
@@ -51,6 +41,8 @@ function ContentSharingV2({
5141 const [ collaboratorsData , setCollaboratorsData ] = React . useState < Collaborations | null > ( null ) ;
5242 const [ owner , setOwner ] = React . useState ( { id : '' , email : '' , name : '' } ) ;
5343
44+ const { formatMessage } = useIntl ( ) ;
45+ const { addNotification } = useNotification ( ) ;
5446 const { sharingService } = useSharingService ( {
5547 api,
5648 avatarUrlMap,
@@ -84,8 +76,42 @@ function ContentSharingV2({
8476 setOwner ( { id : ownedBy . id , email : ownedBy . login , name : ownedBy . name } ) ;
8577 } , [ ] ) ;
8678
79+ // Handle initial data retrieval errors
80+ const getError = React . useCallback (
81+ ( error : ElementsXhrError ) => {
82+ // display only one component-level notification at a time
83+ if ( hasError ) {
84+ return ;
85+ }
86+
87+ let errorMessage ;
88+ if ( error . status ) {
89+ errorMessage = messages [ CONTENT_SHARING_ERRORS [ error . status ] ] ;
90+ } else if ( error . response && error . response . status ) {
91+ errorMessage = messages [ CONTENT_SHARING_ERRORS [ error . response . status ] ] ;
92+ } else {
93+ errorMessage = messages . loadingError ;
94+ }
95+
96+ if ( ! errorMessage ) {
97+ errorMessage = messages . defaultErrorNoticeText ;
98+ }
99+
100+ setHasError ( true ) ;
101+ addNotification ( {
102+ closeButtonAriaLabel : formatMessage ( messages . noticeCloseLabel ) ,
103+ sensitivity : 'foreground' as const ,
104+ typeIconAriaLabel : formatMessage ( messages . errorNoticeIcon ) ,
105+ variant : 'error' ,
106+ styledText : formatMessage ( errorMessage ) ,
107+ } ) ;
108+ } ,
109+ [ hasError , addNotification , formatMessage ] ,
110+ ) ;
111+
87112 // Reset state if the API has changed
88113 React . useEffect ( ( ) => {
114+ setHasError ( false ) ;
89115 setItem ( null ) ;
90116 setSharedLink ( null ) ;
91117 setCurrentUser ( null ) ;
@@ -100,10 +126,14 @@ function ContentSharingV2({
100126 if ( ! api || isEmpty ( api ) || item ) return ;
101127
102128 ( async ( ) => {
103- const itemData = await fetchItem ( { api, itemId, itemType } ) ;
104- handleGetItemSuccess ( itemData ) ;
129+ try {
130+ const itemData = await fetchItem ( { api, itemId, itemType } ) ;
131+ handleGetItemSuccess ( itemData ) ;
132+ } catch ( error ) {
133+ getError ( error ) ;
134+ }
105135 } ) ( ) ;
106- } , [ api , item , itemId , itemType , sharedLink , handleGetItemSuccess ] ) ;
136+ } , [ api , item , itemId , itemType , sharedLink , handleGetItemSuccess , getError ] ) ;
107137
108138 // Get current user
109139 React . useEffect ( ( ) => {
@@ -122,10 +152,14 @@ function ContentSharingV2({
122152 } ;
123153
124154 ( async ( ) => {
125- const userData = await fetchCurrentUser ( { api, itemId } ) ;
126- getUserSuccess ( userData ) ;
155+ try {
156+ const userData = await fetchCurrentUser ( { api, itemId } ) ;
157+ getUserSuccess ( userData ) ;
158+ } catch ( error ) {
159+ getError ( error ) ;
160+ }
127161 } ) ( ) ;
128- } , [ api , currentUser , item , itemId , itemType , sharedLink ] ) ;
162+ } , [ api , currentUser , item , itemId , itemType , sharedLink , getError ] ) ;
129163
130164 // Get collaborators
131165 React . useEffect ( ( ) => {
@@ -176,24 +210,20 @@ function ContentSharingV2({
176210 const config = { sharedLinkEmail : false } ;
177211
178212 return (
179- < Internationalize language = { language } messages = { messages } >
180- < Providers hasProviders = { hasProviders } >
181- { item && (
182- < UnifiedShareModal
183- config = { config }
184- collaborationRoles = { collaborationRoles }
185- collaborators = { collaborators }
186- contactService = { contactService }
187- currentUser = { currentUser }
188- item = { item }
189- sharedLink = { sharedLink }
190- sharingService = { sharingService }
191- >
192- { children }
193- </ UnifiedShareModal >
194- ) }
195- </ Providers >
196- </ Internationalize >
213+ item && (
214+ < UnifiedShareModal
215+ config = { config }
216+ collaborationRoles = { collaborationRoles }
217+ collaborators = { collaborators }
218+ contactService = { contactService }
219+ currentUser = { currentUser }
220+ item = { item }
221+ sharedLink = { sharedLink }
222+ sharingService = { sharingService }
223+ >
224+ { children }
225+ </ UnifiedShareModal >
226+ )
197227 ) ;
198228}
199229
0 commit comments