Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/elements/content-explorer/ContentExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export interface ContentExplorerProps {
metadataQuery?: MetadataQuery;
metadataViewProps?: Omit<
MetadataViewContainerProps,
'hasError' | 'currentCollection' | 'metadataTemplate' | 'onMetadataFilter'
'hasError' | 'currentCollection' | 'metadataTemplate' | 'selectedKeys'
>;
onCreate?: (item: BoxItem) => void;
onDelete?: (item: BoxItem) => void;
Expand Down Expand Up @@ -1647,7 +1647,10 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
return maxWidthColumns;
};

getMetadataViewProps = (): ContentExplorerProps['metadataViewProps'] => {
getMetadataViewProps = (): Omit<
MetadataViewContainerProps,
'hasError' | 'currentCollection' | 'metadataTemplate'
> => {
const { metadataViewProps } = this.props;
const { onSelectionChange } = metadataViewProps ?? {};
const { selectedItemIds } = this.state;
Expand Down
43 changes: 28 additions & 15 deletions src/elements/content-explorer/MetadataViewContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ const MetadataViewContainer = ({
const clonedTemplate = cloneDeep(metadataTemplate);
let fields = clonedTemplate?.fields || [];

// Filter fields to only include those that have corresponding columns
const columnIds = newColumns.map(col => col.id);
fields = fields.filter((field: MetadataTemplateField) => {
// For metadata fields, check if the column ID matches the field key
// Column IDs for metadata fields are typically in format: metadata.template.fieldKey
return columnIds.some(columnId => {
const trimmedColumnId = trimMetadataFieldPrefix(columnId);
return trimmedColumnId === field.key;
});
});

// Check if item_name field already exists to avoid duplicates
const hasItemNameField = fields.some((field: MetadataTemplateField) => field.key === ITEM_FILTER_NAME);

Expand Down Expand Up @@ -185,7 +196,7 @@ const MetadataViewContainer = ({
}) || [],
},
];
}, [formatMessage, metadataTemplate]);
}, [formatMessage, metadataTemplate, newColumns]);

const initialFilterValues = React.useMemo(
() => transformInitialFilterValuesToInternal(initialFilterValuesProp),
Expand All @@ -203,20 +214,6 @@ const MetadataViewContainer = ({
[onFilterSubmit, onMetadataFilter],
);

const transformedActionBarProps = React.useMemo(() => {
return {
...actionBarProps,
initialFilterValues,
onFilterSubmit: handleFilterSubmit,
filterGroups,

predefinedFilterOptions: {
[PredefinedFilterName.KeywordSearchFilterGroup]: { isDisabled: true },
[PredefinedFilterName.LocationFilterGroup]: { isDisabled: true },
},
};
}, [actionBarProps, initialFilterValues, handleFilterSubmit, filterGroups]);

// Create a wrapper function that calls both. The wrapper function should follow the signature of onSortChange from RAC
const handleSortChange = React.useCallback(
({ column, direction }: SortDescriptor) => {
Expand All @@ -239,6 +236,22 @@ const MetadataViewContainer = ({
[onSortChangeInternal, tableProps],
);

const transformedActionBarProps = React.useMemo(() => {
return {
...actionBarProps,
initialFilterValues,
onFilterSubmit: handleFilterSubmit,
filterGroups,
sortDropdownProps: {
onSortChange: handleSortChange,
},
predefinedFilterOptions: {
[PredefinedFilterName.KeywordSearchFilterGroup]: { isDisabled: true },
[PredefinedFilterName.LocationFilterGroup]: { isDisabled: true },
},
};
}, [actionBarProps, initialFilterValues, handleFilterSubmit, handleSortChange, filterGroups]);

// Create new tableProps with our wrapper function
const newTableProps = {
...tableProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,12 +442,7 @@ describe('elements/content-explorer/ContentExplorer', () => {
'name',
],
};
const fieldsToShow = [
{ key: `${metadataFieldNamePrefix}.name`, canEdit: false, displayName: 'Alias' },
{ key: `${metadataFieldNamePrefix}.industry`, canEdit: true },
{ key: `${metadataFieldNamePrefix}.last_contacted_at`, canEdit: true },
{ key: `${metadataFieldNamePrefix}.role`, canEdit: true },
];

const columns = [
{
// Always include the name column
Expand All @@ -472,9 +467,9 @@ describe('elements/content-explorer/ContentExplorer', () => {
metadataViewProps: {
columns,
isSelectionEnabled: true,
onMetadataFilter: jest.fn(),
},
metadataQuery,
fieldsToShow,
defaultView,
features: {
contentExplorer: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ describe('elements/content-explorer/MetadataViewContainer', () => {
];

const mockMetadataTemplateFields: MetadataTemplateField[] = [
{
id: 'field1',
key: 'item.name',
displayName: 'Name',
type: 'string',
},
{
id: 'field2',
key: 'industry',
Expand Down Expand Up @@ -101,6 +95,30 @@ describe('elements/content-explorer/MetadataViewContainer', () => {
minWidth: 250,
maxWidth: 250,
},
{
textValue: 'Contact Role',
id: 'role',
type: 'string',
allowsSorting: true,
minWidth: 250,
maxWidth: 250,
},
{
textValue: 'Status',
id: 'status',
type: 'string',
allowsSorting: true,
minWidth: 250,
maxWidth: 250,
},
{
textValue: 'Price',
id: 'price',
type: 'string',
allowsSorting: true,
minWidth: 250,
maxWidth: 250,
},
],
metadataTemplate: mockMetadataTemplate,
onMetadataFilter: jest.fn(),
Expand Down Expand Up @@ -264,9 +282,10 @@ describe('elements/content-explorer/MetadataViewContainer', () => {
actionBarProps: { initialFilterValues },
});

expect(screen.getByRole('button', { name: 'All Filters 3' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'All Filters 2' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: /Industry/i })).toHaveTextContent(/\(1\)/);
expect(screen.getByRole('button', { name: /Category/i })).toHaveTextContent(/\(2\)/);
// Category filter should not be present since there's no corresponding column
expect(screen.queryByRole('button', { name: /Category/i })).not.toBeInTheDocument();
});

test('should handle empty metadata template fields', () => {
Expand Down Expand Up @@ -334,12 +353,6 @@ describe('elements/content-explorer/MetadataViewContainer', () => {
const templateWithoutOptions: MetadataTemplate = {
...mockMetadataTemplate,
fields: [
{
id: 'field1',
key: 'name',
displayName: 'File Name',
type: 'string',
},
{
id: 'field2',
key: 'industry',
Expand All @@ -350,11 +363,11 @@ describe('elements/content-explorer/MetadataViewContainer', () => {
],
};

renderComponent({ metadataTemplate: templateWithoutOptions });
renderComponent({
metadataTemplate: templateWithoutOptions,
});

expect(screen.getByRole('button', { name: 'All Filters' })).toBeInTheDocument();
expect(screen.getAllByRole('button', { name: 'Name' })).toHaveLength(1); // Only the one added by component
expect(screen.getByRole('button', { name: 'File Name' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Industry' })).toBeInTheDocument();
});

Expand Down Expand Up @@ -546,4 +559,53 @@ describe('elements/content-explorer/MetadataViewContainer', () => {
).not.toBeInTheDocument();
});
});

test('should filter fields based on columns provided', () => {
const template: MetadataTemplate = {
...mockMetadataTemplate,
fields: [
{
id: 'field1',
key: 'status',
displayName: 'Status',
type: 'enum',
options: [
{ id: 's1', key: 'Active' },
{ id: 's2', key: 'Inactive' },
],
},
{
id: 'field2',
key: 'price',
displayName: 'Price',
type: 'float',
},
{
id: 'field3',
key: 'category',
displayName: 'Category',
type: 'multiSelect',
options: [
{ id: 'c1', key: 'tech' },
{ id: 'c2', key: 'finance' },
],
},
],
};

// Only provide columns for 'status' and 'price', not 'category'
renderComponent({
metadataTemplate: template,
});

// Should show filters for fields that have corresponding columns
expect(screen.getByRole('button', { name: 'All Filters' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Status' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Price' })).toBeInTheDocument();

// Should NOT show filter for 'category' since there's no corresponding column
expect(screen.queryByRole('button', { name: 'Category' })).not.toBeInTheDocument();
// Should NOT show filter for 'industry' since it's not in the provided columns
expect(screen.queryByRole('button', { name: 'Industry' })).not.toBeInTheDocument();
});
});