0013098: Password field
authorMichael Spahn <m.spahn@metaways.de>
Fri, 19 May 2017 10:10:07 +0000 (12:10 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Fri, 19 May 2017 15:04:12 +0000 (17:04 +0200)
https://forge.tine20.org/view.php?id=13098

Change-Id: Idb709182ac154ad63da36529cfd15f827d0654d9
Reviewed-on: http://gerrit.tine20.com/customers/4710
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Filemanager/js/nodeActions.js
tine20/Tinebase/Tinebase.jsb2
tine20/Tinebase/css/widgets/PasswordTriggerField.css [new file with mode: 0644]
tine20/Tinebase/js/widgets/dialog/PasswordDialog.js [new file with mode: 0644]
tine20/Tinebase/js/widgets/form/PasswordTriggerField.js [new file with mode: 0644]
tine20/Tinebase/js/widgets/form/UidTriggerField.js

index a984467..ee78688 100644 (file)
@@ -295,31 +295,33 @@ Tine.Filemanager.nodeActions.Publish = {
             return;
         }
 
-        Ext.MessageBox.prompt(app.i18n._('Publish'), app.i18n._('Add password protection for published data (empty password = no password)'), function(btn, password) {
-            if (btn == 'ok') {
-                var date = new Date();
-                date.setDate(date.getDate() + 30);
-
-                var record = new Tine.Filemanager.Model.DownloadLink({
-                    node_id: selections[0].id,
-                    expiry_time: date,
-                    password: password
-                });
-                Tine.Filemanager.downloadLinkRecordBackend.saveRecord(record, {
-                    success: function (record) {
-                        // TODO: add mail-button
-                        Ext.MessageBox.show({
-                            title: selections[0].data.type == 'folder' ? app.i18n._('Folder has been published successfully') : app.i18n._('File has been published successfully'),
-                            msg: String.format(app.i18n._("Url: {0}") + '<br />' + app.i18n._("Valid Until: {1}"), record.get('url'), record.get('expiry_time')),
-                            minWidth: 900,
-                            buttons: Ext.Msg.OK,
-                            icon: Ext.MessageBox.INFO,
-                        });
-                    }, failure: Tine.Tinebase.ExceptionHandler.handleRequestException, scope: this
-                });
-            }
+        var passwordDialog = new Tine.Tinebase.widgets.dialog.PasswordDialog({
+            allowEmptyPassword: true
+        });
+        passwordDialog.openWindow();
+
+        passwordDialog.on('passwordEntered', function (password) {
+            var date = new Date();
+            date.setDate(date.getDate() + 30);
+
+            var record = new Tine.Filemanager.Model.DownloadLink({
+                node_id: selections[0].id,
+                expiry_time: date,
+                password: password
+            });
+            Tine.Filemanager.downloadLinkRecordBackend.saveRecord(record, {
+                success: function (record) {
+                    // TODO: add mail-button
+                    Ext.MessageBox.show({
+                        title: selections[0].data.type == 'folder' ? app.i18n._('Folder has been published successfully') : app.i18n._('File has been published successfully'),
+                        msg: String.format(app.i18n._("Url: {0}") + '<br />' + app.i18n._("Valid Until: {1}"), record.get('url'), record.get('expiry_time')),
+                        minWidth: 900,
+                        buttons: Ext.Msg.OK,
+                        icon: Ext.MessageBox.INFO,
+                    });
+                }, failure: Tine.Tinebase.ExceptionHandler.handleRequestException, scope: this
+            });
         }, this);
-
     },
     actionUpdater: function(action, grants, records, isFilterSelect) {
         var enabled = !isFilterSelect
index 312497e..db1fa8e 100644 (file)
           "path": "js/widgets/form/"
         },
         {
+          "text": "PasswordTriggerField.js",
+          "path": "js/widgets/form/"
+        },
+        {
+          "text": "PasswordDialog.js",
+          "path": "js/widgets/dialog/"
+        },
+        {
           "text": "RecordForm.js",
           "path": "js/widgets/form/"
         },
           "path": "css/widgets/"
         },
         {
+          "text": "PasswordTriggerField.css",
+          "path": "css/widgets/"
+        },
+        {
           "text": "RecordPrinter.css",
           "path": "css/widgets/"
         },
diff --git a/tine20/Tinebase/css/widgets/PasswordTriggerField.css b/tine20/Tinebase/css/widgets/PasswordTriggerField.css
new file mode 100644 (file)
index 0000000..ebf4042
--- /dev/null
@@ -0,0 +1,7 @@
+.tw-passwordTriggerField .x-form-field-wrap .x-form-trigger {
+    background-image: url(../../../images/locked-lockCombo.gif);
+}
+
+.tw-passwordTriggerField .x-form-field-wrap .x-form-trigger.locked {
+    background-image: url(../../../images/unlocked-lockCombo.gif);
+}
\ No newline at end of file
diff --git a/tine20/Tinebase/js/widgets/dialog/PasswordDialog.js b/tine20/Tinebase/js/widgets/dialog/PasswordDialog.js
new file mode 100644 (file)
index 0000000..3a26108
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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.Tinebase.widgets.dialog');
+
+Tine.Tinebase.widgets.dialog.PasswordDialog = Ext.extend(Ext.Panel, {
+    layout: 'fit',
+    border: false,
+    frame: false,
+
+    /**
+     * ok button action held here
+     */
+    okAction: null,
+
+    /**
+     * Allow to proceed with an empty password
+     */
+    allowEmptyPassword: false,
+
+    /**
+     * Entered password
+     */
+    password: null,
+
+    /**
+     * Constructor.
+     */
+    initComponent: function () {
+        this.addEvents(
+            /**
+             * If the dialog will close and a password were choisen
+             * @param node
+             */
+            'passwordEntered'
+        );
+
+        this.items = [{
+            border: false,
+            frame: true,
+            layout: 'border',
+            items: [{
+                region: 'center',
+                xtype: 'columnform',
+                labelAlign: 'top',
+                formDefaults: {
+                    xtype: 'textfield',
+                    anchor: '100%',
+                    labelSeparator: '',
+                    columnWidth: .333
+                },
+                items: [
+                    [{
+                        columnWidth: 1,
+                        xtype: 'tw-passwordTriggerField',
+                        fieldLabel: i18n._('Password'),
+                        name: 'password',
+                        maxLength: 100,
+                        allowBlank: false,
+                        listeners: {
+                            scope: this,
+                            keyup: this.onChange.createDelegate(this)
+                        }
+                    }]
+                ]
+            }]
+        }];
+
+        var me = this;
+        this.okAction = new Ext.Action({
+            disabled: !this.allowEmptyPassword,
+            text: 'Ok',
+            iconCls: 'action_saveAndClose',
+            minWidth: 70,
+            handler: this.onOk.createDelegate(me),
+            scope: this
+        });
+
+        this.bbar = [
+            '->',
+            this.okAction
+        ];
+
+        Tine.Filemanager.FilePickerDialog.superclass.initComponent.call(this);
+    },
+
+    /**
+     * Disable ok button if no password entered
+     * @param el
+     */
+    onChange: function (el) {
+        this.password = el.getValue();
+        this.okAction.setDisabled(!this.allowEmptyPassword && el.getValue().length === 0)
+    },
+
+    /**
+     * button handler
+     */
+    onOk: function () {
+        this.fireEvent('passwordEntered', this.password);
+        this.window.close();
+    },
+
+    /**
+     * Creates a new pop up dialog/window (acc. configuration)
+     *
+     * @returns {null}
+     */
+    openWindow: function () {
+        this.window = Tine.WindowFactory.getWindow({
+            title: i18n._('Set password'),
+            closeAction: 'close',
+            modal: true,
+            width: 400,
+            height: 150,
+            layout: 'fit',
+            plain: true,
+            bodyStyle: 'padding:5px;',
+
+            items: [
+                this
+            ]
+        });
+
+        return this.window;
+    }
+});
\ No newline at end of file
diff --git a/tine20/Tinebase/js/widgets/form/PasswordTriggerField.js b/tine20/Tinebase/js/widgets/form/PasswordTriggerField.js
new file mode 100644 (file)
index 0000000..df61102
--- /dev/null
@@ -0,0 +1,41 @@
+/* 
+ * 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.Tinebase.widgets.form');
+
+/**
+ * Simple password field widget to allow toggling between text and password field
+ *
+ * @namespace   Tine.Tinebase.widgets.form
+ * @author      Michael Spahn <m.spahn@metaways.de>
+ * @class       Tine.Tinebase.widgets.form.PasswordTriggerField
+ * @extends     Ext.form.TriggerField
+ */
+Tine.Tinebase.widgets.form.PasswordTriggerField = Ext.extend(Ext.form.TriggerField, {
+    itemCls: 'tw-passwordTriggerField',
+    enableKeyEvents: true,
+
+    defaultAutoCreate: {tag: "input", type: "password", size: "16", autocomplete: "off"},
+
+    initTrigger: function () {
+        Tine.Tinebase.widgets.form.PasswordTriggerField.superclass.initTrigger.apply(this, arguments);
+        this.trigger.addClass('locked');
+    },
+
+    onTriggerClick: function () {
+        if (this.el.dom.type === 'text') {
+            this.el.dom.type = 'password';
+            this.trigger.addClass('locked');
+        } else {
+            this.el.dom.type = 'text';
+            this.trigger.removeClass('locked');
+        }
+    }
+});
+
+Ext.reg('tw-passwordTriggerField', Tine.Tinebase.widgets.form.PasswordTriggerField);
index 1748fc6..44f903d 100644 (file)
@@ -28,7 +28,9 @@ Tine.Tinebase.widgets.form.UidTriggerField = Ext.extend(Ext.form.TriggerField, {
      * Overrides initComponent to reenable field if it is empty
      */
     initComponent: function () {
-        this.on('keyup', this.manageTriggerField);
+        this.on('keyup', function() {
+            this.setHideTrigger(!!this.getValue())
+        }, this);
 
         Tine.Tinebase.widgets.form.UidTriggerField.superclass.initComponent.call(this);
     },