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

Commit

Permalink
feature(Tinebase): allow creation of new files in filePicker
Browse files Browse the repository at this point in the history
Change-Id: I6fe6b7e44fc237623807fdca3858e24d8686b5e9
Reviewed-on: http://gerrit.tine20.com/customers/14727
Tested-by: Jenkins CI (http://ci.tine20.com/) <tine20-jenkins@metaways.de>
Reviewed-by: Cornelius Weiss <c.weiss@metaways.de>
  • Loading branch information
corneliusweiss committed Nov 22, 2019
1 parent aca4ece commit 0e0ec9d
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 6 deletions.
114 changes: 110 additions & 4 deletions tine20/Filemanager/js/FilePicker.js
Expand Up @@ -77,6 +77,24 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
*/
requiredGrants: ['readGrant'],

/**
* allow creation of new files
* @cfg {Boolean} allowCreateNew
*/
allowCreateNew: false,

/**
* initial fileName for new files
* @cfg {String} initialNewFileName
*/
initialNewFileName: '',

/**
* initial path
* @cfg {String} initialPath
*/
initialPath: null,

/**
* Constructor.
*/
Expand Down Expand Up @@ -127,12 +145,81 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
items: [
this.gridPanel
]
}, {
region: 'north',
border: false,
hidden: !this.allowCreateNew,
layout: 'vbox',
// height: 58,
height: 32,
items: [{
layout: 'form',
labelAlign: 'left',
frame: true,
items: {
xtype: 'textfield',
ref: '../../../fileNameField',
fieldLabel: 'Save as',
value: this.initialNewFileName,
width: 300,
enableKeyEvents: true,
validate: Ext.emptyFn,
listeners: {
keyup: this.onFileNameFieldChange.createDelegate(this),
focus: (field) => {
const value = String(field.getValue());
let end = null;
if (_.isRegExp(this.constraint)) {
const match = value.match(this.constraint);
if (match) {
end = match.index
}
}

field.focus();
field.selectText(0, end);
}
}
}
}/*, { // @TODO: must somehow cope with tree and grid selections...
xtype: 'toolbar',
items: [
this.gridPanel.action_createFolder
]
}*/],
}]
}];


Tine.Filemanager.FilePicker.superclass.initComponent.call(this);
},

afterRender: function() {
Tine.Filemanager.FilePicker.superclass.afterRender.call(this);
},

onFileNameFieldChange: function(field, e) {
this.gridPanel.selectionModel.clearSelections();

const basePath = _.get(this.treePanel.getSelectedContainer(), 'path')
const node = new Tine.Filemanager.Model.Node({
id: 'newFile',
type: 'file',
name: field.getValue(),
path: basePath + '/' + field.getValue()
});

if(basePath && this.checkConstraint([node])) {
field.clearInvalid();
this.selection = [node];
this.fireEvent('nodeSelected', this.selection);
} else {
field.markInvalid(_('Invalid Filename'));
this.selection = [];
this.fireEvent('invalidNodeSelected');
}
},

/**
* Updates selected element and triggers an event
*/
Expand All @@ -151,6 +238,10 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
me.selection.push(node.data || node);
});

if (this.allowCreateNew && this.selection.length) {
this.fileNameField.setValue(this.selection[0].name);
}

this.fireEvent('nodeSelected', this.selection);
},

Expand Down Expand Up @@ -192,18 +283,24 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {

var me = this;

let defaultFilters = this.initialPath ? [
{field: 'query', operator: 'contains', value: ''},
{field: 'path', operator: 'equals', value: this.initialPath}
] : null;

var gridPanel = new Tine.Filemanager.NodeGridPanel({
app: me.app,
height: 200,
width: 200,
border: false,
frame: false,
readOnly: true,
readOnly: !this.allowCreateNew,
enableDD: false,
enableDrag: false,
treePanel: this.getTreePanel(),
hasQuickSearchFilterToolbarPlugin: false,
stateIdSuffix: '-FilePicker',
defaultFilters: defaultFilters,
plugins: [this.getTreePanel().getFilterPlugin()]
});

Expand Down Expand Up @@ -280,16 +377,25 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
* checkes if user has requested grant for given node
*
* @param {Tine.Filemanager.Model.Node} node
* @param {Array} grant
* @param {Array} grants
* @return bool
*/
hasGrant: function(node, grants) {
var _ = window.lodash,
condition = true;

if (this.allowCreateNew) {
if (node.id === 'newFile') {
node = new Tine.Filemanager.Model.Node(this.treePanel.getSelectedContainer());
grants = ['addGrant'];
} else {
grants = ['editGrant'];
}
}

_.each(grants, function(grant) {
condition = condition && _.get(node, 'data.account_grants.' + grant, false);
if (grant == 'addGrant' && node.isVirtual()) {
if (grant === 'addGrant' && node.isVirtual()) {
condition = false;
}
});
Expand Down Expand Up @@ -326,7 +432,7 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
renderer: function (value, metadata, record) {

var app = Tine.Tinebase.appMgr.get('Filemanager');
if (record.data.type == 'folder') {
if (record.data.type === 'folder') {
return app.i18n._("Folder");
}
else {
Expand Down
23 changes: 22 additions & 1 deletion tine20/Filemanager/js/FilePickerDialog.js
Expand Up @@ -34,6 +34,24 @@ Tine.Filemanager.FilePickerDialog = Ext.extend(Tine.Tinebase.dialog.Dialog, {
*/
singleSelect: true,

/**
* allow creation of new files
* @cfg {Boolean} allowCreateNew
*/
allowCreateNew: false,

/**
* initial fileName for new files
* @cfg {String} initialNewFileName
*/
initialNewFileName: '',

/**
* initial path
* @cfg {String} initialPath
*/
initialPath: null,

/**
* A constraint allows to alter the selection behaviour of the picker, for example only allow to select files.
*
Expand Down Expand Up @@ -109,7 +127,10 @@ Tine.Filemanager.FilePickerDialog = Ext.extend(Tine.Tinebase.dialog.Dialog, {
var picker = new Tine.Filemanager.FilePicker({
requiredGrants: this.requiredGrants,
constraint: this.constraint,
singleSelect: this.singleSelect
singleSelect: this.singleSelect,
allowCreateNew: this.allowCreateNew,
initialNewFileName: this.initialNewFileName,
initialPath: this.initialPath
});

picker.on('nodeSelected', this.onNodesSelected.createDelegate(this));
Expand Down
12 changes: 11 additions & 1 deletion tine20/Filemanager/js/NodeGridPanel.js
Expand Up @@ -89,7 +89,7 @@ Tine.Filemanager.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {

this.gridConfig.cm = this.getColumnModel();

this.defaultFilters = [
this.defaultFilters = this.defaultFilters || [
{field: 'query', operator: 'contains', value: ''},
{field: 'path', operator: 'equals', value: Tine.Tinebase.container.getMyFileNodePath()}
];
Expand Down Expand Up @@ -988,6 +988,16 @@ Tine.Filemanager.NodeGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
}
},

/**
* gets currently displayed node in case a path filter is set
* NOTE: this data is unreloved as it comes from filter and not through json convert!
*
* @return {Object}
*/
getFilteredNode: function () {
return _.get(_.find(_.get(this, 'store.reader.jsonData.filter', {}), {field: 'path'}), 'value');
},

/**
* update grid nodeRecord with fileRecord data
*
Expand Down

0 comments on commit 0e0ec9d

Please sign in to comment.