Skip to content

Commit

Permalink
Merge branch 'pu/ccheng/filepicker_uploadbtn' into '2023.11'
Browse files Browse the repository at this point in the history
fix(Filemanager/js): allow filepicker create file in source mode

See merge request tine20/tine20!4497
  • Loading branch information
ccheng-dev committed Feb 27, 2024
2 parents 83c08ff + 3f92e7f commit c721d4c
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 65 deletions.
20 changes: 17 additions & 3 deletions tests/e2etests/src/test/Felamimail/message.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,26 @@ describe('message', () => {
const fileToUpload = 'src/test/Felamimail/attachment.txt';
await expect(popupWindow).toClick('.x-btn-text', {text: 'Datei hinzufügen'});
const filePickerWindow = await lib.getNewWindow();
await expect(filePickerWindow).toClick('span',{text: 'Mein Gerät'});
await filePickerWindow.waitForTimeout(2000); //musst wait for input!
await expect(filePickerWindow).toClick('span',{text: 'Meine Ordner', clickCount: 2});
await filePickerWindow.waitForTimeout(5000); //musst wait!
await expect(filePickerWindow).toClick('.x-grid3-cell-inner.x-grid3-col-name', {text: 'Persönliche Dateien von ' + process.env.TEST_USER, clickCount: 2});
await filePickerWindow.waitForTimeout(2000); //musst wait!
await filePickerWindow.waitForSelector('input[type=file]');
const inputUploadHandle = await filePickerWindow.$('input[type=file]');
await inputUploadHandle.uploadFile(fileToUpload);


await filePickerWindow.waitForTimeout(1000);
await expect(filePickerWindow).toClick('button', {text: 'Abbrechen'});

await expect(popupWindow).toClick('.x-btn-text', {text: 'Datei hinzufügen'});
const filePickerWindowNew = await lib.getNewWindow();
await expect(filePickerWindowNew).toClick('span',{text: 'Meine Ordner'});
await filePickerWindowNew.waitForTimeout(500);
await expect(filePickerWindowNew).toClick('.x-grid3-cell-inner.x-grid3-col-name', {text: 'Persönliche Dateien von ' + process.env.TEST_USER, clickCount: 2});
await filePickerWindowNew.waitForTimeout(1000);
await expect(filePickerWindowNew).toClick('.x-grid3-cell-inner.x-grid3-col-name', {text:'attachment.txt'});
await expect(filePickerWindowNew).toClick('button', {text: 'Ok'});

await popupWindow.waitForTimeout(2000);
await expect(popupWindow).toMatchElement('.x-grid3-cell-inner.x-grid3-col-name', {text:'attachment.txt'});
await popupWindow.waitForTimeout(2000); //musst wait for upload complete!
Expand Down
11 changes: 8 additions & 3 deletions tine20/Felamimail/js/MessageFileAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ Ext.extend(Tine.Felamimail.MessageFileAction, Ext.Action, {

showFileMenu: async function () {
this.initSplitButton();

const selection = _.map(this.initialConfig.selections, 'data');

if (!this.suggestionsLoaded || this.mode === 'fileInstant') {
Expand Down Expand Up @@ -256,8 +255,9 @@ Ext.extend(Tine.Felamimail.MessageFileAction, Ext.Action, {
},

loadSuggestions: async function (messages) {
if (this.isSuggestionLoading) return;
this.isSuggestionLoading = true;
const suggestionIds = [];

this.setIconClass('x-btn-wait');
this.menu.hide();
this.menu.removeAll();
Expand Down Expand Up @@ -309,11 +309,16 @@ Ext.extend(Tine.Felamimail.MessageFileAction, Ext.Action, {
}
});

if (suggestionIds.length > 0) {
this.menu.addItem('-');
}

this.addDefaultSentImapFolder();
this.addStaticMenuItems();
this.addDownloadMenuItem();

this.suggestionsLoaded = true;
this.isSuggestionLoading = false;
this.setIconClass('action_file');
});
},
Expand Down Expand Up @@ -361,7 +366,6 @@ Ext.extend(Tine.Felamimail.MessageFileAction, Ext.Action, {
},

addStaticMenuItems: function() {
this.menu.addItem('-');
this.menu.addItem({
text: this.app.i18n._('File (in Filemanager) ...'),
hidden: ! Tine.Tinebase.common.hasRight('run', 'Filemanager'),
Expand Down Expand Up @@ -519,6 +523,7 @@ Ext.extend(Tine.Felamimail.MessageFileAction, Ext.Action, {

selectFilemanagerFolder: function(item, e) {
const filePickerDialog = new Tine.Filemanager.FilePickerDialog({
mode: 'target',
constraint: 'folder',
singleSelect: true,
requiredGrants: ['addGrant']
Expand Down
105 changes: 56 additions & 49 deletions tine20/Filemanager/js/FilePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
}

this.allowCreateNewFile = this.mode === 'target' && this.constraint !== 'folder' && (this.fileName || this.files.length === 1);
this.allowManageExternalFile = this.mode === 'source' && this.constraint !== 'folder';

var model = Tine.Filemanager.Model.Node;
const model = Tine.Filemanager.Model.Node;
this.app = Tine.Tinebase.appMgr.get(model.getMeta('appName'));

this.treePanel = this.getTreePanel();
this.gridPanel = this.getGridPanel();

this.addEvents(
/**
* @event nodeSelected
Expand All @@ -111,7 +112,6 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
*/
'invalidNodeSelected'
);

this.items = [{
layout: 'border',
border: false,
Expand Down Expand Up @@ -149,7 +149,6 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
}, {
region: 'north',
border: false,
hidden: !this.allowCreateNewFile,
layout: 'hbox',
height: 38,
frame: true,
Expand All @@ -158,13 +157,65 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
border: false,
frame: true
},
items: [{
items: [
{
xtype: 'buttongroup',
buttonAlign: 'left',
ref: '../../../actionToolbar',
items: [
Ext.apply(this.createFolderButton = new Ext.Button(this.gridPanel.action_createFolder), {
handler: () => {
const currentPath = this.treePanel.getSelectedContainer()?.path;
if (! currentPath) return;
Ext.MessageBox.prompt(this.app.i18n._('New Folder'), this.app.i18n._('Please enter the name of the new folder:'), async function (btn, text) {
const nodeName = 'folder';
if (currentPath && btn === 'ok') {
if (!text) {
Ext.Msg.alert(String.format(this.app.i18n._('No {0} added'), nodeName), String.format(this.app.i18n._('You have to supply a {0} name!'), nodeName));
return;
}

if (!Tine.Filemanager.Model.Node.isNameValid(text)) {
Ext.Msg.alert(String.format(this.app.i18n._('No {0} added'), nodeName), this.app.i18n._('Illegal characters: ') + text);
return;
}

const filename = `${currentPath}${text}/`;
await Tine.Filemanager.nodeBackend.createFolder(filename)
.then((result) => {
// messageBus does the trick!
})
.catch((e) => {
if (e.message === "file exists") {
Ext.Msg.alert(String.format(this.app.i18n._('No {0} added'), nodeName), this.app.i18n._('Folder with this name already exists!'));
}
});
}
}, this);
}
}),
Ext.apply(new Ext.Button(this.gridPanel.action_file_upload),{
hidden: !this.allowManageExternalFile,
}),
[{
hidden: !this.allowManageExternalFile,
xtype: 'buttongroup',
items: [],
plugins: [{
ptype: 'ux.itemregistry',
key: 'Filemanager-FilePicker-ActionToolbar-leftbtngrp'
}],
}]
]
},
{
flex: 1,
}, {
layout: 'form',
labelAlign: 'left',
width: 450,
frame: true,
hidden: !this.allowCreateNewFile,
items: {
xtype: 'textfield',
ref: '../../../fileNameField',
Expand Down Expand Up @@ -201,55 +252,11 @@ Tine.Filemanager.FilePicker = Ext.extend(Ext.Container, {
}]
}]
}];
this.on('show', () => {
if (_.get(this, 'createFolderButton.setHidden')) {
this.createFolderButton.setHidden(!this.allowCreateNewFile);
}
});
this.on('hide', () => {
if (_.get(this, 'createFolderButton.setHidden')) {
this.createFolderButton?.setHidden(true);
}
});

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

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

const editDialog = this.findParentBy((c) => {return c instanceof Tine.Tinebase.dialog.Dialog});
editDialog.fbar.insert(0, this.createFolderButton = new Ext.Button(Object.assign({... Tine.Filemanager.nodeActions.CreateFolder}, {
hidden: this.hidden || !this.allowCreateNewFile, // @TODO hide if other plugin is active!
handler: () => {
const currentPath = this.treePanel.getSelectedContainer()?.path;
if (! currentPath) return;
Ext.MessageBox.prompt(this.app.i18n._('New Folder'), this.app.i18n._('Please enter the name of the new folder:'), async function (btn, text) {
if (currentPath && btn === 'ok') {
if (!text) {
Ext.Msg.alert(String.format(this.app.i18n._('No {0} added'), nodeName), String.format(this.app.i18n._('You have to supply a {0} name!'), nodeName));
return;
}

if (!Tine.Filemanager.Model.Node.isNameValid(text)) {
Ext.Msg.alert(String.format(this.app.i18n._('No {0} added'), nodeName), this.app.i18n._('Illegal characters: ') + forbidden);
return;
}

const filename = `${currentPath}${text}/`;
await Tine.Filemanager.nodeBackend.createFolder(filename)
.then((result) => {
// messageBus does the trick!
})
.catch((e) => {
if (e.message === "file exists") {
Ext.Msg.alert(String.format(this.app.i18n._('No {0} added'), nodeName), this.app.i18n._('Folder with this name already exists!'));
}
});
}
}, this);
}
})));
},

checkState: function() {
Expand Down
1 change: 1 addition & 0 deletions tine20/Filemanager/js/nodeActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ Tine.Filemanager.nodeActions.Move = {
var filePickerDialog = new Tine.Filemanager.FilePickerDialog({
windowTitle: app.i18n._('Move Items'),
singleSelect: true,
mode: 'target',
constraint: (targetNode) => {
return Tine.Filemanager.nodeActionsMgr.checkConstraints('move', targetNode, records);
}
Expand Down
3 changes: 3 additions & 0 deletions tine20/Filemanager/translations/de.po
Original file line number Diff line number Diff line change
Expand Up @@ -986,3 +986,6 @@ msgstr "Gemeinsame Dateimanager-Favoriten verwalten"

msgid "Create or update shared filemanager favorites'"
msgstr "Gemeinsame Dateimanager-Favoriten erstellen oder bearbeiten"

msgid "Attachments: Anyone who has access to the record can see the data"
msgstr "Anhänge: Jeder der Zugriff auf Datensatz hat kann daten sehen"
11 changes: 7 additions & 4 deletions tine20/OnlyOfficeIntegrator/js/createDocumentAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Promise.all([
actionUpdater: function(action, grants, records, isFilterSelect, filteredContainers) {
const recordData = _.get(filteredContainers, '[0]');
const isAttachment = _.get(recordData, 'container_id.account_grants', false);

// hack for attachments where grants are not evaluated
let enabled = _.get(action, 'isUploadGrid', false);
if (isAttachment) {
Expand All @@ -72,7 +72,8 @@ Promise.all([
// filemanager -> path
const fileManagerCreateDocumentAction = new Ext.Action(Ext.applyIf({
getPath: async function (baseAction, type) {
return _.get(baseAction, 'filteredContainers[0].path');
const action = baseAction.initialConfig;
return _.get(baseAction, 'filteredContainers[0].path') || _.get(action, 'filteredContainers[0].path');
},
getName: async function (baseAction, type) {
return new Promise((resolve) => {
Expand Down Expand Up @@ -115,8 +116,10 @@ Promise.all([
rowspan: 2,
iconAlign: 'top'
}), 2);



// file picker
Ext.ux.ItemRegistry.registerItem('Filemanager-FilePicker-ActionToolbar-leftbtngrp', fileManagerCreateDocumentAction, 20);

// upload grids -> tempFile
const uploadGridCreateDocumentAction = new Ext.Action(Ext.applyIf({
isUploadGrid: true,
Expand Down
5 changes: 4 additions & 1 deletion tine20/OnlyOfficeIntegrator/js/editDocumentAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ Promise.all([

// preview panel
Ext.ux.ItemRegistry.registerItem('Tine-Filemanager-QuicklookPanel', editDocumentAction, 100);


// file picker
Ext.ux.ItemRegistry.registerItem('Filemanager-FilePicker-ActionToolbar-leftbtngrp', editDocumentAction, 30);

// dblclick actions
Tine.on('filesystem.fileDoubleClick', (fileNode, dblClickHandlers) => {
const dbClickPreference = Tine.Tinebase.registry.get('preferences').get('fileDblClickAction');
Expand Down
4 changes: 3 additions & 1 deletion tine20/Tinebase/js/widgets/ActionUpdater.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@
action.initialConfig.selections = records;
action.initialConfig.isFilterSelect = isFilterSelect;
action.initialConfig.selectionModel = selectionModel;

if (container) {
action.initialConfig.filteredContainers = container;
}
}, this);

},
Expand Down
27 changes: 23 additions & 4 deletions tine20/Tinebase/js/widgets/relation/GenericPickerGridPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,19 @@ Tine.widgets.relation.GenericPickerGridPanel = Ext.extend(Tine.widgets.grid.Pick
* creates the toolbar
*/
initTbar: function() {
var items = [this.getModelCombo(), ' '];
let items = [this.getModelCombo(), ' '];
items = items.concat(this.createSearchCombos());

this.tbar = new Ext.Toolbar({
items: items
this.descriptionField = new Ext.form.Label({
text: '',
});
this.tbar = new Ext.Panel({
layout: 'fit',
items: [
this.descriptionField,
new Ext.Toolbar({
items: items
})
]
});
},

Expand Down Expand Up @@ -525,6 +533,17 @@ Tine.widgets.relation.GenericPickerGridPanel = Ext.extend(Tine.widgets.grid.Pick
* @param {Number} index the selection index
*/
onModelComboSelect: function(combo, selected, index) {
if (selected.get('appName') === 'Filemanager') {
const app = Tine.Tinebase.appMgr.get('Filemanager');
const description = app.i18n._("Attachments: Anyone who has access to the record can see the data");
const link = app.i18n._("Links: Rights of the respective application are respected");
const el = document.createElement('div');
el.innerHTML = description;
el.style.padding = '5px';

this.descriptionField.show();
this.descriptionField.update(el.outerHTML);
}
this.showSearchCombo(selected.get('appName'), selected.get('modelName'));
},

Expand Down

0 comments on commit c721d4c

Please sign in to comment.