diff --git a/app/react/App/scss/modules/_search.scss b/app/react/App/scss/modules/_search.scss
index 97520e83a3b..660437aaa5e 100644
--- a/app/react/App/scss/modules/_search.scss
+++ b/app/react/App/scss/modules/_search.scss
@@ -13,7 +13,7 @@
position: relative;
display: block;
max-width: 100%;
-
+
@media (min-width: 768px) {
max-width: calc(100% - 550px);
width: 632px;
@@ -234,12 +234,13 @@
}
.admin-filter {
- span, label {
- color: #2B56C1;
+ span,
+ label {
+ color: #2b56c1;
}
input {
- border: #2B56C1;
+ border: #2b56c1;
}
}
@@ -363,6 +364,42 @@
}
}
+.search__filter--selected__media {
+ margin-top: 8px;
+
+ img {
+ object-fit: contain;
+ object-position: center;
+ width: 100%;
+ height: 100%;
+ background-color: #fafafa;
+ }
+
+ .video-container {
+ height: 100%;
+
+ > div:first-child {
+ padding-bottom: initial;
+ overflow: initial;
+ height: 100%;
+ display: flex;
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+
+ .react-player {
+ height: auto !important;
+ }
+ }
+ }
+}
+
+.search__filter--selected__media-toolbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 12px;
+}
+
.switcher-wrapper {
float: right;
span {
diff --git a/app/react/Forms/components/MediaField.tsx b/app/react/Forms/components/MediaField.tsx
new file mode 100644
index 00000000000..15917f5d7e6
--- /dev/null
+++ b/app/react/Forms/components/MediaField.tsx
@@ -0,0 +1,56 @@
+import React, { useMemo, useState } from 'react';
+import { ObjectId } from 'mongodb';
+
+import { AttachmentSchema } from 'shared/types/commonTypes';
+import { RenderAttachment } from 'app/Attachments/components/RenderAttachment';
+import { Translate } from 'app/I18N';
+import { Icon } from 'app/UI';
+import { MediaModal } from 'app/Metadata/components/MediaModal';
+
+interface MediaFieldProps {
+ attachments: AttachmentSchema[];
+ value: string | ObjectId | null;
+ onChange: (val: string | ObjectId | null) => void;
+}
+
+const MediaField = ({ attachments, value, onChange }: MediaFieldProps) => {
+ const [openModal, setOpenModal] = useState(false);
+
+ const selectedImage = useMemo(() => attachments.find(a => a._id === value), [attachments, value]);
+
+ const handleCloseMediaModal = () => {
+ setOpenModal(false);
+ };
+
+ const handleImageRemove = () => {
+ onChange(null);
+ };
+
+ return (
+
+ {!!selectedImage &&
}
+
+
+
+
+ {!!selectedImage && (
+
+ )}
+
+
+
+
+ );
+};
+
+export default MediaField;
diff --git a/app/react/Forms/index.js b/app/react/Forms/index.js
index fef830ba972..7649b3f403b 100644
--- a/app/react/Forms/index.js
+++ b/app/react/Forms/index.js
@@ -20,7 +20,7 @@ import Switcher from './components/Switcher';
import Geolocation from './components/Geolocation';
import LinkField from './components/LinkField';
import FormValue from './components/FormValue';
-
+import MediaField from './components/MediaField';
export * from './components/MultiSuggest';
export {
@@ -47,4 +47,5 @@ export {
LinkField,
FormValue,
LookupMultiSelect,
+ MediaField,
};
diff --git a/app/react/Metadata/components/MediaModal.tsx b/app/react/Metadata/components/MediaModal.tsx
index 3a03bfb139c..17f82ac982e 100644
--- a/app/react/Metadata/components/MediaModal.tsx
+++ b/app/react/Metadata/components/MediaModal.tsx
@@ -1,5 +1,4 @@
import React from 'react';
-import { connect } from 'react-redux';
import ReactModal from 'react-modal';
import { Tabs, TabLink, TabContent } from 'react-tabs-redux';
import filesize from 'filesize';
@@ -18,10 +17,10 @@ export interface MediaModalProps {
selectedId: string | ObjectId | null;
}
-export const MediaModalCmp = ({
+export const MediaModal = ({
isOpen,
onClose,
- attachments,
+ attachments = [],
onChange,
selectedId,
}: MediaModalProps) => {
@@ -94,19 +93,3 @@ export const MediaModalCmp = ({
);
};
-
-const mapStateToProps = (state: any, ownProps: any) => {
- const { selectedDocuments } = state.library.ui.toJS();
-
- const attachments: AttachmentSchema[] = selectedDocuments[0]
- ? selectedDocuments[0].attachments
- : [];
-
- return {
- attachments,
- };
-};
-
-const mapDispatchToProps = {};
-
-export const MediaModal = connect(mapStateToProps, mapDispatchToProps)(MediaModalCmp);
diff --git a/app/react/Metadata/components/MetadataFormFields.js b/app/react/Metadata/components/MetadataFormFields.js
index a4f18b7ab3c..e160034ae4e 100644
--- a/app/react/Metadata/components/MetadataFormFields.js
+++ b/app/react/Metadata/components/MetadataFormFields.js
@@ -9,7 +9,6 @@ import { Field } from 'react-redux-form';
import { propertyTypes } from 'shared/propertyTypes';
import { getSuggestions } from 'app/Metadata/actions/actions';
import { Translate } from 'app/I18N';
-import { Icon } from 'UI';
import {
DatePicker,
DateRange,
@@ -24,9 +23,9 @@ import {
Numeric,
Select,
LookupMultiSelect,
+ MediaField,
} from '../../ReactReduxForms';
import MultipleEditionFieldWarning from './MultipleEditionFieldWarning';
-import { MediaModal } from './MediaModal';
export const translateOptions = thesauri =>
thesauri
@@ -45,31 +44,10 @@ export const translateOptions = thesauri =>
.toJS();
export class MetadataFormFields extends Component {
- constructor(props) {
- super(props);
- this.state = { openMediaModal: false, selectedAttachmentId: null };
-
- this.handleOpenMediaModal = this.handleOpenMediaModal.bind(this);
- this.handleCloseMediaModal = this.handleCloseMediaModal.bind(this);
- this.handleImageChange = this.handleImageChange.bind(this);
- }
-
- handleOpenMediaModal() {
- this.setState({ openMediaModal: true });
- }
-
- handleCloseMediaModal() {
- this.setState({ openMediaModal: false });
- }
-
- handleImageChange(id) {
- this.setState({ selectedAttachmentId: id });
- }
-
getField(property, _model, thesauris) {
let thesauri;
let totalPossibleOptions = 0;
- const { dateFormat, version, entityThesauris } = this.props;
+ const { dateFormat, version, entityThesauris, attachments } = this.props;
const propertyType = property.type;
switch (propertyType) {
@@ -162,25 +140,7 @@ export class MetadataFormFields extends Component {
return ;
case 'media':
case 'image':
- return (
-
-
-
-
- URL (address for image or media file)
-
-
-
-
- );
+ return ;
case 'preview':
return (
@@ -274,11 +234,19 @@ MetadataFormFields.propTypes = {
version: PropTypes.string,
entityThesauris: PropTypes.instanceOf(Immutable.Map),
highlightedProps: PropTypes.arrayOf(PropTypes.string),
+ attachments: PropTypes.arrayOf(PropTypes.object),
};
-export const mapStateToProps = state => ({
- dateFormat: state.settings.collection.get('dateFormat'),
- entityThesauris: state.entityThesauris,
-});
+export const mapStateToProps = state => {
+ const { selectedDocuments } = state.library.ui.toJS();
+
+ const attachments = selectedDocuments[0] ? selectedDocuments[0].attachments : [];
+
+ return {
+ dateFormat: state.settings.collection.get('dateFormat'),
+ entityThesauris: state.entityThesauris,
+ attachments,
+ };
+};
export default connect(mapStateToProps)(MetadataFormFields);
diff --git a/app/react/Metadata/components/specs/MediaModal.spec.tsx b/app/react/Metadata/components/specs/MediaModal.spec.tsx
new file mode 100644
index 00000000000..3df8affa3b5
--- /dev/null
+++ b/app/react/Metadata/components/specs/MediaModal.spec.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+import thunk from 'redux-thunk';
+import { shallow, ShallowWrapper } from 'enzyme';
+import ReactModal from 'react-modal';
+import configureMockStore from 'redux-mock-store';
+import { Provider } from 'react-redux';
+
+import { MediaModal, MediaModalProps } from '../MediaModal';
+
+const mockStore = configureMockStore([thunk]);
+const store = mockStore({});
+
+describe('Attachments Modal', () => {
+ let component: ShallowWrapper;
+ let props: MediaModalProps;
+
+ beforeEach(() => {
+ props = {
+ onClose: jasmine.createSpy('onClose'),
+ onChange: jasmine.createSpy('onChange'),
+ isOpen: true,
+ attachments: [],
+ selectedId: '1',
+ };
+ });
+
+ const render = (otherProps = {}) => {
+ component = shallow(
+
+
+
+ ).dive();
+ };
+
+ it('Should pass isOpen props to Media modal.', () => {
+ render({ isOpen: false });
+ expect(component.find(ReactModal).props().isOpen).toBe(false);
+ render({ isOpen: true });
+ expect(component.find(ReactModal).props().isOpen).toBe(true);
+ });
+
+ it('Should call onClose', () => {
+ render();
+
+ const closeButton = component.find('.attachments-modal__close');
+ closeButton.simulate('click');
+
+ expect(props.onClose).toHaveBeenCalled();
+ });
+});
diff --git a/app/react/ReactReduxForms/index.js b/app/react/ReactReduxForms/index.js
index d237e4451b4..5d93ddf2d3d 100644
--- a/app/react/ReactReduxForms/index.js
+++ b/app/react/ReactReduxForms/index.js
@@ -33,3 +33,4 @@ export const Geolocation = props =>
;
export const NestedMultiselect = props => ;
export const FormGroup = props => ;
+export const MediaField = props => ;