diff --git a/src/elements/content-sidebar/MetadataSidebarRedesign.tsx b/src/elements/content-sidebar/MetadataSidebarRedesign.tsx index c977dd7d67..b804f2b777 100644 --- a/src/elements/content-sidebar/MetadataSidebarRedesign.tsx +++ b/src/elements/content-sidebar/MetadataSidebarRedesign.tsx @@ -10,6 +10,7 @@ import { AddMetadataTemplateDropdown } from '@box/metadata-editor'; import API from '../../api'; import SidebarContent from './SidebarContent'; +import { MetadataEmptyState } from '@box/metadata-editor'; import { withAPIContext } from '../common/api-context'; import { withErrorBoundary } from '../common/error-boundary'; import { withLogger } from '../common/logger'; @@ -31,6 +32,7 @@ const MARK_NAME_JS_READY = `${ORIGIN_METADATA_SIDEBAR_REDESIGN}_${EVENT_JS_READY mark(MARK_NAME_JS_READY); export interface ExternalProps { + isBoxAiSuggestionsEnabled: boolean; isFeatureEnabled: boolean; } @@ -53,12 +55,12 @@ export interface MetadataSidebarRedesignProps extends PropsWithoutContext, Error api: API; } -function MetadataSidebarRedesign({ api, elementId, fileId, onError, isFeatureEnabled }: MetadataSidebarRedesignProps) { +function MetadataSidebarRedesign({ api, elementId, fileId,isBoxAiSuggestionsEnabled, onError, isFeatureEnabled }: MetadataSidebarRedesignProps) { const { formatMessage } = useIntl(); const [selectedTemplates, setSelectedTemplates] = React.useState>([]); - const { templates, errorMessage, status } = useSidebarMetadataFetcher(api, fileId, onError, isFeatureEnabled); + const {editors, file, templates, errorMessage, status } = useSidebarMetadataFetcher(api, fileId, onError, isFeatureEnabled); const metadataDropdown = status === STATUS.SUCCESS && templates && ( ); + const showEditor = file && templates && editors; + const showEmptyState = showEditor && editors.length === 0; + return ( )} + {showEmptyState && ( + + )} + ); } diff --git a/src/elements/content-sidebar/hooks/useSidebarMetadataFetcher.ts b/src/elements/content-sidebar/hooks/useSidebarMetadataFetcher.ts index 0fe877a566..dc46ba8601 100644 --- a/src/elements/content-sidebar/hooks/useSidebarMetadataFetcher.ts +++ b/src/elements/content-sidebar/hooks/useSidebarMetadataFetcher.ts @@ -4,7 +4,7 @@ import { type MessageDescriptor } from 'react-intl'; import API from '../../../api'; import { type ElementsXhrError } from '../../../common/types/api'; import { isUserCorrectableError } from '../../../utils/error'; -import { FIELD_IS_EXTERNALLY_OWNED, FIELD_PERMISSIONS, FIELD_PERMISSIONS_CAN_UPLOAD } from '../../../constants'; +import { FIELD_IS_EXTERNALLY_OWNED, FIELD_PERMISSIONS, FIELD_PERMISSIONS_CAN_UPLOAD, IS_ERROR_DISPLAYED} from '../../../constants'; import messages from '../../common/messages'; @@ -19,9 +19,10 @@ export enum STATUS { SUCCESS = 'success', } interface DataFetcher { - status: STATUS; + editors: Array; file: BoxItem | null; errorMessage: MessageDescriptor | null; + status: STATUS; templates: Array; } @@ -35,6 +36,7 @@ function useSidebarMetadataFetcher( const [file, setFile] = React.useState(null); const [templates, setTemplates] = React.useState(null); const [errorMessage, setErrorMessage] = React.useState(null); + const [editors, setEditors] = React.useState>([]); const onApiError = React.useCallback( (error: ElementsXhrError, code: string, message: MessageDescriptor) => { @@ -51,7 +53,8 @@ function useSidebarMetadataFetcher( ); const fetchMetadataSuccessCallback = React.useCallback( - ({ templates: fetchedTemplates }: { editors: Array; templates: Array }) => { + ({ editors: fetchedEditors, templates: fetchedTemplates }: { editors: Array; templates: Array }) => { + setEditors(fetchedEditors); setErrorMessage(null); setStatus(STATUS.SUCCESS); setTemplates(fetchedTemplates); @@ -61,6 +64,7 @@ function useSidebarMetadataFetcher( const fetchMetadataErrorCallback = React.useCallback( (e: ElementsXhrError, code: string) => { + setEditors(null); setTemplates(null); onApiError(e, code, messages.sidebarMetadataFetchingErrorContent); }, @@ -115,9 +119,10 @@ function useSidebarMetadataFetcher( }, [api, fetchFileErrorCallback, fetchFileSuccessCallback, fileId, status]); return { - status, file, + editors, errorMessage, + status, templates, }; } diff --git a/src/elements/content-sidebar/stories/MetadataSidebarRedesign.stories.tsx b/src/elements/content-sidebar/stories/MetadataSidebarRedesign.stories.tsx index d6bb46a277..fa9c7e38d0 100644 --- a/src/elements/content-sidebar/stories/MetadataSidebarRedesign.stories.tsx +++ b/src/elements/content-sidebar/stories/MetadataSidebarRedesign.stories.tsx @@ -1,10 +1,11 @@ import { type StoryObj } from '@storybook/react'; import { fn } from '@storybook/test'; -import { type ComponentProps } from 'react'; +import React, { type ComponentProps } from 'react'; import MetadataSidebarRedesign from '../MetadataSidebarRedesign'; import ContentSidebar from '../ContentSidebar'; const fileIdWithMetadata = global.FILE_ID; +const fileIdWithNoMetadata = '416047501580'; const mockFeatures = { 'metadata.redesign.enabled': true, }; @@ -15,6 +16,7 @@ const mockLogger = { }; const defaultMetadataSidebarProps: ComponentProps = { + isBoxAiSuggestionsEnabled: true, isFeatureEnabled: true, onError: fn, }; @@ -30,6 +32,27 @@ export default { token: global.TOKEN, metadataSidebarProps: defaultMetadataSidebarProps, }, + render: args => { + return ; + }, }; export const AddTemplateDropdownMenu: StoryObj = {}; + +export const EmptyStateWithBoxAiEnabled: StoryObj = { + args: { + fileId: fileIdWithNoMetadata, + metadataSidebarProps: { + ...defaultMetadataSidebarProps, + }, + },}; + +export const EmptyStateWithBoxAiDisabled: StoryObj = { + args: { + fileId: fileIdWithNoMetadata, + metadataSidebarProps: { + ...defaultMetadataSidebarProps, + isBoxAiSuggestionsEnabled: false, + }, + }, +};