diff --git a/localization/react-intl/src/app/components/media/MediaOrigin.json b/localization/react-intl/src/app/components/media/MediaOrigin.json
new file mode 100644
index 000000000..e09355d05
--- /dev/null
+++ b/localization/react-intl/src/app/components/media/MediaOrigin.json
@@ -0,0 +1,52 @@
+[
+ {
+ "id": "MediaOrigin.userMerged",
+ "description": "Message for User Merged",
+ "defaultMessage": "User Merged"
+ },
+ {
+ "id": "MediaOrigin.userMergedTooltip",
+ "description": "Tooltip message for User Merged",
+ "defaultMessage": "{user} added this media by merging from another cluster"
+ },
+ {
+ "id": "MediaOrigin.userMatched",
+ "description": "Message for User Matched",
+ "defaultMessage": "User Matched"
+ },
+ {
+ "id": "MediaOrigin.userMatchedTooltip",
+ "description": "Tooltip message for User Matched",
+ "defaultMessage": "{user} accepted this media as a suggested match"
+ },
+ {
+ "id": "MediaOrigin.userAdded",
+ "description": "This media was added by a user.",
+ "defaultMessage": "User Added"
+ },
+ {
+ "id": "MediaOrigin.userAddedTooltip",
+ "description": "Tooltip message for User Added",
+ "defaultMessage": "{user} uploaded this media using the Check interface"
+ },
+ {
+ "id": "MediaOrigin.tiplineSubmitted",
+ "description": "Message for Tipline Submitted",
+ "defaultMessage": "Tipline Submitted"
+ },
+ {
+ "id": "MediaOrigin.tiplineSubmittedTooltip",
+ "description": "Tooltip message for Tipline Submitted",
+ "defaultMessage": "Original cluster media submitted by Tipline User"
+ },
+ {
+ "id": "MediaOrigin.autoMatched",
+ "description": "Message for Auto Matched",
+ "defaultMessage": "Auto Matched"
+ },
+ {
+ "id": "MediaOrigin.autoMatchedTooltip",
+ "description": "Tooltip message for Auto Matched",
+ "defaultMessage": "Automatically matched media by Check"
+ }
+]
\ No newline at end of file
diff --git a/src/app/components/cds/Sandbox.js b/src/app/components/cds/Sandbox.js
index da3f8f5cf..2a7413d83 100644
--- a/src/app/components/cds/Sandbox.js
+++ b/src/app/components/cds/Sandbox.js
@@ -27,6 +27,7 @@ import TabWrapper from './menus-lists-dialogs/TabWrapper';
import Reorder from '../layout/Reorder';
import AddIcon from '../../icons/settings.svg';
import CalendarIcon from '../../icons/calendar_month.svg';
+import MediaOrigin from '../media/MediaOrigin';
import ListIcon from '../../icons/list.svg';
import FigmaColorLogo from '../../icons/figma_color.svg';
import ArticleCard from '../search/SearchResultsCards/ArticleCard';
@@ -484,6 +485,10 @@ const SandboxComponent = ({ admin }) => {
label: 'Tabs',
value: 'tabs',
},
+ {
+ label: 'Media Cluster Origin Buttons',
+ value: 'media-cluster-origin-buttons',
+ },
]}
value={categoryTab}
wrapContent
@@ -2383,6 +2388,31 @@ const SandboxComponent = ({ admin }) => {
}
+ { (categoryTab === 'all' || categoryTab === 'media-cluster-origin-buttons') && (
+
+
+
+ Media Origin
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
);
};
diff --git a/src/app/components/media/MediaCardLargeFooter.js b/src/app/components/media/MediaCardLargeFooter.js
index 6d3771fc4..f97c1f6fc 100644
--- a/src/app/components/media/MediaCardLargeFooter.js
+++ b/src/app/components/media/MediaCardLargeFooter.js
@@ -99,26 +99,29 @@ const MediaCardLargeFooter = ({
{ footerBody && !inModal ? <>{transcriptionOrExtractedFooter}> : null }
{ !inModal ?
- ), (
-
- ), (
-
- ),
+ details={[
+ (
+
+ ),
+ (
+
+ ),
+ (
+
+ ),
]}
/>
: null
diff --git a/src/app/components/media/MediaOrigin.js b/src/app/components/media/MediaOrigin.js
new file mode 100644
index 000000000..f28b87b89
--- /dev/null
+++ b/src/app/components/media/MediaOrigin.js
@@ -0,0 +1,152 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { FormattedMessage, FormattedHTMLMessage } from 'react-intl';
+import ButtonMain from '../cds/buttons-checkboxes-chips/ButtonMain';
+import Person from '../../icons/person.svg';
+import PersonAdd from '../../icons/person_add.svg';
+import PersonCheck from '../../icons/person_check.svg';
+import Bolt from '../../icons/bolt.svg';
+import Tipline from '../../icons/question_answer.svg';
+import Tooltip from '../cds/alerts-and-prompts/Tooltip';
+
+const allowedTypes = new Set(['typeA', 'typeB', 'typeC', 'typeD', 'typeE']);
+
+const getIconAndMessage = (type, user) => {
+ switch (type) {
+ case 'typeA':
+ return {
+ icon: ,
+ message: (
+
+ ),
+ tooltipMessage: (
+
+ ),
+ };
+ case 'typeB':
+ return {
+ icon: ,
+ message: (
+
+ ),
+ tooltipMessage: (
+
+ ),
+ };
+ case 'typeC':
+ return {
+ icon: ,
+ message: (
+
+ ),
+ tooltipMessage: (
+
+ ),
+ };
+ case 'typeD':
+ return {
+ icon: ,
+ message: (
+
+ ),
+ tooltipMessage: (
+
+ ),
+ };
+ case 'typeE':
+ return {
+ icon: ,
+ message: (
+
+ ),
+ tooltipMessage: (
+
+ ),
+ };
+ default:
+ return {
+ icon: null,
+ message: null,
+ tooltipMessage: null,
+ };
+ }
+};
+
+const MediaOrigin = ({ type, user }) => {
+ if (!allowedTypes.has(type)) {
+ return null;
+ }
+
+ const { icon, message, tooltipMessage } = getIconAndMessage(type, user);
+
+ return (
+
+
+
+
+
+ );
+};
+
+MediaOrigin.defaultProps = {
+ user: 'Unknown User',
+};
+
+MediaOrigin.propTypes = {
+ type: PropTypes.string.isRequired,
+ user: PropTypes.string,
+};
+
+export default MediaOrigin;
diff --git a/src/app/components/media/MediaOrigin.test.js b/src/app/components/media/MediaOrigin.test.js
new file mode 100644
index 000000000..5275db0bc
--- /dev/null
+++ b/src/app/components/media/MediaOrigin.test.js
@@ -0,0 +1,39 @@
+import React from 'react';
+import MediaOrigin from './MediaOrigin';
+import { mountWithIntl } from '../../../../test/unit/helpers/intl-test';
+import Person from '../../icons/person.svg';
+import PersonAdd from '../../icons/person_add.svg';
+import PersonCheck from '../../icons/person_check.svg';
+import Bolt from '../../icons/bolt.svg';
+import Tipline from '../../icons/question_answer.svg';
+
+describe('', () => {
+ it('should render a button with the correct icon and message for each type', () => {
+ const userMerged = mountWithIntl();
+ expect(userMerged.find(Person).length).toEqual(1);
+ expect(userMerged.html()).toMatch('User Merged');
+
+ const userMatched = mountWithIntl();
+ expect(userMatched.find(PersonCheck).length).toEqual(1);
+ expect(userMatched.html()).toMatch('User Matched');
+
+
+ const userAdded = mountWithIntl();
+ expect(userAdded.find(PersonAdd).length).toEqual(1);
+ expect(userAdded.html()).toMatch('User Added');
+
+ const tiplineSubmitted = mountWithIntl();
+ expect(tiplineSubmitted.find(Tipline).length).toEqual(1);
+ expect(tiplineSubmitted.html()).toMatch('Tipline Submitted');
+
+ const autoMatched = mountWithIntl();
+ expect(autoMatched.find(Bolt).length).toEqual(1);
+ expect(autoMatched.html()).toMatch('Auto Matched');
+ });
+
+
+ it('should return null for invalid type', () => {
+ const wrapper = mountWithIntl();
+ expect(wrapper.find('FormattedMessage').length).toEqual(0);
+ });
+});