Skip to content

Commit

Permalink
Merge pull request #77 from schulcloud/246-download-delete-copy-files
Browse files Browse the repository at this point in the history
246 download and delete files
  • Loading branch information
Langleu authored Feb 2, 2017
2 parents edd222d + a2c23ac commit 8d3be8e
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Permissions, Server, Notification } from '../../core/helpers/';

class s3Service {
class FileService {
constructor() {}

getUrl(fileName, fileType, storageContext) {
getUrl(fileName, fileType, storageContext, action) {
const s3SignedUrl = Server.service('/fileStorage/signedUrl');

var data = {
storageContext: storageContext,
fileName: fileName,
fileType: fileType
fileType: fileType,
action: action
};

return s3SignedUrl.create(data)
Expand All @@ -23,7 +24,6 @@ class s3Service {

getFileList(storageContext) {
const fileStorageService = Server.service('/fileStorage');
const currentUser = Server.get('user');
return fileStorageService.find({
query: {
storageContext: storageContext
Expand All @@ -34,6 +34,16 @@ class s3Service {
Notification.showError(err.message);
});
}

deleteFile(storageContext, fileName) {
const fileStorageService = Server.service('/fileStorage');
return fileStorageService.remove(null, {
query: {
storageContext: storageContext,
fileName: fileName
}
});
}
}

export default new s3Service();
export default new FileService();
8 changes: 5 additions & 3 deletions src/modules/core/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import Permissions from './permissions';
import Server from './server';
import Notification from './notification';
import LTICustomer from './ltiCustomer';
import s3Service from './s3Service';
import FileService from './fileService';
import Form from './form';
import RandomIdGenerator from './randomIdGenerator';

export {
App,
Expand All @@ -14,6 +15,7 @@ export {
Server,
Notification,
LTICustomer,
s3Service,
Form
FileService,
Form,
RandomIdGenerator
};
13 changes: 13 additions & 0 deletions src/modules/core/helpers/randomIdGenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class RandomIdGenerator {
generateRandomId() {
const s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};

return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
}
export default new RandomIdGenerator();
46 changes: 43 additions & 3 deletions src/modules/file-explorer/actions/file-explorer.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import axios from 'axios';
import {s3Service} from '../../core/helpers';
import { Permissions, Server } from '../../core/helpers/';
import {FileService} from '../../core/helpers';
import {Permissions, Server, Notification} from '../../core/helpers/';

const saveFile = (url, fileName) => {
var options = {
responseType: 'blob'
};

axios.get(url, options).then(res => {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(res.data);
a.download = fileName;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
});
};

export default {
upload: (files) => {
const currentUser = Server.get('user');
Promise.all(files.map((file) => {
return s3Service.getUrl(file.name, file.type, `users/${currentUser._id}`)
return FileService.getUrl(file.name, file.type, `users/${currentUser._id}`, 'putObject')
.then((signedUrl) => {
var options = {
headers: signedUrl.header
Expand All @@ -16,5 +31,30 @@ export default {
})).then(res => {
window.location.reload();
});
},

download: (file) => {
const currentUser = Server.get('user');
return FileService.getUrl(file.name, null, `users/${currentUser._id}`, 'getObject')
.then((signedUrl) => {
if (!signedUrl.url) {
Notification.showError("Beim Downloaden der Datei ist etwas schief gelaufen!");
return;
}

saveFile(signedUrl.url, file.name);
}).catch(err => {
Notification.showError(err.message);
});
},

delete: (file) => {
const currentUser = Server.get('user');
return FileService.deleteFile(`users/${currentUser._id}`, file.name, null)
.then((res) => {
window.location.reload();
}).catch(err => {
Notification.showError(err.message);
});
}
};
70 changes: 55 additions & 15 deletions src/modules/file-explorer/components/files.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,71 @@ class Files extends React.Component {

constructor(props) {
super(props);
}

this.state = {};
handleOnDownloadClick(file) {
this.props.actions.download(file);
}

getFilesUI() {
handleOnDeleteClick(file) {
this.props.actions.delete(file);
}

getFileDeleteModalUI(file) {
return (
<div className="modal fade" id={`deleteFileModal${file.id}`} role="dialog" aria-labelledby="myModalLabel">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 className="modal-title" id="myModalLabel">Datei löschen</h4>
</div>
<div className="modal-body">
<p>Möchtest du die Datei wirklich löschen?</p>
<span>
<button type="button" className="btn btn-default" data-dismiss="modal" aria-label="Close">
Abbrechen
</button>
<button onClick={this.handleOnDeleteClick.bind(this, file)} type="button" className="btn btn-primary" data-dismiss="modal" aria-label="Close">
Löschen
</button>
</span>
</div>
</div>
</div>
</div>
);
}

getFileUI(file) {
return (
<div>
{this.props.files.map((file) => {
return (
<div className="col-sm-6 col-xs-12 col-md-4" key={file.name}>
<div className="card file">
<div className="container-fluid">
<div className="row">
<div className="col-sm-6 col-xs-12 col-md-4" key={`file${file.id}`}>
<div className="card file">
<div className="card-block">
<div className="card-title">
<div className="col-sm-3 no-padding">
<div className="file-preview" style={{'background-image': 'url(' + file.thumbnail + ')'}}></div>
</div>
<div className="col-sm-9">
<strong>{file.name}</strong>
</div>
<large>{file.name}</large>
</div>
<div className="card-text">
<i className="fa fa-cloud-download" aria-hidden="true" onClick={this.handleOnDownloadClick.bind(this, file)}/>
<i className="fa fa-trash-o" aria-hidden="true" data-toggle="modal" data-target={`#deleteFileModal${file.id}`}/>
</div>
</div>
</div>
</div>
);
})}
{ this.getFileDeleteModalUI(file) }
</div>
);
}

getFilesUI() {
return (
<div>
{this.props.files.map((file) => {
return this.getFileUI(file);
})}
</div>
);
}
Expand Down
26 changes: 16 additions & 10 deletions src/modules/file-explorer/containers/file-explorer.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import {render} from 'react-dom';
import {compose} from 'react-komposer';
import { s3Service } from '../../core/helpers';
import { Permissions, Server, Notification } from '../../core/helpers/';
import { FileService } from '../../core/helpers';
import { Permissions, Server, Notification, RandomIdGenerator } from '../../core/helpers/';

import component from '../components/file-explorer';
import actions from '../actions/file-explorer';

const composer = (props, onData) => {
const currentUser = Server.get('user');
s3Service.getFileList(`users/${currentUser._id}`)
FileService.getFileList(`users/${currentUser._id}`)
.then(res => {
let componentData = {
actions,
files: res
};
onData(null, componentData);
}).catch(err => {
Notification.showError(err.message);
let componentData = {actions, files: []};

// if the storage provider does not return any files, there's no empty array but an ugly error message
if( Object.prototype.toString.call( res ) === '[object Array]' ) {
componentData.files = res;
componentData.files.forEach(f => f.id = RandomIdGenerator.generateRandomId());
} else {
Notification.showError("Deine Schule hat bislang noch keine Dateiverwaltung ausgewählt");
}

onData(null, componentData);
}).catch(err => {
Notification.showError(err);
});
};

Expand Down
34 changes: 19 additions & 15 deletions src/modules/file-explorer/styles/files.scss
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
@import '../../core/styles/colors.scss';

.files {
width:100%;
float:left;
margin-bottom:40px;
width: 100%;
float: left;
margin-bottom: 40px;

h5 {
color: $colorHPIRed;
padding:10px 0px 20px;
padding: 10px 0px 20px;
}

.card.file {
box-shadow: 0px 1px 2px rgba(0,0,0,0.1);
height:65px;
line-height:63px;
.modal-body {
button {
margin-left: 5px;
}
}

.card.file {
&:hover {
box-shadow: 0px 1px 4px rgba(0,0,0,0.2);
background:#f9f9f9;
cursor: pointer;
background: #f9f9f9;
}

.file-preview {
width:90%;
height:65px;
float:left;
width: 90%;
height: 65px;
float: left;
background: no-repeat center center;
background-size:cover;
background-size: cover;
}

.fa {
margin-right:15px;
margin-right: 15px;
color:#ccc;
&:hover {
cursor: pointer;
}
}
}
}
1 change: 1 addition & 0 deletions src/modules/file-explorer/styles/upload.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
width:100%;
float:left;
padding:40px 0px;
cursor: pointer;

.drop-zone {
width:100%;
Expand Down

0 comments on commit 8d3be8e

Please sign in to comment.