Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3494 media field revamp #3524

Merged
merged 44 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c80ef71
Initial modal UI
vkozinec Mar 11, 2021
bfc4ce4
Open and close media modal
yacky Mar 12, 2021
e953d79
show attachments in media modal
yacky Mar 15, 2021
2996e4c
RenderAttachment Component
konzz Mar 15, 2021
610faea
vaultsync storing attachment id instead of url to file
konzz Mar 16, 2021
bbe2de6
Use RenderAttachment component in MediaModal
yacky Mar 16, 2021
ea405cd
add onChange and selectedId props to MediaModal
yacky Mar 16, 2021
c1a367d
Added a migration to populate mimetype on files
Mar 16, 2021
5d60352
Remove migration that populates mimetype on files
Mar 16, 2021
402342f
Styled media modal items, image and video
vkozinec Mar 17, 2021
b9a7890
updated csv to use attachments when importing image or media fields
konzz Mar 21, 2021
36eb569
add selected image to state
yacky Mar 18, 2021
93893ee
Styled RenderAttachment component in sidebar
vkozinec Mar 19, 2021
cc043ed
Added initial media modal test
vkozinec Mar 19, 2021
eb2c19d
media field form component
yacky Mar 19, 2021
1cb1981
fix basic modal test for media modal
yacky Mar 19, 2021
dd2ba00
remove unused variables and functions
yacky Mar 19, 2021
826e45f
Filter image and media files in media modal. Show selected attachments
yacky Mar 22, 2021
9718fd2
fix some tests
yacky Mar 22, 2021
3e92cb1
fixed typescript error
konzz Mar 22, 2021
80a751a
deleted deprecated comment
konzz Mar 22, 2021
5a78a6f
fix storeKey and form not working
yacky Mar 22, 2021
e21a536
default empty attachments for when creating a new enity
konzz Mar 23, 2021
0d125dd
media modal test
yacky Mar 23, 2021
ef422da
fix test describe
yacky Mar 23, 2021
3525487
undo changes to csv import and vault sync
konzz Mar 24, 2021
ec9ccc3
save url of attachment instead of _id
yacky Mar 25, 2021
d1aca27
add from url tab
yacky Mar 25, 2021
64f8775
open default tab2 if edit url
yacky Mar 26, 2021
bf87085
Add label to media modal
yacky Mar 26, 2021
b591dc3
image field in edit
yacky Mar 29, 2021
4244fbd
fixed media rendering
konzz Mar 29, 2021
7050c11
Fixed metadata e2e
konzz Mar 29, 2021
4964850
fixed some eslint errors
konzz Mar 29, 2021
075e0f1
fixed eslint error
konzz Mar 29, 2021
3f31c95
fixed issue with attachments in document View
konzz Mar 30, 2021
c24d1f3
destructure props at mapStateToProps
Mar 30, 2021
da4ba1f
QA review fixes
konzz Apr 1, 2021
e0d1c58
Merge branch '3494-media-field-revamp' of github.com:huridocs/uwazi i…
konzz Apr 1, 2021
0fe2efd
remove important from css
yacky Apr 1, 2021
656a801
test media modal local form
yacky Apr 6, 2021
7b6d01b
Merge branch 'development' into 3494-media-field-revamp
konzz Apr 6, 2021
7157ef7
Fixed label and added tooltip
konzz Apr 7, 2021
9127532
updated snapshots
konzz Apr 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 102 additions & 1 deletion app/react/App/scss/modules/_attachments-modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@

&__content {
flex: 1;
overflow: hidden;

> div {
display: flex;
Expand Down Expand Up @@ -90,9 +91,11 @@

&__tabs-content {
flex: 1;
overflow: auto;
overflow-x: hidden;

.tab-content {
padding: 24px 0;
padding: 24px 0 0 0;
height: 100%;

&.centered {
Expand Down Expand Up @@ -124,6 +127,104 @@
color: $c-primary;
}
}

.media-grid {
width: calc(100% + 20px) !important;
max-width: calc(100% + 20px) !important;
mfacar marked this conversation as resolved.
Show resolved Hide resolved
margin-left: -10px;

.row {
display: flex;
flex-wrap: wrap;
}

&-item {
width: 100%;
flex-basis: 100%;
margin-bottom: 15px;
padding-left: 10px;
padding-right: 10px;
cursor: pointer;

@media (min-width: 768px) {
width: 33.3333%;
flex-basis: 33.3333%;
}

@media (min-width: 1024px) {
width: 25%;
flex-basis: 25%;
}
}

&-card {
background: #ffffff;
border: 1px solid #dddddd;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.15);
padding: 6px;

&.active {
border-color: $c-type-9;
border-width: 2px;
}

&-header {
h5 {
margin: 0;
font-weight: 500;
font-size: 12px;
line-height: 14px;
}

span {
font-weight: 500;
font-size: 10px;
line-height: 12px;
color: #888888;
}
}

&-content {
padding-top: 85%;
position: relative;
overflow: hidden;

.media {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
overflow: hidden;

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;
}
}
}
}
}
}
}
}
}

Expand Down
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
30 changes: 30 additions & 0 deletions app/react/Attachments/components/RenderAttachment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { AttachmentSchema } from 'shared/types/commonTypes';
import MarkdownMedia from 'app/Markdown/components/MarkdownMedia';
import ReactPlayer from 'react-player';

export const RenderAttachment = ({ attachment }: { attachment: AttachmentSchema }) => {
const { mimetype = '' } = attachment;

if (mimetype.includes('image')) {
return attachment.url ? (
<img src={attachment.url} alt={attachment.originalname} />
) : (
<img src={`/api/files/${attachment.filename}`} alt={attachment.originalname} />
);
}

const isVideoAudio = mimetype.includes('video') || mimetype.includes('audio');

const isFromSupportedSite = attachment.url && ReactPlayer.canPlay(attachment.url);

if (isVideoAudio || isFromSupportedSite) {
return attachment.url ? (
<MarkdownMedia config={`(${attachment.url})`} />
) : (
<MarkdownMedia config={`(/api/files/${attachment.filename})`} />
);
}

return null;
};
142 changes: 142 additions & 0 deletions app/react/Attachments/components/specs/RenderAttachment.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { AttachmentSchema } from 'shared/types/commonTypes';
import MarkdownMedia from 'app/Markdown/components/MarkdownMedia';
import ReactPlayer from 'react-player';
import { RenderAttachment } from '../RenderAttachment';

describe('RenderAttachment', () => {
let component: ShallowWrapper<typeof RenderAttachment>;
let attachment: AttachmentSchema;

describe('unsuported scenarios', () => {
describe('no mimetype', () => {
beforeEach(() => {
attachment = {
url: 'http://somewhere.org',
originalname: 'A Sad Cat',
};

component = shallow(<RenderAttachment attachment={attachment} />);
});

it('should return null', () => {
expect(component.type()).toEqual(null);
});
});

describe('unsuported mimetype', () => {
beforeEach(() => {
attachment = {
filename: 'c4ts.pdf',
mimetype: 'application/pdf',
originalname: 'A Sad Cat',
};

component = shallow(<RenderAttachment attachment={attachment} />);
});

it('should return null', () => {
expect(component.type()).toEqual(null);
});
});
});

describe('image', () => {
describe('from url', () => {
beforeEach(() => {
attachment = {
url: 'http://awesomecats.org/ahappycat',
mimetype: 'image/png',
originalname: 'A Happy Cat',
};

component = shallow(<RenderAttachment attachment={attachment} />);
});

it('should render a tag image with the url of the image', () => {
const img = component.find('img');
expect(img.props().src).toBe(attachment.url);
expect(img.props().alt).toBe(attachment.originalname);
});
});

describe('from file', () => {
beforeEach(() => {
attachment = {
filename: '4h4ppyc47.png',
mimetype: 'image/png',
originalname: 'A Happy Cat',
};

component = shallow(<RenderAttachment attachment={attachment} />);
});

it('should render a tag image with the url of the image', () => {
const img = component.find('img');
expect(img.props().src).toBe('/api/files/4h4ppyc47.png');
expect(img.props().alt).toBe(attachment.originalname);
});
});
});

describe('video / audio', () => {
describe('from url', () => {
beforeEach(() => {
attachment = {
url: 'http://awesomecats.org/ahappycat.mp4',
mimetype: 'video/mp4',
originalname: 'A Happy Cat',
};

component = shallow(<RenderAttachment attachment={attachment} />);
});

it('should render a MarkdownMedia component', () => {
const video: ShallowWrapper<typeof MarkdownMedia> = component.find(MarkdownMedia);
expect(video.props()).toEqual({
config: '(http://awesomecats.org/ahappycat.mp4)',
compact: false,
});
});
});

describe('from file', () => {
beforeEach(() => {
attachment = {
filename: '4h4ppyc47.mp4',
mimetype: 'audio/mp4',
originalname: 'A Happy Cat',
};

component = shallow(<RenderAttachment attachment={attachment} />);
});

it('should render a tag image with the url of the image', () => {
const video: ShallowWrapper<typeof MarkdownMedia> = component.find(MarkdownMedia);
expect(video.props()).toEqual({ config: '(/api/files/4h4ppyc47.mp4)', compact: false });
});
});

describe('from known media sites', () => {
beforeEach(() => {
attachment = {
url: 'http://reacplayer.valid.url?w=happycat',
mimetype: 'application/html',
originalname: 'A Happy Cat',
};

jest.spyOn(ReactPlayer, 'canPlay').mockReturnValue(true);
mfacar marked this conversation as resolved.
Show resolved Hide resolved
component = shallow(<RenderAttachment attachment={attachment} />);
});

it('should render a tag image with the url of the image', () => {
const video: ShallowWrapper<typeof MarkdownMedia> = component.find(MarkdownMedia);
expect(video.props()).toEqual({
config: '(http://reacplayer.valid.url?w=happycat)',
compact: false,
});
});
});
});
});
1 change: 1 addition & 0 deletions app/react/Documents/components/DocumentSidePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ export class DocumentSidePanel extends Component {
showTitle
showType
groupGeolocations
storeKey={this.props.storeKey}
konzz marked this conversation as resolved.
Show resolved Hide resolved
/>
<FileList
files={documents}
Expand Down
Loading