box-ui-elements 23.4.0-beta.37 → 23.4.0-beta.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/explorer.css +1 -1
- package/dist/explorer.js +1 -1
- package/dist/preview.css +1 -1
- package/dist/preview.js +1 -1
- package/dist/sidebar.css +1 -1
- package/dist/sidebar.js +1 -1
- package/es/common/types/metadata.js.flow +5 -4
- package/es/common/types/metadata.js.map +1 -1
- package/es/elements/content-explorer/stories/tests/MetadataView-visual.stories.js +43 -22
- package/es/elements/content-explorer/stories/tests/MetadataView-visual.stories.js.map +1 -1
- package/es/features/metadata-instance-editor/CascadePolicy.js +6 -3
- package/es/features/metadata-instance-editor/CascadePolicy.js.flow +8 -2
- package/es/features/metadata-instance-editor/CascadePolicy.js.map +1 -1
- package/es/features/metadata-instance-editor/Instance.js +1 -0
- package/es/features/metadata-instance-editor/Instance.js.flow +1 -0
- package/es/features/metadata-instance-editor/Instance.js.map +1 -1
- package/es/src/elements/content-explorer/stories/tests/MetadataView-visual.stories.d.ts +1 -1
- package/package.json +3 -3
- package/src/common/types/metadata.js +5 -4
- package/src/elements/content-explorer/stories/tests/MetadataView-visual.stories.tsx +47 -31
- package/src/features/metadata-instance-editor/CascadePolicy.js +8 -2
- package/src/features/metadata-instance-editor/Instance.js +1 -0
- package/src/features/metadata-instance-editor/__tests__/CascadePolicy.test.js +45 -0
|
@@ -2,6 +2,6 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
2
2
|
import ContentExplorer from '../../ContentExplorer';
|
|
3
3
|
type Story = StoryObj<typeof ContentExplorer>;
|
|
4
4
|
export declare const metadataView: Story;
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const metadataViewV2: Story;
|
|
6
6
|
declare const meta: Meta<typeof ContentExplorer>;
|
|
7
7
|
export default meta;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "box-ui-elements",
|
|
3
|
-
"version": "23.4.0-beta.
|
|
3
|
+
"version": "23.4.0-beta.38",
|
|
4
4
|
"description": "Box UI Elements",
|
|
5
5
|
"author": "Box (https://www.box.com/)",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
"@babel/types": "^7.24.7",
|
|
131
131
|
"@box/blueprint-web": "12.43.0",
|
|
132
132
|
"@box/blueprint-web-assets": "4.61.5",
|
|
133
|
-
"@box/box-ai-agent-selector": "^0.
|
|
133
|
+
"@box/box-ai-agent-selector": "^0.52.0",
|
|
134
134
|
"@box/box-ai-content-answers": "^0.124.1",
|
|
135
135
|
"@box/box-item-type-selector": "^0.61.12",
|
|
136
136
|
"@box/cldr-data": "^34.2.0",
|
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
"peerDependencies": {
|
|
300
300
|
"@box/blueprint-web": "12.43.0",
|
|
301
301
|
"@box/blueprint-web-assets": "4.61.5",
|
|
302
|
-
"@box/box-ai-agent-selector": "^0.
|
|
302
|
+
"@box/box-ai-agent-selector": "^0.52.0",
|
|
303
303
|
"@box/box-ai-content-answers": "^0.124.1",
|
|
304
304
|
"@box/box-item-type-selector": "^0.61.12",
|
|
305
305
|
"@box/cldr-data": ">=34.2.0",
|
|
@@ -87,14 +87,15 @@ type MetadataType = {
|
|
|
87
87
|
global?: MetadataSkillsTemplate,
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
+
type MetadataCascadePolicyConfiguration = {
|
|
91
|
+
agent: string,
|
|
92
|
+
};
|
|
93
|
+
|
|
90
94
|
type MetadataCascadePolicy = {
|
|
91
95
|
canEdit?: boolean,
|
|
92
96
|
id?: string,
|
|
93
97
|
cascadePolicyType?: string,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
type MetadataCascadePolicyConfiguration = {
|
|
97
|
-
agent: string,
|
|
98
|
+
cascadePolicyConfiguration?: MetadataCascadePolicyConfiguration,
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
type MetadataCascadingPolicyData = {
|
|
@@ -5,45 +5,61 @@ import ContentExplorer from '../../ContentExplorer';
|
|
|
5
5
|
import { DEFAULT_HOSTNAME_API } from '../../../../constants';
|
|
6
6
|
import { mockMetadata, mockSchema } from '../../../common/__mocks__/mockMetadata';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const metadataSource = `enterprise_${EID}.${templateName}`;
|
|
11
|
-
const metadataSourceFieldName = `metadata.${metadataSource}`;
|
|
8
|
+
// The intent behind relying on mockMetadata is to allow a developer to paste in their own metadata template schema for use with live API calls.
|
|
9
|
+
const { scope: templateScope, templateKey } = mockSchema;
|
|
12
10
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// // Filter items in the folder by existing metadata key
|
|
17
|
-
// query: 'key = :arg1',
|
|
18
|
-
//
|
|
19
|
-
// // Display items with value
|
|
20
|
-
// query_params: { arg1: 'value' },
|
|
11
|
+
const metadataScopeAndKey = `${templateScope}.${templateKey}`;
|
|
12
|
+
const metadataFieldNamePrefix = `metadata.${metadataScopeAndKey}`;
|
|
21
13
|
|
|
22
|
-
|
|
14
|
+
// This is the body of the metadata query API call.
|
|
15
|
+
// https://developer.box.com/guides/metadata/queries/syntax/
|
|
16
|
+
const metadataQuery = {
|
|
17
|
+
from: metadataScopeAndKey,
|
|
18
|
+
ancestor_folder_id: '0',
|
|
19
|
+
sort_by: [
|
|
20
|
+
{
|
|
21
|
+
field_key: `${metadataFieldNamePrefix}.${mockSchema.fields[0].key}`, // Default to sorting by the first field in the schema
|
|
22
|
+
direction: 'asc',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
23
25
|
fields: [
|
|
24
|
-
|
|
25
|
-
`${
|
|
26
|
-
|
|
27
|
-
`${metadataSourceFieldName}.role`,
|
|
26
|
+
// Default to returning all fields in the metadata template schema, and name as a standalone (non-metadata) field
|
|
27
|
+
...mockSchema.fields.map(field => `${metadataFieldNamePrefix}.${field.key}`),
|
|
28
|
+
'name',
|
|
28
29
|
],
|
|
29
30
|
};
|
|
30
31
|
|
|
32
|
+
// Used for metadata view v1
|
|
31
33
|
const fieldsToShow = [
|
|
32
|
-
{ key: `${
|
|
33
|
-
{ key: `${
|
|
34
|
-
{ key: `${
|
|
35
|
-
{ key: `${
|
|
34
|
+
{ key: `${metadataFieldNamePrefix}.name`, canEdit: false, displayName: 'Alias' },
|
|
35
|
+
{ key: `${metadataFieldNamePrefix}.industry`, canEdit: true },
|
|
36
|
+
{ key: `${metadataFieldNamePrefix}.last_contacted_at`, canEdit: true },
|
|
37
|
+
{ key: `${metadataFieldNamePrefix}.role`, canEdit: true },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
// Used for metadata view v2
|
|
41
|
+
const columns = [
|
|
42
|
+
{
|
|
43
|
+
// Always include the name column
|
|
44
|
+
textValue: 'Name',
|
|
45
|
+
id: 'name',
|
|
46
|
+
type: 'string',
|
|
47
|
+
allowSorting: true,
|
|
48
|
+
minWidth: 150,
|
|
49
|
+
maxWidth: 150,
|
|
50
|
+
},
|
|
51
|
+
...mockSchema.fields.map(field => ({
|
|
52
|
+
textValue: field.displayName,
|
|
53
|
+
id: `${metadataFieldNamePrefix}.${field.key}`,
|
|
54
|
+
type: field.type,
|
|
55
|
+
allowSorting: true,
|
|
56
|
+
minWidth: 150,
|
|
57
|
+
maxWidth: 150,
|
|
58
|
+
})),
|
|
36
59
|
];
|
|
37
60
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
id: `${metadataSourceFieldName}.${field.key}`,
|
|
41
|
-
type: field.type,
|
|
42
|
-
allowSorting: true,
|
|
43
|
-
minWidth: 150,
|
|
44
|
-
maxWidth: 150,
|
|
45
|
-
}));
|
|
46
|
-
const defaultView = 'metadata'; // Required prop to paint the metadata view. If not provided, you'll get regular folder view.
|
|
61
|
+
// Switches ContentExplorer to use Metadata View over standard, folder-based view.
|
|
62
|
+
const defaultView = 'metadata';
|
|
47
63
|
|
|
48
64
|
type Story = StoryObj<typeof ContentExplorer>;
|
|
49
65
|
|
|
@@ -55,7 +71,7 @@ export const metadataView: Story = {
|
|
|
55
71
|
},
|
|
56
72
|
};
|
|
57
73
|
|
|
58
|
-
export const
|
|
74
|
+
export const metadataViewV2: Story = {
|
|
59
75
|
args: {
|
|
60
76
|
metadataViewProps: {
|
|
61
77
|
columns,
|
|
@@ -18,7 +18,8 @@ import Link from '../../components/link/Link';
|
|
|
18
18
|
import IconAlertDefault from '../../icons/general/IconAlertDefault';
|
|
19
19
|
import messages from './messages';
|
|
20
20
|
import './CascadePolicy.scss';
|
|
21
|
-
import { STANDARD_AGENT_ID, ENHANCED_AGENT_ID } from './constants';
|
|
21
|
+
import { STANDARD_AGENT_ID, ENHANCED_AGENT_ID, ENHANCED_AGENT_CONFIGURATION } from './constants';
|
|
22
|
+
import type { MetadataCascadePolicyConfiguration } from '../../common/types/metadata';
|
|
22
23
|
|
|
23
24
|
const COMMUNITY_LINK = 'https://support.box.com/hc/en-us/articles/360044195873-Cascading-metadata-in-folders';
|
|
24
25
|
const AI_LINK = 'https://www.box.com/ai';
|
|
@@ -27,6 +28,7 @@ type Props = {
|
|
|
27
28
|
canEdit: boolean,
|
|
28
29
|
canUseAIFolderExtraction: boolean,
|
|
29
30
|
canUseAIFolderExtractionAgentSelector: boolean,
|
|
31
|
+
cascadePolicyConfiguration?: MetadataCascadePolicyConfiguration,
|
|
30
32
|
isAIFolderExtractionEnabled: boolean,
|
|
31
33
|
isCascadingEnabled: boolean,
|
|
32
34
|
isCascadingOverwritten: boolean,
|
|
@@ -43,6 +45,7 @@ const CascadePolicy = ({
|
|
|
43
45
|
canEdit,
|
|
44
46
|
canUseAIFolderExtraction,
|
|
45
47
|
canUseAIFolderExtractionAgentSelector,
|
|
48
|
+
cascadePolicyConfiguration,
|
|
46
49
|
isCascadingEnabled,
|
|
47
50
|
isCascadingOverwritten,
|
|
48
51
|
isCustomMetadata,
|
|
@@ -62,6 +65,8 @@ const CascadePolicy = ({
|
|
|
62
65
|
</div>
|
|
63
66
|
) : null;
|
|
64
67
|
|
|
68
|
+
const isEnhancedAgentSelected = cascadePolicyConfiguration?.agent === ENHANCED_AGENT_CONFIGURATION;
|
|
69
|
+
|
|
65
70
|
const agents = React.useMemo(
|
|
66
71
|
() => [
|
|
67
72
|
{
|
|
@@ -74,9 +79,10 @@ const CascadePolicy = ({
|
|
|
74
79
|
name: formatMessage(messages.enhancedAgentName),
|
|
75
80
|
isEnterpriseDefault: false,
|
|
76
81
|
customIcon: BoxAiAdvancedColor,
|
|
82
|
+
isSelected: isEnhancedAgentSelected,
|
|
77
83
|
},
|
|
78
84
|
],
|
|
79
|
-
[formatMessage],
|
|
85
|
+
[formatMessage, isEnhancedAgentSelected],
|
|
80
86
|
);
|
|
81
87
|
|
|
82
88
|
// BoxAiAgentSelectorWithApiContainer expects a function that returns a Promise<AgentListResponse>
|
|
@@ -700,6 +700,7 @@ class Instance extends React.PureComponent<Props, State> {
|
|
|
700
700
|
<div className="metadata-instance-editor-instance">
|
|
701
701
|
{isCascadingPolicyApplicable && (
|
|
702
702
|
<CascadePolicy
|
|
703
|
+
cascadePolicyConfiguration={cascadePolicy?.cascadePolicyConfiguration}
|
|
703
704
|
canEdit={isEditing && !!cascadePolicy.canEdit}
|
|
704
705
|
canUseAIFolderExtraction={canUseAIFolderExtraction}
|
|
705
706
|
canUseAIFolderExtractionAgentSelector={
|
|
@@ -176,6 +176,51 @@ describe('features/metadata-instance-editor/CascadePolicy', () => {
|
|
|
176
176
|
|
|
177
177
|
expect(onAIAgentSelect).toHaveBeenCalledWith(expectedAgent);
|
|
178
178
|
});
|
|
179
|
+
|
|
180
|
+
test('should render with cascadePolicyConfiguration prop and select enhanced agent if configured', async () => {
|
|
181
|
+
const cascadePolicyConfiguration = {
|
|
182
|
+
agent: 'enhanced_extract_agent',
|
|
183
|
+
};
|
|
184
|
+
render(
|
|
185
|
+
<CascadePolicy
|
|
186
|
+
canEdit
|
|
187
|
+
canUseAIFolderExtraction
|
|
188
|
+
canUseAIFolderExtractionAgentSelector
|
|
189
|
+
shouldShowCascadeOptions
|
|
190
|
+
isAIFolderExtractionEnabled
|
|
191
|
+
cascadePolicyConfiguration={cascadePolicyConfiguration}
|
|
192
|
+
onAIFolderExtractionToggle={jest.fn()}
|
|
193
|
+
/>,
|
|
194
|
+
);
|
|
195
|
+
const aiToggle = screen.getByRole('switch', { name: 'Box AI Autofill' });
|
|
196
|
+
await userEvent.click(aiToggle); // Enable AI
|
|
197
|
+
|
|
198
|
+
expect(aiToggle).toBeChecked();
|
|
199
|
+
|
|
200
|
+
// The Enhanced agent should be selected in the combobox
|
|
201
|
+
const combobox = screen.getByRole('combobox', { name: 'Enhanced' });
|
|
202
|
+
expect(combobox).toBeInTheDocument();
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('should render standard agent if cascadePolicyConfiguration is undefined', async () => {
|
|
206
|
+
render(
|
|
207
|
+
<CascadePolicy
|
|
208
|
+
canEdit
|
|
209
|
+
canUseAIFolderExtraction
|
|
210
|
+
canUseAIFolderExtractionAgentSelector
|
|
211
|
+
shouldShowCascadeOptions
|
|
212
|
+
isAIFolderExtractionEnabled
|
|
213
|
+
onAIFolderExtractionToggle={jest.fn()}
|
|
214
|
+
/>,
|
|
215
|
+
);
|
|
216
|
+
const aiToggle = screen.getByRole('switch', { name: 'Box AI Autofill' });
|
|
217
|
+
await userEvent.click(aiToggle); // Enable AI
|
|
218
|
+
|
|
219
|
+
expect(aiToggle).toBeChecked();
|
|
220
|
+
|
|
221
|
+
// Should default to Standard agent
|
|
222
|
+
expect(screen.getByRole('combobox', { name: 'Standard' })).toBeInTheDocument();
|
|
223
|
+
});
|
|
179
224
|
});
|
|
180
225
|
|
|
181
226
|
describe('AI Autofill Toggle', () => {
|