Skip to content

Commit

Permalink
feat(metadata-sidebar): Add metadata instance list (#3664)
Browse files Browse the repository at this point in the history
* feat(metadata-sidebar): add metadata empty state to metadata sidebar redesign (#3605)

* chore(content-sidebar): Temporarily remove files

while we be working with not yet publish internal library.
Will remove this commit after the library will become publicly
available on NPM and added to BUIE.

feat(metadata-sidebar): MetadataEmptyState

feat(metadata-sidebar): comment api to pass test

feat(metadata-sidebar): uncomment comments

feat(metadata-sidebar): add states

feat(metadata-sidebar): tests update

feat(metadata-sidebar): PR comments

feat(metadata-sidebar): delete git add . in showEditor

feat(metadata-sidebar): PR comments

feat(metadata-sidebar): storybook tests

feat(metadata-sidebar): update unit tests

feat(metadata-sidebar): pr comments

feat(metadata-sidebar): variables name changes

feat(metadata-sidebar): PR comments

feat(metadata-sidebar): PR comments

feat(metadata-sidebar): global token change  and status enum

feat(metadata-sidebar): global token update

feat(metadata-sidebar): global variables and enum upper case change

feat(metadata-sidebar): PR comments

feat(metadata-sidebar): styles import and title deletion

feat(metadata-sidebar): convert type to interface

* feat(metadata-sidebar): missing tests after rebase

---------

Co-authored-by: Dawid Jankowiak <jankowiak.dawid@gmail.com>

* feat(metadata-sidebar): Display MetadataInstanceList

* feat(metadata-sidebar): Add stories for AddTemplateDropdownMenu

Plus fix syncing when some metadata template instances are already loaded

* feat(metadata-sidebar): Move TooltipProvider to ContentSidebar

* feat(metadata-sidebar): Add unit test for showing MetadataInstanceList

* feat(metadata-sidebar): Update stories

* feat(metadata-sidebar): Reorganize stories

* feat(metadata-sidebar): Handle edition cancelation

* feat(metadata-sidebar): bump metadata-editor version

* feat(metadata-sidebar): Don't show list when metadata is being edited

* feat(metadata-sidebar): Bump @box/metadata-editor version

* feat(metadata-sidebar): Fix tests

* feat(metadata-sidebar): Update story name

* feat(metadata-sidebar): Remove data-testid attribute

And timeout

* feat(metadata-sidebar): Use `getByRole` for test expect

Co-authored-by: greg-in-a-box <103291617+greg-in-a-box@users.noreply.github.com>

* feat(metadata-editor): Reorganize showing editor views

+ move AutofillContextProvider where it's needed

---------

Co-authored-by: karolinaru <91914885+karolinaru@users.noreply.github.com>
Co-authored-by: greg-in-a-box <103291617+greg-in-a-box@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 18, 2024
1 parent 33b34d9 commit b4e4b01
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 167 deletions.
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@
"last 2 Edge versions",
"last 2 iOS versions"
],
"development": ["last 1 Chrome versions", "last 1 Firefox versions", "last 1 Safari versions"]
"development": [
"last 1 Chrome versions",
"last 1 Firefox versions",
"last 1 Safari versions"
]
},
"husky": {
"hooks": {
Expand Down Expand Up @@ -128,7 +132,7 @@
"@box/cldr-data": "^34.2.0",
"@box/frontend": "^10.0.0",
"@box/languages": "^1.0.0",
"@box/metadata-editor": "^0.46.1",
"@box/metadata-editor": "^0.50.5",
"@box/react-virtualized": "9.22.3-rc-box.9",
"@cfaester/enzyme-adapter-react-18": "^0.8.0",
"@chromatic-com/storybook": "^1.6.1",
Expand Down Expand Up @@ -304,7 +308,7 @@
"@box/blueprint-web-assets": "^4.21.0",
"@box/box-ai-content-answers": "^0.49.1",
"@box/cldr-data": ">=34.2.0",
"@box/metadata-editor": "^0.46.1",
"@box/metadata-editor": "^0.50.5",
"@box/react-virtualized": "9.22.3-rc-box.9",
"@hapi/address": "^2.1.4",
"axios": "^0.25.0",
Expand Down Expand Up @@ -362,6 +366,8 @@
}
},
"msw": {
"workerDirectory": [".storybook/public"]
"workerDirectory": [
".storybook/public"
]
}
}
61 changes: 32 additions & 29 deletions src/elements/content-sidebar/ContentSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'regenerator-runtime/runtime';
import * as React from 'react';
import noop from 'lodash/noop';
import flow from 'lodash/flow';
import { TooltipProvider } from '@box/blueprint-web';
import type { RouterHistory } from 'react-router-dom';
import API from '../../api';
import APIContext from '../common/api-context';
Expand Down Expand Up @@ -359,35 +360,37 @@ class ContentSidebar extends React.Component<Props, State> {
<Internationalize language={language} messages={messages}>
<APIContext.Provider value={(this.api: any)}>
<NavRouter history={history} initialEntries={[initialPath]}>
<Sidebar
activitySidebarProps={activitySidebarProps}
additionalTabs={additionalTabs}
className={className}
currentUser={currentUser}
detailsSidebarProps={detailsSidebarProps}
docGenSidebarProps={docGenSidebarProps}
file={file}
fileId={fileId}
getPreview={getPreview}
getViewer={getViewer}
hasActivityFeed={hasActivityFeed}
hasAdditionalTabs={hasAdditionalTabs}
hasNav={hasNav}
hasMetadata={hasMetadata}
hasSkills={hasSkills}
hasVersions={hasVersions}
isDefaultOpen={isDefaultOpen}
isLoading={isLoading}
metadataEditors={metadataEditors}
metadataSidebarProps={metadataSidebarProps}
onAnnotationSelect={onAnnotationSelect}
onVersionChange={onVersionChange}
onVersionHistoryClick={onVersionHistoryClick}
versionsSidebarProps={versionsSidebarProps}
wrappedComponentRef={ref => {
this.sidebarRef = ref;
}}
/>
<TooltipProvider>
<Sidebar
activitySidebarProps={activitySidebarProps}
additionalTabs={additionalTabs}
className={className}
currentUser={currentUser}
detailsSidebarProps={detailsSidebarProps}
docGenSidebarProps={docGenSidebarProps}
file={file}
fileId={fileId}
getPreview={getPreview}
getViewer={getViewer}
hasActivityFeed={hasActivityFeed}
hasAdditionalTabs={hasAdditionalTabs}
hasNav={hasNav}
hasMetadata={hasMetadata}
hasSkills={hasSkills}
hasVersions={hasVersions}
isDefaultOpen={isDefaultOpen}
isLoading={isLoading}
metadataEditors={metadataEditors}
metadataSidebarProps={metadataSidebarProps}
onAnnotationSelect={onAnnotationSelect}
onVersionChange={onVersionChange}
onVersionHistoryClick={onVersionHistoryClick}
versionsSidebarProps={versionsSidebarProps}
wrappedComponentRef={ref => {
this.sidebarRef = ref;
}}
/>
</TooltipProvider>
</NavRouter>
</APIContext.Provider>
</Internationalize>
Expand Down
25 changes: 10 additions & 15 deletions src/elements/content-sidebar/MetadataInstanceEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,43 @@
import {
MetadataInstanceForm,
type MetadataTemplateInstance,
UnsavedChangesModal,
type MetadataTemplate,
} from '@box/metadata-editor';
import { AutofillContextProvider, MetadataInstanceForm, type MetadataTemplateInstance } from '@box/metadata-editor';
import noop from 'lodash/noop';
import React from 'react';

export interface MetadataInstanceEditorProps {
isBoxAiSuggestionsEnabled: boolean;
isUnsavedChangesModalOpen: boolean;
template: MetadataTemplateInstance | MetadataTemplate;
template: MetadataTemplateInstance;
onCancel: () => void;
}

const MetadataInstanceEditor: React.FC<MetadataInstanceEditorProps> = ({
isBoxAiSuggestionsEnabled,
isUnsavedChangesModalOpen,
template,
onCancel,
}) => {
const handleSubmit = () => {
// TODO in a future PR
};
const handleCancel = () => {
// TODO in a future PR
onCancel();
};
const handleDelete = () => {
// TODO in a future PR
};

return (
<>
<AutofillContextProvider isAiSuggestionsFeatureEnabled={isBoxAiSuggestionsEnabled}>
<MetadataInstanceForm
isAiSuggestionsFeatureEnabled={isBoxAiSuggestionsEnabled}
isLoading={false}
selectedTemplateInstance={template}
onCancel={handleCancel}
onDelete={handleDelete}
onSubmit={handleSubmit}
isUnsavedChangesModalOpen={isUnsavedChangesModalOpen}
setIsUnsavedChangesModalOpen={noop}
/>
<UnsavedChangesModal
onDismiss={handleCancel}
onSaveAndContinue={handleSubmit}
open={isUnsavedChangesModalOpen}
/>
</>
</AutofillContextProvider>
);
};

Expand Down
65 changes: 41 additions & 24 deletions src/elements/content-sidebar/MetadataSidebarRedesign.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { InlineError, LoadingIndicator } from '@box/blueprint-web';
import {
AddMetadataTemplateDropdown,
MetadataEmptyState,
MetadataInstanceList,
type MetadataTemplateInstance,
type MetadataTemplate,
} from '@box/metadata-editor';
import noop from 'lodash/noop';

import API from '../../api';
import SidebarContent from './SidebarContent';
Expand Down Expand Up @@ -67,36 +69,39 @@ function MetadataSidebarRedesign({
onError,
isFeatureEnabled,
}: MetadataSidebarRedesignProps) {
const { formatMessage } = useIntl();

const [selectedTemplates, setSelectedTemplates] = React.useState<Array<MetadataTemplate>>([]);
const [editingTemplate, setEditingTemplate] = React.useState<MetadataTemplateInstance | MetadataTemplate | null>(
null,
);
const [isUnsavedChangesModalOpen, setIsUnsavedChangesModalOpen] = React.useState<boolean>(false);

const { file, templates, errorMessage, status, templateInstances } = useSidebarMetadataFetcher(
api,
fileId,
onError,
isFeatureEnabled,
);
const { formatMessage } = useIntl();
const [editingTemplate, setEditingTemplate] = React.useState<MetadataTemplateInstance | null>(null);
const [isUnsavedChangesModalOpen, setIsUnsavedChangesModalOpen] = React.useState<boolean>(false);
const [selectedTemplates, setSelectedTemplates] =
React.useState<Array<MetadataTemplateInstance | MetadataTemplate>>(templateInstances);

React.useEffect(() => {
setSelectedTemplates(templateInstances);
}, [templateInstances]);

const handleUnsavedChanges = () => {
setIsUnsavedChangesModalOpen(true);
};

const handleTemplateSelect = (selectedTemplate: MetadataTemplate) => {
const handleTemplateSelect = (selectedTemplate: MetadataTemplateInstance) => {
setSelectedTemplates([...selectedTemplates, selectedTemplate]);
setEditingTemplate(selectedTemplate);
};

const metadataDropdown = status === STATUS.SUCCESS && templates && (
<AddMetadataTemplateDropdown
availableTemplates={templates}
selectedTemplates={selectedTemplates}
selectedTemplates={selectedTemplates as MetadataTemplate[]}
onSelect={(selectedTemplate): void => {
editingTemplate ? handleUnsavedChanges() : handleTemplateSelect(selectedTemplate);
editingTemplate
? handleUnsavedChanges()
: handleTemplateSelect(selectedTemplate as MetadataTemplateInstance);
}}
/>
);
Expand All @@ -108,7 +113,11 @@ function MetadataSidebarRedesign({
);

const showTemplateInstances = file && templates && templateInstances;
const showEmptyState = showTemplateInstances && templateInstances.length === 0 && !editingTemplate;

const showLoading = status === STATUS.LOADING;
const showEmptyState = !showLoading && showTemplateInstances && templateInstances.length === 0 && !editingTemplate;
const showEditor = !showEmptyState && editingTemplate;
const showList = !showEditor && templateInstances.length > 0 && !editingTemplate;

return (
<SidebarContent
Expand All @@ -120,19 +129,27 @@ function MetadataSidebarRedesign({
>
<div className="bcs-MetadataSidebarRedesign-content">
{errorMessageDisplay}
{status === STATUS.LOADING && (
<LoadingIndicator aria-label={formatMessage(messages.loading)} data-testid="loading" />
)}
{showEmptyState ? (
{showLoading && <LoadingIndicator aria-label={formatMessage(messages.loading)} />}
{showEmptyState && (
<MetadataEmptyState level={'file'} isBoxAiSuggestionsFeatureEnabled={isBoxAiSuggestionsEnabled} />
) : (
editingTemplate && (
<MetadataInstanceEditor
isBoxAiSuggestionsEnabled={isBoxAiSuggestionsEnabled}
isUnsavedChangesModalOpen={isUnsavedChangesModalOpen}
template={editingTemplate}
/>
)
)}
{editingTemplate && (
<MetadataInstanceEditor
isBoxAiSuggestionsEnabled={isBoxAiSuggestionsEnabled}
isUnsavedChangesModalOpen={isUnsavedChangesModalOpen}
template={editingTemplate}
onCancel={() => setEditingTemplate(null)}
/>
)}
{showList && (
<MetadataInstanceList
isAiSuggestionsFeatureEnabled={isBoxAiSuggestionsEnabled}
onEdit={templateInstance => {
setEditingTemplate(templateInstance);
}}
onEditWithAutofill={noop}
templateInstances={templateInstances}
/>
)}
</div>
</SidebarContent>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
import React from 'react';
import { type MetadataTemplate } from '@box/metadata-editor';
import { type MetadataTemplateInstance } from '@box/metadata-editor';
import { screen, render } from '../../../test-utils/testing-library';
import MetadataInstanceEditor, { MetadataInstanceEditorProps } from '../MetadataInstanceEditor';

describe('MetadataInstanceEditor', () => {
const mockCustomMetadataTemplate: MetadataTemplate = {
const mockCustomMetadataTemplate: MetadataTemplateInstance = {
id: 'template-id',
fields: [],
scope: 'global',
templateKey: 'properties',
type: 'template-id',
hidden: false,
canEdit: true,
};

const mockMetadataTemplate: MetadataTemplate = { ...mockCustomMetadataTemplate, displayName: 'Template Name' };
const mockMetadataTemplateInstance: MetadataTemplateInstance = {
...mockCustomMetadataTemplate,
displayName: 'Template Name',
};

const defaultProps: MetadataInstanceEditorProps = {
isBoxAiSuggestionsEnabled: true,
isUnsavedChangesModalOpen: false,
template: mockMetadataTemplate,
template: mockMetadataTemplateInstance,
onCancel: jest.fn(),
};

test('should render MetadataInstanceForm with correct props', () => {
render(<MetadataInstanceEditor {...defaultProps} />);

const templateHeader = screen.getByText(mockMetadataTemplate.displayName);
const templateHeader = screen.getByText(mockMetadataTemplateInstance.displayName);
expect(templateHeader).toBeInTheDocument();
});

Expand Down
Loading

0 comments on commit b4e4b01

Please sign in to comment.