box-ui-elements 24.0.0-beta.2 β 24.0.0-beta.4
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/DEVELOPING.md +1 -1
- 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/elements/common/content-answers/ContentAnswersModal.js +1 -0
- package/es/elements/common/content-answers/ContentAnswersModal.js.map +1 -1
- package/es/elements/common/withBlueprintModernization.js +16 -0
- package/es/elements/common/withBlueprintModernization.js.map +1 -0
- package/es/elements/content-explorer/ContentExplorer.js +2 -1
- package/es/elements/content-explorer/ContentExplorer.js.map +1 -1
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js +5 -0
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js.flow +6 -0
- package/es/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js.map +1 -1
- package/es/elements/content-picker/ContentPicker.js +4 -1
- package/es/elements/content-picker/ContentPicker.js.flow +4 -1
- package/es/elements/content-picker/ContentPicker.js.map +1 -1
- package/es/elements/content-picker/stories/tests/ContentPicker-visual.stories.js +5 -0
- package/es/elements/content-picker/stories/tests/ContentPicker-visual.stories.js.flow +6 -0
- package/es/elements/content-picker/stories/tests/ContentPicker-visual.stories.js.map +1 -1
- package/es/elements/content-preview/ContentPreview.js +3 -1
- package/es/elements/content-preview/ContentPreview.js.flow +3 -0
- package/es/elements/content-preview/ContentPreview.js.map +1 -1
- package/es/elements/content-preview/stories/tests/ContentPreview-visual.stories.js +5 -0
- package/es/elements/content-preview/stories/tests/ContentPreview-visual.stories.js.flow +7 -1
- package/es/elements/content-preview/stories/tests/ContentPreview-visual.stories.js.map +1 -1
- package/es/elements/content-sharing/ContentSharing.js +4 -1
- package/es/elements/content-sharing/ContentSharing.js.flow +4 -1
- package/es/elements/content-sharing/ContentSharing.js.map +1 -1
- package/es/elements/content-sidebar/ContentSidebar.js +3 -1
- package/es/elements/content-sidebar/ContentSidebar.js.flow +3 -0
- package/es/elements/content-sidebar/ContentSidebar.js.map +1 -1
- package/es/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.js +5 -0
- package/es/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.js.map +1 -1
- package/es/elements/content-uploader/ContentUploader.js +3 -1
- package/es/elements/content-uploader/ContentUploader.js.map +1 -1
- package/es/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js +5 -0
- package/es/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js.flow +6 -0
- package/es/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js.map +1 -1
- package/es/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.js +51 -0
- package/es/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.js.map +1 -0
- package/es/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.scss +29 -0
- package/es/features/classification/applied-by-ai-classification-reason/messages.js +13 -0
- package/es/features/classification/applied-by-ai-classification-reason/messages.js.map +1 -0
- package/es/features/classification/types.js +2 -0
- package/es/features/classification/types.js.map +1 -0
- package/es/src/elements/common/__tests__/withBlueprintModernization.test.d.ts +1 -0
- package/es/src/elements/common/withBlueprintModernization.d.ts +3 -0
- package/es/src/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.d.ts +5 -0
- package/es/src/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.d.ts +6 -0
- package/es/src/features/classification/applied-by-ai-classification-reason/__tests__/AppliedByAiClassificationReason.test.d.ts +1 -0
- package/es/src/features/classification/applied-by-ai-classification-reason/messages.d.ts +13 -0
- package/es/src/features/classification/types.d.ts +6 -0
- package/i18n/bn-IN.js +4 -2
- package/i18n/bn-IN.properties +2 -2
- package/i18n/da-DK.js +4 -2
- package/i18n/da-DK.properties +2 -2
- package/i18n/de-DE.js +4 -2
- package/i18n/de-DE.properties +2 -2
- package/i18n/en-AU.js +2 -0
- package/i18n/en-CA.js +2 -0
- package/i18n/en-GB.js +2 -0
- package/i18n/en-US.js +2 -0
- package/i18n/en-US.properties +4 -0
- package/i18n/en-x-pseudo.js +2 -0
- package/i18n/es-419.js +4 -2
- package/i18n/es-419.properties +2 -2
- package/i18n/es-ES.js +4 -2
- package/i18n/es-ES.properties +2 -2
- package/i18n/fi-FI.js +4 -2
- package/i18n/fi-FI.properties +2 -2
- package/i18n/fr-CA.js +4 -2
- package/i18n/fr-CA.properties +2 -2
- package/i18n/fr-FR.js +4 -2
- package/i18n/fr-FR.properties +2 -2
- package/i18n/hi-IN.js +4 -2
- package/i18n/hi-IN.properties +2 -2
- package/i18n/it-IT.js +4 -2
- package/i18n/it-IT.properties +2 -2
- package/i18n/ja-JP.js +2 -0
- package/i18n/ko-KR.js +4 -2
- package/i18n/ko-KR.properties +2 -2
- package/i18n/nb-NO.js +4 -2
- package/i18n/nb-NO.properties +2 -2
- package/i18n/nl-NL.js +4 -2
- package/i18n/nl-NL.properties +2 -2
- package/i18n/pl-PL.js +4 -2
- package/i18n/pl-PL.properties +2 -2
- package/i18n/pt-BR.js +4 -2
- package/i18n/pt-BR.properties +2 -2
- package/i18n/ru-RU.js +4 -2
- package/i18n/ru-RU.properties +2 -2
- package/i18n/sv-SE.js +4 -2
- package/i18n/sv-SE.properties +2 -2
- package/i18n/tr-TR.js +4 -2
- package/i18n/tr-TR.properties +2 -2
- package/i18n/zh-CN.js +4 -2
- package/i18n/zh-CN.properties +2 -2
- package/i18n/zh-TW.js +4 -2
- package/i18n/zh-TW.properties +2 -2
- package/package.json +1 -1
- package/src/elements/common/__tests__/withBlueprintModernization.test.tsx +91 -0
- package/src/elements/common/content-answers/ContentAnswersModal.tsx +1 -0
- package/src/elements/common/content-answers/__tests__/ContentAnswersModal.test.tsx +1 -2
- package/src/elements/common/withBlueprintModernization.tsx +24 -0
- package/src/elements/content-explorer/ContentExplorer.tsx +4 -1
- package/src/elements/content-explorer/stories/tests/ContentExplorer-visual.stories.js +6 -0
- package/src/elements/content-picker/ContentPicker.js +4 -1
- package/src/elements/content-picker/stories/tests/ContentPicker-visual.stories.js +6 -0
- package/src/elements/content-preview/ContentPreview.js +3 -0
- package/src/elements/content-preview/stories/tests/ContentPreview-visual.stories.js +7 -1
- package/src/elements/content-sharing/ContentSharing.js +4 -1
- package/src/elements/content-sidebar/ContentSidebar.js +3 -0
- package/src/elements/content-sidebar/stories/tests/ContentSidebar-visual.stories.tsx +6 -0
- package/src/elements/content-uploader/ContentUploader.tsx +3 -1
- package/src/elements/content-uploader/stories/tests/ContentUploader-visual.stories.js +6 -0
- package/src/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.scss +29 -0
- package/src/features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason.tsx +55 -0
- package/src/features/classification/applied-by-ai-classification-reason/__tests__/AppliedByAiClassificationReason.test.tsx +105 -0
- package/src/features/classification/applied-by-ai-classification-reason/messages.ts +18 -0
- package/src/features/classification/types.ts +7 -0
|
@@ -100,6 +100,7 @@ import '../common/fonts.scss';
|
|
|
100
100
|
import '../common/base.scss';
|
|
101
101
|
import '../common/modal.scss';
|
|
102
102
|
import './ContentExplorer.scss';
|
|
103
|
+
import { withBlueprintModernization } from '../common/withBlueprintModernization';
|
|
103
104
|
|
|
104
105
|
const GRID_VIEW_MAX_COLUMNS = 7;
|
|
105
106
|
const GRID_VIEW_MIN_COLUMNS = 1;
|
|
@@ -1974,4 +1975,6 @@ class ContentExplorer extends Component<ContentExplorerProps, State> {
|
|
|
1974
1975
|
}
|
|
1975
1976
|
|
|
1976
1977
|
export { ContentExplorer as ContentExplorerComponent };
|
|
1977
|
-
export default flow([makeResponsive, withFeatureConsumer, withFeatureProvider])(
|
|
1978
|
+
export default flow([makeResponsive, withFeatureConsumer, withFeatureProvider, withBlueprintModernization])(
|
|
1979
|
+
ContentExplorer,
|
|
1980
|
+
);
|
|
@@ -28,6 +28,12 @@ export const basic = {
|
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
export const Modernization = {
|
|
32
|
+
args: {
|
|
33
|
+
enableModernizedComponents: true,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
31
37
|
export const openExistingFolder = {
|
|
32
38
|
play: async ({ canvasElement }) => {
|
|
33
39
|
const canvas = within(canvasElement);
|
|
@@ -9,6 +9,7 @@ import React, { Component } from 'react';
|
|
|
9
9
|
import type { Node } from 'react';
|
|
10
10
|
import classNames from 'classnames';
|
|
11
11
|
import debounce from 'lodash/debounce';
|
|
12
|
+
import flow from 'lodash/flow';
|
|
12
13
|
import getProp from 'lodash/get';
|
|
13
14
|
import uniqueid from 'lodash/uniqueId';
|
|
14
15
|
import noop from 'lodash/noop';
|
|
@@ -18,6 +19,8 @@ import UploadDialog from '../common/upload-dialog';
|
|
|
18
19
|
import CreateFolderDialog from '../common/create-folder-dialog';
|
|
19
20
|
import Internationalize from '../common/Internationalize';
|
|
20
21
|
import makeResponsive from '../common/makeResponsive';
|
|
22
|
+
// $FlowFixMe
|
|
23
|
+
import { withBlueprintModernization } from '../common/withBlueprintModernization';
|
|
21
24
|
// $FlowFixMe TypeScript file
|
|
22
25
|
import ThemingStyles from '../common/theming';
|
|
23
26
|
import Pagination from '../../features/pagination';
|
|
@@ -1345,4 +1348,4 @@ class ContentPicker extends Component<Props, State> {
|
|
|
1345
1348
|
}
|
|
1346
1349
|
|
|
1347
1350
|
export { ContentPicker as ContentPickerComponent };
|
|
1348
|
-
export default makeResponsive(ContentPicker);
|
|
1351
|
+
export default flow([makeResponsive, withBlueprintModernization])(ContentPicker);
|
|
@@ -8,6 +8,12 @@ import { DEFAULT_HOSTNAME_API } from '../../../../constants';
|
|
|
8
8
|
|
|
9
9
|
export const basic = {};
|
|
10
10
|
|
|
11
|
+
export const Modernization = {
|
|
12
|
+
args: {
|
|
13
|
+
enableModernizedComponents: true,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
11
17
|
export const withPagination = {
|
|
12
18
|
args: {
|
|
13
19
|
initialPageSize: 1,
|
|
@@ -35,6 +35,8 @@ import { withLogger } from '../common/logger';
|
|
|
35
35
|
import { PREVIEW_FIELDS_TO_FETCH } from '../../utils/fields';
|
|
36
36
|
import { mark } from '../../utils/performance';
|
|
37
37
|
import { withFeatureConsumer, withFeatureProvider } from '../common/feature-checking';
|
|
38
|
+
// $FlowFixMe
|
|
39
|
+
import { withBlueprintModernization } from '../common/withBlueprintModernization';
|
|
38
40
|
import { EVENT_JS_READY } from '../common/logger/constants';
|
|
39
41
|
import ReloadNotification from './ReloadNotification';
|
|
40
42
|
import API from '../../api';
|
|
@@ -1418,6 +1420,7 @@ export default flow([
|
|
|
1418
1420
|
withNavRouter,
|
|
1419
1421
|
withFeatureConsumer,
|
|
1420
1422
|
withFeatureProvider,
|
|
1423
|
+
withBlueprintModernization,
|
|
1421
1424
|
withLogger(ORIGIN_CONTENT_PREVIEW),
|
|
1422
1425
|
withErrorBoundary(ORIGIN_CONTENT_PREVIEW),
|
|
1423
1426
|
])(ContentPreview);
|
|
@@ -30,6 +30,12 @@ export const basic = {
|
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
export const Modernization = {
|
|
34
|
+
args: {
|
|
35
|
+
enableModernizedComponents: true,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
33
39
|
export const closeModal = {
|
|
34
40
|
play: async ({ canvasElement }) => {
|
|
35
41
|
const canvas = within(canvasElement);
|
|
@@ -92,7 +98,7 @@ export const hoverOverCitation = {
|
|
|
92
98
|
|
|
93
99
|
expect(modal.getByText('Based on:')).toBeInTheDocument();
|
|
94
100
|
|
|
95
|
-
const citations = await modal.getAllByTestId('content-answers-citation-status')
|
|
101
|
+
const citations = await modal.getAllByTestId('content-answers-citation-status');
|
|
96
102
|
const citation = citations[0];
|
|
97
103
|
expect(citation).toBeInTheDocument();
|
|
98
104
|
await userEvent.hover(citation);
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import 'regenerator-runtime/runtime';
|
|
10
10
|
import * as React from 'react';
|
|
11
11
|
import API from '../../api';
|
|
12
|
+
// $FlowFixMe
|
|
13
|
+
import { withBlueprintModernization } from '../common/withBlueprintModernization';
|
|
12
14
|
import SharingModal from './SharingModal';
|
|
13
15
|
import { CLIENT_NAME_CONTENT_SHARING, DEFAULT_HOSTNAME_API } from '../../constants';
|
|
14
16
|
import type { ItemType, StringMap } from '../../common/types/core';
|
|
@@ -118,4 +120,5 @@ function ContentSharing({
|
|
|
118
120
|
);
|
|
119
121
|
}
|
|
120
122
|
|
|
121
|
-
export
|
|
123
|
+
export { ContentSharing as ContentSharingComponent };
|
|
124
|
+
export default withBlueprintModernization(ContentSharing);
|
|
@@ -21,6 +21,8 @@ import { EVENT_JS_READY } from '../common/logger/constants';
|
|
|
21
21
|
import { mark } from '../../utils/performance';
|
|
22
22
|
import { SIDEBAR_FIELDS_TO_FETCH, SIDEBAR_FIELDS_TO_FETCH_ARCHIVE } from '../../utils/fields';
|
|
23
23
|
import { withErrorBoundary } from '../common/error-boundary';
|
|
24
|
+
// $FlowFixMe
|
|
25
|
+
import { withBlueprintModernization } from '../common/withBlueprintModernization';
|
|
24
26
|
import {
|
|
25
27
|
isFeatureEnabled as isFeatureEnabledInContext,
|
|
26
28
|
withFeatureConsumer,
|
|
@@ -432,6 +434,7 @@ export { ContentSidebar as ContentSidebarComponent };
|
|
|
432
434
|
export default flow([
|
|
433
435
|
withFeatureConsumer,
|
|
434
436
|
withFeatureProvider,
|
|
437
|
+
withBlueprintModernization,
|
|
435
438
|
withLogger(ORIGIN_CONTENT_SIDEBAR),
|
|
436
439
|
withErrorBoundary(ORIGIN_CONTENT_SIDEBAR),
|
|
437
440
|
])(ContentSidebar);
|
|
@@ -2,6 +2,7 @@ import 'regenerator-runtime/runtime';
|
|
|
2
2
|
import React, { Component } from 'react';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import cloneDeep from 'lodash/cloneDeep';
|
|
5
|
+
import flow from 'lodash/flow';
|
|
5
6
|
import getProp from 'lodash/get';
|
|
6
7
|
import noop from 'lodash/noop';
|
|
7
8
|
import uniqueid from 'lodash/uniqueId';
|
|
@@ -14,6 +15,7 @@ import API from '../../api';
|
|
|
14
15
|
import Browser from '../../utils/Browser';
|
|
15
16
|
import Internationalize from '../common/Internationalize';
|
|
16
17
|
import makeResponsive from '../common/makeResponsive';
|
|
18
|
+
import { withBlueprintModernization } from '../common/withBlueprintModernization';
|
|
17
19
|
import ThemingStyles, { Theme } from '../common/theming';
|
|
18
20
|
import FolderUpload from '../../api/uploads/FolderUpload';
|
|
19
21
|
import { getTypedFileId, getTypedFolderId } from '../../utils/file';
|
|
@@ -1323,5 +1325,5 @@ class ContentUploader extends Component<ContentUploaderProps, State> {
|
|
|
1323
1325
|
}
|
|
1324
1326
|
}
|
|
1325
1327
|
|
|
1326
|
-
export default makeResponsive(ContentUploader);
|
|
1328
|
+
export default flow([makeResponsive, withBlueprintModernization])(ContentUploader);
|
|
1327
1329
|
export { ContentUploader as ContentUploaderComponent, CHUNKED_UPLOAD_MIN_SIZE_BYTES };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
$reason-font-size: 13px; // Overriding Blueprint to match current sidebar styles
|
|
2
|
+
|
|
3
|
+
.AppliedByAiClassificationReason {
|
|
4
|
+
.AppliedByAiClassificationReason-headerText {
|
|
5
|
+
font-size: $reason-font-size;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.AppliedByAiClassificationReason-answer {
|
|
9
|
+
font-size: $reason-font-size;
|
|
10
|
+
line-height: var(--body-default-line-height);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.AppliedByAiClassificationReason-references {
|
|
14
|
+
> * > * {
|
|
15
|
+
font-size: $reason-font-size;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.AppliedByAiClassificationReason-header {
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
gap: var(--space-2);
|
|
24
|
+
margin: 0 0 var(--space-2);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.AppliedByAiClassificationReason-references {
|
|
28
|
+
margin-top: var(--space-2);
|
|
29
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AnswerContent, References } from '@box/box-ai-content-answers';
|
|
3
|
+
import { Card, Text } from '@box/blueprint-web';
|
|
4
|
+
import BoxAIIconColor from '@box/blueprint-web-assets/icons/Logo/BoxAiLogo';
|
|
5
|
+
import { Size5 } from '@box/blueprint-web-assets/tokens/tokens';
|
|
6
|
+
import { FormattedDate, FormattedMessage } from 'react-intl';
|
|
7
|
+
|
|
8
|
+
import { isValidDate } from '../../../utils/datetime';
|
|
9
|
+
import type { AiClassificationReason } from '../types';
|
|
10
|
+
|
|
11
|
+
import messages from './messages';
|
|
12
|
+
|
|
13
|
+
import './AppliedByAiClassificationReason.scss';
|
|
14
|
+
|
|
15
|
+
export type AppliedByAiClassificationReasonProps = AiClassificationReason;
|
|
16
|
+
|
|
17
|
+
const AppliedByAiClassificationReason = ({ answer, modifiedAt, citations }: AppliedByAiClassificationReasonProps) => {
|
|
18
|
+
const modifiedDate = new Date(modifiedAt);
|
|
19
|
+
const isModifiedDateAvailable = Boolean(modifiedAt) && isValidDate(modifiedDate);
|
|
20
|
+
|
|
21
|
+
const formattedModifiedAt = isModifiedDateAvailable && (
|
|
22
|
+
<FormattedDate value={modifiedDate} month="long" year="numeric" day="numeric" />
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Card className="AppliedByAiClassificationReason">
|
|
27
|
+
<h3 className="AppliedByAiClassificationReason-header">
|
|
28
|
+
<BoxAIIconColor data-testid="box-ai-icon" height={Size5} width={Size5} />
|
|
29
|
+
<Text
|
|
30
|
+
className="AppliedByAiClassificationReason-headerText"
|
|
31
|
+
as="span"
|
|
32
|
+
color="textOnLightSecondary"
|
|
33
|
+
variant="bodyDefaultSemibold"
|
|
34
|
+
>
|
|
35
|
+
{isModifiedDateAvailable ? (
|
|
36
|
+
<FormattedMessage
|
|
37
|
+
{...messages.appliedByBoxAiOnDate}
|
|
38
|
+
values={{ modifiedAt: formattedModifiedAt }}
|
|
39
|
+
/>
|
|
40
|
+
) : (
|
|
41
|
+
<FormattedMessage {...messages.appliedByBoxAi} />
|
|
42
|
+
)}
|
|
43
|
+
</Text>
|
|
44
|
+
</h3>
|
|
45
|
+
<AnswerContent className="AppliedByAiClassificationReason-answer" answer={answer} />
|
|
46
|
+
{citations && (
|
|
47
|
+
<div className="AppliedByAiClassificationReason-references">
|
|
48
|
+
<References citations={citations} />
|
|
49
|
+
</div>
|
|
50
|
+
)}
|
|
51
|
+
</Card>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default AppliedByAiClassificationReason;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { render, screen } from '../../../../test-utils/testing-library';
|
|
4
|
+
import AppliedByAiClassificationReason from '../AppliedByAiClassificationReason';
|
|
5
|
+
|
|
6
|
+
import messages from '../messages';
|
|
7
|
+
|
|
8
|
+
describe('AppliedByAiClassificationReason', () => {
|
|
9
|
+
let defaultProps;
|
|
10
|
+
let modifiedAtDisplayDate;
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
defaultProps = {
|
|
14
|
+
answer: 'This file is marked as Internal Only because it contains non-public financial results.',
|
|
15
|
+
modifiedAt: '2024-01-15T10:30:00Z',
|
|
16
|
+
};
|
|
17
|
+
modifiedAtDisplayDate = 'January 15, 2024';
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const renderComponent = (props = {}) => {
|
|
21
|
+
return render(<AppliedByAiClassificationReason {...defaultProps} {...props} />);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
test('should render AI classification reason with icon, applied date, and reasoning', () => {
|
|
25
|
+
const expectedIconSize = '1.25rem';
|
|
26
|
+
|
|
27
|
+
renderComponent();
|
|
28
|
+
|
|
29
|
+
const boxAiIcon = screen.getByTestId('box-ai-icon');
|
|
30
|
+
const appliedByWithDate = screen.getByRole('heading', {
|
|
31
|
+
level: 3,
|
|
32
|
+
name: messages.appliedByBoxAiOnDate.defaultMessage.replace('{modifiedAt}', modifiedAtDisplayDate),
|
|
33
|
+
});
|
|
34
|
+
const reasonText = screen.getByText(defaultProps.answer);
|
|
35
|
+
const citationsLabel = screen.queryByTestId('content-answers-references-label');
|
|
36
|
+
const noReferencesIconContainer = screen.queryByTestId('content-answers-references-no-references');
|
|
37
|
+
|
|
38
|
+
expect(boxAiIcon).toBeVisible();
|
|
39
|
+
expect(boxAiIcon).toHaveAttribute('height', expectedIconSize);
|
|
40
|
+
expect(boxAiIcon).toHaveAttribute('width', expectedIconSize);
|
|
41
|
+
expect(appliedByWithDate).toBeVisible();
|
|
42
|
+
expect(reasonText).toBeVisible();
|
|
43
|
+
// Assert none of the Reference components are rendered
|
|
44
|
+
expect(citationsLabel).toBeNull();
|
|
45
|
+
expect(noReferencesIconContainer).toBeNull();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('should render no references icon when an empty citations array provided', () => {
|
|
49
|
+
renderComponent({ citations: [] });
|
|
50
|
+
|
|
51
|
+
const noReferencesIconContainer = screen.queryByTestId('content-answers-references-no-references');
|
|
52
|
+
const noReferencesIcon = noReferencesIconContainer.querySelector('svg');
|
|
53
|
+
|
|
54
|
+
expect(noReferencesIcon).toBeVisible();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('should render references when non-empty citations are provided', () => {
|
|
58
|
+
const expectedCitationsCount = 5;
|
|
59
|
+
const expectedCitations = Array.from({ length: expectedCitationsCount }, () => ({
|
|
60
|
+
content: 'file content for citation',
|
|
61
|
+
fileId: 'fileId',
|
|
62
|
+
location: 'cited location',
|
|
63
|
+
title: 'file title',
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
renderComponent({ citations: expectedCitations });
|
|
67
|
+
|
|
68
|
+
const citationsLabel = screen.queryByTestId('content-answers-references-label');
|
|
69
|
+
const citationElements = screen.getAllByTestId('content-answers-citation-status');
|
|
70
|
+
|
|
71
|
+
expect(citationsLabel).toBeVisible();
|
|
72
|
+
expect(citationElements).toHaveLength(expectedCitationsCount);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test.each([null, undefined, 'invalid date str'])(
|
|
76
|
+
'should render applied by without date when modifiedAt is invalid: %s',
|
|
77
|
+
invalidModifiedAt => {
|
|
78
|
+
renderComponent({ modifiedAt: invalidModifiedAt });
|
|
79
|
+
|
|
80
|
+
const appliedByWithoutDate = screen.getByRole('heading', {
|
|
81
|
+
level: 3,
|
|
82
|
+
name: messages.appliedByBoxAi.defaultMessage,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(appliedByWithoutDate).toBeVisible();
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
test('should render long answer text correctly', () => {
|
|
90
|
+
const longAnswer = 'A'.repeat(1000);
|
|
91
|
+
renderComponent({ answer: longAnswer });
|
|
92
|
+
|
|
93
|
+
expect(screen.getByText(longAnswer)).toBeVisible();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('should render answer with special and unicode characters correctly', () => {
|
|
97
|
+
const nonPlainAnswer = 'Answer with special characters and unicode !@#$%^&*()_+-=[]{}|;:,.<>? πππδΈζζ₯ζ¬θͺ';
|
|
98
|
+
|
|
99
|
+
renderComponent({ answer: nonPlainAnswer });
|
|
100
|
+
|
|
101
|
+
const reasonText = screen.getByText(nonPlainAnswer);
|
|
102
|
+
|
|
103
|
+
expect(reasonText).toBeVisible();
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
|
|
3
|
+
const messages = defineMessages({
|
|
4
|
+
appliedByBoxAi: {
|
|
5
|
+
defaultMessage: 'Box AI',
|
|
6
|
+
description:
|
|
7
|
+
'Title of the card that shows the reason why the AI classification was applied when no date is available.',
|
|
8
|
+
id: 'boxui.classification.appliedByBoxAi',
|
|
9
|
+
},
|
|
10
|
+
appliedByBoxAiOnDate: {
|
|
11
|
+
defaultMessage: 'Box AI on {modifiedAt}',
|
|
12
|
+
description:
|
|
13
|
+
'Title of the card that shows the reason why the AI classification was applied on a specific date.',
|
|
14
|
+
id: 'boxui.classification.appliedByBoxAiOnDate',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export default messages;
|