Skip to content

Commit

Permalink
Merge pull request silverstripe#339 from open-sausages/pulls/4.0/repl…
Browse files Browse the repository at this point in the history
…ace-file

File replacement action
  • Loading branch information
Damian Mooyman authored Dec 20, 2016
2 parents 802e604 + 2db9038 commit e1e82b9
Show file tree
Hide file tree
Showing 39 changed files with 2,019 additions and 643 deletions.
1,117 changes: 600 additions & 517 deletions client/dist/js/bundle.js

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions client/dist/styles/bundle.css
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,10 @@
content:"";
}

.asset-dropzone--button{
position:static;
}

.uploadfield__dropzone{
position:relative;
left:0;
Expand Down Expand Up @@ -685,6 +689,101 @@
content:"I";
}

.preview__container{
position:relative;
}

.preview__toolbar{
position:absolute;
top:50%;
right:0;
-webkit-transform:translateY(-50%);
transform:translateY(-50%);
height:auto;
max-height:100%;
border-bottom-left-radius:.25rem;
border-top-left-radius:.25rem;
overflow:hidden;
}

.preview__toolbar-button--link:before{
content:"=";
}

.preview__toolbar-button--replace:before{
content:"b";
}

.preview__toolbar-button--remove:before{
content:"D";
}

.preview__toolbar-button{
padding:11px 0;
height:47px;
width:47px;
overflow:hidden;
background:#000;
opacity:.55;
color:#fff;
border:0;
}

.preview__toolbar-button:active,.preview__toolbar-button:focus,.preview__toolbar-button:hover{
color:#b3b3b3;
text-decoration:none;
}

.preview__toolbar-button:before{
padding:0 11px;
font-family:silverstripe;
font-style:normal;
speak:none;
line-height:1;
font-size:25px;
height:25px;
width:25px;
vertical-align:middle;
}

.preview__progress{
height:18px;
width:75%;
position:absolute;
top:50%;
left:50%;
-webkit-transform:translateX(-50%) translateY(-50%);
transform:translateX(-50%) translateY(-50%);
border-radius:10px;
overflow:hidden;
background:#e6e6e6;
}

.preview__progress-bar{
height:100%;
background:#29abe2;
width:0;
}

.preview__message{
position:absolute;
bottom:0;
left:0;
right:0;
opacity:.8;
padding:1.5385rem;
}

.preview__message--error{
color:#fff;
background:#d40404;
}

.preview__message--success{
color:#fff;
background:#3fa142;
}

.gallery,.gallery__main,.gallery__outer{
position:relative;
}
Expand Down Expand Up @@ -1042,6 +1141,7 @@

@media (min-width:992px){
.editor{
box-sizing:content-box;
width:300px;
border-left:1px solid #d9dee2;
position:relative;
Expand Down Expand Up @@ -1343,5 +1443,6 @@
position:absolute;
top:0;
left:-.76925rem;
z-index:2;
}

1 change: 1 addition & 0 deletions client/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
"AssetAdmin.LOADMORE": "Load more",
"AssetAdmin.NOITEMSFOUND": "No items found",
"AssetAdmin.PROMPTFOLDERNAME": "Please enter a folder name (or blank to cancel)",
"AssetAdmin.REPlACE_FILE_SUCCESS": "Upload successful, the file will be replaced when you Save.",
"AssetAdmin.SAVE": "Save",
"AssetAdmin.SELECT": "Select",
"AssetAdmin.SIZE": "Size",
Expand Down
1 change: 1 addition & 0 deletions client/lang/src/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"AssetAdmin.LOADMORE": "Load more",
"AssetAdmin.NOITEMSFOUND": "No items found",
"AssetAdmin.PROMPTFOLDERNAME": "Please enter a folder name (or blank to cancel)",
"AssetAdmin.REPlACE_FILE_SUCCESS": "Upload successful, the file will be replaced when you Save.",
"AssetAdmin.SAVE": "Save",
"AssetAdmin.SELECT": "Select",
"AssetAdmin.SIZE": "Size",
Expand Down
5 changes: 4 additions & 1 deletion client/src/boot/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ import galleryReducer from 'state/gallery/GalleryReducer';
import queuedFilesReducer from 'state/queuedFiles/QueuedFilesReducer';
import AssetAdminRouter from 'containers/AssetAdmin/AssetAdminRouter';
import uploadFieldReducer from 'state/uploadField/UploadFieldReducer';
import previewFieldReducer from 'state/previewField/PreviewFieldReducer';
import Injector from 'lib/Injector';
import UploadField from 'components/UploadField/UploadField';
import PreviewImageField from 'components/PreviewImageField/PreviewImageField';
import HistoryList from 'containers/HistoryList/HistoryList';

document.addEventListener('DOMContentLoaded', () => {
Injector.register('UploadField', UploadField);
Injector.register('PreviewImageField', PreviewImageField);
Injector.register('HistoryList', HistoryList);

const sectionConfig = Config.getSection('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin');


reactRouteRegister.add({
path: sectionConfig.url,
component: AssetAdminRouter,
Expand Down Expand Up @@ -47,5 +49,6 @@ document.addEventListener('DOMContentLoaded', () => {
gallery: galleryReducer,
queuedFiles: queuedFilesReducer,
uploadField: uploadFieldReducer,
previewField: previewFieldReducer,
}));
});
63 changes: 47 additions & 16 deletions client/src/components/AssetDropzone/AssetDropzone.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import ReactDOM from 'react-dom';
import SilverStripeComponent from 'lib/SilverStripeComponent';
import i18n from 'i18n';
import DropzoneLib from 'dropzone';
import { fileSize } from 'lib/DataFormat';
import $ from 'jQuery';
import { getFileExtension } from 'lib/DataFormat';

let idCounter = 0;

Expand Down Expand Up @@ -51,6 +51,12 @@ class AssetDropzone extends SilverStripeComponent {
this.props.options
));

// attach the name as a class to the hidden input for easier identification
const name = this.props.name;
if (name) {
this.dropzone.hiddenFileInput.classList.add(`dz-input-${name}`);
}

// Set the user warning displayed when a user attempts to remove a file.
// If the props hasn't been passed there will be no warning when removing files.
if (typeof this.props.promptOnRemove !== 'undefined') {
Expand Down Expand Up @@ -266,8 +272,14 @@ class AssetDropzone extends SilverStripeComponent {
formData.append('SecurityID', this.props.securityID);
formData.append('ParentID', this.props.folderId);

const newXhr = Object.assign({}, xhr, {
abort: () => {
this.dropzone.cancelUpload(file);
xhr.abort();
},
});
if (typeof this.props.handleSending === 'function') {
this.props.handleSending(file, xhr, formData);
this.props.handleSending(file, newXhr, formData);
}
}

Expand All @@ -286,7 +298,24 @@ class AssetDropzone extends SilverStripeComponent {
* @param file (object) - File interface. See https://developer.mozilla.org/en-US/docs/Web/API/File
*/
handleAddedFile(file) {
if (this.props.options.maxFiles && this.dropzone.files.length > this.props.options.maxFiles) {
this.dropzone.removeFile(this.dropzone.files[0]);
if (typeof this.props.handleMaxFilesExceeded === 'function') {
// can add a warning message here
this.props.handleMaxFilesExceeded(file);
}
// shouldn't return error, as there isn't a way to catch it...
return Promise.resolve();
}

// check with parent if there are other forms of validation to be done
if (typeof this.props.canFileUpload === 'function' && !this.props.canFileUpload(file)) {
this.dropzone.removeFile(file);
return Promise.resolve();
}

if (!this.props.canUpload) {
this.dropzone.removeFile(file);
return Promise.reject(new Error(i18n._t('AssetAdmin.DROPZONE_CANNOT_UPLOAD')));
}

Expand Down Expand Up @@ -326,9 +355,9 @@ class AssetDropzone extends SilverStripeComponent {
category: this.getFileCategory(file.type),
filename: file.name,
queuedId: file._queuedId,
size: fileSize(file.size),
size: file.size,
title: this.getFileTitle(file.name),
extension: this.getFileExtension(file.name),
extension: getFileExtension(file.name),
type: file.type,
url: preview.thumbnailURL,
};
Expand All @@ -352,12 +381,6 @@ class AssetDropzone extends SilverStripeComponent {
.replace(/-_/, ' ');
}

getFileExtension(filename) {
return /[.]/.exec(filename)
? filename.replace(/^.+[.]/, '')
: '';
}

/**
* Returns a promise for loading an image to get the dataURL for previewing.
*
Expand Down Expand Up @@ -409,28 +432,34 @@ class AssetDropzone extends SilverStripeComponent {
/**
* Event handler for failed uploads.
*
* @param file (object) - File interface. See https://developer.mozilla.org/en-US/docs/Web/API/File
* @param errorMessage (string)
* @param {object} file - File interface. See https://developer.mozilla.org/en-US/docs/Web/API/File
* @param {string} message
*/
handleError(file, messages) {
handleError(file, message) {
// remove files list, as they are no longer needed
this.dropzone.removeFile(file);

if (typeof this.props.handleError === 'function') {
this.props.handleError(file, messages);
this.props.handleError(file, message);
}
}

/**
* Event handler for successfully upload files.
*
* @param object file - File interface. See https://developer.mozilla.org/en-US/docs/Web/API/File
* @param {object} file - File interface. See https://developer.mozilla.org/en-US/docs/Web/API/File
*/
handleSuccess(file) {
// remove files list, as they are no longer needed
this.dropzone.removeFile(file);

this.props.handleSuccess(file);
}

/**
* Set the text displayed when a user tries to remove a file.
*
* @param string userPrompt - The message to display.
* @param {string} userPrompt - The message to display.
*/
setPromptOnRemove(userPrompt) {
this.dropzone.options.dictRemoveFileConfirmation = userPrompt;
Expand All @@ -447,6 +476,8 @@ AssetDropzone.propTypes = {
handleError: React.PropTypes.func.isRequired,
handleSending: React.PropTypes.func,
handleSuccess: React.PropTypes.func.isRequired,
handleMaxFilesExceeded: React.PropTypes.func,
canFileUpload: React.PropTypes.func,
options: React.PropTypes.shape({
url: React.PropTypes.string.isRequired,
}),
Expand Down
4 changes: 4 additions & 0 deletions client/src/components/AssetDropzone/AssetDropzone.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@
}
}
}

.asset-dropzone--button {
position: static;
}
Loading

0 comments on commit e1e82b9

Please sign in to comment.