Skip to content

Commit 8e33f02

Browse files
Merge branch 'box:master' into WEBAPP-33012
2 parents cf44f80 + 141cf6e commit 8e33f02

File tree

10 files changed

+234
-88
lines changed

10 files changed

+234
-88
lines changed

i18n/ja-JP.properties

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -583,17 +583,17 @@ be.messageCenter.product = 製品
583583
# Title for the message center modal
584584
be.messageCenter.title = 最新情報
585585
# Text shown in error notification banner
586-
be.metadataUpdateErrorNotification = Unable to save changes. Please try again.
586+
be.metadataUpdateErrorNotification = 変更を保存できません。もう一度お試しください。
587587
# Text shown in success notification banner
588-
be.metadataUpdateSuccessNotification = {numSelected, plural, =1 {1 document updated} other {# documents updated} }
588+
be.metadataUpdateSuccessNotification = {numSelected, plural, =1 {1ドキュメントが更新されました} other {#ドキュメントが更新されました} }
589589
# Text for modified date with modified prefix.
590590
be.modifiedDate = 修正日: {date}
591591
# Text for modified date with user with modified prefix.
592592
be.modifiedDateBy = 更新日: {date}、更新者: {name}
593593
# Label for a button that displays more options
594594
be.moreOptions = その他のオプション
595595
# Display text for field when there are multiple items selected and have different value
596-
be.multipleValues = Multiple Values
596+
be.multipleValues = 複数の値
597597
# Name ascending option shown in the share access drop down select.
598598
be.nameASC = 名前: A → Z
599599
# Name descending option shown in the share access drop down select.
@@ -841,7 +841,7 @@ be.sort = 並べ替え
841841
# Label for status skill card in the preview sidebar
842842
be.statusSkill = ステータス
843843
# Generic success label.
844-
be.success = Success
844+
be.success = 成功
845845
# Shown instead of todays date.
846846
be.today = 今日
847847
# Label for keywords/topics skill section in the preview sidebar
@@ -977,7 +977,7 @@ boxui.classification.add = 追加
977977
# Title of the card that shows the reason why the AI classification was applied when no date is available.
978978
boxui.classification.appliedByBoxAi = Box AI
979979
# Title of the card that shows the reason why the AI classification was applied on a specific date.
980-
boxui.classification.appliedByBoxAiOnDate = Box AI on {modifiedAt}
980+
boxui.classification.appliedByBoxAiOnDate = Box AIによる変更日{modifiedAt}
981981
# Header for classification section in sidebar
982982
boxui.classification.classification = 分類
983983
# Classification label color name as dark blue

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
"@box/languages": "^1.0.0",
137137
"@box/metadata-editor": "^0.122.12",
138138
"@box/metadata-filter": "^1.19.2",
139-
"@box/metadata-view": "^0.48.6",
139+
"@box/metadata-view": "^0.48.14",
140140
"@box/react-virtualized": "^9.22.3-rc-box.10",
141141
"@box/types": "^0.2.1",
142142
"@cfaester/enzyme-adapter-react-18": "^0.8.0",
@@ -303,7 +303,7 @@
303303
"@box/item-icon": "^0.17.15",
304304
"@box/metadata-editor": "^0.122.12",
305305
"@box/metadata-filter": "^1.19.2",
306-
"@box/metadata-view": "^0.48.6",
306+
"@box/metadata-view": "^0.48.14",
307307
"@box/react-virtualized": "^9.22.3-rc-box.10",
308308
"@box/types": "^0.2.1",
309309
"@hapi/address": "^2.1.4",

scripts/cut_release.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ build_assets() {
124124
printf "${green}Built locales!${end}"
125125
}
126126

127+
set_assets_version() {
128+
printf "${blue}Setting version in assets...${end}"
129+
130+
# Replace the version variable in the transpiled output
131+
sed "s/__VERSION__/'$VERSION'/g" es/constants.js > es/constants.js.tmp && mv es/constants.js.tmp es/constants.js
132+
133+
# Replace the version placeholder in the bundled output
134+
for file in dist/*.js; do
135+
sed "s/0.0.0-semantically-released/$VERSION/g" ${file} > ${file}.tmp && mv ${file}.tmp ${file}
136+
done
137+
138+
printf "${green}Set assets to ${VERSION}!${end}"
139+
}
140+
127141
push_to_npm() {
128142
printf "${blue}Publishing assets to npmjs...${end}"
129143
npm publish --access public --tag "$DIST" || return 1
@@ -251,6 +265,9 @@ push_new_release() {
251265
return 0
252266
fi
253267

268+
# Set the version in the build assets
269+
set_assets_version || return 1
270+
254271
# package.json should be the only updated and uncommitted file
255272
check_uncommitted_files_ignoring_package_json || return 1
256273

src/elements/content-explorer/ContentExplorer.tsx

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import cloneDeep from 'lodash/cloneDeep';
55
import debounce from 'lodash/debounce';
66
import flow from 'lodash/flow';
77
import getProp from 'lodash/get';
8+
import isEqual from 'lodash/isEqual';
89
import noop from 'lodash/noop';
910
import throttle from 'lodash/throttle';
1011
import uniqueid from 'lodash/uniqueId';
@@ -144,7 +145,7 @@ export interface ContentExplorerProps {
144145
metadataQuery?: MetadataQuery;
145146
metadataViewProps?: Omit<
146147
MetadataViewContainerProps,
147-
'hasError' | 'currentCollection' | 'metadataTemplate' | 'onMetadataFilter'
148+
'hasError' | 'currentCollection' | 'metadataTemplate' | 'selectedKeys'
148149
>;
149150
onCreate?: (item: BoxItem) => void;
150151
onDelete?: (item: BoxItem) => void;
@@ -424,6 +425,8 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
424425
metadataTemplate,
425426
};
426427

428+
this.validateSelectedItemIds(metadataQueryCollection.items || []);
429+
427430
// if v2, fetch folder name and add to state
428431
if (metadataQuery?.ancestor_folder_id && isFeatureEnabled(features, 'contentExplorer.metadataViewV2')) {
429432
this.api.getFolderAPI().getFolderFields(
@@ -1010,6 +1013,35 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
10101013
this.setState({ currentCollection: newCollection, selected: newSelectedItem }, callback);
10111014
}
10121015

1016+
/**
1017+
* Validates selectedItemIds to ensure all selected IDs exist in current items
1018+
* This should be called whenever currentCollection changes
1019+
*
1020+
* @private
1021+
* @param {BoxItem[]} items - current items in the collection
1022+
* @return {void}
1023+
*/
1024+
validateSelectedItemIds = (items: BoxItem[]): void => {
1025+
const { selectedItemIds } = this.state;
1026+
1027+
if (selectedItemIds === 'all' || selectedItemIds.size === 0) {
1028+
// If all/none items are selected, no need to change anything
1029+
return;
1030+
}
1031+
1032+
const validSelectedIds = new Set<string>();
1033+
1034+
items.forEach(item => {
1035+
if (selectedItemIds.has(item.id)) {
1036+
validSelectedIds.add(item.id);
1037+
}
1038+
});
1039+
1040+
if (!isEqual(validSelectedIds, selectedItemIds)) {
1041+
this.setState({ selectedItemIds: validSelectedIds });
1042+
}
1043+
};
1044+
10131045
/**
10141046
* Attempts to generate a thumbnail for the given item and assigns the
10151047
* item its thumbnail url if successful
@@ -1046,6 +1078,9 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
10461078
const newCollection = { ...currentCollection } as const;
10471079

10481080
newCollection.items = items.map(item => (item.id === newItem.id ? newItem : item));
1081+
1082+
this.validateSelectedItemIds(newCollection.items);
1083+
10491084
this.setState({ currentCollection: newCollection });
10501085
};
10511086

@@ -1612,25 +1647,32 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
16121647
return maxWidthColumns;
16131648
};
16141649

1615-
getMetadataViewProps = (): ContentExplorerProps['metadataViewProps'] => {
1650+
getMetadataViewProps = (): Omit<
1651+
MetadataViewContainerProps,
1652+
'hasError' | 'currentCollection' | 'metadataTemplate'
1653+
> => {
16161654
const { metadataViewProps } = this.props;
1617-
const { tableProps } = metadataViewProps ?? {};
1618-
const { onSelectionChange } = tableProps ?? {};
1619-
const { selectedItemIds } = this.state;
1655+
const { onSelectionChange } = metadataViewProps ?? {};
1656+
const { currentPageNumber, markers, selectedItemIds } = this.state;
1657+
const hasNextMarker: boolean = !!markers[currentPageNumber + 1];
1658+
const hasPrevMarker: boolean = currentPageNumber === 1 || !!markers[currentPageNumber - 1];
16201659

16211660
return {
16221661
...metadataViewProps,
1623-
tableProps: {
1624-
...tableProps,
1625-
selectedKeys: selectedItemIds,
1626-
onSelectionChange: (ids: Selection) => {
1627-
onSelectionChange?.(ids);
1628-
const isSelectionEmpty = ids !== 'all' && ids.size === 0;
1629-
this.setState({
1630-
selectedItemIds: ids,
1631-
...(isSelectionEmpty && { isMetadataSidePanelOpen: false }),
1632-
});
1633-
},
1662+
selectedKeys: selectedItemIds,
1663+
onSelectionChange: (ids: Selection) => {
1664+
onSelectionChange?.(ids);
1665+
const isSelectionEmpty = ids !== 'all' && ids.size === 0;
1666+
this.setState({
1667+
selectedItemIds: ids,
1668+
...(isSelectionEmpty && { isMetadataSidePanelOpen: false }),
1669+
});
1670+
},
1671+
paginationProps: {
1672+
onMarkerBasedPageChange: this.markerBasedPaginate,
1673+
hasNextMarker,
1674+
hasPrevMarker,
1675+
type: 'marker',
16341676
},
16351677
};
16361678
};
@@ -1701,6 +1743,8 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
17011743
return clonedItem;
17021744
});
17031745

1746+
this.validateSelectedItemIds(updatedItems);
1747+
17041748
this.setState({
17051749
currentCollection: {
17061750
items: updatedItems,
@@ -1905,7 +1949,7 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
19051949
viewMode={viewMode}
19061950
/>
19071951

1908-
{!isErrorView && (
1952+
{!isErrorView && !isMetadataViewV2Feature && (
19091953
<Footer>
19101954
<Pagination
19111955
hasNextMarker={hasNextMarker}

src/elements/content-explorer/MetadataViewContainer.tsx

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
RangeType,
99
} from '@box/metadata-filter';
1010
import {
11+
IconColumnVariant,
1112
MetadataView,
1213
PredefinedFilterName,
1314
type FilterValues,
@@ -155,6 +156,17 @@ const MetadataViewContainer = ({
155156
const clonedTemplate = cloneDeep(metadataTemplate);
156157
let fields = clonedTemplate?.fields || [];
157158

159+
// Filter fields to only include those that have corresponding columns
160+
const columnIds = newColumns.map(col => col.id);
161+
fields = fields.filter((field: MetadataTemplateField) => {
162+
// For metadata fields, check if the column ID matches the field key
163+
// Column IDs for metadata fields are typically in format: metadata.template.fieldKey
164+
return columnIds.some(columnId => {
165+
const trimmedColumnId = trimMetadataFieldPrefix(columnId);
166+
return trimmedColumnId === field.key;
167+
});
168+
});
169+
158170
// Check if item_name field already exists to avoid duplicates
159171
const hasItemNameField = fields.some((field: MetadataTemplateField) => field.key === ITEM_FILTER_NAME);
160172

@@ -185,7 +197,7 @@ const MetadataViewContainer = ({
185197
}) || [],
186198
},
187199
];
188-
}, [formatMessage, metadataTemplate]);
200+
}, [formatMessage, metadataTemplate, newColumns]);
189201

190202
const initialFilterValues = React.useMemo(
191203
() => transformInitialFilterValuesToInternal(initialFilterValuesProp),
@@ -203,20 +215,6 @@ const MetadataViewContainer = ({
203215
[onFilterSubmit, onMetadataFilter],
204216
);
205217

206-
const transformedActionBarProps = React.useMemo(() => {
207-
return {
208-
...actionBarProps,
209-
initialFilterValues,
210-
onFilterSubmit: handleFilterSubmit,
211-
filterGroups,
212-
213-
predefinedFilterOptions: {
214-
[PredefinedFilterName.KeywordSearchFilterGroup]: { isDisabled: true },
215-
[PredefinedFilterName.LocationFilterGroup]: { isDisabled: true },
216-
},
217-
};
218-
}, [actionBarProps, initialFilterValues, handleFilterSubmit, filterGroups]);
219-
220218
// Create a wrapper function that calls both. The wrapper function should follow the signature of onSortChange from RAC
221219
const handleSortChange = React.useCallback(
222220
({ column, direction }: SortDescriptor) => {
@@ -239,9 +237,26 @@ const MetadataViewContainer = ({
239237
[onSortChangeInternal, tableProps],
240238
);
241239

240+
const transformedActionBarProps = React.useMemo(() => {
241+
return {
242+
...actionBarProps,
243+
initialFilterValues,
244+
onFilterSubmit: handleFilterSubmit,
245+
filterGroups,
246+
sortDropdownProps: {
247+
onSortChange: handleSortChange,
248+
},
249+
predefinedFilterOptions: {
250+
[PredefinedFilterName.KeywordSearchFilterGroup]: { isDisabled: true },
251+
[PredefinedFilterName.LocationFilterGroup]: { isDisabled: true },
252+
},
253+
};
254+
}, [actionBarProps, initialFilterValues, handleFilterSubmit, handleSortChange, filterGroups]);
255+
242256
// Create new tableProps with our wrapper function
243257
const newTableProps = {
244258
...tableProps,
259+
iconColumnVariant: IconColumnVariant.INLINE,
245260
onSortChange: handleSortChange,
246261
};
247262

src/elements/content-explorer/__tests__/ContentExplorer.test.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -442,12 +442,7 @@ describe('elements/content-explorer/ContentExplorer', () => {
442442
'name',
443443
],
444444
};
445-
const fieldsToShow = [
446-
{ key: `${metadataFieldNamePrefix}.name`, canEdit: false, displayName: 'Alias' },
447-
{ key: `${metadataFieldNamePrefix}.industry`, canEdit: true },
448-
{ key: `${metadataFieldNamePrefix}.last_contacted_at`, canEdit: true },
449-
{ key: `${metadataFieldNamePrefix}.role`, canEdit: true },
450-
];
445+
451446
const columns = [
452447
{
453448
// Always include the name column
@@ -471,12 +466,10 @@ describe('elements/content-explorer/ContentExplorer', () => {
471466
const metadataViewV2ElementProps: Partial<ContentExplorerProps> = {
472467
metadataViewProps: {
473468
columns,
474-
tableProps: {
475-
isSelectAllEnabled: true,
476-
},
469+
isSelectionEnabled: true,
470+
onMetadataFilter: jest.fn(),
477471
},
478472
metadataQuery,
479-
fieldsToShow,
480473
defaultView,
481474
features: {
482475
contentExplorer: {

0 commit comments

Comments
 (0)