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.
@@ -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 withNewMetadataView: Story;
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.37",
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.48.5",
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.48.5",
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
- const EID = '0';
9
- const templateName = 'templateName';
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 metadataQuery = {
14
- from: metadataSource,
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
- ancestor_folder_id: '313259567207',
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
- `${metadataSourceFieldName}.name`,
25
- `${metadataSourceFieldName}.industry`,
26
- `${metadataSourceFieldName}.last_contacted_at`,
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: `${metadataSourceFieldName}.name`, canEdit: false, displayName: 'Alias' },
33
- { key: `${metadataSourceFieldName}.industry`, canEdit: true },
34
- { key: `${metadataSourceFieldName}.last_contacted_at`, canEdit: true },
35
- { key: `${metadataSourceFieldName}.role`, canEdit: true },
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
- const columns = mockSchema.fields.map(field => ({
39
- textValue: field.displayName,
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 withNewMetadataView: Story = {
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', () => {