Skip to content
This repository has been archived by the owner on Jul 25, 2023. It is now read-only.

Commit

Permalink
Add File and Image Widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
avoinea committed Aug 12, 2020
1 parent cbe1492 commit 329c8e2
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export { BooleanWidget } from './theme/Widgets/BooleanWidget';
export { DatetimeWidget } from './theme/Widgets/DatetimeWidget';
export { DateWidget } from './theme/Widgets/DateWidget';
export { EmailWidget } from './theme/Widgets/EmailWidget';
export { FileWidget } from './theme/Widgets/FileWidget';
export { ImageWidget } from './theme/Widgets/ImageWidget';
export { PasswordWidget } from './theme/Widgets/PasswordWidget';
export { RelationsWidget } from './theme/Widgets/RelationsWidget';
export { RelationWidget } from './theme/Widgets/RelationWidget';
Expand Down
39 changes: 39 additions & 0 deletions src/components/theme/Widgets/FileWidget.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import cx from 'classnames';
import { flattenToAppURL } from '@plone/volto/helpers';

const niceBytes = (bytes) => {
bytes = Number(bytes);

const divider = 1000;
const magnitude = (Math.log(bytes) / Math.log(divider)) | 0;
const result = bytes / Math.pow(divider, magnitude);
const fixed = result.toFixed(2);

const suffix = magnitude ? 'kMGTPEZY'[magnitude - 1] + 'B' : 'B';

return fixed + suffix;
};

export const FileWidget = ({ value, children, className }) => {
if (!value) {
return '';
}

const url = flattenToAppURL(value.download || value.filename || value);
const filename = value.filename || url;
const size = value.size || 0;
const ctype = value['content-type'] || '';
return (
<a
title={ctype || filename}
href={url}
className={cx(className, 'file', 'widget')}
data-size={size}
data-size-fmt={niceBytes(size)}
data-content-type={ctype}
>
{children ? children(filename) : filename}
</a>
);
};
45 changes: 45 additions & 0 deletions src/components/theme/Widgets/FileWidget.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { FileWidget } from './FileWidget';

describe('FileWidget', () => {
it('renders an empty file view widget component', () => {
const component = renderer.create(<FileWidget />);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders a simple file view widget component', () => {
const component = renderer.create(
<FileWidget className="metadata" value="/foo-bar.pdf" />,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders a file view widget component', () => {
const component = renderer.create(
<FileWidget className="metadata" value={{ download: '/foo-bar.pdf' }} />,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders a file view widget component with children', () => {
const component = renderer.create(
<FileWidget
className="metadata"
value={{
download: '/foo-bar.pdf',
filename: 'foo-bar.pdf',
'content-type': 'application/x-pdf',
size: 123456,
}}
>
{(child) => <strong>{child}</strong>}
</FileWidget>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});
});
31 changes: 31 additions & 0 deletions src/components/theme/Widgets/ImageWidget.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import cx from 'classnames';
import { flattenToAppURL } from '@plone/volto/helpers';

const niceBytes = (bytes) => {
bytes = Number(bytes);

const divider = 1000;
const magnitude = (Math.log(bytes) / Math.log(divider)) | 0;
const result = bytes / Math.pow(divider, magnitude);
const fixed = result.toFixed(2);

const suffix = magnitude ? 'kMGTPEZY'[magnitude - 1] + 'B' : 'B';

return fixed + suffix;
};

export const ImageWidget = ({ value, className }) =>
value ? (
<span className={cx(className, 'image', 'widget')}>
<img
src={flattenToAppURL(value.download)}
alt={value.file_name || ''}
data-size={value.size || 0}
data-size-fmt={niceBytes(value.size || 0)}
data-content-type={value['content-type'] || ''}
/>
</span>
) : (
''
);
35 changes: 35 additions & 0 deletions src/components/theme/Widgets/ImageWidget.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { ImageWidget } from './ImageWidget';

describe('ImageWidget', () => {
it('renders an empty image view widget component', () => {
const component = renderer.create(<ImageWidget />);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders an image view widget component', () => {
const component = renderer.create(
<ImageWidget className="metadata" value={{ download: '/foo-bar.png' }} />,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders an image view widget component with children', () => {
const component = renderer.create(
<ImageWidget
className="metadata"
value={{
download: '/foo-bar.png',
file_name: 'foo-bar.png',
}}
>
{(child) => <strong>{child}</strong>}
</ImageWidget>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});
});
44 changes: 44 additions & 0 deletions src/components/theme/Widgets/__snapshots__/FileWidget.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FileWidget renders a file view widget component 1`] = `
<a
className="metadata file widget"
data-content-type=""
data-size={0}
data-size-fmt="0.00B"
href="/foo-bar.pdf"
title="/foo-bar.pdf"
>
/foo-bar.pdf
</a>
`;

exports[`FileWidget renders a file view widget component with children 1`] = `
<a
className="metadata file widget"
data-content-type="application/x-pdf"
data-size={123456}
data-size-fmt="123.46kB"
href="/foo-bar.pdf"
title="application/x-pdf"
>
<strong>
foo-bar.pdf
</strong>
</a>
`;

exports[`FileWidget renders a simple file view widget component 1`] = `
<a
className="metadata file widget"
data-content-type=""
data-size={0}
data-size-fmt="0.00B"
href="/foo-bar.pdf"
title="/foo-bar.pdf"
>
/foo-bar.pdf
</a>
`;

exports[`FileWidget renders an empty file view widget component 1`] = `""`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ImageWidget renders an empty image view widget component 1`] = `""`;

exports[`ImageWidget renders an image view widget component 1`] = `
<span
className="metadata image widget"
>
<img
alt=""
data-content-type=""
data-size={0}
data-size-fmt="0.00B"
src="/foo-bar.png"
/>
</span>
`;

exports[`ImageWidget renders an image view widget component with children 1`] = `
<span
className="metadata image widget"
>
<img
alt="foo-bar.png"
data-content-type=""
data-size={0}
data-size-fmt="0.00B"
src="/foo-bar.png"
/>
</span>
`;
6 changes: 6 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { BooleanWidget } from './components';
import { DatetimeWidget } from './components';
import { DateWidget } from './components';
import { EmailWidget } from './components';
import { FileWidget } from './components';
import { getWidgetView } from './helpers';
import { ImageWidget } from './components';
import { PasswordWidget } from './components';
import { RelationsWidget } from './components';
import { RelationWidget } from './components';
Expand All @@ -21,6 +23,8 @@ const applyConfig = (config) => {
id: {
subjects: TokenWidget,
relatedItems: RelationsWidget,
image: ImageWidget,
file: FileWidget,
},
widget: {
array: ArrayWidget,
Expand All @@ -29,6 +33,8 @@ const applyConfig = (config) => {
date: DateWidget,
datetime: DatetimeWidget,
email: EmailWidget,
file: FileWidget,
image: ImageWidget,
password: PasswordWidget,
relation: RelationWidget,
relations: RelationsWidget,
Expand Down

0 comments on commit 329c8e2

Please sign in to comment.