0013176: Revision settings in fm dialog
authorMichael Spahn <m.spahn@metaways.de>
Fri, 2 Jun 2017 16:03:29 +0000 (18:03 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 14 Jun 2017 13:14:39 +0000 (15:14 +0200)
https://forge.tine20.org/view.php?id=13176

Change-Id: I4cac496a8eb8314a5c8f45cdef9169fa3d877939
Reviewed-on: http://gerrit.tine20.com/customers/4823
Tested-by: Jenkins CI (http://ci.tine20.com/)
Tested-by: sstamer <s.stamer@metaways.de>
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Filemanager/Controller/Node.php
tine20/Filemanager/Filemanager.jsb2
tine20/Filemanager/css/Filemanager.css
tine20/Filemanager/js/NodeEditDialog.js
tine20/Filemanager/js/RevisionPanel.js [new file with mode: 0644]
tine20/Tinebase/FileSystem.php

index c716083..edb3e7c 100644 (file)
@@ -169,6 +169,10 @@ class Filemanager_Controller_Node extends Tinebase_Controller_Record_Abstract
             }
         }
 
+        if (!Tinebase_Core::getUser()->hasGrant($_record, Tinebase_Model_Grants::GRANT_ADMIN, 'Tinebase_Model_Tree_Node')) {
+            $_record->{Tinebase_Model_Tree_Node::XPROPS_REVISION} = $_oldRecord->{Tinebase_Model_Tree_Node::XPROPS_REVISION};
+        }
+
         $nodePath = null;
         if (Tinebase_Model_Tree_FileObject::TYPE_FOLDER === $_record->type) {
             $nodePath = Tinebase_Model_Tree_Node_Path::createFromStatPath($this->_backend->getPathOfNode($_record->getId(), true));
index f0f8ee6..3b78f40 100644 (file)
         {
           "text": "NotificationGridPanel.js",
           "path": "js/"
+        },
+        {
+          "text": "RevisionPanel.js",
+          "path": "js/"
         }
       ]
     },
index bc06ad5..b05020f 100644 (file)
 
 .x-btn-large .action_publish {
     background-image: url("../../images/oxygen/32x32/apps/package-network.png");
+}
+
+.revision-checkbox-field .x-form-check-wrap {
+    display: inline;
+}
+
+.revision-checkbox-field input:last-child {
+    margin-left: 5px;
+}
+
+.revision-container {
+    margin-left: 20px;
 }
\ No newline at end of file
index 08063ea..d4c3620 100644 (file)
@@ -50,7 +50,7 @@ Tine.Filemanager.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
             text: this.app.i18n._('Save locally'),
             handler: this.onDownload,
             iconCls: 'action_filemanager_save_all',
-            disabled: false,
+            disabled: this.record.data.type === 'folder',
             scope: this
         });
         
@@ -85,7 +85,7 @@ Tine.Filemanager.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
     onDownload: function() {
         Tine.Filemanager.downloadFile(this.record);
     },
-    
+
     /**
      * returns dialog
      * @return {Object}
@@ -93,6 +93,8 @@ Tine.Filemanager.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
      */
     getFormItems: function() {
         var me = this,
+            _ = window.lodash,
+            fsConfig = Tine.Tinebase.configManager.get('filesystem'),
             formFieldDefaults = {
             xtype:'textfield',
             anchor: '100%',
@@ -120,6 +122,14 @@ Tine.Filemanager.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
             editDialog: this
         });
 
+        var revisionPanel = {};
+
+        if (_.get(fsConfig, 'modLogActive', false)) {
+            revisionPanel = new Tine.Filemanager.RevisionPanel({
+                editDialog: this
+            });
+        }
+
         return {
             xtype: 'tabpanel',
             border: false,
@@ -207,9 +217,7 @@ Tine.Filemanager.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
                                 }
                                 ]]
                         }]
-                    }
-                    
-                    ]
+                    }, revisionPanel]
                 }, {
                     // activities and tags
                     layout: 'accordion',
@@ -260,9 +268,8 @@ Tine.Filemanager.NodeEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
                 grantsPanel,
                 notificationPanel
             ]
-        };
+        }
     }
-    
 });
 
 /**
diff --git a/tine20/Filemanager/js/RevisionPanel.js b/tine20/Filemanager/js/RevisionPanel.js
new file mode 100644 (file)
index 0000000..2b61ea3
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Tine 2.0
+ *
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+Ext.ns('Tine.Filemanager');
+
+Tine.Filemanager.RevisionPanel = Ext.extend(Ext.form.FieldSet, {
+
+    editDialog: null,
+    app: null,
+
+    layout: 'hfit',
+
+    keep: null,
+
+    keepNum: null,
+    keepNumInput: null,
+
+    keepMonth: null,
+    keepMonthInput: null,
+
+    config: null,
+    readOnly: false,
+
+    initComponent: function () {
+        var _ = window.lodash;
+
+        this.config = Tine.Tinebase.configManager.get('filesystem');
+
+        this.app = this.app || Tine.Tinebase.appMgr.get('Filemanager');
+        this.title = this.title || this.app.i18n._('Revision');
+
+        this.editDialog.on('load', this.onRecordLoad, this);
+        this.editDialog.on('save', this.onSave, this);
+
+        var type = _.get(this.editDialog, 'record.data.type');
+        var adminGrant = _.get(this.editDialog, 'record.data.account_grants.adminGrant', false);
+
+        if (type !== 'folder' || !adminGrant) {
+            this.readOnly = true;
+        }
+
+        this.hasOwnRevisionSettings = new Ext.form.Checkbox({
+            checked: false,
+            disabled: this.readOnly,
+            boxLabel: this.app.i18n._('This folder has own revision settings'),
+            listeners: {scope: this, check: this.onOwnRevisionCheck}
+        });
+
+        this.items = [{
+            items: [this.hasOwnRevisionSettings, [{
+                xtype: 'container',
+                cls: 'revision-container',
+                margins: '0 20 0 0',
+                items: [{
+                    xtype: 'checkbox',
+                    boxLabel: this.app.i18n._('Revision active'),
+                    name: 'keep',
+                    columnWidth: 1,
+                    readOnly: false,
+                    disabled: false,
+                    ref: '../../keep',
+                    listeners: {scope: this, check: this.onKeepCheck}
+                }, {
+                    xtype: 'container',
+                    cls: 'revision-checkbox-field',
+                    items: [{
+                        xtype: 'checkbox',
+                        boxLabel: this.app.i18n._('Limit revision amount to'),
+                        name: 'keepNum',
+                        columnWidth: 1,
+                        readOnly: false,
+                        disabled: false,
+                        ref: '../../../keepNum',
+                        listeners: {scope: this, check: this.onKeepNumCheck}
+                    }, {
+                        xtype: 'numberfield',
+                        ref: '../../../keepNumInput'
+                    }]
+                }, {
+                    xtype: 'container',
+                    cls: 'revision-checkbox-field',
+                    items: [{
+                        xtype: 'checkbox',
+                        boxLabel: this.app.i18n._('Hold-back in months'),
+                        name: 'keepMonth',
+                        columnWidth: 1,
+                        readOnly: false,
+                        disabled: false,
+                        ref: '../../../keepMonth',
+                        listeners: {scope: this, check: this.onKeepMonthCheck}
+                    }, {
+                        xtype: 'numberfield',
+                        ref: '../../../keepMonthInput'
+                    }]
+                }]
+            }]]
+        }];
+
+        this.supr().initComponent.call(this);
+
+        this.manageFields();
+    },
+
+    onKeepCheck: function (cb, checked) {
+        this.manageFields();
+
+        if (false === checked) {
+            this.keepNum.setValue(false);
+            this.keepMonth.setValue(false);
+        }
+    },
+
+    onKeepNumCheck: function (cb, checked) {
+        this.manageFields();
+
+        if (false === checked) {
+            this.keepNumInput.setValue(null);
+        }
+    },
+
+    onKeepMonthCheck: function (cb, checked) {
+        this.manageFields();
+
+        if (false === checked) {
+            this.keepMonthInput.setValue(null);
+        }
+    },
+
+    manageFields: function () {
+        this.keep.setDisabled(this.readOnly || false === this.hasOwnRevisionSettings.getValue());
+
+        this.keepNum.setDisabled(this.keep.disabled || false === this.keep.getValue());
+        this.keepNumInput.setDisabled(this.keep.disabled || false === this.keep.getValue() || false === this.keepNum.getValue());
+
+        this.keepMonth.setDisabled(this.keep.disabled || false === this.keep.getValue());
+        this.keepMonthInput.setDisabled(this.keep.disabled || false === this.keep.getValue() || false === this.keepMonth.getValue());
+    },
+
+    onOwnRevisionCheck: function (cb, checked) {
+        this.manageFields();
+    },
+
+    onRecordLoad: function (editDialog, record, ticketFn) {
+        var _ = window.lodash;
+
+        this.hasOwnRevisionSettings.setValue(record.id === _.get(record, 'data.revisionProps.nodeId'));
+        this.keep.setValue(_.get(record, 'data.revisionProps.keep', _.get(this.config, 'modLogActive', false)));
+
+        if (_.get(record, 'data.revisionProps.keepNum', _.get(this.config, 'numKeepRevisions', false))) {
+            this.keepNum.setValue(true);
+            this.keepNumInput.setValue(_.get(record, 'data.revisionProps.keepNum', _.get(this.config, 'numKeepRevisions')));
+        }
+
+        if (_.get(record, 'data.revisionProps.keepMonth', _.get(this.config, 'monthKeepRevisions', false))) {
+            this.keepMonth.setValue(true);
+            this.keepMonthInput.setValue(_.get(record, 'data.revisionProps.keepMonth', _.get(this.config, 'monthKeepRevisions')));
+        }
+    },
+
+    onSave: function (editDialog, record, ticketFn) {
+        if (this.readOnly) {
+            return;
+        }
+
+        var _ = window.lodash;
+
+        // In case there is no own setting, we don't need to persist current values we just empty it
+        // When reloaded the server is supposed to send the correct inherited values
+        if (false === this.hasOwnRevisionSettings.getValue()) {
+            _.set(record, 'data.revisionProps', {});
+            return;
+        }
+
+        var data = {};
+
+        _.set(data, 'nodeId', record.id);
+        _.set(data, 'keep', this.keep.getValue());
+        _.set(data, 'keepNum', this.keepNumInput.getValue());
+        _.set(data, 'keepMonth', this.keepMonthInput.getValue());
+
+        _.set(record, 'data.revisionProps', data);
+    }
+});
\ No newline at end of file
index 493de80..3f1e5fc 100644 (file)
@@ -1025,21 +1025,19 @@ class Tinebase_FileSystem implements
                     }
                 }
 
-                if (Tinebase_Model_Tree_FileObject::TYPE_FOLDER === $node->type) {
-                    if ($node->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION) == $oldParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION) &&
-                        $node->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION) != $newParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION)
-                    ) {
-                        $node->{Tinebase_Model_Tree_Node::XPROPS_REVISION} = $newParent->{Tinebase_Model_Tree_Node::XPROPS_REVISION};
-                        $oldValue = $oldParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION);
-                        $newValue = $newParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION);
-                        $oldValue = count($oldValue) > 0 ? json_encode($oldValue) : null;
-                        $newValue = count($newValue) > 0 ? json_encode($newValue) : null;
-                        if (null === $newValue) {
-                            $node->{Tinebase_Model_Tree_Node::XPROPS_REVISION} = null;
-                        }
-                        // update revisionProps of subtree if changed
-                        $this->_recursiveInheritFolderPropertyUpdate($node, Tinebase_Model_Tree_Node::XPROPS_REVISION, $newValue, $oldValue, false);
+                if ($node->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION) == $oldParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION) &&
+                    $node->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION) != $newParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION)
+                ) {
+                    $node->{Tinebase_Model_Tree_Node::XPROPS_REVISION} = $newParent->{Tinebase_Model_Tree_Node::XPROPS_REVISION};
+                    $oldValue = $oldParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION);
+                    $newValue = $newParent->xprops(Tinebase_Model_Tree_Node::XPROPS_REVISION);
+                    $oldValue = count($oldValue) > 0 ? json_encode($oldValue) : null;
+                    $newValue = count($newValue) > 0 ? json_encode($newValue) : null;
+                    if (null === $newValue) {
+                        $node->{Tinebase_Model_Tree_Node::XPROPS_REVISION} = null;
                     }
+                    // update revisionProps of subtree if changed
+                    $this->_recursiveInheritPropertyUpdate($node, Tinebase_Model_Tree_Node::XPROPS_REVISION, $newValue, $oldValue, false);
                 }
 
                 $node->parent_id = $newParent->getId();
@@ -1726,7 +1724,7 @@ class Tinebase_FileSystem implements
                 $newValue = count($newValue) > 0 ? json_encode($newValue) : null;
 
                 // update revisionProps of subtree if changed
-                $this->_recursiveInheritFolderPropertyUpdate($_node, Tinebase_Model_Tree_Node::XPROPS_REVISION, $newValue, $oldValue, false);
+                $this->_recursiveInheritPropertyUpdate($_node, Tinebase_Model_Tree_Node::XPROPS_REVISION, $newValue, $oldValue, false);
             }
 
             $newNode = $this->_getTreeNodeBackend()->update($_node);