Skip to content

Commit 707cb68

Browse files
Merge pull request #13177 from rummatee/issue7629
Create Folders when moving files
2 parents 1fd6741 + 2cebdbb commit 707cb68

File tree

4 files changed

+151
-3
lines changed

4 files changed

+151
-3
lines changed

core/css/styles.scss

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,10 +701,9 @@ code {
701701
position: relative;
702702

703703
.dirtree {
704-
width: 100%;
705704
flex-wrap: wrap;
706705
padding-left: 12px;
707-
padding-right: 44px;
706+
padding-right: 0px;
708707
box-sizing: border-box;
709708

710709
div:first-child a {
@@ -746,6 +745,47 @@ code {
746745
#picker-showgridview:focus + #picker-view-toggle {
747746
opacity: 1;
748747
}
748+
749+
.actions.creatable {
750+
flex-wrap: wrap;
751+
padding: 0px;
752+
box-sizing: border-box;
753+
display: inline-flex;
754+
float: none;
755+
max-height: 36px;
756+
max-width: 36px;
757+
background-color: var(--color-background-dark);
758+
border: 1px solid var(--color-border-dark);
759+
border-radius: var(--border-radius-pill);
760+
position: absolute;
761+
top: 4px;
762+
763+
.icon.icon-add{
764+
background-image: var(--icon-add-000);
765+
background-size: 16px 16px;
766+
max-height:36px;
767+
width:36px;
768+
margin:0px;
769+
770+
}
771+
772+
a {
773+
width: 36px;
774+
padding: 0px;
775+
position: static;
776+
}
777+
778+
.menu {
779+
top:100%;
780+
margin:10px;
781+
margin-left: 0px;
782+
form {
783+
display:flex;
784+
margin:10px;
785+
}
786+
}
787+
788+
}
749789

750790
.filelist-container {
751791
box-sizing: border-box;

core/js/jquery.ocdialog.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
position: 'fixed'
3535
});
3636

37+
this.enterCallback = null;
38+
3739
$(document).on('keydown keyup', function(event) {
3840
if (
3941
event.target !== self.$dialog.get(0) &&
@@ -54,6 +56,11 @@
5456
// Enter
5557
if(event.keyCode === 13) {
5658
event.stopImmediatePropagation();
59+
if (self.enterCallback !== null) {
60+
self.enterCallback();
61+
event.preventDefault();
62+
return false;
63+
}
5764
if(event.type === 'keyup') {
5865
event.preventDefault();
5966
return false;
@@ -206,6 +213,12 @@
206213
widget: function() {
207214
return this.$dialog;
208215
},
216+
setEnterCallback: function(callback) {
217+
this.enterCallback = callback;
218+
},
219+
unsetEnterCallback: function() {
220+
this.enterCallback = null;
221+
},
209222
close: function() {
210223
this._destroyOverlay();
211224
var self = this;

core/js/oc-dialogs.js

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,16 @@ var OCdialogs = {
205205
}
206206

207207
var emptyText = t('core', 'No files in here');
208+
var newText = t('files', 'New folder');
208209
if (type === this.FILEPICKER_TYPE_COPY || type === this.FILEPICKER_TYPE_MOVE || type === this.FILEPICKER_TYPE_COPY_MOVE) {
209210
emptyText = t('core', 'No more subfolders in here');
210211
}
211212

212213
this.filepicker.loading = true;
213214
this.filepicker.filesClient = (OCA.Sharing && OCA.Sharing.PublicApp && OCA.Sharing.PublicApp.fileList)? OCA.Sharing.PublicApp.fileList.filesClient: OC.Files.getClient();
214215

216+
this.filelist = null;
217+
215218
$.when(this._getFilePickerTemplate()).then(function($tmpl) {
216219
self.filepicker.loading = false;
217220
var dialogName = 'oc-dialog-filepicker-content';
@@ -229,7 +232,8 @@ var OCdialogs = {
229232
self.$filePicker = $tmpl.octemplate({
230233
dialog_name: dialogName,
231234
title: title,
232-
emptytext: emptyText
235+
emptytext: emptyText,
236+
newtext: newText
233237
}).data('path', '').data('multiselect', multiselect).data('mimetype', mimetypeFilter);
234238

235239
if (modal === undefined) {
@@ -254,6 +258,86 @@ var OCdialogs = {
254258
self._getGridSettings();
255259
}
256260

261+
var newButton = self.$filePicker.find('.actions.creatable .button-add');
262+
newButton.on('focus', function() {
263+
self.$filePicker.ocdialog('setEnterCallback', function() {
264+
event.stopImmediatePropagation();
265+
event.preventDefault();
266+
newButton.click();
267+
});
268+
});
269+
newButton.on('blur', function() {
270+
self.$filePicker.ocdialog('unsetEnterCallback');
271+
});
272+
273+
OC.registerMenu(newButton,self.$filePicker.find('.menu'),function () {
274+
$input.focus();
275+
self.$filePicker.ocdialog('setEnterCallback', function() {
276+
event.stopImmediatePropagation();
277+
event.preventDefault();
278+
self.$form.submit();
279+
});
280+
var newName = $input.val();
281+
lastPos = newName.lastIndexOf('.');
282+
if (lastPos === -1) {
283+
lastPos = newName.length;
284+
}
285+
$input.selectRange(0, lastPos);
286+
});
287+
var $form = self.$filePicker.find('.filenameform');
288+
var $input = $form.find('input[type=\'text\']');
289+
var $submit = $form.find('input[type=\'submit\']');
290+
$submit.on('click',function(event) {
291+
event.stopImmediatePropagation();
292+
event.preventDefault();
293+
$form.submit();
294+
});
295+
296+
var checkInput = function () {
297+
var filename = $input.val();
298+
try {
299+
if (!Files.isFileNameValid(filename)) {
300+
// Files.isFileNameValid(filename) throws an exception itself
301+
} else if (self.filelist.find(function(file){return file.name === this;},filename)) {
302+
throw t('files', '{newName} already exists', {newName: filename}, undefined, {
303+
escape: false
304+
});
305+
} else {
306+
return true;
307+
}
308+
} catch (error) {
309+
$input.attr('title', error);
310+
$input.tooltip({placement: 'right', trigger: 'manual', 'container': '.newFolderMenu'});
311+
$input.tooltip('fixTitle');
312+
$input.tooltip('show');
313+
$input.addClass('error');
314+
}
315+
return false;
316+
};
317+
318+
$form.on('submit', function(event) {
319+
event.stopPropagation();
320+
event.preventDefault();
321+
322+
if (checkInput()) {
323+
var newname = $input.val();
324+
self.filepicker.filesClient.createDirectory(self.$filePicker.data('path') + "/" + newname).always(function (status) {
325+
self._fillFilePicker(self.$filePicker.data('path') + newname );
326+
});
327+
OC.hideMenus();
328+
self.$filePicker.ocdialog('unsetEnterCallback');
329+
self.$filePicker.click();
330+
$input.val(newText);
331+
}
332+
});
333+
$input.keypress(function(event) {
334+
if (event.keyCode === 13 || event.which === 13) {
335+
event.stopImmediatePropagation();
336+
event.preventDefault();
337+
$form.submit();
338+
}
339+
});
340+
257341
self.$filePicker.ready(function() {
258342
self.$fileListHeader = self.$filePicker.find('.filelist thead tr');
259343
self.$filelist = self.$filePicker.find('.filelist tbody');
@@ -912,6 +996,7 @@ var OCdialogs = {
912996
self.$fileListHeader.find('[data-sort=' + self.filepicker.sortField + '] .sort-indicator').addClass('icon-triangle-s');
913997
}
914998
self.filepicker.filesClient.getFolderContents(dir).then(function(status, files) {
999+
self.filelist = files;
9151000
if (filter && filter.length > 0 && filter.indexOf('*') === -1) {
9161001
files = files.filter(function (file) {
9171002
return file.type === 'dir' || filter.indexOf(file.mimetype) !== -1;

core/templates/filepicker.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<div id="{dialog_name}" title="{title}">
22
<span class="dirtree breadcrumb"></span>
3+
<span class="actions creatable"><a href="#" class="icon icon-add button button-add"></a>
4+
<nav class="menu popovermenu bubble menu-left newFolderMenu">
5+
<ul><li>
6+
<form class="filenameform">
7+
<input type="text" value={newtext}>
8+
<input class="icon-confirm" type="submit" value="">
9+
</form>
10+
</li></ul>
11+
</nav>
12+
</span>
313
<input type="checkbox" class="hidden-visually" id="picker-showgridview" checked="checked" />
414
<label id="picker-view-toggle" for="picker-showgridview" class="button icon-toggle-filelist"></label>
515
<div class="filelist-container">

0 commit comments

Comments
 (0)