box-ui-elements 24.0.0-beta.4 → 24.0.0-beta.5
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.js +1 -1
- package/dist/openwith.js +1 -1
- package/dist/picker.js +1 -1
- package/dist/preview.js +1 -1
- package/dist/sharing.js +1 -1
- package/dist/sidebar.js +1 -1
- package/dist/uploader.js +1 -1
- package/es/api/Metadata.js +98 -13
- package/es/api/Metadata.js.flow +110 -12
- package/es/api/Metadata.js.map +1 -1
- package/es/elements/common/messages.js +16 -0
- package/es/elements/common/messages.js.flow +25 -0
- package/es/elements/common/messages.js.map +1 -1
- package/es/elements/content-explorer/Content.js +2 -1
- package/es/elements/content-explorer/Content.js.map +1 -1
- package/es/elements/content-explorer/ContentExplorer.js +19 -5
- package/es/elements/content-explorer/ContentExplorer.js.map +1 -1
- package/es/elements/content-explorer/MetadataQueryAPIHelper.js +61 -4
- package/es/elements/content-explorer/MetadataQueryAPIHelper.js.map +1 -1
- package/es/elements/content-explorer/MetadataSidePanel.js +40 -14
- package/es/elements/content-explorer/MetadataSidePanel.js.map +1 -1
- package/es/elements/content-explorer/MetadataViewContainer.js +55 -4
- package/es/elements/content-explorer/MetadataViewContainer.js.map +1 -1
- package/es/elements/content-explorer/stories/tests/MetadataView-visual.stories.js +61 -13
- package/es/elements/content-explorer/stories/tests/MetadataView-visual.stories.js.map +1 -1
- package/es/elements/content-explorer/utils.js +140 -12
- package/es/elements/content-explorer/utils.js.map +1 -1
- package/es/src/elements/content-explorer/ContentExplorer.d.ts +11 -3
- package/es/src/elements/content-explorer/MetadataQueryAPIHelper.d.ts +11 -1
- package/es/src/elements/content-explorer/MetadataSidePanel.d.ts +6 -3
- package/es/src/elements/content-explorer/MetadataViewContainer.d.ts +3 -1
- package/es/src/elements/content-explorer/stories/tests/MetadataView-visual.stories.d.ts +1 -0
- package/es/src/elements/content-explorer/utils.d.ts +9 -3
- package/i18n/bn-IN.js +4 -0
- package/i18n/bn-IN.properties +4 -0
- package/i18n/da-DK.js +4 -0
- package/i18n/da-DK.properties +4 -0
- package/i18n/de-DE.js +5 -1
- package/i18n/de-DE.properties +4 -0
- package/i18n/en-AU.js +4 -0
- package/i18n/en-AU.properties +4 -0
- package/i18n/en-CA.js +4 -0
- package/i18n/en-CA.properties +4 -0
- package/i18n/en-GB.js +4 -0
- package/i18n/en-GB.properties +4 -0
- package/i18n/en-US.js +4 -0
- package/i18n/en-US.properties +8 -0
- package/i18n/en-x-pseudo.js +4 -0
- package/i18n/es-419.js +5 -1
- package/i18n/es-419.properties +4 -0
- package/i18n/es-ES.js +5 -1
- package/i18n/es-ES.properties +4 -0
- package/i18n/fi-FI.js +4 -0
- package/i18n/fi-FI.properties +4 -0
- package/i18n/fr-CA.js +4 -0
- package/i18n/fr-CA.properties +4 -0
- package/i18n/fr-FR.js +4 -0
- package/i18n/fr-FR.properties +4 -0
- package/i18n/hi-IN.js +4 -0
- package/i18n/hi-IN.properties +4 -0
- package/i18n/it-IT.js +4 -0
- package/i18n/it-IT.properties +4 -0
- package/i18n/ja-JP.js +6 -2
- package/i18n/ja-JP.properties +6 -2
- package/i18n/ko-KR.js +4 -0
- package/i18n/ko-KR.properties +4 -0
- package/i18n/nb-NO.js +4 -0
- package/i18n/nb-NO.properties +4 -0
- package/i18n/nl-NL.js +4 -0
- package/i18n/nl-NL.properties +4 -0
- package/i18n/pl-PL.js +4 -0
- package/i18n/pl-PL.properties +4 -0
- package/i18n/pt-BR.js +4 -0
- package/i18n/pt-BR.properties +4 -0
- package/i18n/ru-RU.js +5 -1
- package/i18n/ru-RU.properties +4 -0
- package/i18n/sv-SE.js +4 -0
- package/i18n/sv-SE.properties +4 -0
- package/i18n/tr-TR.js +5 -1
- package/i18n/tr-TR.properties +4 -0
- package/i18n/zh-CN.js +4 -0
- package/i18n/zh-CN.properties +4 -0
- package/i18n/zh-TW.js +4 -0
- package/i18n/zh-TW.properties +4 -0
- package/package.json +1 -1
- package/src/api/Metadata.js +110 -12
- package/src/api/__tests__/Metadata.test.js +120 -0
- package/src/elements/common/messages.js +25 -0
- package/src/elements/content-explorer/Content.tsx +1 -0
- package/src/elements/content-explorer/ContentExplorer.tsx +220 -181
- package/src/elements/content-explorer/MetadataQueryAPIHelper.ts +89 -4
- package/src/elements/content-explorer/MetadataSidePanel.tsx +55 -14
- package/src/elements/content-explorer/MetadataViewContainer.tsx +61 -1
- package/src/elements/content-explorer/__tests__/ContentExplorer.test.tsx +36 -2
- package/src/elements/content-explorer/__tests__/MetadataQueryAPIHelper.test.ts +8 -5
- package/src/elements/content-explorer/__tests__/MetadataSidePanel.test.tsx +145 -3
- package/src/elements/content-explorer/stories/tests/MetadataView-visual.stories.tsx +54 -8
- package/src/elements/content-explorer/utils.ts +150 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetadataView-visual.stories.js","names":["http","HttpResponse","Download","SignMeOthers","Sign","expect","fn","userEvent","waitFor","within","screen","noop","ContentExplorer","DEFAULT_HOSTNAME_API","mockMetadata","mockSchema","mockRootFolder","scope","templateScope","templateKey","metadataScopeAndKey","metadataFieldNamePrefix","metadataQuery","from","ancestor_folder_id","order_by","field_key","fields","key","direction","map","field","fieldsToShow","canEdit","displayName","columns","textValue","id","type","allowsSorting","minWidth","maxWidth","defaultView","metadataView","args","metadataViewV2ElementProps","metadataViewProps","features","contentExplorer","metadataViewV2","metadataViewV2WithInlineCustomActionsElementProps","_objectSpread","tableProps","isSelectAllEnabled","itemActionMenuProps","actions","label","onClick","icon","subMenuTrigger","subMenuActions","metadataViewV2WithBulkItemActions","bulkItemActions","metadataViewV2SortsFromHeader","play","canvas","getByRole","name","toBeInTheDocument","firstRow","industryHeader","click","metadataViewV2WithCustomActions","ellipsesButton","initialFilterActionBarProps","initialFilterValues","value","metadataViewV2WithInitialFilterValues","actionBarProps","toHaveTextContent","contactRoleChip","fileTypeChip","sidePanelOpenWithSingleItemSelected","checkbox","metadataButton","metadataViewV2WithBulkItemActionMenuShowsItemActionMenu","findByRole","ellipsisButton","downloadAction","meta","title","component","global","FEATURE_FLAGS","rootFolderId","FOLDER_ID","token","TOKEN","parameters","msw","handlers","post","json","get"],"sources":["../../../../../src/elements/content-explorer/stories/tests/MetadataView-visual.stories.tsx"],"sourcesContent":["import type { Meta, StoryObj } from '@storybook/react';\nimport { http, HttpResponse } from 'msw';\nimport { Download, SignMeOthers } from '@box/blueprint-web-assets/icons/Fill/index';\nimport { Sign } from '@box/blueprint-web-assets/icons/Line';\nimport { expect, fn, userEvent, waitFor, within, screen } from 'storybook/test';\nimport noop from 'lodash/noop';\n\nimport ContentExplorer from '../../ContentExplorer';\nimport { DEFAULT_HOSTNAME_API } from '../../../../constants';\nimport { mockMetadata, mockSchema } from '../../../common/__mocks__/mockMetadata';\nimport { mockRootFolder } from '../../../common/__mocks__/mockRootFolder';\n\n// 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.\nconst { scope: templateScope, templateKey } = mockSchema;\n\nconst metadataScopeAndKey = `${templateScope}.${templateKey}`;\nconst metadataFieldNamePrefix = `metadata.${metadataScopeAndKey}`;\n\n// This is the body of the metadata query API call.\n// https://developer.box.com/guides/metadata/queries/syntax/\nconst metadataQuery = {\n from: metadataScopeAndKey,\n ancestor_folder_id: '0',\n order_by: [\n {\n field_key: `${metadataFieldNamePrefix}.${mockSchema.fields[0].key}`, // Default to sorting by the first field in the schema\n direction: 'asc',\n },\n ],\n fields: [\n // Default to returning all fields in the metadata template schema, and name as a standalone (non-metadata) field\n ...mockSchema.fields.map(field => `${metadataFieldNamePrefix}.${field.key}`),\n 'name',\n ],\n};\n\n// Used for metadata view v1\nconst fieldsToShow = [\n { key: `${metadataFieldNamePrefix}.name`, canEdit: false, displayName: 'Alias' },\n { key: `${metadataFieldNamePrefix}.industry`, canEdit: true },\n { key: `${metadataFieldNamePrefix}.last_contacted_at`, canEdit: true },\n { key: `${metadataFieldNamePrefix}.role`, canEdit: true },\n];\n\n// Used for metadata view v2\nconst columns = [\n {\n // Always include the name column\n textValue: 'Name',\n id: 'name',\n type: 'string',\n allowsSorting: true,\n minWidth: 150,\n maxWidth: 150,\n },\n ...mockSchema.fields.map(field => ({\n textValue: field.displayName,\n id: `${metadataFieldNamePrefix}.${field.key}`,\n type: field.type,\n allowsSorting: true,\n minWidth: 150,\n maxWidth: 150,\n })),\n];\n\n// Switches ContentExplorer to use Metadata View over standard, folder-based view.\nconst defaultView = 'metadata';\n\nexport const metadataView: Story = {\n args: {\n metadataQuery,\n fieldsToShow,\n defaultView,\n },\n};\n\nconst metadataViewV2ElementProps = {\n metadataViewProps: {\n columns,\n },\n metadataQuery,\n fieldsToShow,\n defaultView,\n features: {\n contentExplorer: {\n metadataViewV2: true,\n },\n },\n};\n\nconst metadataViewV2WithInlineCustomActionsElementProps = {\n ...metadataViewV2ElementProps,\n metadataViewProps: {\n columns,\n tableProps: {\n isSelectAllEnabled: true,\n },\n itemActionMenuProps: {\n actions: [\n {\n label: 'Download',\n onClick: noop,\n icon: Download,\n },\n ],\n subMenuTrigger: {\n label: 'Sign',\n icon: Sign,\n },\n subMenuActions: [\n {\n label: 'Request Signature',\n onClick: noop,\n icon: SignMeOthers,\n },\n ],\n },\n },\n};\n\nconst metadataViewV2WithBulkItemActions = {\n ...metadataViewV2ElementProps,\n bulkItemActions: [\n {\n label: 'Download',\n onClick: fn(),\n },\n ],\n metadataViewProps: {\n columns,\n tableProps: {\n isSelectAllEnabled: true,\n },\n },\n};\n\nexport const metadataViewV2: Story = {\n args: metadataViewV2ElementProps,\n};\n\n// @TODO Assert that rows are actually sorted in a different order, once handleSortChange is implemented\nexport const metadataViewV2SortsFromHeader: Story = {\n args: metadataViewV2ElementProps,\n play: async ({ canvas }) => {\n await waitFor(() => {\n expect(canvas.getByRole('row', { name: /Industry/i })).toBeInTheDocument();\n });\n\n const firstRow = canvas.getByRole('row', { name: /Industry/i });\n const industryHeader = within(firstRow).getByRole('columnheader', { name: 'Industry' });\n userEvent.click(industryHeader);\n },\n};\n\nexport const metadataViewV2WithCustomActions: Story = {\n args: metadataViewV2WithInlineCustomActionsElementProps,\n play: async ({ canvas }) => {\n await waitFor(() => {\n expect(canvas.getByRole('row', { name: /Child 2/i })).toBeInTheDocument();\n });\n const firstRow = canvas.getByRole('row', { name: /Child 2/i });\n const ellipsesButton = within(firstRow).getByRole('button', { name: 'Action menu' });\n userEvent.click(ellipsesButton);\n },\n};\n\nconst initialFilterActionBarProps = {\n initialFilterValues: {\n 'industry-filter': { value: ['Legal'] },\n 'mimetype-filter': { value: ['boxnoteType', 'documentType', 'threedType'] },\n 'role-filter': { value: ['Developer', 'Business Owner', 'Marketing'] },\n },\n};\n\nexport const metadataViewV2WithInitialFilterValues: Story = {\n args: {\n ...metadataViewV2ElementProps,\n metadataViewProps: {\n columns,\n actionBarProps: initialFilterActionBarProps,\n },\n },\n play: async ({ canvas }) => {\n // Wait for chips to update with initial values\n await waitFor(() => {\n expect(canvas.getByRole('button', { name: /Industry/i })).toHaveTextContent(/\\(1\\)/);\n });\n // Other chips should reflect initialized values\n const contactRoleChip = canvas.getByRole('button', { name: /Contact Role/i });\n expect(contactRoleChip).toHaveTextContent(/\\(3\\)/);\n\n const fileTypeChip = canvas.getByRole('button', { name: /Box Note/i });\n expect(fileTypeChip).toHaveTextContent(/\\+2/);\n },\n};\n\nexport const sidePanelOpenWithSingleItemSelected: Story = {\n args: {\n ...metadataViewV2ElementProps,\n metadataViewProps: {\n columns,\n tableProps: {\n isSelectAllEnabled: true,\n },\n },\n },\n play: async ({ canvas }) => {\n await waitFor(() => {\n expect(canvas.getByRole('row', { name: /Child 2/i })).toBeInTheDocument();\n });\n\n // Select the first row by clicking its checkbox\n const firstRow = canvas.getByRole('row', { name: /Child 2/i });\n const checkbox = within(firstRow).getByRole('checkbox');\n await userEvent.click(checkbox);\n\n const metadataButton = canvas.getByRole('button', { name: 'Metadata' });\n await userEvent.click(metadataButton);\n },\n};\n\nexport const metadataViewV2WithBulkItemActionMenuShowsItemActionMenu: Story = {\n args: metadataViewV2WithBulkItemActions,\n play: async ({ canvas }) => {\n const firstRow = await canvas.findByRole('row', { name: /Child 2/i });\n expect(firstRow).toBeInTheDocument();\n\n const checkbox = within(firstRow).getByRole('checkbox');\n await userEvent.click(checkbox);\n\n const ellipsisButton = canvas.getByRole('button', { name: 'Bulk actions' });\n expect(ellipsisButton).toBeInTheDocument();\n await userEvent.click(ellipsisButton);\n\n const downloadAction = screen.getByRole('menuitem', { name: 'Download' });\n expect(downloadAction).toBeInTheDocument();\n },\n};\n\nconst meta: Meta<typeof ContentExplorer> = {\n title: 'Elements/ContentExplorer/tests/MetadataView/visual',\n component: ContentExplorer,\n args: {\n features: global.FEATURE_FLAGS,\n rootFolderId: global.FOLDER_ID,\n token: global.TOKEN,\n },\n parameters: {\n msw: {\n handlers: [\n http.post(`${DEFAULT_HOSTNAME_API}/2.0/metadata_queries/execute_read`, () => {\n return HttpResponse.json(mockMetadata);\n }),\n http.get(`${DEFAULT_HOSTNAME_API}/2.0/metadata_templates/enterprise/templateName/schema`, () => {\n return HttpResponse.json(mockSchema);\n }),\n http.get(`${DEFAULT_HOSTNAME_API}/2.0/folders/:id`, () => {\n return HttpResponse.json(mockRootFolder);\n }),\n ],\n },\n },\n};\n\ntype Story = StoryObj<typeof meta>;\n\nexport default meta;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MetadataView-visual.stories.js","names":["http","HttpResponse","Download","SignMeOthers","Sign","expect","fn","userEvent","waitFor","within","screen","noop","orderBy","ContentExplorer","DEFAULT_HOSTNAME_API","mockMetadata","mockSchema","mockRootFolder","scope","templateScope","templateKey","metadataScopeAndKey","metadataFieldNamePrefix","metadataQuery","from","ancestor_folder_id","order_by","field_key","fields","key","direction","map","field","fieldsToShow","canEdit","displayName","columns","textValue","id","type","allowsSorting","minWidth","maxWidth","defaultView","metadataView","args","metadataViewV2ElementProps","metadataViewProps","features","contentExplorer","metadataViewV2","metadataViewV2WithInlineCustomActionsElementProps","_objectSpread","tableProps","isSelectAllEnabled","itemActionMenuProps","actions","label","onClick","icon","subMenuTrigger","subMenuActions","metadataViewV2WithBulkItemActions","bulkItemActions","metadataViewV2SortsFromHeader","play","canvas","industryHeader","findByRole","name","toBeInTheDocument","firstRow","click","metadataViewV2WithCustomActions","getByRole","ellipsesButton","initialFilterActionBarProps","initialFilterValues","value","metadataViewV2WithInitialFilterValues","actionBarProps","toHaveTextContent","contactRoleChip","fileTypeChip","sidePanelOpenWithSingleItemSelected","checkbox","metadataButton","metadataViewV2WithBulkItemActionMenuShowsItemActionMenu","ellipsisButton","downloadAction","sidePanelOpenWithMultipleItemsSelected","firstItem","secondItem","getAllByRole","secondCheckbox","meta","title","component","global","FEATURE_FLAGS","rootFolderId","FOLDER_ID","token","TOKEN","parameters","msw","handlers","post","request","body","clone","json","orderByDirection","orderByFieldKey","sortedMetadata","entries","get"],"sources":["../../../../../src/elements/content-explorer/stories/tests/MetadataView-visual.stories.tsx"],"sourcesContent":["import type { Meta, StoryObj } from '@storybook/react';\nimport { http, HttpResponse } from 'msw';\nimport { Download, SignMeOthers } from '@box/blueprint-web-assets/icons/Fill/index';\nimport { Sign } from '@box/blueprint-web-assets/icons/Line';\nimport { expect, fn, userEvent, waitFor, within, screen } from 'storybook/test';\n\nimport noop from 'lodash/noop';\nimport orderBy from 'lodash/orderBy';\n\nimport ContentExplorer from '../../ContentExplorer';\nimport { DEFAULT_HOSTNAME_API } from '../../../../constants';\nimport { mockMetadata, mockSchema } from '../../../common/__mocks__/mockMetadata';\nimport { mockRootFolder } from '../../../common/__mocks__/mockRootFolder';\n\n// 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.\nconst { scope: templateScope, templateKey } = mockSchema;\n\nconst metadataScopeAndKey = `${templateScope}.${templateKey}`;\nconst metadataFieldNamePrefix = `metadata.${metadataScopeAndKey}`;\n\n// This is the body of the metadata query API call.\n// https://developer.box.com/guides/metadata/queries/syntax/\nconst metadataQuery = {\n from: metadataScopeAndKey,\n ancestor_folder_id: '0',\n order_by: [\n {\n field_key: `${metadataFieldNamePrefix}.${mockSchema.fields[0].key}`, // Default to sorting by the first field in the schema\n direction: 'asc',\n },\n ],\n fields: [\n // Default to returning all fields in the metadata template schema, and name as a standalone (non-metadata) field\n ...mockSchema.fields.map(field => `${metadataFieldNamePrefix}.${field.key}`),\n 'name',\n ],\n};\n\n// Used for metadata view v1\nconst fieldsToShow = [\n { key: `${metadataFieldNamePrefix}.name`, canEdit: false, displayName: 'Alias' },\n { key: `${metadataFieldNamePrefix}.industry`, canEdit: true },\n { key: `${metadataFieldNamePrefix}.last_contacted_at`, canEdit: true },\n { key: `${metadataFieldNamePrefix}.role`, canEdit: true },\n];\n\n// Used for metadata view v2\nconst columns = [\n {\n // Always include the name column\n textValue: 'Name',\n id: 'name',\n type: 'string',\n allowsSorting: true,\n minWidth: 150,\n maxWidth: 150,\n },\n ...mockSchema.fields.map(field => ({\n textValue: field.displayName,\n id: `${metadataFieldNamePrefix}.${field.key}`,\n type: field.type,\n allowsSorting: true,\n minWidth: 150,\n maxWidth: 150,\n })),\n];\n\n// Switches ContentExplorer to use Metadata View over standard, folder-based view.\nconst defaultView = 'metadata';\n\nexport const metadataView: Story = {\n args: {\n metadataQuery,\n fieldsToShow,\n defaultView,\n },\n};\n\nconst metadataViewV2ElementProps = {\n metadataViewProps: {\n columns,\n },\n metadataQuery,\n fieldsToShow,\n defaultView,\n features: {\n contentExplorer: {\n metadataViewV2: true,\n },\n },\n};\n\nconst metadataViewV2WithInlineCustomActionsElementProps = {\n ...metadataViewV2ElementProps,\n metadataViewProps: {\n columns,\n tableProps: {\n isSelectAllEnabled: true,\n },\n itemActionMenuProps: {\n actions: [\n {\n label: 'Download',\n onClick: noop,\n icon: Download,\n },\n ],\n subMenuTrigger: {\n label: 'Sign',\n icon: Sign,\n },\n subMenuActions: [\n {\n label: 'Request Signature',\n onClick: noop,\n icon: SignMeOthers,\n },\n ],\n },\n },\n};\n\nconst metadataViewV2WithBulkItemActions = {\n ...metadataViewV2ElementProps,\n bulkItemActions: [\n {\n label: 'Download',\n onClick: fn(),\n },\n ],\n metadataViewProps: {\n columns,\n tableProps: {\n isSelectAllEnabled: true,\n },\n },\n};\n\nexport const metadataViewV2: Story = {\n args: metadataViewV2ElementProps,\n};\n\nexport const metadataViewV2SortsFromHeader: Story = {\n args: metadataViewV2ElementProps,\n play: async ({ canvas }) => {\n const industryHeader = await canvas.findByRole('columnheader', { name: 'Industry' });\n expect(industryHeader).toBeInTheDocument();\n\n const firstRow = await canvas.findByRole('row', { name: /Child 2/i });\n expect(firstRow).toBeInTheDocument();\n\n await userEvent.click(industryHeader);\n },\n};\n\nexport const metadataViewV2WithCustomActions: Story = {\n args: metadataViewV2WithInlineCustomActionsElementProps,\n play: async ({ canvas }) => {\n await waitFor(() => {\n expect(canvas.getByRole('row', { name: /Child 2/i })).toBeInTheDocument();\n });\n const firstRow = canvas.getByRole('row', { name: /Child 2/i });\n const ellipsesButton = within(firstRow).getByRole('button', { name: 'Action menu' });\n userEvent.click(ellipsesButton);\n },\n};\n\nconst initialFilterActionBarProps = {\n initialFilterValues: {\n 'industry-filter': { value: ['Legal'] },\n 'mimetype-filter': { value: ['boxnoteType', 'documentType', 'threedType'] },\n 'role-filter': { value: ['Developer', 'Business Owner', 'Marketing'] },\n },\n};\n\nexport const metadataViewV2WithInitialFilterValues: Story = {\n args: {\n ...metadataViewV2ElementProps,\n metadataViewProps: {\n columns,\n actionBarProps: initialFilterActionBarProps,\n },\n },\n play: async ({ canvas }) => {\n // Wait for chips to update with initial values\n await waitFor(() => {\n expect(canvas.getByRole('button', { name: /Industry/i })).toHaveTextContent(/\\(1\\)/);\n });\n // Other chips should reflect initialized values\n const contactRoleChip = canvas.getByRole('button', { name: /Contact Role/i });\n expect(contactRoleChip).toHaveTextContent(/\\(3\\)/);\n\n const fileTypeChip = canvas.getByRole('button', { name: /Box Note/i });\n expect(fileTypeChip).toHaveTextContent(/\\+2/);\n },\n};\n\nexport const sidePanelOpenWithSingleItemSelected: Story = {\n args: {\n ...metadataViewV2ElementProps,\n metadataViewProps: {\n columns,\n tableProps: {\n isSelectAllEnabled: true,\n },\n },\n },\n play: async ({ canvas }) => {\n await waitFor(() => {\n expect(canvas.getByRole('row', { name: /Child 2/i })).toBeInTheDocument();\n });\n\n // Select the first row by clicking its checkbox\n const firstRow = canvas.getByRole('row', { name: /Child 2/i });\n const checkbox = within(firstRow).getByRole('checkbox');\n await userEvent.click(checkbox);\n\n const metadataButton = canvas.getByRole('button', { name: 'Metadata' });\n await userEvent.click(metadataButton);\n },\n};\n\nexport const metadataViewV2WithBulkItemActionMenuShowsItemActionMenu: Story = {\n args: metadataViewV2WithBulkItemActions,\n play: async ({ canvas }) => {\n const firstRow = await canvas.findByRole('row', { name: /Child 2/i });\n expect(firstRow).toBeInTheDocument();\n\n const checkbox = within(firstRow).getByRole('checkbox');\n await userEvent.click(checkbox);\n\n const ellipsisButton = canvas.getByRole('button', { name: 'Bulk actions' });\n expect(ellipsisButton).toBeInTheDocument();\n await userEvent.click(ellipsisButton);\n\n const downloadAction = screen.getByRole('menuitem', { name: 'Download' });\n expect(downloadAction).toBeInTheDocument();\n },\n};\n\nexport const sidePanelOpenWithMultipleItemsSelected: Story = {\n args: {\n ...metadataViewV2ElementProps,\n metadataViewProps: {\n columns,\n tableProps: {\n isSelectAllEnabled: true,\n },\n },\n },\n\n play: async ({ canvas }) => {\n await waitFor(() => {\n expect(canvas.getByRole('row', { name: /Child 2/i })).toBeInTheDocument();\n });\n\n // Select the first row by clicking its checkbox\n const firstItem = canvas.getByRole('row', { name: /Child 2/i });\n const checkbox = within(firstItem).getByRole('checkbox');\n await userEvent.click(checkbox);\n\n // Select the second row by clicking its checkbox\n const secondItem = canvas.getAllByRole('row', { name: /Child 1/i })[0];\n const secondCheckbox = within(secondItem).getByRole('checkbox');\n await userEvent.click(secondCheckbox);\n\n const metadataButton = canvas.getByRole('button', { name: 'Metadata' });\n await userEvent.click(metadataButton);\n },\n};\n\nconst meta: Meta<typeof ContentExplorer> = {\n title: 'Elements/ContentExplorer/tests/MetadataView/visual',\n component: ContentExplorer,\n args: {\n features: global.FEATURE_FLAGS,\n rootFolderId: global.FOLDER_ID,\n token: global.TOKEN,\n },\n parameters: {\n msw: {\n handlers: [\n // Note that the Metadata API backend normally handles the sorting. The mocks below simulate the sorting for specific cases, but may not 100% accurately reflect the backend behavior.\n http.post(`${DEFAULT_HOSTNAME_API}/2.0/metadata_queries/execute_read`, async ({ request }) => {\n const body = await request.clone().json();\n const orderByDirection = body.order_by[0].direction;\n const orderByFieldKey = body.order_by[0].field_key;\n\n // Hardcoded case for sorting by industry\n if (orderByFieldKey === `industry` && orderByDirection === 'ASC') {\n const sortedMetadata = orderBy(\n mockMetadata.entries,\n 'metadata.enterprise_0.templateName.industry',\n 'asc',\n );\n return HttpResponse.json({ ...mockMetadata, entries: sortedMetadata });\n }\n return HttpResponse.json(mockMetadata);\n }),\n http.get(`${DEFAULT_HOSTNAME_API}/2.0/metadata_templates/enterprise/templateName/schema`, () => {\n return HttpResponse.json(mockSchema);\n }),\n http.get(`${DEFAULT_HOSTNAME_API}/2.0/folders/:id`, () => {\n return HttpResponse.json(mockRootFolder);\n }),\n ],\n },\n },\n};\n\ntype Story = StoryObj<typeof meta>;\n\nexport default meta;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
2
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
3
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
4
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
+
import React, { useMemo } from 'react';
|
|
2
7
|
import { useIntl } from 'react-intl';
|
|
8
|
+
import isNil from 'lodash/isNil';
|
|
9
|
+
import xor from 'lodash/xor';
|
|
10
|
+
import { MULTI_VALUE_DEFAULT_OPTION, MULTI_VALUE_DEFAULT_VALUE } from '@box/metadata-editor';
|
|
3
11
|
import messages from '../common/messages';
|
|
4
12
|
|
|
13
|
+
// Specific type for metadata field value in the item
|
|
14
|
+
// Note: Item doesn't have field value in metadata object if that field is not set, so the value will be undefined in this case
|
|
15
|
+
|
|
5
16
|
// Get selected item text
|
|
6
17
|
export function useSelectedItemText(currentCollection, selectedItemIds) {
|
|
7
18
|
const {
|
|
@@ -25,8 +36,78 @@ export function useSelectedItemText(currentCollection, selectedItemIds) {
|
|
|
25
36
|
}, [currentCollection.items, formatMessage, selectedItemIds]);
|
|
26
37
|
}
|
|
27
38
|
|
|
39
|
+
// Check if the field value is empty.
|
|
40
|
+
// Note: 0 doesn't represent empty here because of float type field
|
|
41
|
+
export function isEmptyValue(value) {
|
|
42
|
+
if (isNil(value)) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// date, string, enum
|
|
47
|
+
if (value === '') {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// multiSelect
|
|
52
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// float
|
|
57
|
+
if (Number.isNaN(value)) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Check if the field values are equal based on the field types
|
|
64
|
+
export function areFieldValuesEqual(value1, value2) {
|
|
65
|
+
if (isEmptyValue(value1) && isEmptyValue(value2)) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Handle multiSelect arrays comparison
|
|
70
|
+
if (Array.isArray(value1) && Array.isArray(value2)) {
|
|
71
|
+
return xor(value1, value2).length === 0;
|
|
72
|
+
}
|
|
73
|
+
return value1 === value2;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Return default form value by field type
|
|
77
|
+
function getDefaultValueByFieldType(fieldType) {
|
|
78
|
+
if (fieldType === 'date' || fieldType === 'enum' || fieldType === 'float' || fieldType === 'string') {
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
if (fieldType === 'multiSelect') {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Set the field value in Metadata Form based on the field type
|
|
88
|
+
function getFieldValue(fieldType, fieldValue) {
|
|
89
|
+
if (isNil(fieldValue)) {
|
|
90
|
+
return getDefaultValueByFieldType(fieldType);
|
|
91
|
+
}
|
|
92
|
+
return fieldValue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Check if the field value in Metadata Form is multi-values such as "Multiple values"
|
|
96
|
+
export function isMultiValuesField(fieldType, fieldValue) {
|
|
97
|
+
if (fieldType === 'multiSelect') {
|
|
98
|
+
return Array.isArray(fieldValue) && fieldValue.length === 1 && fieldValue[0] === MULTI_VALUE_DEFAULT_VALUE;
|
|
99
|
+
}
|
|
100
|
+
if (fieldType === 'enum') {
|
|
101
|
+
return fieldValue === MULTI_VALUE_DEFAULT_VALUE;
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
28
106
|
// Get template instance based on metadata template and selected items
|
|
29
|
-
export function
|
|
107
|
+
export function useTemplateInstance(metadataTemplate, selectedItems, isEditing) {
|
|
108
|
+
const {
|
|
109
|
+
formatMessage
|
|
110
|
+
} = useIntl();
|
|
30
111
|
const {
|
|
31
112
|
displayName,
|
|
32
113
|
fields,
|
|
@@ -43,16 +124,63 @@ export function getTemplateInstance(metadataTemplate, selectedItems) {
|
|
|
43
124
|
key,
|
|
44
125
|
options,
|
|
45
126
|
type: fieldType
|
|
46
|
-
}) =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
127
|
+
}) => {
|
|
128
|
+
const defaultItemField = {
|
|
129
|
+
displayName: fieldDisplayName,
|
|
130
|
+
hidden: fieldHidden,
|
|
131
|
+
id: fieldId,
|
|
132
|
+
key,
|
|
133
|
+
options,
|
|
134
|
+
type: fieldType,
|
|
135
|
+
value: getFieldValue(fieldType, undefined)
|
|
136
|
+
};
|
|
137
|
+
const firstSelectedItem = selectedItems[0];
|
|
138
|
+
const firstSelectedItemFieldValue = firstSelectedItem.metadata[scope][templateKey][key];
|
|
139
|
+
|
|
140
|
+
// Case 1: Single selected item
|
|
141
|
+
if (selectedItems.length <= 1) {
|
|
142
|
+
return _objectSpread(_objectSpread({}, defaultItemField), {}, {
|
|
143
|
+
value: firstSelectedItemFieldValue
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Case 2.1: Multiple selected items, but all have the same initial value
|
|
148
|
+
const allItemsHaveSameInitialValue = selectedItems.every(selectedItem => areFieldValuesEqual(selectedItem.metadata[scope][templateKey][key], firstSelectedItemFieldValue));
|
|
149
|
+
if (allItemsHaveSameInitialValue) {
|
|
150
|
+
return _objectSpread(_objectSpread({}, defaultItemField), {}, {
|
|
151
|
+
value: getFieldValue(fieldType, firstSelectedItemFieldValue)
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Case 2.2: Multiple selected items, but some have different initial values
|
|
156
|
+
// Case 2.2.1: Edit Mode
|
|
157
|
+
if (isEditing) {
|
|
158
|
+
let fieldValue = getFieldValue(fieldType, undefined);
|
|
159
|
+
// Add MultiValue Option if the field is multiSelect or enum
|
|
160
|
+
if (fieldType === 'multiSelect' || fieldType === 'enum') {
|
|
161
|
+
fieldValue = fieldType === 'enum' ? MULTI_VALUE_DEFAULT_VALUE : [MULTI_VALUE_DEFAULT_VALUE];
|
|
162
|
+
const multiValueOption = options?.find(option => option.key === MULTI_VALUE_DEFAULT_VALUE);
|
|
163
|
+
if (!multiValueOption) {
|
|
164
|
+
options?.push(MULTI_VALUE_DEFAULT_OPTION);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return _objectSpread(_objectSpread({}, defaultItemField), {}, {
|
|
168
|
+
value: fieldValue
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Case: 2.2.2 View Mode
|
|
174
|
+
*
|
|
175
|
+
* We want to show "Multiple values" label for multiple dates across files selection.
|
|
176
|
+
* We use fragment here to bypass check in shared feature.
|
|
177
|
+
* This feature tries to parse string as date if the string is passed as value.
|
|
178
|
+
*/
|
|
179
|
+
const multipleValuesText = formatMessage(messages.multipleValues);
|
|
180
|
+
return _objectSpread(_objectSpread({}, defaultItemField), {}, {
|
|
181
|
+
value: /*#__PURE__*/React.createElement(React.Fragment, null, multipleValuesText)
|
|
182
|
+
});
|
|
183
|
+
});
|
|
56
184
|
return {
|
|
57
185
|
canEdit: true,
|
|
58
186
|
displayName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":["useMemo","useIntl","messages","useSelectedItemText","currentCollection","selectedItemIds","formatMessage","selectedCount","items","length","size","selectedKey","id","values","next","value","selectedItem","find","item","name","numFilesSelected","numSelected","getTemplateInstance","metadataTemplate","selectedItems","displayName","fields","hidden","scope","templateKey","type","selectedItemsFields","map","fieldDisplayName","fieldHidden","fieldId","key","options","fieldType","metadata","canEdit"],"sources":["../../../src/elements/content-explorer/utils.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport type { MetadataTemplate } from '@box/metadata-editor';\nimport type { Selection } from 'react-aria-components';\nimport type { BoxItem, Collection } from '../../common/types/core';\n\nimport messages from '../common/messages';\n\n// Get selected item text\nexport function useSelectedItemText(currentCollection: Collection, selectedItemIds: Selection): string {\n const { formatMessage } = useIntl();\n\n return useMemo(() => {\n const selectedCount = selectedItemIds === 'all' ? currentCollection.items.length : selectedItemIds.size;\n if (selectedCount === 0) return '';\n\n // Case 1: Single selected item - show item name\n if (selectedCount === 1) {\n const selectedKey =\n selectedItemIds === 'all' ? currentCollection.items[0].id : selectedItemIds.values().next().value;\n const selectedItem = currentCollection.items.find(item => item.id === selectedKey);\n return selectedItem?.name ?? '';\n }\n\n // Case 2: Multiple selected items - show count\n return formatMessage(messages.numFilesSelected, { numSelected: selectedCount });\n }, [currentCollection.items, formatMessage, selectedItemIds]);\n}\n\n// Get template instance based on metadata template and selected items\nexport function getTemplateInstance(metadataTemplate: MetadataTemplate, selectedItems: BoxItem[]) {\n const { displayName, fields, hidden, id, scope, templateKey, type } = metadataTemplate;\n\n const selectedItemsFields = fields.map(\n ({ displayName: fieldDisplayName, hidden: fieldHidden, id: fieldId, key, options, type: fieldType }) => ({\n displayName: fieldDisplayName,\n hidden: fieldHidden,\n id: fieldId,\n key,\n options,\n type: fieldType,\n // TODO: Add support for multiple selected items\n value: selectedItems[0].metadata[scope][templateKey][key],\n }),\n );\n\n return {\n canEdit: true,\n displayName,\n hidden,\n id,\n fields: selectedItemsFields,\n scope,\n templateKey,\n type,\n };\n}\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,OAAO,QAAQ,YAAY;AAMpC,OAAOC,QAAQ,MAAM,oBAAoB;;AAEzC;AACA,OAAO,SAASC,mBAAmBA,CAACC,iBAA6B,EAAEC,eAA0B,EAAU;EACnG,MAAM;IAAEC;EAAc,CAAC,GAAGL,OAAO,CAAC,CAAC;EAEnC,OAAOD,OAAO,CAAC,MAAM;IACjB,MAAMO,aAAa,GAAGF,eAAe,KAAK,KAAK,GAAGD,iBAAiB,CAACI,KAAK,CAACC,MAAM,GAAGJ,eAAe,CAACK,IAAI;IACvG,IAAIH,aAAa,KAAK,CAAC,EAAE,OAAO,EAAE;;IAElC;IACA,IAAIA,aAAa,KAAK,CAAC,EAAE;MACrB,MAAMI,WAAW,GACbN,eAAe,KAAK,KAAK,GAAGD,iBAAiB,CAACI,KAAK,CAAC,CAAC,CAAC,CAACI,EAAE,GAAGP,eAAe,CAACQ,MAAM,CAAC,CAAC,CAACC,IAAI,CAAC,CAAC,CAACC,KAAK;MACrG,MAAMC,YAAY,GAAGZ,iBAAiB,CAACI,KAAK,CAACS,IAAI,CAACC,IAAI,IAAIA,IAAI,CAACN,EAAE,KAAKD,WAAW,CAAC;MAClF,OAAOK,YAAY,EAAEG,IAAI,IAAI,EAAE;IACnC;;IAEA;IACA,OAAOb,aAAa,CAACJ,QAAQ,CAACkB,gBAAgB,EAAE;MAAEC,WAAW,EAAEd;IAAc,CAAC,CAAC;EACnF,CAAC,EAAE,CAACH,iBAAiB,CAACI,KAAK,EAAEF,aAAa,EAAED,eAAe,CAAC,CAAC;AACjE;;AAEA;AACA,OAAO,SAASiB,mBAAmBA,CAACC,gBAAkC,EAAEC,aAAwB,EAAE;EAC9F,MAAM;IAAEC,WAAW;IAAEC,MAAM;IAAEC,MAAM;IAAEf,EAAE;IAAEgB,KAAK;IAAEC,WAAW;IAAEC;EAAK,CAAC,GAAGP,gBAAgB;EAEtF,MAAMQ,mBAAmB,GAAGL,MAAM,CAACM,GAAG,CAClC,CAAC;IAAEP,WAAW,EAAEQ,gBAAgB;IAAEN,MAAM,EAAEO,WAAW;IAAEtB,EAAE,EAAEuB,OAAO;IAAEC,GAAG;IAAEC,OAAO;IAAEP,IAAI,EAAEQ;EAAU,CAAC,MAAM;IACrGb,WAAW,EAAEQ,gBAAgB;IAC7BN,MAAM,EAAEO,WAAW;IACnBtB,EAAE,EAAEuB,OAAO;IACXC,GAAG;IACHC,OAAO;IACPP,IAAI,EAAEQ,SAAS;IACf;IACAvB,KAAK,EAAES,aAAa,CAAC,CAAC,CAAC,CAACe,QAAQ,CAACX,KAAK,CAAC,CAACC,WAAW,CAAC,CAACO,GAAG;EAC5D,CAAC,CACL,CAAC;EAED,OAAO;IACHI,OAAO,EAAE,IAAI;IACbf,WAAW;IACXE,MAAM;IACNf,EAAE;IACFc,MAAM,EAAEK,mBAAmB;IAC3BH,KAAK;IACLC,WAAW;IACXC;EACJ,CAAC;AACL","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"utils.js","names":["React","useMemo","useIntl","isNil","xor","MULTI_VALUE_DEFAULT_OPTION","MULTI_VALUE_DEFAULT_VALUE","messages","useSelectedItemText","currentCollection","selectedItemIds","formatMessage","selectedCount","items","length","size","selectedKey","id","values","next","value","selectedItem","find","item","name","numFilesSelected","numSelected","isEmptyValue","Array","isArray","Number","isNaN","areFieldValuesEqual","value1","value2","getDefaultValueByFieldType","fieldType","undefined","getFieldValue","fieldValue","isMultiValuesField","useTemplateInstance","metadataTemplate","selectedItems","isEditing","displayName","fields","hidden","scope","templateKey","type","selectedItemsFields","map","fieldDisplayName","fieldHidden","fieldId","key","options","defaultItemField","firstSelectedItem","firstSelectedItemFieldValue","metadata","_objectSpread","allItemsHaveSameInitialValue","every","multiValueOption","option","push","multipleValuesText","multipleValues","createElement","Fragment","canEdit"],"sources":["../../../src/elements/content-explorer/utils.ts"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { useIntl } from 'react-intl';\nimport isNil from 'lodash/isNil';\nimport xor from 'lodash/xor';\n\nimport {\n MULTI_VALUE_DEFAULT_OPTION,\n MULTI_VALUE_DEFAULT_VALUE,\n type MetadataTemplate,\n type MetadataFormFieldValue,\n} from '@box/metadata-editor';\nimport type { MetadataFieldType } from '@box/metadata-view';\nimport type { Selection } from 'react-aria-components';\nimport type { BoxItem, Collection } from '../../common/types/core';\n\nimport messages from '../common/messages';\n\n// Specific type for metadata field value in the item\n// Note: Item doesn't have field value in metadata object if that field is not set, so the value will be undefined in this case\ntype ItemMetadataFieldValue = string | number | Array<string> | null | undefined;\n\n// Get selected item text\nexport function useSelectedItemText(currentCollection: Collection, selectedItemIds: Selection): string {\n const { formatMessage } = useIntl();\n\n return useMemo(() => {\n const selectedCount = selectedItemIds === 'all' ? currentCollection.items.length : selectedItemIds.size;\n if (selectedCount === 0) return '';\n\n // Case 1: Single selected item - show item name\n if (selectedCount === 1) {\n const selectedKey =\n selectedItemIds === 'all' ? currentCollection.items[0].id : selectedItemIds.values().next().value;\n const selectedItem = currentCollection.items.find(item => item.id === selectedKey);\n return selectedItem?.name ?? '';\n }\n\n // Case 2: Multiple selected items - show count\n return formatMessage(messages.numFilesSelected, { numSelected: selectedCount });\n }, [currentCollection.items, formatMessage, selectedItemIds]);\n}\n\n// Check if the field value is empty.\n// Note: 0 doesn't represent empty here because of float type field\nexport function isEmptyValue(value: ItemMetadataFieldValue) {\n if (isNil(value)) {\n return true;\n }\n\n // date, string, enum\n if (value === '') {\n return true;\n }\n\n // multiSelect\n if (Array.isArray(value) && value.length === 0) {\n return true;\n }\n\n // float\n if (Number.isNaN(value)) {\n return true;\n }\n\n return false;\n}\n\n// Check if the field values are equal based on the field types\nexport function areFieldValuesEqual(value1: ItemMetadataFieldValue, value2: ItemMetadataFieldValue) {\n if (isEmptyValue(value1) && isEmptyValue(value2)) {\n return true;\n }\n\n // Handle multiSelect arrays comparison\n if (Array.isArray(value1) && Array.isArray(value2)) {\n return xor(value1, value2).length === 0;\n }\n\n return value1 === value2;\n}\n\n// Return default form value by field type\nfunction getDefaultValueByFieldType(fieldType: MetadataFieldType) {\n if (fieldType === 'date' || fieldType === 'enum' || fieldType === 'float' || fieldType === 'string') {\n return '';\n }\n if (fieldType === 'multiSelect') {\n return [];\n }\n return undefined;\n}\n\n// Set the field value in Metadata Form based on the field type\nfunction getFieldValue(fieldType: MetadataFieldType, fieldValue: ItemMetadataFieldValue) {\n if (isNil(fieldValue)) {\n return getDefaultValueByFieldType(fieldType);\n }\n return fieldValue;\n}\n\n// Check if the field value in Metadata Form is multi-values such as \"Multiple values\"\nexport function isMultiValuesField(fieldType: MetadataFieldType, fieldValue: MetadataFormFieldValue) {\n if (fieldType === 'multiSelect') {\n return Array.isArray(fieldValue) && fieldValue.length === 1 && fieldValue[0] === MULTI_VALUE_DEFAULT_VALUE;\n }\n if (fieldType === 'enum') {\n return fieldValue === MULTI_VALUE_DEFAULT_VALUE;\n }\n return false;\n}\n\n// Get template instance based on metadata template and selected items\nexport function useTemplateInstance(metadataTemplate: MetadataTemplate, selectedItems: BoxItem[], isEditing: boolean) {\n const { formatMessage } = useIntl();\n const { displayName, fields, hidden, id, scope, templateKey, type } = metadataTemplate;\n\n const selectedItemsFields = fields.map(\n ({ displayName: fieldDisplayName, hidden: fieldHidden, id: fieldId, key, options, type: fieldType }) => {\n const defaultItemField = {\n displayName: fieldDisplayName,\n hidden: fieldHidden,\n id: fieldId,\n key,\n options,\n type: fieldType,\n value: getFieldValue(fieldType as MetadataFieldType, undefined),\n };\n\n const firstSelectedItem = selectedItems[0];\n const firstSelectedItemFieldValue = firstSelectedItem.metadata[scope][templateKey][key];\n\n // Case 1: Single selected item\n if (selectedItems.length <= 1) {\n return {\n ...defaultItemField,\n value: firstSelectedItemFieldValue,\n };\n }\n\n // Case 2.1: Multiple selected items, but all have the same initial value\n const allItemsHaveSameInitialValue = selectedItems.every(selectedItem =>\n areFieldValuesEqual(selectedItem.metadata[scope][templateKey][key], firstSelectedItemFieldValue),\n );\n\n if (allItemsHaveSameInitialValue) {\n return {\n ...defaultItemField,\n value: getFieldValue(fieldType as MetadataFieldType, firstSelectedItemFieldValue),\n };\n }\n\n // Case 2.2: Multiple selected items, but some have different initial values\n // Case 2.2.1: Edit Mode\n if (isEditing) {\n let fieldValue = getFieldValue(fieldType as MetadataFieldType, undefined);\n // Add MultiValue Option if the field is multiSelect or enum\n if (fieldType === 'multiSelect' || fieldType === 'enum') {\n fieldValue = fieldType === 'enum' ? MULTI_VALUE_DEFAULT_VALUE : [MULTI_VALUE_DEFAULT_VALUE];\n const multiValueOption = options?.find(option => option.key === MULTI_VALUE_DEFAULT_VALUE);\n if (!multiValueOption) {\n options?.push(MULTI_VALUE_DEFAULT_OPTION);\n }\n }\n return {\n ...defaultItemField,\n value: fieldValue,\n };\n }\n\n /**\n * Case: 2.2.2 View Mode\n *\n * We want to show \"Multiple values\" label for multiple dates across files selection.\n * We use fragment here to bypass check in shared feature.\n * This feature tries to parse string as date if the string is passed as value.\n */\n const multipleValuesText = formatMessage(messages.multipleValues);\n return {\n ...defaultItemField,\n value: React.createElement(React.Fragment, null, multipleValuesText),\n };\n },\n );\n\n return {\n canEdit: true,\n displayName,\n hidden,\n id,\n fields: selectedItemsFields,\n scope,\n templateKey,\n type,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import 'regenerator-runtime/runtime';
|
|
3
3
|
import React, { Component } from 'react';
|
|
4
4
|
import { AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
5
|
-
import type { Selection } from 'react-aria-components';
|
|
5
|
+
import type { Key, Selection } from 'react-aria-components';
|
|
6
|
+
import type { MetadataTemplateField } from '@box/metadata-editor';
|
|
6
7
|
import API from '../../api';
|
|
7
8
|
import MetadataQueryAPIHelper from '../../features/metadata-based-view/MetadataQueryAPIHelper';
|
|
8
9
|
import LocalStore from '../../utils/LocalStore';
|
|
@@ -68,7 +69,7 @@ export interface ContentExplorerProps {
|
|
|
68
69
|
rootFolderId?: string;
|
|
69
70
|
sharedLink?: string;
|
|
70
71
|
sharedLinkPassword?: string;
|
|
71
|
-
sortBy?: SortBy;
|
|
72
|
+
sortBy?: SortBy | Key;
|
|
72
73
|
sortDirection?: SortDirection;
|
|
73
74
|
staticHost?: string;
|
|
74
75
|
staticPath?: string;
|
|
@@ -203,6 +204,13 @@ declare class ContentExplorer extends Component<ContentExplorerProps, State> {
|
|
|
203
204
|
* @return {void}
|
|
204
205
|
*/
|
|
205
206
|
showMetadataQueryResults(): void;
|
|
207
|
+
/**
|
|
208
|
+
* Update selected items' metadata instances based on original and new field values in the metadata instance form
|
|
209
|
+
*
|
|
210
|
+
* @private
|
|
211
|
+
* @return {void}
|
|
212
|
+
*/
|
|
213
|
+
updateMetadataV2: (items: BoxItem[], operations: JSONPatchOperations, templateOldFields: MetadataTemplateField[], templateNewFields: MetadataTemplateField[], successCallback: () => void, errorCallback: ErrorCallback) => Promise<void>;
|
|
206
214
|
/**
|
|
207
215
|
* Resets the collection so that the loading bar starts showing
|
|
208
216
|
*
|
|
@@ -333,7 +341,7 @@ declare class ContentExplorer extends Component<ContentExplorerProps, State> {
|
|
|
333
341
|
* @param {string} sortDirection - sort direction
|
|
334
342
|
* @return {void}
|
|
335
343
|
*/
|
|
336
|
-
sort: (sortBy: SortBy, sortDirection: SortDirection) => void;
|
|
344
|
+
sort: (sortBy: SortBy | Key, sortDirection: SortDirection) => void;
|
|
337
345
|
/**
|
|
338
346
|
* Sets state with currentCollection updated to have `items.selected` properties
|
|
339
347
|
* set according to the given selected param. Also updates the selected item in the
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { MetadataTemplateField } from '@box/metadata-editor';
|
|
1
2
|
import API from '../../api';
|
|
2
3
|
import type { MetadataQuery as MetadataQueryType, MetadataQueryResponseData } from '../../common/types/metadataQueries';
|
|
3
4
|
import type { MetadataTemplateSchemaResponse, MetadataTemplate, MetadataFieldValue } from '../../common/types/metadata';
|
|
4
5
|
import type { ElementsXhrError } from '../../common/types/api';
|
|
5
|
-
import type { Collection } from '../../common/types/core';
|
|
6
|
+
import type { Collection, BoxItem } from '../../common/types/core';
|
|
6
7
|
type SuccessCallback = (metadataQueryCollection: Collection, metadataTemplate: MetadataTemplate) => void;
|
|
7
8
|
type ErrorCallback = (e: ElementsXhrError) => void;
|
|
8
9
|
export default class MetadataQueryAPIHelper {
|
|
@@ -18,9 +19,18 @@ export default class MetadataQueryAPIHelper {
|
|
|
18
19
|
flattenMetadata: (metadata?: MetadataType) => MetadataType;
|
|
19
20
|
getDataWithTypes: (templateSchemaResponse?: MetadataTemplateSchemaResponse) => Collection;
|
|
20
21
|
getTemplateSchemaInfo: (data: MetadataQueryResponseData) => Promise<MetadataTemplateSchemaResponse | void>;
|
|
22
|
+
/**
|
|
23
|
+
* Generate operations for all fields update in the metadata sidepanel
|
|
24
|
+
*
|
|
25
|
+
* @private
|
|
26
|
+
* @return {JSONPatchOperations}
|
|
27
|
+
*/
|
|
28
|
+
generateOperations: (item: BoxItem, templateOldFields: MetadataTemplateField[], templateNewFields: MetadataTemplateField[]) => JSONPatchOperations;
|
|
21
29
|
queryMetadata: () => Promise<MetadataQueryResponseData>;
|
|
22
30
|
fetchMetadataQueryResults: (metadataQuery: MetadataQueryType, successCallback: SuccessCallback, errorCallback: ErrorCallback) => Promise<void>;
|
|
23
31
|
updateMetadata: (file: BoxItem, field: string, oldValue: MetadataFieldValue | null, newValue: MetadataFieldValue | null, successCallback: () => void, errorCallback: ErrorCallback) => Promise<void>;
|
|
32
|
+
updateMetadataWithOperations: (item: BoxItem, operations: JSONPatchOperations, successCallback: () => void, errorCallback: ErrorCallback) => Promise<void>;
|
|
33
|
+
bulkUpdateMetadata: (items: BoxItem[], templateOldFields: MetadataTemplateField[], templateNewFields: MetadataTemplateField[], successCallback: () => void, errorCallback: ErrorCallback) => Promise<void>;
|
|
24
34
|
/**
|
|
25
35
|
* Verify that the metadata query has required fields and update it if necessary
|
|
26
36
|
* For a file item, default fields included in the response are "type", "id", "etag"
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { JSONPatchOperations, type MetadataTemplateField } from '@box/metadata-editor';
|
|
2
3
|
import type { Selection } from 'react-aria-components';
|
|
3
|
-
import type { Collection } from '../../common/types/core';
|
|
4
|
+
import type { BoxItem, Collection } from '../../common/types/core';
|
|
4
5
|
import type { MetadataTemplate } from '../../common/types/metadata';
|
|
5
6
|
import './MetadataSidePanel.scss';
|
|
6
7
|
export interface MetadataSidePanelProps {
|
|
7
8
|
currentCollection: Collection;
|
|
8
|
-
onClose: () => void;
|
|
9
9
|
metadataTemplate: MetadataTemplate;
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
onUpdate: (items: BoxItem[], operations: JSONPatchOperations, templateOldFields: MetadataTemplateField[], templateNewFields: MetadataTemplateField[], successCallback: () => void, errorCallback: ErrorCallback) => Promise<void>;
|
|
12
|
+
refreshCollection: () => void;
|
|
10
13
|
selectedItemIds: Selection;
|
|
11
14
|
}
|
|
12
|
-
declare const MetadataSidePanel: ({ currentCollection, onClose,
|
|
15
|
+
declare const MetadataSidePanel: ({ currentCollection, metadataTemplate, onClose, onUpdate, refreshCollection, selectedItemIds, }: MetadataSidePanelProps) => React.JSX.Element;
|
|
13
16
|
export default MetadataSidePanel;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { EnumType, MetadataFormFieldValue } from '@box/metadata-filter';
|
|
3
3
|
import { type MetadataViewProps } from '@box/metadata-view';
|
|
4
|
+
import { type Key } from '@react-types/shared';
|
|
4
5
|
import type { Collection } from '../../common/types/core';
|
|
5
6
|
import type { MetadataTemplate } from '../../common/types/metadata';
|
|
6
7
|
type EnumToStringArray<T> = T extends EnumType ? string[] : T;
|
|
@@ -16,6 +17,7 @@ export interface MetadataViewContainerProps extends Omit<MetadataViewProps, 'ite
|
|
|
16
17
|
actionBarProps?: ActionBarProps;
|
|
17
18
|
currentCollection: Collection;
|
|
18
19
|
metadataTemplate: MetadataTemplate;
|
|
20
|
+
onSortChange?: (sortBy: Key, sortDirection: string) => void;
|
|
19
21
|
}
|
|
20
|
-
declare const MetadataViewContainer: ({ actionBarProps, columns, currentCollection, metadataTemplate, ...rest }: MetadataViewContainerProps) => React.JSX.Element;
|
|
22
|
+
declare const MetadataViewContainer: ({ actionBarProps, columns, currentCollection, metadataTemplate, onSortChange: onSortChangeInternal, ...rest }: MetadataViewContainerProps) => React.JSX.Element;
|
|
21
23
|
export default MetadataViewContainer;
|
|
@@ -7,6 +7,7 @@ export declare const metadataViewV2WithCustomActions: Story;
|
|
|
7
7
|
export declare const metadataViewV2WithInitialFilterValues: Story;
|
|
8
8
|
export declare const sidePanelOpenWithSingleItemSelected: Story;
|
|
9
9
|
export declare const metadataViewV2WithBulkItemActionMenuShowsItemActionMenu: Story;
|
|
10
|
+
export declare const sidePanelOpenWithMultipleItemsSelected: Story;
|
|
10
11
|
declare const meta: Meta<typeof ContentExplorer>;
|
|
11
12
|
type Story = StoryObj<typeof meta>;
|
|
12
13
|
export default meta;
|
|
@@ -1,22 +1,28 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type MetadataTemplate, type MetadataFormFieldValue } from '@box/metadata-editor';
|
|
2
|
+
import type { MetadataFieldType } from '@box/metadata-view';
|
|
2
3
|
import type { Selection } from 'react-aria-components';
|
|
3
4
|
import type { BoxItem, Collection } from '../../common/types/core';
|
|
5
|
+
type ItemMetadataFieldValue = string | number | Array<string> | null | undefined;
|
|
4
6
|
export declare function useSelectedItemText(currentCollection: Collection, selectedItemIds: Selection): string;
|
|
5
|
-
export declare function
|
|
7
|
+
export declare function isEmptyValue(value: ItemMetadataFieldValue): boolean;
|
|
8
|
+
export declare function areFieldValuesEqual(value1: ItemMetadataFieldValue, value2: ItemMetadataFieldValue): boolean;
|
|
9
|
+
export declare function isMultiValuesField(fieldType: MetadataFieldType, fieldValue: MetadataFormFieldValue): boolean;
|
|
10
|
+
export declare function useTemplateInstance(metadataTemplate: MetadataTemplate, selectedItems: BoxItem[], isEditing: boolean): {
|
|
6
11
|
canEdit: boolean;
|
|
7
12
|
displayName: string;
|
|
8
13
|
hidden: boolean;
|
|
9
14
|
id: string;
|
|
10
15
|
fields: {
|
|
16
|
+
value: any;
|
|
11
17
|
displayName: string;
|
|
12
18
|
hidden: boolean;
|
|
13
19
|
id: string;
|
|
14
20
|
key: string;
|
|
15
21
|
options: import("@box/metadata-editor").MetadataTemplateFieldOption[];
|
|
16
22
|
type: import("@box/metadata-editor").MetadataTemplateFieldType;
|
|
17
|
-
value: any;
|
|
18
23
|
}[];
|
|
19
24
|
scope: string;
|
|
20
25
|
templateKey: string;
|
|
21
26
|
type: string;
|
|
22
27
|
};
|
|
28
|
+
export {};
|
package/i18n/bn-IN.js
CHANGED
|
@@ -291,9 +291,12 @@ export default {
|
|
|
291
291
|
"be.messageCenter.previewError": "দুঃখিত, এই ইমেজটি দেখাতে আমরা সমস্যার সম্মুখীন হচ্ছি।",
|
|
292
292
|
"be.messageCenter.product": "পণ্য",
|
|
293
293
|
"be.messageCenter.title": "নতুন কী",
|
|
294
|
+
"be.metadataUpdateErrorNotification": "Unable to save changes. Please try again.",
|
|
295
|
+
"be.metadataUpdateSuccessNotification": " {numSelected, plural, =1 {1 document updated} other {# documents updated} } ",
|
|
294
296
|
"be.modifiedDate": "সংশোধিত {date}",
|
|
295
297
|
"be.modifiedDateBy": "{name}-এর দ্বারা {date}-এ সংশোধিত",
|
|
296
298
|
"be.moreOptions": "আরও বিকল্প",
|
|
299
|
+
"be.multipleValues": "Multiple Values",
|
|
297
300
|
"be.nameASC": "নাম: A → Z",
|
|
298
301
|
"be.nameDESC": "নাম: Z → A",
|
|
299
302
|
"be.nameDate": "{name}-এর দ্বারা {date}",
|
|
@@ -417,6 +420,7 @@ export default {
|
|
|
417
420
|
"be.skillUnknownError": "এই দক্ষতাটি চালনা করার সময় বা এর ডেটা প্রাপ্তির সময় কিছু ত্রুটি ঘটেছে।",
|
|
418
421
|
"be.sort": "বাছাই করুন",
|
|
419
422
|
"be.statusSkill": "স্থিতি",
|
|
423
|
+
"be.success": "Success",
|
|
420
424
|
"be.today": "আজ",
|
|
421
425
|
"be.topicsSkill": "টপিকগুলি",
|
|
422
426
|
"be.transcriptEdit": "সম্পাদনা করতে যে কোনও নির্বাচন ক্লিক করুন।",
|
package/i18n/bn-IN.properties
CHANGED
|
@@ -966,6 +966,10 @@ boxui.categorySelector.label.more = আরও
|
|
|
966
966
|
boxui.checkboxTooltip.iconInfoText = তথ্য
|
|
967
967
|
# Button to add classification on an item
|
|
968
968
|
boxui.classification.add = যোগ করুন
|
|
969
|
+
# Title of the card that shows the reason why the AI classification was applied when no date is available.
|
|
970
|
+
boxui.classification.appliedByBoxAi = Box AI
|
|
971
|
+
# Title of the card that shows the reason why the AI classification was applied on a specific date.
|
|
972
|
+
boxui.classification.appliedByBoxAiOnDate = Box AI on {modifiedAt}
|
|
969
973
|
# Header for classification section in sidebar
|
|
970
974
|
boxui.classification.classification = শ্রেণিবিভাজন
|
|
971
975
|
# Classification label color name as dark blue
|
package/i18n/da-DK.js
CHANGED
|
@@ -291,9 +291,12 @@ export default {
|
|
|
291
291
|
"be.messageCenter.previewError": "Vi har desværre problemer med at vise dette billede.",
|
|
292
292
|
"be.messageCenter.product": "Produkt",
|
|
293
293
|
"be.messageCenter.title": "Nyheder",
|
|
294
|
+
"be.metadataUpdateErrorNotification": "Unable to save changes. Please try again.",
|
|
295
|
+
"be.metadataUpdateSuccessNotification": " {numSelected, plural, =1 {1 document updated} other {# documents updated} } ",
|
|
294
296
|
"be.modifiedDate": "Ændret {date}",
|
|
295
297
|
"be.modifiedDateBy": "Ændret {date} af {name}",
|
|
296
298
|
"be.moreOptions": "Flere muligheder",
|
|
299
|
+
"be.multipleValues": "Multiple Values",
|
|
297
300
|
"be.nameASC": "Navn: A → Å",
|
|
298
301
|
"be.nameDESC": "Navn: Å → A",
|
|
299
302
|
"be.nameDate": "{date} af {name}",
|
|
@@ -417,6 +420,7 @@ export default {
|
|
|
417
420
|
"be.skillUnknownError": "Der opstod et problem under kørsel af denne færdighed eller i forbindelse med hentning af tilhørende data.",
|
|
418
421
|
"be.sort": "Sortér",
|
|
419
422
|
"be.statusSkill": "Status",
|
|
423
|
+
"be.success": "Success",
|
|
420
424
|
"be.today": "i dag",
|
|
421
425
|
"be.topicsSkill": "Emner",
|
|
422
426
|
"be.transcriptEdit": "Klik på et afsnit for at redigere.",
|
package/i18n/da-DK.properties
CHANGED
|
@@ -966,6 +966,10 @@ boxui.categorySelector.label.more = Mere
|
|
|
966
966
|
boxui.checkboxTooltip.iconInfoText = Oplysninger
|
|
967
967
|
# Button to add classification on an item
|
|
968
968
|
boxui.classification.add = Tilføj
|
|
969
|
+
# Title of the card that shows the reason why the AI classification was applied when no date is available.
|
|
970
|
+
boxui.classification.appliedByBoxAi = Box AI
|
|
971
|
+
# Title of the card that shows the reason why the AI classification was applied on a specific date.
|
|
972
|
+
boxui.classification.appliedByBoxAiOnDate = Box AI on {modifiedAt}
|
|
969
973
|
# Header for classification section in sidebar
|
|
970
974
|
boxui.classification.classification = Klassificering
|
|
971
975
|
# Classification label color name as dark blue
|
package/i18n/de-DE.js
CHANGED
|
@@ -291,9 +291,12 @@ export default {
|
|
|
291
291
|
"be.messageCenter.previewError": "Leider kann dieses Bild derzeit nicht angezeigt werden.",
|
|
292
292
|
"be.messageCenter.product": "Produkt",
|
|
293
293
|
"be.messageCenter.title": "Neuerungen",
|
|
294
|
+
"be.metadataUpdateErrorNotification": "Unable to save changes. Please try again.",
|
|
295
|
+
"be.metadataUpdateSuccessNotification": " {numSelected, plural, =1 {1 document updated} other {# documents updated} } ",
|
|
294
296
|
"be.modifiedDate": "Geändert am {date}",
|
|
295
297
|
"be.modifiedDateBy": "Geändert am {date} von {name}",
|
|
296
298
|
"be.moreOptions": "Weitere Optionen",
|
|
299
|
+
"be.multipleValues": "Multiple Values",
|
|
297
300
|
"be.nameASC": "Name: A → Z",
|
|
298
301
|
"be.nameDESC": "Name: Z → A",
|
|
299
302
|
"be.nameDate": "Am {date} von {name}",
|
|
@@ -417,6 +420,7 @@ export default {
|
|
|
417
420
|
"be.skillUnknownError": "Beim Ausführen dieses Skills oder Abrufen seiner Daten ist ein Fehler aufgetreten.",
|
|
418
421
|
"be.sort": "Sortieren",
|
|
419
422
|
"be.statusSkill": "Status",
|
|
423
|
+
"be.success": "Success",
|
|
420
424
|
"be.today": "heute",
|
|
421
425
|
"be.topicsSkill": "Themen",
|
|
422
426
|
"be.transcriptEdit": "Klicken Sie auf einen beliebigen Abschnitt, um ihn zu bearbeiten.",
|
|
@@ -483,7 +487,7 @@ export default {
|
|
|
483
487
|
"boxui.categorySelector.label.more": "Mehr",
|
|
484
488
|
"boxui.checkboxTooltip.iconInfoText": "Informationen",
|
|
485
489
|
"boxui.classification.add": "Hinzufügen",
|
|
486
|
-
"boxui.classification.appliedByBoxAi": "Box
|
|
490
|
+
"boxui.classification.appliedByBoxAi": "Box-KI",
|
|
487
491
|
"boxui.classification.appliedByBoxAiOnDate": "Box AI on {modifiedAt}",
|
|
488
492
|
"boxui.classification.classification": "Klassifizierung",
|
|
489
493
|
"boxui.classification.classificationDarkBlue": "Dunkelblau",
|
package/i18n/de-DE.properties
CHANGED
|
@@ -966,6 +966,10 @@ boxui.categorySelector.label.more = Mehr
|
|
|
966
966
|
boxui.checkboxTooltip.iconInfoText = Informationen
|
|
967
967
|
# Button to add classification on an item
|
|
968
968
|
boxui.classification.add = Hinzufügen
|
|
969
|
+
# Title of the card that shows the reason why the AI classification was applied when no date is available.
|
|
970
|
+
boxui.classification.appliedByBoxAi = Box-KI
|
|
971
|
+
# Title of the card that shows the reason why the AI classification was applied on a specific date.
|
|
972
|
+
boxui.classification.appliedByBoxAiOnDate = Box AI on {modifiedAt}
|
|
969
973
|
# Header for classification section in sidebar
|
|
970
974
|
boxui.classification.classification = Klassifizierung
|
|
971
975
|
# Classification label color name as dark blue
|
package/i18n/en-AU.js
CHANGED
|
@@ -291,9 +291,12 @@ export default {
|
|
|
291
291
|
"be.messageCenter.previewError": "Sorry, we're having trouble showing this image.",
|
|
292
292
|
"be.messageCenter.product": "Product",
|
|
293
293
|
"be.messageCenter.title": "What's New",
|
|
294
|
+
"be.metadataUpdateErrorNotification": "Unable to save changes. Please try again.",
|
|
295
|
+
"be.metadataUpdateSuccessNotification": " {numSelected, plural, =1 {1 document updated} other {# documents updated} } ",
|
|
294
296
|
"be.modifiedDate": "Modified {date}",
|
|
295
297
|
"be.modifiedDateBy": "Modified {date} by {name}",
|
|
296
298
|
"be.moreOptions": "More Options",
|
|
299
|
+
"be.multipleValues": "Multiple Values",
|
|
297
300
|
"be.nameASC": "Name: A → Z",
|
|
298
301
|
"be.nameDESC": "Name: Z → A",
|
|
299
302
|
"be.nameDate": "{date} by {name}",
|
|
@@ -417,6 +420,7 @@ export default {
|
|
|
417
420
|
"be.skillUnknownError": "Something went wrong while running this skill or fetching its data.",
|
|
418
421
|
"be.sort": "Sort",
|
|
419
422
|
"be.statusSkill": "Status",
|
|
423
|
+
"be.success": "Success",
|
|
420
424
|
"be.today": "today",
|
|
421
425
|
"be.topicsSkill": "Topics",
|
|
422
426
|
"be.transcriptEdit": "Click any section to edit.",
|
package/i18n/en-AU.properties
CHANGED
|
@@ -966,6 +966,10 @@ boxui.categorySelector.label.more = More
|
|
|
966
966
|
boxui.checkboxTooltip.iconInfoText = Info
|
|
967
967
|
# Button to add classification on an item
|
|
968
968
|
boxui.classification.add = Add
|
|
969
|
+
# Title of the card that shows the reason why the AI classification was applied when no date is available.
|
|
970
|
+
boxui.classification.appliedByBoxAi = Box AI
|
|
971
|
+
# Title of the card that shows the reason why the AI classification was applied on a specific date.
|
|
972
|
+
boxui.classification.appliedByBoxAiOnDate = Box AI on {modifiedAt}
|
|
969
973
|
# Header for classification section in sidebar
|
|
970
974
|
boxui.classification.classification = Classification
|
|
971
975
|
# Classification label color name as dark blue
|