Skip to content

Commit 0e57a09

Browse files
SaraVieiraCompuIves
authored andcommitted
add bulk delete and add to project to media (codesandbox#1468)
<!-- Is it a Bug fix, feature, docs update, ... --> **What kind of change does this PR introduce?** A feature, adds selections to media so you can add several to project at once and also delete several at once closes codesandbox#941 ![screenshot 2019-01-14 at 23 11 31](https://user-images.githubusercontent.com/1051509/51144626-dbc43f80-1851-11e9-9f91-c3df4f8a97f0.png)
1 parent 22b46fe commit 0e57a09

File tree

3 files changed

+169
-56
lines changed

3 files changed

+169
-56
lines changed

packages/app/src/app/pages/common/Modals/StorageManagementModal/FilesList/elements.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import styled from 'styled-components';
1+
import styled, { css } from 'styled-components';
22
import delayEffect from 'common/utils/animation/delay-effect';
33

44
export const HeaderTitle = styled.th`
@@ -8,6 +8,15 @@ export const HeaderTitle = styled.th`
88
color: rgba(255, 255, 255, 0.9);
99
`;
1010

11+
export const Buttons = styled.div`
12+
margin: 0.5rem 0;
13+
display: flex;
14+
15+
> *:not(:last-child) {
16+
margin-right: 0.5rem;
17+
}
18+
`;
19+
1120
export const Table = styled.table`
1221
${delayEffect(0.2)};
1322
width: 100%;
@@ -46,3 +55,27 @@ export const FileRow = styled.tr`
4655
color: rgba(255, 255, 255, 0.9);
4756
}
4857
`;
58+
59+
export const CheckBox = styled.span`
60+
${props =>
61+
props.selected
62+
? css`
63+
background: ${props.color} url('') no-repeat 50%/10px;
64+
background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 10 9' xmlns='http://www.w3.org/2000/svg'><path d='M1 4.88l2.378 2.435L9.046 1.6' stroke-width='1.6' stroke='%23FFF' fill='none' fill-rule='evenodd' stroke-linecap='round' stroke-linejoin='round'/></svg>");
65+
`
66+
: css`
67+
background: rgba(0, 0, 0, 0.3) url('') no-repeat 50%/10px;
68+
background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 10 9' xmlns='http://www.w3.org/2000/svg'><path fill='rgba(255, 255, 255, 0.2)/></svg>");
69+
`};
70+
border: 2px solid rgba(255, 255, 255, 0.5);
71+
margin-left: 1rem;
72+
box-shadow: none;
73+
display: inline-block;
74+
border-radius: 3.5px;
75+
width: 16px;
76+
height: 16px;
77+
outline: none;
78+
vertical-align: middle;
79+
transition: 0.15s ease all;
80+
cursor: pointer;
81+
`;
Lines changed: 127 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,135 @@
1-
import React from 'react';
1+
import React, { Component } from 'react';
22
import moment from 'moment';
3-
import { sortBy } from 'lodash-es';
3+
import { sortBy, isEmpty } from 'lodash-es';
44
import filesize from 'filesize';
5+
import Button from 'app/components/Button';
56
import DeleteFileButton from '../DeleteFileButton';
67
import AddFileToSandboxButton from '../AddFileToSandboxButton';
7-
import { HeaderTitle, Table, StatBody, Body, FileRow } from './elements';
8+
import {
9+
HeaderTitle,
10+
Table,
11+
StatBody,
12+
Body,
13+
FileRow,
14+
CheckBox,
15+
Buttons,
16+
} from './elements';
817

9-
function FilesList({ files, deleteFile, addFileToSandbox }) {
10-
return (
11-
<div css={{ margin: '0 2rem' }}>
12-
<Table>
13-
<thead>
14-
<tr style={{ height: '3rem' }}>
15-
<HeaderTitle>File</HeaderTitle>
16-
<HeaderTitle>Created</HeaderTitle>
17-
<HeaderTitle>Size</HeaderTitle>
18-
<HeaderTitle />
19-
<HeaderTitle />
20-
</tr>
21-
</thead>
22-
<Body>
23-
{sortBy(files, 'name').map((f, i) => (
24-
<FileRow index={i} key={f.id}>
25-
<td
26-
style={{
27-
maxWidth: 100,
28-
whiteSpace: 'nowrap',
29-
overflow: 'hidden',
30-
textOverflow: 'ellipsis',
31-
}}
32-
title={f.name}
33-
>
34-
<a target="_blank" rel="noreferrer noopener" href={f.url}>
35-
{f.name}
36-
</a>
37-
</td>
38-
<td>{moment(f.insertedAt).format('ll')}</td>
39-
<td>{filesize(f.objectSize)}</td>
40-
<StatBody
41-
style={{ padding: '0.55rem 0.5rem', cursor: 'pointer' }}
42-
>
43-
<AddFileToSandboxButton
44-
url={f.url}
45-
name={f.name}
46-
onAddFileToSandbox={addFileToSandbox}
47-
/>
48-
</StatBody>
49-
<StatBody
50-
style={{ padding: '0.55rem 0.5rem', cursor: 'pointer' }}
51-
>
52-
<DeleteFileButton id={f.id} onDelete={deleteFile} />
53-
</StatBody>
54-
</FileRow>
55-
))}
56-
</Body>
57-
</Table>
58-
</div>
59-
);
18+
const someSelected = obj =>
19+
Object.keys(obj).filter(key => obj[key] === true) && !isEmpty(obj);
20+
21+
class FilesList extends Component {
22+
state = {};
23+
24+
toggleCheckbox = (e, id) => {
25+
this.setState(state => ({
26+
[id]: !state[id],
27+
}));
28+
};
29+
30+
getSelection = () => {
31+
const selectedIds = Object.keys(this.state);
32+
const selected = this.props.files.filter(file =>
33+
selectedIds.includes(file.id)
34+
);
35+
return selected;
36+
};
37+
render() {
38+
const {
39+
files,
40+
deleteFile,
41+
addFileToSandbox,
42+
deleteFiles,
43+
addFilesToSandbox,
44+
} = this.props;
45+
return (
46+
<div css={{ margin: '0 2rem' }}>
47+
{someSelected(this.state) ? (
48+
<Buttons>
49+
<Button small onClick={() => deleteFiles(Object.keys(this.state))}>
50+
Delete all selected
51+
</Button>
52+
<Button
53+
small
54+
onClick={() => addFilesToSandbox(this.getSelection())}
55+
>
56+
Add all selected to project
57+
</Button>
58+
</Buttons>
59+
) : null}
60+
<Table>
61+
<thead>
62+
<tr
63+
css={`
64+
height: 3rem;
65+
`}
66+
>
67+
<HeaderTitle
68+
css={`
69+
padding-left: 1rem;
70+
max-width: 20px;
71+
`}
72+
/>
73+
<HeaderTitle>File</HeaderTitle>
74+
<HeaderTitle>Created</HeaderTitle>
75+
<HeaderTitle>Size</HeaderTitle>
76+
<HeaderTitle />
77+
<HeaderTitle />
78+
</tr>
79+
</thead>
80+
<Body>
81+
{sortBy(files, 'name').map((f, i) => (
82+
<FileRow index={i} key={f.id}>
83+
<td>
84+
<CheckBox
85+
name={f.id}
86+
onClick={e => this.toggleCheckbox(e, f.id)}
87+
selected={this.state[f.id]}
88+
/>
89+
</td>
90+
<td
91+
css={`
92+
max-width: 100;
93+
white-space: nowrap;
94+
overflow: hidden;
95+
text-overflow: ellipsis;
96+
`}
97+
title={f.name}
98+
>
99+
<a target="_blank" rel="noreferrer noopener" href={f.url}>
100+
{f.name}
101+
</a>
102+
</td>
103+
104+
<td>{moment(f.insertedAt).format('ll')}</td>
105+
<td>{filesize(f.objectSize)}</td>
106+
<StatBody
107+
css={`
108+
padding: 0.55rem 0.5rem;
109+
cursor: pointer;
110+
`}
111+
>
112+
<AddFileToSandboxButton
113+
url={f.url}
114+
name={f.name}
115+
onAddFileToSandbox={addFileToSandbox}
116+
/>
117+
</StatBody>
118+
<StatBody
119+
css={`
120+
padding: 0.55rem 0.5rem;
121+
cursor: pointer;
122+
`}
123+
>
124+
<DeleteFileButton id={f.id} onDelete={deleteFile} />
125+
</StatBody>
126+
</FileRow>
127+
))}
128+
</Body>
129+
</Table>
130+
</div>
131+
);
132+
}
60133
}
61134

62135
export default FilesList;

packages/app/src/app/pages/common/Modals/StorageManagementModal/index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ class StorageManagementModal extends React.Component {
2727
<Title>Storage Management</Title>
2828
<SubTitle>
2929
Used {filesize(store.usedStorage)}
30-
{' / '}Total {filesize(store.maxStorage)}
30+
{' / '}
31+
Total {filesize(store.maxStorage)}
3132
</SubTitle>
3233
</JustifiedArea>
3334
<Description>
@@ -39,6 +40,12 @@ class StorageManagementModal extends React.Component {
3940
<FilesList
4041
files={store.uploadedFiles}
4142
deleteFile={signals.files.deletedUploadedFile}
43+
deleteFiles={files =>
44+
files.map(id => signals.files.deletedUploadedFile({ id }))
45+
}
46+
addFilesToSandbox={files =>
47+
files.map(signals.files.addedFileToSandbox)
48+
}
4249
addFileToSandbox={signals.files.addedFileToSandbox}
4350
/>
4451
)}

0 commit comments

Comments
 (0)