diff --git a/i18n/en-US.properties b/i18n/en-US.properties index 3b3af9c2ab..287db0601b 100644 --- a/i18n/en-US.properties +++ b/i18n/en-US.properties @@ -846,8 +846,12 @@ be.uploadsProvidedFolderNameInvalidMessage = Provided folder name, {name}, could be.uploadsRetryButtonTooltip = Retry upload # Error message shown when account storage limit has been reached be.uploadsStorageLimitErrorMessage = Account storage limit reached +# Message displayed in the activity feed to represent the range of versions actioned by a single user. {name} is the user who did the action. {actionMessage} is the action. {versions} is a range of versions. +be.versionCollapsed = {name} {actionMessage} v{versions} # Message displayed in the activity feed for a deleted version. {name} is the user who performed the action. {version_number} is the file version string. be.versionDeleted = {name} deleted v{version_number} +# Message displayed in the activity feed to represent the range of versions actioned by multiple users. {numberOfCollaborators} is a number. {actionMessage} is the action. {versions} is a range of versions. +be.versionMultipleUsersCollapsed = {numberOfCollaborators} collaborators {actionMessage} v{versions} # Message displayed in the activity feed to represent the range of versions uploaded by multiple users. {numberOfCollaborators} is a number and {versions} is a range of versions. be.versionMultipleUsersUploaded = {numberOfCollaborators} collaborators uploaded v{versions} # Message displayed in the activity feed for a promoted version. {name} is the user who performed the action. {version_promoted} is the originating file version string. {version_number} is the file version string. diff --git a/src/elements/common/messages.js b/src/elements/common/messages.js index 854e873ee9..c443242cbc 100644 --- a/src/elements/common/messages.js +++ b/src/elements/common/messages.js @@ -857,6 +857,18 @@ const messages = defineMessages({ description: 'Message displayed in the activity feed to represent the range of versions uploaded by a single user. {name} is the user who uploaded. {versions} is a range of versions.', }, + versionMultipleUsersCollapsed: { + id: 'be.versionMultipleUsersCollapsed', + defaultMessage: '{numberOfCollaborators} collaborators {actionMessage} v{versions}', + description: + 'Message displayed in the activity feed to represent the range of versions actioned by multiple users. {numberOfCollaborators} is a number. {actionMessage} is the action. {versions} is a range of versions.', + }, + versionCollapsed: { + id: 'be.versionCollapsed', + defaultMessage: '{name} {actionMessage} v{versions}', + description: + 'Message displayed in the activity feed to represent the range of versions actioned by a single user. {name} is the user who did the action. {actionMessage} is the action. {versions} is a range of versions.', + }, versionUploaded: { id: 'be.versionUploaded', defaultMessage: '{name} uploaded v{version_number}', diff --git a/src/elements/content-sidebar/activity-feed/activity-feed/ActivityFeed.js b/src/elements/content-sidebar/activity-feed/activity-feed/ActivityFeed.js index 664075a135..146e7241bb 100644 --- a/src/elements/content-sidebar/activity-feed/activity-feed/ActivityFeed.js +++ b/src/elements/content-sidebar/activity-feed/activity-feed/ActivityFeed.js @@ -403,7 +403,7 @@ class ActivityFeed extends React.Component { hasReplies={hasReplies} hasVersions={hasVersions} isDisabled={isDisabled} - items={collapseFeedState(feedItems)} + items={shouldUseUAA ? feedItems : collapseFeedState(feedItems)} mentionSelectorContacts={mentionSelectorContacts} onAnnotationDelete={onAnnotationDelete} onAnnotationEdit={onAnnotationEdit} diff --git a/src/elements/content-sidebar/activity-feed/version/CollapsedVersion.js b/src/elements/content-sidebar/activity-feed/version/CollapsedVersion.js index 54a5bfc6f3..9e70e4638b 100644 --- a/src/elements/content-sidebar/activity-feed/version/CollapsedVersion.js +++ b/src/elements/content-sidebar/activity-feed/version/CollapsedVersion.js @@ -13,21 +13,48 @@ import messages from '../../../common/messages'; import selectors from '../../../common/selectors/version'; import { ACTIVITY_TARGETS } from '../../../common/interactionTargets'; import type { User, FileVersions } from '../../../../common/types/core'; +import { ACTION_TYPE_CREATED, ACTION_TYPE_RESTORED, ACTION_TYPE_TRASHED } from '../../../../constants'; import './Version.scss'; +const ACTION_MESSAGE_UPLOAD = 'uploaded'; +const ACTION_MESSAGE_RESTORE = 'restored'; +const ACTION_MESSAGE_TRASH = 'deleted'; + function getMessageForAction( action: string, - collaborators: { [collaborator_id: string]: User }, + collaborators: { [collaborator_id: string]: User } = {}, version_start: number, version_end: number, + shouldUseUAA?: boolean, + action_by?: User[], ): React.Node { - // We only support collapsing for multiple upload versions - if (action !== 'upload') { + if ( + action !== 'upload' && + action !== ACTION_TYPE_RESTORED && + action !== ACTION_TYPE_TRASHED && + action !== ACTION_TYPE_CREATED + ) { return null; } + let actionMessage = ''; + switch (action) { + case ACTION_TYPE_CREATED: + actionMessage = ACTION_MESSAGE_UPLOAD; + break; + case ACTION_TYPE_RESTORED: + actionMessage = ACTION_MESSAGE_RESTORE; + break; + case ACTION_TYPE_TRASHED: + actionMessage = ACTION_MESSAGE_TRASH; + break; + default: + actionMessage = ''; + break; + } + const collaboratorIDs = Object.keys(collaborators); - const numberOfCollaborators = collaboratorIDs.length; + const numberOfCollaborators = shouldUseUAA ? action_by?.length : collaboratorIDs.length; const versionRange: React.Node = ( @@ -36,13 +63,40 @@ function getMessageForAction( ); if (numberOfCollaborators === 1) { - const collaborator = collaborators[collaboratorIDs[0]]; + const collaborator = shouldUseUAA ? action_by?.[0] : collaborators[collaboratorIDs[0]]; + + if (shouldUseUAA) { + return ( + {collaborator?.name}, + versions: versionRange, + actionMessage, + }} + /> + ); + } + return ( {collaborator.name}, + name: {collaborator?.name}, + versions: versionRange, + }} + /> + ); + } + + if (shouldUseUAA) { + return ( + ); @@ -60,6 +114,8 @@ function getMessageForAction( } type Props = { + action_by?: User[], + action_type?: string, collaborators: { [collaborator_id: string]: User }, id: string, intl: IntlShape, @@ -71,14 +127,25 @@ type Props = { }; const CollapsedVersion = (props: Props): React.Node => { + const { + action_by, + action_type = ACTION_TYPE_CREATED, + collaborators, + id, + intl, + onInfo, + shouldUseUAA, + versions, + version_start, + version_end, + } = props; // $FlowFixMe - const action = selectors.getVersionAction(props); - const { collaborators, id, intl, onInfo, shouldUseUAA, versions, version_start, version_end } = props; + const action = shouldUseUAA ? action_type : selectors.getVersionAction(props); return ( - {getMessageForAction(action, collaborators, version_start, version_end)} + {getMessageForAction(action, collaborators, version_start, version_end, shouldUseUAA, action_by)} {onInfo ? ( diff --git a/src/elements/content-sidebar/activity-feed/version/__tests__/CollapsedVersion.test.js b/src/elements/content-sidebar/activity-feed/version/__tests__/CollapsedVersion.test.js index 93b49174ec..55db0ae9b8 100644 --- a/src/elements/content-sidebar/activity-feed/version/__tests__/CollapsedVersion.test.js +++ b/src/elements/content-sidebar/activity-feed/version/__tests__/CollapsedVersion.test.js @@ -1,86 +1,87 @@ import * as React from 'react'; -import { shallow } from 'enzyme'; - +import { render, screen } from '@testing-library/react'; +import { IntlProvider } from 'react-intl'; +import { ACTION_TYPE_CREATED, ACTION_TYPE_RESTORED, ACTION_TYPE_TRASHED } from '../../../../../constants'; +import CollapsedVersion from '../CollapsedVersion'; import selectors from '../../../../common/selectors/version'; -import { CollapsedVersionBase as CollapsedVersion } from '../CollapsedVersion'; -const translationProps = { - intl: { formatMessage: () => {} }, -}; +jest.mock('react-intl', () => ({ + ...jest.requireActual('react-intl'), +})); describe('elements/content-sidebar/ActivityFeed/version/CollapsedVersion', () => { - const render = item => shallow(); - beforeEach(() => { selectors.getVersionAction = jest.fn().mockReturnValue('upload'); }); - test('should correctly render for single collaborator', () => { - const version_start = 1; - const version_end = 10; - const item = { - collaborators: { 1: { name: 'Person one', id: 1 } }, - version_start, - version_end, - }; + const intl = { + formatMessage: jest.fn().mockImplementation(message => message.defaultMessage), + }; + + const renderComponent = props => + render( + + + , + ); - const wrapper = render(item); - const formattedMessage = wrapper.find('FormattedMessage'); - expect(wrapper).toMatchSnapshot(); + test('should correctly render for single collaborator', () => { + renderComponent(); - const renderedVersionsMessage = shallow(formattedMessage.prop('values').versions); - expect(renderedVersionsMessage).toMatchSnapshot(); + expect(screen.getByText('Person one')).toBeInTheDocument(); + expect(screen.getByText('uploaded v')).toBeInTheDocument(); + expect(screen.getByText('1 - 10')).toBeInTheDocument(); }); test('should correctly render for multiple collaborators', () => { - const version_start = 1; - const version_end = 10; - const item = { - collaborators: { - 1: { name: 'Person one', id: 1 }, - 2: { name: 'Person two', id: 2 }, - }, - version_start, - version_end, - }; + renderComponent({ + collaborators: { 1: { name: 'Person one', id: 1 }, 2: { name: 'Person two', id: 2 } }, + }); - const wrapper = render(item); - const formattedMessage = wrapper.find('FormattedMessage'); - - expect(wrapper).toMatchSnapshot(); - - const renderedVersionsMessage = shallow(formattedMessage.prop('values').versions); - expect(renderedVersionsMessage).toMatchSnapshot(); + expect(screen.getByText('2 collaborators uploaded v')).toBeInTheDocument(); + expect(screen.getByText('1 - 10')).toBeInTheDocument(); }); test('should correctly render info icon if onInfo is passed', () => { - const item = { + renderComponent({ onInfo: () => {}, - collaborators: { - 1: { name: 'Person one', id: 1 }, - 2: { name: 'Person two', id: 2 }, - }, - version_start: 1, - version_end: 10, - }; + }); - const wrapper = render(item); - - expect(wrapper.exists('IconInfo')).toBe(true); + expect(screen.getByLabelText('Get version information')).toBeInTheDocument(); }); test('should not render a message if action is not upload', () => { selectors.getVersionAction.mockReturnValueOnce('delete'); - const item = { - collaborators: { 1: { name: 'Person one', id: 1 } }, - version_start: 1, - version_end: 10, - }; + renderComponent(); - const wrapper = render(item); - const formattedMessage = wrapper.find('FormattedMessage'); + expect(screen.queryByText('Person one')).not.toBeInTheDocument(); + }); - expect(formattedMessage.length).toBe(0); + test.each` + actionType | actionText + ${ACTION_TYPE_RESTORED} | ${'restored v'} + ${ACTION_TYPE_TRASHED} | ${'deleted v'} + ${ACTION_TYPE_CREATED} | ${'uploaded v'} + `('should correctly render when shouldUseUAA is true with actionType $actionType', ({ actionType, actionText }) => { + renderComponent({ + shouldUseUAA: true, + action_type: actionType, + action_by: [{ name: 'John Doe', id: 3 }], + version_start: 2, + version_end: 4, + }); + + expect(screen.getByText('John Doe')).toBeInTheDocument(); + expect(screen.getByText(actionText)).toBeInTheDocument(); + expect(screen.getByText('2 - 4')).toBeInTheDocument(); }); }); diff --git a/src/elements/content-sidebar/activity-feed/version/__tests__/__snapshots__/CollapsedVersion.test.js.snap b/src/elements/content-sidebar/activity-feed/version/__tests__/__snapshots__/CollapsedVersion.test.js.snap deleted file mode 100644 index f96e71bb21..0000000000 --- a/src/elements/content-sidebar/activity-feed/version/__tests__/__snapshots__/CollapsedVersion.test.js.snap +++ /dev/null @@ -1,77 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`elements/content-sidebar/ActivityFeed/version/CollapsedVersion should correctly render for multiple collaborators 1`] = ` - - - - 1 - - - 10 - , - } - } - /> - - -`; - -exports[`elements/content-sidebar/ActivityFeed/version/CollapsedVersion should correctly render for multiple collaborators 2`] = ` - - 1 - - - 10 - -`; - -exports[`elements/content-sidebar/ActivityFeed/version/CollapsedVersion should correctly render for single collaborator 1`] = ` - - - - Person one - , - "versions": - 1 - - - 10 - , - } - } - /> - - -`; - -exports[`elements/content-sidebar/ActivityFeed/version/CollapsedVersion should correctly render for single collaborator 2`] = ` - - 1 - - - 10 - -`;