Skip to content

Commit

Permalink
Merge branch '3494-media-field-revamp' of github.com:huridocs/uwazi i…
Browse files Browse the repository at this point in the history
…nto 3494-media-field-revamp
  • Loading branch information
konzz committed Mar 21, 2021
2 parents d5334f7 + dc3c94e commit fdf54ea
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 71 deletions.
45 changes: 41 additions & 4 deletions app/react/App/scss/modules/_search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
position: relative;
display: block;
max-width: 100%;

@media (min-width: 768px) {
max-width: calc(100% - 550px);
width: 632px;
Expand Down Expand Up @@ -234,12 +234,13 @@
}

.admin-filter {
span, label {
color: #2B56C1;
span,
label {
color: #2b56c1;
}

input {
border: #2B56C1;
border: #2b56c1;
}
}

Expand Down Expand Up @@ -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 {
Expand Down
56 changes: 56 additions & 0 deletions app/react/Forms/components/MediaField.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="search__filter--selected__media">
{!!selectedImage && <RenderAttachment attachment={selectedImage} />}

<div className="search__filter--selected__media-toolbar">
<button type="button" onClick={() => setOpenModal(true)} className="btn btn-success">
<Icon icon="plus" /> <Translate>Select supporting file</Translate>
</button>

{!!selectedImage && (
<button type="button" onClick={handleImageRemove} className="btn btn-danger ">
<Icon icon="trash-alt" />
</button>
)}
</div>

<MediaModal
isOpen={openModal}
onClose={handleCloseMediaModal}
onChange={onChange}
selectedId={value}
attachments={attachments}
/>
</div>
);
};

export default MediaField;
3 changes: 2 additions & 1 deletion app/react/Forms/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -47,4 +47,5 @@ export {
LinkField,
FormValue,
LookupMultiSelect,
MediaField,
};
21 changes: 2 additions & 19 deletions app/react/Metadata/components/MediaModal.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -18,10 +17,10 @@ export interface MediaModalProps {
selectedId: string | ObjectId | null;
}

export const MediaModalCmp = ({
export const MediaModal = ({
isOpen,
onClose,
attachments,
attachments = [],
onChange,
selectedId,
}: MediaModalProps) => {
Expand Down Expand Up @@ -94,19 +93,3 @@ export const MediaModalCmp = ({
</ReactModal>
);
};

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);
62 changes: 15 additions & 47 deletions app/react/Metadata/components/MetadataFormFields.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -24,9 +23,9 @@ import {
Numeric,
Select,
LookupMultiSelect,
MediaField,
} from '../../ReactReduxForms';
import MultipleEditionFieldWarning from './MultipleEditionFieldWarning';
import { MediaModal } from './MediaModal';

export const translateOptions = thesauri =>
thesauri
Expand All @@ -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) {
Expand Down Expand Up @@ -162,25 +140,7 @@ export class MetadataFormFields extends Component {
return <LinkField model={_model} />;
case 'media':
case 'image':
return (
<div>
<Field model={_model}>
<textarea rows="6" className="form-control" />
</Field>
&nbsp;<em>URL (address for image or media file)</em>
<br />
<button type="button" onClick={this.handleOpenMediaModal} className="btn btn-success">
<Icon icon="plus" />
<Translate>Select image</Translate>
</button>
<MediaModal
isOpen={this.state.openMediaModal}
onClose={this.handleCloseMediaModal}
onChange={this.handleImageChange}
selectedId={this.state.selectedAttachmentId}
/>
</div>
);
return <MediaField model={_model} attachments={attachments} />;
case 'preview':
return (
<div>
Expand Down Expand Up @@ -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);
50 changes: 50 additions & 0 deletions app/react/Metadata/components/specs/MediaModal.spec.tsx
Original file line number Diff line number Diff line change
@@ -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(
<Provider store={store}>
<MediaModal {...props} {...otherProps} />
</Provider>
).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();
});
});
1 change: 1 addition & 0 deletions app/react/ReactReduxForms/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ export const Geolocation = props => <Control component={forms.Geolocation} {...p
export const LinkField = props => <Control component={forms.LinkField} {...props} />;
export const NestedMultiselect = props => <forms.NestedMultiselect {...props} />;
export const FormGroup = props => <forms.FormGroup {...props} />;
export const MediaField = props => <Control component={forms.MediaField} {...props} />;

0 comments on commit fdf54ea

Please sign in to comment.