diff options
Diffstat (limited to 'apps/files_external/js')
-rw-r--r-- | apps/files_external/js/app.js | 112 | ||||
-rw-r--r-- | apps/files_external/js/mountsfilelist.js | 149 | ||||
-rw-r--r-- | apps/files_external/js/oauth1.js | 82 | ||||
-rw-r--r-- | apps/files_external/js/oauth2.js | 5 | ||||
-rw-r--r-- | apps/files_external/js/public_key.js | 5 | ||||
-rw-r--r-- | apps/files_external/js/rollingqueue.js | 137 | ||||
-rw-r--r-- | apps/files_external/js/settings.js | 1513 | ||||
-rw-r--r-- | apps/files_external/js/statusmanager.js | 613 |
8 files changed, 10 insertions, 2606 deletions
diff --git a/apps/files_external/js/app.js b/apps/files_external/js/app.js deleted file mode 100644 index 4f91e2e78b0..00000000000 --- a/apps/files_external/js/app.js +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com> - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -if (!OCA.Files_External) { - /** - * @namespace - */ - OCA.Files_External = {}; -} -/** - * @namespace - */ -OCA.Files_External.App = { - - fileList: null, - - initList: function($el) { - if (this.fileList) { - return this.fileList; - } - - this.fileList = new OCA.Files_External.FileList( - $el, - { - fileActions: this._createFileActions() - } - ); - - this._extendFileList(this.fileList); - this.fileList.appName = t('files_external', 'External storage'); - return this.fileList; - }, - - removeList: function() { - if (this.fileList) { - this.fileList.$fileList.empty(); - } - }, - - _createFileActions: function() { - // inherit file actions from the files app - var fileActions = new OCA.Files.FileActions(); - fileActions.registerDefaultActions(); - - // when the user clicks on a folder, redirect to the corresponding - // folder in the files app instead of opening it directly - fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) { - OCA.Files.App.setActiveView('files', {silent: true}); - OCA.Files.App.fileList.changeDirectory(OC.joinPaths(context.$file.attr('data-path'), filename), true, true); - }); - fileActions.setDefault('dir', 'Open'); - return fileActions; - }, - - _extendFileList: function(fileList) { - // remove size column from summary - fileList.fileSummary.$el.find('.filesize').remove(); - } -}; - -window.addEventListener('DOMContentLoaded', function() { - $('#app-content-extstoragemounts').on('show', function(e) { - OCA.Files_External.App.initList($(e.target)); - }); - $('#app-content-extstoragemounts').on('hide', function() { - OCA.Files_External.App.removeList(); - }); - - /* Status Manager */ - if ($('#filesApp').val()) { - - $('#app-content-files') - .add('#app-content-extstoragemounts') - .on('changeDirectory', function(e){ - if (e.dir === '/') { - var mount_point = e.previousDir.split('/', 2)[1]; - // Every time that we return to / root folder from a mountpoint, mount_point status is rechecked - OCA.Files_External.StatusManager.getMountPointList(function() { - OCA.Files_External.StatusManager.recheckConnectivityForMount([mount_point], true); - }); - } - }) - .on('fileActionsReady', function(e){ - if ($.isArray(e.$files)) { - if (OCA.Files_External.StatusManager.mountStatus === null || - OCA.Files_External.StatusManager.mountPointList === null || - _.size(OCA.Files_External.StatusManager.mountStatus) !== _.size(OCA.Files_External.StatusManager.mountPointList)) { - // Will be the very first check when the files view will be loaded - OCA.Files_External.StatusManager.launchFullConnectivityCheckOneByOne(); - } else { - // When we change between general files view and external files view - OCA.Files_External.StatusManager.getMountPointList(function(){ - var fileNames = []; - $.each(e.$files, function(key, value){ - fileNames.push(value.attr('data-file')); - }); - // Recheck if launched but work from cache - OCA.Files_External.StatusManager.recheckConnectivityForMount(fileNames, false); - }); - } - } - }); - } - /* End Status Manager */ -}); diff --git a/apps/files_external/js/mountsfilelist.js b/apps/files_external/js/mountsfilelist.js deleted file mode 100644 index 3b88ec070db..00000000000 --- a/apps/files_external/js/mountsfilelist.js +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com> - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ -(function() { - - /** - * @class OCA.Files_External.FileList - * @augments OCA.Files.FileList - * - * @classdesc External storage file list. - * - * Displays a list of mount points visible - * for the current user. - * - * @param $el container element with existing markup for the .files-controls - * and a table - * @param [options] map of options, see other parameters - **/ - var FileList = function($el, options) { - this.initialize($el, options); - }; - - FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, - /** @lends OCA.Files_External.FileList.prototype */ { - appName: 'External storage', - - _allowSelection: false, - - /** - * @private - */ - initialize: function($el, options) { - OCA.Files.FileList.prototype.initialize.apply(this, arguments); - if (this.initialized) { - return; - } - }, - - /** - * @param {OCA.Files_External.MountPointInfo} fileData - */ - _createRow: function(fileData) { - // TODO: hook earlier and render the whole row here - var $tr = OCA.Files.FileList.prototype._createRow.apply(this, arguments); - var $scopeColumn = $('<td class="column-scope column-last"><span></span></td>'); - var $backendColumn = $('<td class="column-backend"></td>'); - var scopeText = t('files_external', 'Personal'); - if (fileData.scope === 'system') { - scopeText = t('files_external', 'System'); - } - $tr.find('.filesize,.date').remove(); - $scopeColumn.find('span').text(scopeText); - $backendColumn.text(fileData.backend); - $tr.find('td.filename').after($scopeColumn).after($backendColumn); - return $tr; - }, - - updateEmptyContent: function() { - var dir = this.getCurrentDirectory(); - if (dir === '/') { - // root has special permissions - this.$el.find('.emptyfilelist.emptycontent').toggleClass('hidden', !this.isEmpty); - this.$el.find('.files-filestable thead th').toggleClass('hidden', this.isEmpty); - } - else { - OCA.Files.FileList.prototype.updateEmptyContent.apply(this, arguments); - } - }, - - getDirectoryPermissions: function() { - return OC.PERMISSION_READ | OC.PERMISSION_DELETE; - }, - - updateStorageStatistics: function() { - // no op because it doesn't have - // storage info like free space / used space - }, - - reload: function() { - this.showMask(); - if (this._reloadCall?.abort) { - this._reloadCall.abort(); - } - - // there is only root - this._setCurrentDir('/', false); - - this._reloadCall = $.ajax({ - url: OC.linkToOCS('apps/files_external/api/v1') + 'mounts', - data: { - format: 'json' - }, - type: 'GET', - beforeSend: function(xhr) { - xhr.setRequestHeader('OCS-APIREQUEST', 'true'); - } - }); - var callBack = this.reloadCallback.bind(this); - return this._reloadCall.then(callBack, callBack); - }, - - reloadCallback: function(result) { - delete this._reloadCall; - this.hideMask(); - - if (result.ocs && result.ocs.data) { - this.setFiles(this._makeFiles(result.ocs.data)); - return true; - } - return false; - }, - - /** - * Converts the OCS API response data to a file info - * list - * @param OCS API mounts array - * @return array of file info maps - */ - _makeFiles: function(data) { - var files = _.map(data, function(fileData) { - fileData.icon = OC.imagePath('core', 'filetypes/folder-external'); - fileData.mountType = 'external'; - return fileData; - }); - - files.sort(this._sortComparator); - - return files; - } - }); - - /** - * Mount point info attributes. - * - * @typedef {Object} OCA.Files_External.MountPointInfo - * - * @property {String} name mount point name - * @property {String} scope mount point scope "personal" or "system" - * @property {String} backend external storage backend name - */ - - OCA.Files_External.FileList = FileList; -})(); diff --git a/apps/files_external/js/oauth1.js b/apps/files_external/js/oauth1.js deleted file mode 100644 index 0fee36077c6..00000000000 --- a/apps/files_external/js/oauth1.js +++ /dev/null @@ -1,82 +0,0 @@ -window.addEventListener('DOMContentLoaded', function() { - - function displayGranted($tr) { - $tr.find('.configuration input.auth-param').attr('disabled', 'disabled').addClass('disabled-success'); - } - - OCA.Files_External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { - if (authMechanism === 'oauth1::oauth1') { - var config = $tr.find('.configuration'); - config.append($(document.createElement('input')) - .addClass('button auth-param') - .attr('type', 'button') - .attr('value', t('files_external', 'Grant access')) - .attr('name', 'oauth1_grant') - ); - - onCompletion.then(function() { - var configured = $tr.find('[data-parameter="configured"]'); - if ($(configured).val() == 'true') { - displayGranted($tr); - } else { - var app_key = $tr.find('.configuration [data-parameter="app_key"]').val(); - var app_secret = $tr.find('.configuration [data-parameter="app_secret"]').val(); - if (app_key != '' && app_secret != '') { - var pos = window.location.search.indexOf('oauth_token') + 12; - var token = $tr.find('.configuration [data-parameter="token"]'); - if (pos != -1 && window.location.search.substr(pos, $(token).val().length) == $(token).val()) { - var token_secret = $tr.find('.configuration [data-parameter="token_secret"]'); - var statusSpan = $tr.find('.status span'); - statusSpan.removeClass(); - statusSpan.addClass('waiting'); - $.post(OC.filePath('files_external', 'ajax', 'oauth1.php'), { step: 2, app_key: app_key, app_secret: app_secret, request_token: $(token).val(), request_token_secret: $(token_secret).val() }, function(result) { - if (result && result.status == 'success') { - $(token).val(result.access_token); - $(token_secret).val(result.access_token_secret); - $(configured).val('true'); - OCA.Files_External.Settings.mountConfig.saveStorageConfig($tr, function(status) { - if (status) { - displayGranted($tr); - } - }); - } else { - OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring OAuth1')); - } - }); - } - } - } - }); - } - }); - - $('#externalStorage').on('click', '[name="oauth1_grant"]', function(event) { - event.preventDefault(); - var tr = $(this).parent().parent(); - var app_key = $(this).parent().find('[data-parameter="app_key"]').val(); - var app_secret = $(this).parent().find('[data-parameter="app_secret"]').val(); - if (app_key != '' && app_secret != '') { - var configured = $(this).parent().find('[data-parameter="configured"]'); - var token = $(this).parent().find('[data-parameter="token"]'); - var token_secret = $(this).parent().find('[data-parameter="token_secret"]'); - $.post(OC.filePath('files_external', 'ajax', 'oauth1.php'), { step: 1, app_key: app_key, app_secret: app_secret, callback: location.protocol + '//' + location.host + location.pathname }, function(result) { - if (result && result.status == 'success') { - $(configured).val('false'); - $(token).val(result.data.request_token); - $(token_secret).val(result.data.request_token_secret); - OCA.Files_External.Settings.mountConfig.saveStorageConfig(tr, function() { - window.location = result.data.url; - }); - } else { - OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring OAuth1')); - } - }); - } else { - OC.dialogs.alert( - t('files_external', 'Please provide a valid app key and secret.'), - t('files_external', 'Error configuring OAuth1') - ); - } - }); - -}); diff --git a/apps/files_external/js/oauth2.js b/apps/files_external/js/oauth2.js index 086a95f038f..53309b477ee 100644 --- a/apps/files_external/js/oauth2.js +++ b/apps/files_external/js/oauth2.js @@ -1,3 +1,8 @@ +/** + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ window.addEventListener('DOMContentLoaded', function() { function displayGranted($tr) { diff --git a/apps/files_external/js/public_key.js b/apps/files_external/js/public_key.js index 7fa47f09f1b..8af5e6d4a49 100644 --- a/apps/files_external/js/public_key.js +++ b/apps/files_external/js/public_key.js @@ -1,3 +1,8 @@ +/** + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2015 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ window.addEventListener('DOMContentLoaded', function() { OCA.Files_External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { diff --git a/apps/files_external/js/rollingqueue.js b/apps/files_external/js/rollingqueue.js deleted file mode 100644 index df3797ada89..00000000000 --- a/apps/files_external/js/rollingqueue.js +++ /dev/null @@ -1,137 +0,0 @@ -/** - * ownCloud - * - * @author Juan Pablo Villafañez Ramos <jvillafanez@owncloud.com> - * @author Jesus Macias Portela <jesus@owncloud.com> - * @copyright (C) 2014 ownCloud, Inc. - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -(function(){ -/** - * Launch several functions at thee same time. The number of functions - * running at the same time is controlled by the queueWindow param - * - * The function list come in the following format: - * - * var flist = [ - * { - * funcName: function () { - * var d = $.Deferred(); - * setTimeout(function(){d.resolve();}, 1000); - * return d; - * } - * }, - * { - * funcName: $.get, - * funcArgs: [ - * OC.filePath('files_external', 'ajax', 'connectivityCheck.php'), - * {}, - * function () { - * console.log('titoooo'); - * } - * ] - * }, - * { - * funcName: $.get, - * funcArgs: [ - * OC.filePath('files_external', 'ajax', 'connectivityCheck.php') - * ], - * done: function () { - * console.log('yuupi'); - * }, - * always: function () { - * console.log('always done'); - * } - * } - *]; - * - * functions MUST implement the deferred interface - * - * @param functionList list of functions that the queue will run - * (check example above for the expected format) - * @param queueWindow specify the number of functions that will - * be executed at the same time - */ -var RollingQueue = function (functionList, queueWindow, callback) { - this.queueWindow = queueWindow || 1; - this.functionList = functionList; - this.callback = callback; - this.counter = 0; - this.runQueue = function() { - this.callbackCalled = false; - this.deferredsList = []; - if (!$.isArray(this.functionList)) { - throw "functionList must be an array"; - } - - for (var i = 0; i < this.queueWindow; i++) { - this.launchNext(); - } - }; - - this.hasNext = function() { - return (this.counter in this.functionList); - }; - - this.launchNext = function() { - var currentCounter = this.counter++; - if (currentCounter in this.functionList) { - var funcData = this.functionList[currentCounter]; - if ($.isFunction(funcData.funcName)) { - var defObj = funcData.funcName.apply(funcData.funcName, funcData.funcArgs); - this.deferredsList.push(defObj); - if ($.isFunction(funcData.done)) { - defObj.done(funcData.done); - } - - if ($.isFunction(funcData.fail)) { - defObj.fail(funcData.fail); - } - - if ($.isFunction(funcData.always)) { - defObj.always(funcData.always); - } - - if (this.hasNext()) { - var self = this; - defObj.always(function(){ - _.defer($.proxy(function(){ - self.launchNext(); - }, self)); - }); - } else { - if (!this.callbackCalled) { - this.callbackCalled = true; - if ($.isFunction(this.callback)) { - $.when.apply($, this.deferredsList) - .always($.proxy(function(){ - this.callback(); - }, this) - ); - } - } - } - return defObj; - } - } - return false; - }; -}; - -if (!OCA.Files_External) { - OCA.Files_External = {}; -} - -if (!OCA.Files_External.StatusManager) { - OCA.Files_External.StatusManager = {}; -} - -OCA.Files_External.StatusManager.RollingQueue = RollingQueue; - -})(); diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js deleted file mode 100644 index d3e9fd44c0d..00000000000 --- a/apps/files_external/js/settings.js +++ /dev/null @@ -1,1513 +0,0 @@ -/* - * Copyright (c) 2014 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -(function(){ - -/** - * Returns the selection of applicable users in the given configuration row - * - * @param $row configuration row - * @return array array of user names - */ -function getSelection($row) { - var values = $row.find('.applicableUsers').select2('val'); - if (!values || values.length === 0) { - values = []; - } - return values; -} - -function getSelectedApplicable($row) { - var users = []; - var groups = []; - var multiselect = getSelection($row); - $.each(multiselect, function(index, value) { - // FIXME: don't rely on string parts to detect groups... - var pos = (value.indexOf)?value.indexOf('(group)'): -1; - if (pos !== -1) { - groups.push(value.substr(0, pos)); - } else { - users.push(value); - } - }); - - // FIXME: this should be done in the multiselect change event instead - $row.find('.applicable') - .data('applicable-groups', groups) - .data('applicable-users', users); - - return { users, groups }; -} - -function highlightBorder($element, highlight) { - $element.toggleClass('warning-input', highlight); - return highlight; -} - -function isInputValid($input) { - var optional = $input.hasClass('optional'); - switch ($input.attr('type')) { - case 'text': - case 'password': - if ($input.val() === '' && !optional) { - return false; - } - break; - } - return true; -} - -function highlightInput($input) { - switch ($input.attr('type')) { - case 'text': - case 'password': - return highlightBorder($input, !isInputValid($input)); - } -} - -/** - * Initialize select2 plugin on the given elements - * - * @param {Array<Object>} array of jQuery elements - * @param {number} userListLimit page size for result list - */ -function initApplicableUsersMultiselect($elements, userListLimit) { - var escapeHTML = function (text) { - return text.toString() - .split('&').join('&') - .split('<').join('<') - .split('>').join('>') - .split('"').join('"') - .split('\'').join('''); - }; - if (!$elements.length) { - return; - } - return $elements.select2({ - placeholder: t('files_external', 'Type to select user or group.'), - allowClear: true, - multiple: true, - toggleSelect: true, - dropdownCssClass: 'files-external-select2', - //minimumInputLength: 1, - ajax: { - url: OC.generateUrl('apps/files_external/applicable'), - dataType: 'json', - quietMillis: 100, - data: function (term, page) { // page is the one-based page number tracked by Select2 - return { - pattern: term, //search term - limit: userListLimit, // page size - offset: userListLimit*(page-1) // page number starts with 0 - }; - }, - results: function (data) { - if (data.status === 'success') { - - var results = []; - var userCount = 0; // users is an object - - // add groups - $.each(data.groups, function(gid, group) { - results.push({name:gid+'(group)', displayname:group, type:'group' }); - }); - // add users - $.each(data.users, function(id, user) { - userCount++; - results.push({name:id, displayname:user, type:'user' }); - }); - - - var more = (userCount >= userListLimit) || (data.groups.length >= userListLimit); - return {results: results, more: more}; - } else { - //FIXME add error handling - } - } - }, - initSelection: function(element, callback) { - var users = {}; - users['users'] = []; - var toSplit = element.val().split(","); - for (var i = 0; i < toSplit.length; i++) { - users['users'].push(toSplit[i]); - } - - $.ajax(OC.generateUrl('displaynames'), { - type: 'POST', - contentType: 'application/json', - data: JSON.stringify(users), - dataType: 'json' - }).done(function(data) { - var results = []; - if (data.status === 'success') { - $.each(data.users, function(user, displayname) { - if (displayname !== false) { - results.push({name:user, displayname:displayname, type:'user'}); - } - }); - callback(results); - } else { - //FIXME add error handling - } - }); - }, - id: function(element) { - return element.name; - }, - formatResult: function (element) { - var $result = $('<span><div class="avatardiv"></div><span>'+escapeHTML(element.displayname)+'</span></span>'); - var $div = $result.find('.avatardiv') - .attr('data-type', element.type) - .attr('data-name', element.name) - .attr('data-displayname', element.displayname); - if (element.type === 'group') { - var url = OC.imagePath('core','actions/group'); - $div.html('<img width="32" height="32" src="'+url+'">'); - } - return $result.get(0).outerHTML; - }, - formatSelection: function (element) { - if (element.type === 'group') { - return '<span title="'+escapeHTML(element.name)+'" class="group">'+escapeHTML(element.displayname+' '+t('files_external', '(Group)'))+'</span>'; - } else { - return '<span title="'+escapeHTML(element.name)+'" class="user">'+escapeHTML(element.displayname)+'</span>'; - } - }, - escapeMarkup: function (m) { return m; } // we escape the markup in formatResult and formatSelection - }).on('select2-loaded', function() { - $.each($('.avatardiv'), function(i, div) { - var $div = $(div); - if ($div.data('type') === 'user') { - $div.avatar($div.data('name'),32); - } - }); - }).on('change', function(event) { - highlightBorder($(event.target).closest('.applicableUsersContainer').find('.select2-choices'), !event.val.length); - }); -} - -/** - * @class OCA.Files_External.Settings.StorageConfig - * - * @classdesc External storage config - */ -var StorageConfig = function(id) { - this.id = id; - this.backendOptions = {}; -}; -// Keep this in sync with \OCA\Files_External\MountConfig::STATUS_* -StorageConfig.Status = { - IN_PROGRESS: -1, - SUCCESS: 0, - ERROR: 1, - INDETERMINATE: 2 -}; -StorageConfig.Visibility = { - NONE: 0, - PERSONAL: 1, - ADMIN: 2, - DEFAULT: 3 -}; -/** - * @memberof OCA.Files_External.Settings - */ -StorageConfig.prototype = { - _url: null, - - /** - * Storage id - * - * @type int - */ - id: null, - - /** - * Mount point - * - * @type string - */ - mountPoint: '', - - /** - * Backend - * - * @type string - */ - backend: null, - - /** - * Authentication mechanism - * - * @type string - */ - authMechanism: null, - - /** - * Backend-specific configuration - * - * @type Object.<string,object> - */ - backendOptions: null, - - /** - * Mount-specific options - * - * @type Object.<string,object> - */ - mountOptions: null, - - /** - * Creates or saves the storage. - * - * @param {Function} [options.success] success callback, receives result as argument - * @param {Function} [options.error] error callback - */ - save: function(options) { - var self = this; - var url = OC.generateUrl(this._url); - var method = 'POST'; - if (_.isNumber(this.id)) { - method = 'PUT'; - url = OC.generateUrl(this._url + '/{id}', {id: this.id}); - } - - $.ajax({ - type: method, - url: url, - contentType: 'application/json', - data: JSON.stringify(this.getData()), - success: function(result) { - self.id = result.id; - if (_.isFunction(options.success)) { - options.success(result); - } - }, - error: options.error - }); - }, - - /** - * Returns the data from this object - * - * @return {Array} JSON array of the data - */ - getData: function() { - var data = { - mountPoint: this.mountPoint, - backend: this.backend, - authMechanism: this.authMechanism, - backendOptions: this.backendOptions, - testOnly: true - }; - if (this.id) { - data.id = this.id; - } - if (this.mountOptions) { - data.mountOptions = this.mountOptions; - } - return data; - }, - - /** - * Recheck the storage - * - * @param {Function} [options.success] success callback, receives result as argument - * @param {Function} [options.error] error callback - */ - recheck: function(options) { - if (!_.isNumber(this.id)) { - if (_.isFunction(options.error)) { - options.error(); - } - return; - } - $.ajax({ - type: 'GET', - url: OC.generateUrl(this._url + '/{id}', {id: this.id}), - data: {'testOnly': true}, - success: options.success, - error: options.error - }); - }, - - /** - * Deletes the storage - * - * @param {Function} [options.success] success callback - * @param {Function} [options.error] error callback - */ - destroy: function(options) { - if (!_.isNumber(this.id)) { - // the storage hasn't even been created => success - if (_.isFunction(options.success)) { - options.success(); - } - return; - } - $.ajax({ - type: 'DELETE', - url: OC.generateUrl(this._url + '/{id}', {id: this.id}), - success: options.success, - error: options.error - }); - }, - - /** - * Validate this model - * - * @return {boolean} false if errors exist, true otherwise - */ - validate: function() { - if (this.mountPoint === '') { - return false; - } - if (!this.backend) { - return false; - } - if (this.errors) { - return false; - } - return true; - } -}; - -/** - * @class OCA.Files_External.Settings.GlobalStorageConfig - * @augments OCA.Files_External.Settings.StorageConfig - * - * @classdesc Global external storage config - */ -var GlobalStorageConfig = function(id) { - this.id = id; - this.applicableUsers = []; - this.applicableGroups = []; -}; -/** - * @memberOf OCA.Files_External.Settings - */ -GlobalStorageConfig.prototype = _.extend({}, StorageConfig.prototype, - /** @lends OCA.Files_External.Settings.GlobalStorageConfig.prototype */ { - _url: 'apps/files_external/globalstorages', - - /** - * Applicable users - * - * @type Array.<string> - */ - applicableUsers: null, - - /** - * Applicable groups - * - * @type Array.<string> - */ - applicableGroups: null, - - /** - * Storage priority - * - * @type int - */ - priority: null, - - /** - * Returns the data from this object - * - * @return {Array} JSON array of the data - */ - getData: function() { - var data = StorageConfig.prototype.getData.apply(this, arguments); - return _.extend(data, { - applicableUsers: this.applicableUsers, - applicableGroups: this.applicableGroups, - priority: this.priority, - }); - } -}); - -/** - * @class OCA.Files_External.Settings.UserStorageConfig - * @augments OCA.Files_External.Settings.StorageConfig - * - * @classdesc User external storage config - */ -var UserStorageConfig = function(id) { - this.id = id; -}; -UserStorageConfig.prototype = _.extend({}, StorageConfig.prototype, - /** @lends OCA.Files_External.Settings.UserStorageConfig.prototype */ { - _url: 'apps/files_external/userstorages' -}); - -/** - * @class OCA.Files_External.Settings.UserGlobalStorageConfig - * @augments OCA.Files_External.Settings.StorageConfig - * - * @classdesc User external storage config - */ -var UserGlobalStorageConfig = function (id) { - this.id = id; -}; -UserGlobalStorageConfig.prototype = _.extend({}, StorageConfig.prototype, - /** @lends OCA.Files_External.Settings.UserStorageConfig.prototype */ { - - _url: 'apps/files_external/userglobalstorages' -}); - -/** - * @class OCA.Files_External.Settings.MountOptionsDropdown - * - * @classdesc Dropdown for mount options - * - * @param {Object} $container container DOM object - */ -var MountOptionsDropdown = function() { -}; -/** - * @memberof OCA.Files_External.Settings - */ -MountOptionsDropdown.prototype = { - /** - * Dropdown element - * - * @var Object - */ - $el: null, - - /** - * Show dropdown - * - * @param {Object} $container container - * @param {Object} mountOptions mount options - * @param {Array} visibleOptions enabled mount options - */ - show: function($container, mountOptions, visibleOptions) { - if (MountOptionsDropdown._last) { - MountOptionsDropdown._last.hide(); - } - - var $el = $(OCA.Files_External.Templates.mountOptionsDropDown({ - mountOptionsEncodingLabel: t('files_external', 'Compatibility with Mac NFD encoding (slow)'), - mountOptionsEncryptLabel: t('files_external', 'Enable encryption'), - mountOptionsPreviewsLabel: t('files_external', 'Enable previews'), - mountOptionsSharingLabel: t('files_external', 'Enable sharing'), - mountOptionsFilesystemCheckLabel: t('files_external', 'Check for changes'), - mountOptionsFilesystemCheckOnce: t('files_external', 'Never'), - mountOptionsFilesystemCheckDA: t('files_external', 'Once every direct access'), - mountOptionsReadOnlyLabel: t('files_external', 'Read only'), - deleteLabel: t('files_external', 'Disconnect') - })); - this.$el = $el; - - var storage = $container[0].parentNode.className; - - this.setOptions(mountOptions, visibleOptions, storage); - - this.$el.appendTo($container); - MountOptionsDropdown._last = this; - - this.$el.trigger('show'); - }, - - hide: function() { - if (this.$el) { - this.$el.trigger('hide'); - this.$el.remove(); - this.$el = null; - MountOptionsDropdown._last = null; - } - }, - - /** - * Returns the mount options from the dropdown controls - * - * @return {Object} options mount options - */ - getOptions: function() { - var options = {}; - - this.$el.find('input, select').each(function() { - var $this = $(this); - var key = $this.attr('name'); - var value = null; - if ($this.attr('type') === 'checkbox') { - value = $this.prop('checked'); - } else { - value = $this.val(); - } - if ($this.attr('data-type') === 'int') { - value = parseInt(value, 10); - } - options[key] = value; - }); - return options; - }, - - /** - * Sets the mount options to the dropdown controls - * - * @param {Object} options mount options - * @param {Array} visibleOptions enabled mount options - */ - setOptions: function(options, visibleOptions, storage) { - if (storage === 'owncloud') { - var ind = visibleOptions.indexOf('encrypt'); - if (ind > 0) { - visibleOptions.splice(ind, 1); - } - } - var $el = this.$el; - _.each(options, function(value, key) { - var $optionEl = $el.find('input, select').filterAttr('name', key); - if ($optionEl.attr('type') === 'checkbox') { - if (_.isString(value)) { - value = (value === 'true'); - } - $optionEl.prop('checked', !!value); - } else { - $optionEl.val(value); - } - }); - $el.find('.optionRow').each(function(i, row){ - var $row = $(row); - var optionId = $row.find('input, select').attr('name'); - if (visibleOptions.indexOf(optionId) === -1 && !$row.hasClass('persistent')) { - $row.hide(); - } else { - $row.show(); - } - }); - } -}; - -/** - * @class OCA.Files_External.Settings.MountConfigListView - * - * @classdesc Mount configuration list view - * - * @param {Object} $el DOM object containing the list - * @param {Object} [options] - * @param {number} [options.userListLimit] page size in applicable users dropdown - */ -var MountConfigListView = function($el, options) { - this.initialize($el, options); -}; - -MountConfigListView.ParameterFlags = { - OPTIONAL: 1, - USER_PROVIDED: 2 -}; - -MountConfigListView.ParameterTypes = { - TEXT: 0, - BOOLEAN: 1, - PASSWORD: 2, - HIDDEN: 3 -}; - -/** - * @memberOf OCA.Files_External.Settings - */ -MountConfigListView.prototype = _.extend({ - - /** - * jQuery element containing the config list - * - * @type Object - */ - $el: null, - - /** - * Storage config class - * - * @type Class - */ - _storageConfigClass: null, - - /** - * Flag whether the list is about user storage configs (true) - * or global storage configs (false) - * - * @type bool - */ - _isPersonal: false, - - /** - * Page size in applicable users dropdown - * - * @type int - */ - _userListLimit: 30, - - /** - * List of supported backends - * - * @type Object.<string,Object> - */ - _allBackends: null, - - /** - * List of all supported authentication mechanisms - * - * @type Object.<string,Object> - */ - _allAuthMechanisms: null, - - _encryptionEnabled: false, - - /** - * @param {Object} $el DOM object containing the list - * @param {Object} [options] - * @param {number} [options.userListLimit] page size in applicable users dropdown - */ - initialize: function($el, options) { - var self = this; - this.$el = $el; - this._isPersonal = ($el.data('admin') !== true); - if (this._isPersonal) { - this._storageConfigClass = OCA.Files_External.Settings.UserStorageConfig; - } else { - this._storageConfigClass = OCA.Files_External.Settings.GlobalStorageConfig; - } - - if (options && !_.isUndefined(options.userListLimit)) { - this._userListLimit = options.userListLimit; - } - - this._encryptionEnabled = options.encryptionEnabled; - this._canCreateLocal = options.canCreateLocal; - - // read the backend config that was carefully crammed - // into the data-configurations attribute of the select - this._allBackends = this.$el.find('.selectBackend').data('configurations'); - this._allAuthMechanisms = this.$el.find('#addMountPoint .authentication').data('mechanisms'); - - this._initEvents(); - }, - - /** - * Custom JS event handlers - * Trigger callback for all existing configurations - */ - whenSelectBackend: function(callback) { - this.$el.find('tbody tr:not(#addMountPoint)').each(function(i, tr) { - var backend = $(tr).find('.backend').data('identifier'); - callback($(tr), backend); - }); - this.on('selectBackend', callback); - }, - whenSelectAuthMechanism: function(callback) { - var self = this; - this.$el.find('tbody tr:not(#addMountPoint)').each(function(i, tr) { - var authMechanism = $(tr).find('.selectAuthMechanism').val(); - callback($(tr), authMechanism, self._allAuthMechanisms[authMechanism]['scheme']); - }); - this.on('selectAuthMechanism', callback); - }, - - /** - * Initialize DOM event handlers - */ - _initEvents: function() { - var self = this; - - var onChangeHandler = _.bind(this._onChange, this); - //this.$el.on('input', 'td input', onChangeHandler); - this.$el.on('keyup', 'td input', onChangeHandler); - this.$el.on('paste', 'td input', onChangeHandler); - this.$el.on('change', 'td input:checkbox', onChangeHandler); - this.$el.on('change', '.applicable', onChangeHandler); - - this.$el.on('click', '.status>span', function() { - self.recheckStorageConfig($(this).closest('tr')); - }); - - this.$el.on('click', 'td.mountOptionsToggle .icon-delete', function() { - self.deleteStorageConfig($(this).closest('tr')); - }); - - this.$el.on('click', 'td.save>.icon-checkmark', function () { - self.saveStorageConfig($(this).closest('tr')); - }); - - this.$el.on('click', 'td.mountOptionsToggle>.icon-more', function() { - $(this).attr('aria-expanded', 'true'); - self._showMountOptionsDropdown($(this).closest('tr')); - }); - - this.$el.on('change', '.selectBackend', _.bind(this._onSelectBackend, this)); - this.$el.on('change', '.selectAuthMechanism', _.bind(this._onSelectAuthMechanism, this)); - - this.$el.on('change', '.applicableToAllUsers', _.bind(this._onChangeApplicableToAllUsers, this)); - }, - - _onChange: function(event) { - var self = this; - var $target = $(event.target); - if ($target.closest('.dropdown').length) { - // ignore dropdown events - return; - } - highlightInput($target); - var $tr = $target.closest('tr'); - this.updateStatus($tr, null); - }, - - _onSelectBackend: function(event) { - var $target = $(event.target); - var $tr = $target.closest('tr'); - - var storageConfig = new this._storageConfigClass(); - storageConfig.mountPoint = $tr.find('.mountPoint input').val(); - storageConfig.backend = $target.val(); - $tr.find('.mountPoint input').val(''); - - var onCompletion = jQuery.Deferred(); - $tr = this.newStorage(storageConfig, onCompletion); - $tr.find('.applicableToAllUsers').prop('checked', false).trigger('change'); - onCompletion.resolve(); - - $tr.find('td.configuration').children().not('[type=hidden]').first().focus(); - this.saveStorageConfig($tr); - }, - - _onSelectAuthMechanism: function(event) { - var $target = $(event.target); - var $tr = $target.closest('tr'); - var authMechanism = $target.val(); - - var onCompletion = jQuery.Deferred(); - this.configureAuthMechanism($tr, authMechanism, onCompletion); - onCompletion.resolve(); - - this.saveStorageConfig($tr); - }, - - _onChangeApplicableToAllUsers: function(event) { - var $target = $(event.target); - var $tr = $target.closest('tr'); - var checked = $target.is(':checked'); - - $tr.find('.applicableUsersContainer').toggleClass('hidden', checked); - if (!checked) { - $tr.find('.applicableUsers').select2('val', '', true); - } - - this.saveStorageConfig($tr); - }, - - /** - * Configure the storage config with a new authentication mechanism - * - * @param {jQuery} $tr config row - * @param {string} authMechanism - * @param {jQuery.Deferred} onCompletion - */ - configureAuthMechanism: function($tr, authMechanism, onCompletion) { - var authMechanismConfiguration = this._allAuthMechanisms[authMechanism]; - var $td = $tr.find('td.configuration'); - $td.find('.auth-param').remove(); - - $.each(authMechanismConfiguration['configuration'], _.partial( - this.writeParameterInput, $td, _, _, ['auth-param'] - ).bind(this)); - - this.trigger('selectAuthMechanism', - $tr, authMechanism, authMechanismConfiguration['scheme'], onCompletion - ); - }, - - /** - * Create a config row for a new storage - * - * @param {StorageConfig} storageConfig storage config to pull values from - * @param {jQuery.Deferred} onCompletion - * @param {boolean} deferAppend - * @return {jQuery} created row - */ - newStorage: function(storageConfig, onCompletion, deferAppend) { - var mountPoint = storageConfig.mountPoint; - var backend = this._allBackends[storageConfig.backend]; - - if (!backend) { - backend = { - name: 'Unknown: ' + storageConfig.backend, - invalid: true - }; - } - - // FIXME: Replace with a proper Handlebar template - var $template = this.$el.find('tr#addMountPoint'); - var $tr = $template.clone(); - if (!deferAppend) { - $tr.insertBefore($template); - } - - $tr.data('storageConfig', storageConfig); - $tr.show(); - $tr.find('td.mountOptionsToggle, td.save, td.remove').removeClass('hidden'); - $tr.find('td').last().removeAttr('style'); - $tr.removeAttr('id'); - $tr.find('select#selectBackend'); - if (!deferAppend) { - initApplicableUsersMultiselect($tr.find('.applicableUsers'), this._userListLimit); - } - - if (storageConfig.id) { - $tr.data('id', storageConfig.id); - } - - $tr.find('.backend').text(backend.name); - if (mountPoint === '') { - mountPoint = this._suggestMountPoint(backend.name); - } - $tr.find('.mountPoint input').val(mountPoint); - $tr.addClass(backend.identifier); - $tr.find('.backend').data('identifier', backend.identifier); - - if (backend.invalid || (backend.identifier === 'local' && !this._canCreateLocal)) { - $tr.find('[name=mountPoint]').prop('disabled', true); - $tr.find('.applicable,.mountOptionsToggle').empty(); - $tr.find('.save').empty(); - if (backend.invalid) { - this.updateStatus($tr, false, 'Unknown backend: ' + backend.name); - } - return $tr; - } - - var selectAuthMechanism = $('<select class="selectAuthMechanism"></select>'); - var neededVisibility = (this._isPersonal) ? StorageConfig.Visibility.PERSONAL : StorageConfig.Visibility.ADMIN; - $.each(this._allAuthMechanisms, function(authIdentifier, authMechanism) { - if (backend.authSchemes[authMechanism.scheme] && (authMechanism.visibility & neededVisibility)) { - selectAuthMechanism.append( - $('<option value="'+authMechanism.identifier+'" data-scheme="'+authMechanism.scheme+'">'+authMechanism.name+'</option>') - ); - } - }); - if (storageConfig.authMechanism) { - selectAuthMechanism.val(storageConfig.authMechanism); - } else { - storageConfig.authMechanism = selectAuthMechanism.val(); - } - $tr.find('td.authentication').append(selectAuthMechanism); - - var $td = $tr.find('td.configuration'); - $.each(backend.configuration, _.partial(this.writeParameterInput, $td).bind(this)); - - this.trigger('selectBackend', $tr, backend.identifier, onCompletion); - this.configureAuthMechanism($tr, storageConfig.authMechanism, onCompletion); - - if (storageConfig.backendOptions) { - $td.find('input, select').each(function() { - var input = $(this); - var val = storageConfig.backendOptions[input.data('parameter')]; - if (val !== undefined) { - if(input.is('input:checkbox')) { - input.prop('checked', val); - } - input.val(storageConfig.backendOptions[input.data('parameter')]); - highlightInput(input); - } - }); - } - - var applicable = []; - if (storageConfig.applicableUsers) { - applicable = applicable.concat(storageConfig.applicableUsers); - } - if (storageConfig.applicableGroups) { - applicable = applicable.concat( - _.map(storageConfig.applicableGroups, function(group) { - return group+'(group)'; - }) - ); - } - if (applicable.length) { - $tr.find('.applicableUsers').val(applicable).trigger('change') - $tr.find('.applicableUsersContainer').removeClass('hidden'); - } else { - // applicable to all - $tr.find('.applicableUsersContainer').addClass('hidden'); - } - $tr.find('.applicableToAllUsers').prop('checked', !applicable.length); - - var priorityEl = $('<input type="hidden" class="priority" value="' + backend.priority + '" />'); - $tr.append(priorityEl); - - if (storageConfig.mountOptions) { - $tr.find('input.mountOptions').val(JSON.stringify(storageConfig.mountOptions)); - } else { - // FIXME default backend mount options - $tr.find('input.mountOptions').val(JSON.stringify({ - 'encrypt': true, - 'previews': true, - 'enable_sharing': false, - 'filesystem_check_changes': 1, - 'encoding_compatibility': false, - 'readonly': false, - })); - } - - return $tr; - }, - - /** - * Load storages into config rows - */ - loadStorages: function() { - var self = this; - - var onLoaded1 = $.Deferred(); - var onLoaded2 = $.Deferred(); - - this.$el.find('.externalStorageLoading').removeClass('hidden'); - $.when(onLoaded1, onLoaded2).always(() => { - self.$el.find('.externalStorageLoading').addClass('hidden'); - }) - - if (this._isPersonal) { - // load userglobal storages - $.ajax({ - type: 'GET', - url: OC.generateUrl('apps/files_external/userglobalstorages'), - data: {'testOnly' : true}, - contentType: 'application/json', - success: function(result) { - var onCompletion = jQuery.Deferred(); - var $rows = $(); - Object.values(result).forEach(function(storageParams) { - var storageConfig; - var isUserGlobal = storageParams.type === 'system' && self._isPersonal; - storageParams.mountPoint = storageParams.mountPoint.substr(1); // trim leading slash - if (isUserGlobal) { - storageConfig = new UserGlobalStorageConfig(); - } else { - storageConfig = new self._storageConfigClass(); - } - _.extend(storageConfig, storageParams); - var $tr = self.newStorage(storageConfig, onCompletion,true); - - // userglobal storages must be at the top of the list - $tr.detach(); - self.$el.prepend($tr); - - var $authentication = $tr.find('.authentication'); - $authentication.text($authentication.find('select option:selected').text()); - - // disable any other inputs - $tr.find('.mountOptionsToggle, .remove').empty(); - $tr.find('input:not(.user_provided), select:not(.user_provided)').attr('disabled', 'disabled'); - - if (isUserGlobal) { - $tr.find('.configuration').find(':not(.user_provided)').remove(); - } else { - // userglobal storages do not expose configuration data - $tr.find('.configuration').text(t('files_external', 'Admin defined')); - } - $rows = $rows.add($tr); - }); - initApplicableUsersMultiselect(self.$el.find('.applicableUsers'), this._userListLimit); - self.$el.find('tr#addMountPoint').before($rows); - var mainForm = $('#files_external'); - if (result.length === 0 && mainForm.attr('data-can-create') === 'false') { - mainForm.hide(); - $('a[href="#external-storage"]').parent().hide(); - $('.emptycontent').show(); - } - onCompletion.resolve(); - onLoaded1.resolve(); - } - }); - } else { - onLoaded1.resolve(); - } - - var url = this._storageConfigClass.prototype._url; - - $.ajax({ - type: 'GET', - url: OC.generateUrl(url), - contentType: 'application/json', - success: function(result) { - result = Object.values(result); - var onCompletion = jQuery.Deferred(); - var $rows = $(); - result.forEach(function(storageParams) { - storageParams.mountPoint = (storageParams.mountPoint === '/')? '/' : storageParams.mountPoint.substr(1); // trim leading slash - var storageConfig = new self._storageConfigClass(); - _.extend(storageConfig, storageParams); - var $tr = self.newStorage(storageConfig, onCompletion, true); - - // don't recheck config automatically when there are a large number of storages - if (result.length < 20) { - self.recheckStorageConfig($tr); - } else { - self.updateStatus($tr, StorageConfig.Status.INDETERMINATE, t('files_external', 'Automatic status checking is disabled due to the large number of configured storages, click to check status')); - } - $rows = $rows.add($tr); - }); - initApplicableUsersMultiselect($rows.find('.applicableUsers'), this._userListLimit); - self.$el.find('tr#addMountPoint').before($rows); - onCompletion.resolve(); - onLoaded2.resolve(); - } - }); - }, - - /** - * @param {jQuery} $td - * @param {string} parameter - * @param {string} placeholder - * @param {Array} classes - * @return {jQuery} newly created input - */ - writeParameterInput: function($td, parameter, placeholder, classes) { - var hasFlag = function(flag) { - return (placeholder.flags & flag) === flag; - }; - classes = $.isArray(classes) ? classes : []; - classes.push('added'); - if (hasFlag(MountConfigListView.ParameterFlags.OPTIONAL)) { - classes.push('optional'); - } - - if (hasFlag(MountConfigListView.ParameterFlags.USER_PROVIDED)) { - if (this._isPersonal) { - classes.push('user_provided'); - } else { - return; - } - } - - var newElement; - - var trimmedPlaceholder = placeholder.value; - if (placeholder.type === MountConfigListView.ParameterTypes.PASSWORD) { - newElement = $('<input type="password" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />'); - } else if (placeholder.type === MountConfigListView.ParameterTypes.BOOLEAN) { - var checkboxId = _.uniqueId('checkbox_'); - newElement = $('<div><label><input type="checkbox" id="'+checkboxId+'" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />'+ trimmedPlaceholder+'</label></div>'); - } else if (placeholder.type === MountConfigListView.ParameterTypes.HIDDEN) { - newElement = $('<input type="hidden" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />'); - } else { - newElement = $('<input type="text" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />'); - } - - if (placeholder.defaultValue) { - if (placeholder.type === MountConfigListView.ParameterTypes.BOOLEAN) { - newElement.find('input').prop('checked', placeholder.defaultValue); - } else { - newElement.val(placeholder.defaultValue); - } - } - - if (placeholder.tooltip) { - newElement.attr('title', placeholder.tooltip); - } - - highlightInput(newElement); - $td.append(newElement); - return newElement; - }, - - /** - * Gets the storage model from the given row - * - * @param $tr row element - * @return {OCA.Files_External.StorageConfig} storage model instance - */ - getStorageConfig: function($tr) { - var storageId = $tr.data('id'); - if (!storageId) { - // new entry - storageId = null; - } - - var storage = $tr.data('storageConfig'); - if (!storage) { - storage = new this._storageConfigClass(storageId); - } - storage.errors = null; - storage.mountPoint = $tr.find('.mountPoint input').val(); - storage.backend = $tr.find('.backend').data('identifier'); - storage.authMechanism = $tr.find('.selectAuthMechanism').val(); - - var classOptions = {}; - var configuration = $tr.find('.configuration input'); - var missingOptions = []; - $.each(configuration, function(index, input) { - var $input = $(input); - var parameter = $input.data('parameter'); - if ($input.attr('type') === 'button') { - return; - } - if (!isInputValid($input) && !$input.hasClass('optional')) { - missingOptions.push(parameter); - return; - } - if ($(input).is(':checkbox')) { - if ($(input).is(':checked')) { - classOptions[parameter] = true; - } else { - classOptions[parameter] = false; - } - } else { - classOptions[parameter] = $(input).val(); - } - }); - - storage.backendOptions = classOptions; - if (missingOptions.length) { - storage.errors = { - backendOptions: missingOptions - }; - } - - // gather selected users and groups - if (!this._isPersonal) { - var multiselect = getSelectedApplicable($tr); - var users = multiselect.users || []; - var groups = multiselect.groups || []; - var isApplicableToAllUsers = $tr.find('.applicableToAllUsers').is(':checked'); - - if (isApplicableToAllUsers) { - storage.applicableUsers = []; - storage.applicableGroups = []; - } else { - storage.applicableUsers = users; - storage.applicableGroups = groups; - - if (!storage.applicableUsers.length && !storage.applicableGroups.length) { - if (!storage.errors) { - storage.errors = {}; - } - storage.errors['requiredApplicable'] = true; - } - } - - storage.priority = parseInt($tr.find('input.priority').val() || '100', 10); - } - - var mountOptions = $tr.find('input.mountOptions').val(); - if (mountOptions) { - storage.mountOptions = JSON.parse(mountOptions); - } - - return storage; - }, - - /** - * Deletes the storage from the given tr - * - * @param $tr storage row - * @param Function callback callback to call after save - */ - deleteStorageConfig: function($tr) { - var self = this; - var configId = $tr.data('id'); - if (!_.isNumber(configId)) { - // deleting unsaved storage - $tr.remove(); - return; - } - var storage = new this._storageConfigClass(configId); - - OC.dialogs.confirm(t('files_external', 'Are you sure you want to disconnect this external storage? It will make the storage unavailable in Nextcloud and will lead to a deletion of these files and folders on any sync client that is currently connected but will not delete any files and folders on the external storage itself.', { - storage: this.mountPoint - }), t('files_external', 'Delete storage?'), function(confirm) { - if (confirm) { - self.updateStatus($tr, StorageConfig.Status.IN_PROGRESS); - - storage.destroy({ - success: function () { - $tr.remove(); - }, - error: function () { - self.updateStatus($tr, StorageConfig.Status.ERROR); - } - }); - } - }); - }, - - /** - * Saves the storage from the given tr - * - * @param $tr storage row - * @param Function callback callback to call after save - * @param concurrentTimer only update if the timer matches this - */ - saveStorageConfig:function($tr, callback, concurrentTimer) { - var self = this; - var storage = this.getStorageConfig($tr); - if (!storage || !storage.validate()) { - return false; - } - - this.updateStatus($tr, StorageConfig.Status.IN_PROGRESS); - storage.save({ - success: function(result) { - if (concurrentTimer === undefined - || $tr.data('save-timer') === concurrentTimer - ) { - self.updateStatus($tr, result.status); - $tr.data('id', result.id); - - if (_.isFunction(callback)) { - callback(storage); - } - } - }, - error: function() { - if (concurrentTimer === undefined - || $tr.data('save-timer') === concurrentTimer - ) { - self.updateStatus($tr, StorageConfig.Status.ERROR); - } - } - }); - }, - - /** - * Recheck storage availability - * - * @param {jQuery} $tr storage row - * @return {boolean} success - */ - recheckStorageConfig: function($tr) { - var self = this; - var storage = this.getStorageConfig($tr); - if (!storage.validate()) { - return false; - } - - this.updateStatus($tr, StorageConfig.Status.IN_PROGRESS); - storage.recheck({ - success: function(result) { - self.updateStatus($tr, result.status, result.statusMessage); - }, - error: function() { - self.updateStatus($tr, StorageConfig.Status.ERROR); - } - }); - }, - - /** - * Update status display - * - * @param {jQuery} $tr - * @param {number} status - * @param {string} message - */ - updateStatus: function($tr, status, message) { - var $statusSpan = $tr.find('.status span'); - switch (status) { - case null: - // remove status - break; - case StorageConfig.Status.IN_PROGRESS: - $statusSpan.attr('class', 'icon-loading-small'); - break; - case StorageConfig.Status.SUCCESS: - $statusSpan.attr('class', 'success icon-checkmark-white'); - break; - case StorageConfig.Status.INDETERMINATE: - $statusSpan.attr('class', 'indeterminate icon-info-white'); - break; - default: - $statusSpan.attr('class', 'error icon-error-white'); - } - if (typeof message === 'string') { - $statusSpan.attr('title', message); - $statusSpan.tooltip(); - } else { - $statusSpan.tooltip('dispose'); - } - }, - - /** - * Suggest mount point name that doesn't conflict with the existing names in the list - * - * @param {string} defaultMountPoint default name - */ - _suggestMountPoint: function(defaultMountPoint) { - var $el = this.$el; - var pos = defaultMountPoint.indexOf('/'); - if (pos !== -1) { - defaultMountPoint = defaultMountPoint.substring(0, pos); - } - defaultMountPoint = defaultMountPoint.replace(/\s+/g, ''); - var i = 1; - var append = ''; - var match = true; - while (match && i < 20) { - match = false; - $el.find('tbody td.mountPoint input').each(function(index, mountPoint) { - if ($(mountPoint).val() === defaultMountPoint+append) { - match = true; - return false; - } - }); - if (match) { - append = i; - i++; - } else { - break; - } - } - return defaultMountPoint + append; - }, - - /** - * Toggles the mount options dropdown - * - * @param {Object} $tr configuration row - */ - _showMountOptionsDropdown: function($tr) { - var self = this; - var storage = this.getStorageConfig($tr); - var $toggle = $tr.find('.mountOptionsToggle'); - var dropDown = new MountOptionsDropdown(); - var visibleOptions = [ - 'previews', - 'filesystem_check_changes', - 'enable_sharing', - 'encoding_compatibility', - 'readonly', - 'delete' - ]; - if (this._encryptionEnabled) { - visibleOptions.push('encrypt'); - } - dropDown.show($toggle, storage.mountOptions || [], visibleOptions); - $('body').on('mouseup.mountOptionsDropdown', function(event) { - var $target = $(event.target); - if ($target.closest('.popovermenu').length) { - return; - } - dropDown.hide(); - }); - - dropDown.$el.on('hide', function() { - var mountOptions = dropDown.getOptions(); - $('body').off('mouseup.mountOptionsDropdown'); - $tr.find('input.mountOptions').val(JSON.stringify(mountOptions)); - $tr.find('td.mountOptionsToggle>.icon-more').attr('aria-expanded', 'false'); - self.saveStorageConfig($tr); - }); - } -}, OC.Backbone.Events); - -window.addEventListener('DOMContentLoaded', function() { - var enabled = $('#files_external').attr('data-encryption-enabled'); - var canCreateLocal = $('#files_external').attr('data-can-create-local'); - var encryptionEnabled = (enabled ==='true')? true: false; - var mountConfigListView = new MountConfigListView($('#externalStorage'), { - encryptionEnabled: encryptionEnabled, - canCreateLocal: (canCreateLocal === 'true') ? true: false, - }); - mountConfigListView.loadStorages(); - - // TODO: move this into its own View class - var $allowUserMounting = $('#allowUserMounting'); - $allowUserMounting.bind('change', function() { - OC.msg.startSaving('#userMountingMsg'); - if (this.checked) { - OCP.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes'); - $('input[name="allowUserMountingBackends\\[\\]"]').prop('checked', true); - $('#userMountingBackends').removeClass('hidden'); - $('input[name="allowUserMountingBackends\\[\\]"]').eq(0).trigger('change'); - } else { - OCP.AppConfig.setValue('files_external', 'allow_user_mounting', 'no'); - $('#userMountingBackends').addClass('hidden'); - } - OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('files_external', 'Saved')}}); - }); - - $('input[name="allowUserMountingBackends\\[\\]"]').bind('change', function() { - OC.msg.startSaving('#userMountingMsg'); - - var userMountingBackends = $('input[name="allowUserMountingBackends\\[\\]"]:checked').map(function(){ - return $(this).val(); - }).get(); - var deprecatedBackends = $('input[name="allowUserMountingBackends\\[\\]"][data-deprecate-to]').map(function(){ - if ($.inArray($(this).data('deprecate-to'), userMountingBackends) !== -1) { - return $(this).val(); - } - return null; - }).get(); - userMountingBackends = userMountingBackends.concat(deprecatedBackends); - - OCP.AppConfig.setValue('files_external', 'user_mounting_backends', userMountingBackends.join()); - OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('files_external', 'Saved')}}); - - // disable allowUserMounting - if(userMountingBackends.length === 0) { - $allowUserMounting.prop('checked', false); - $allowUserMounting.trigger('change'); - - } - }); - - $('#global_credentials').on('submit', function() { - var $form = $(this); - var uid = $form.find('[name=uid]').val(); - var user = $form.find('[name=username]').val(); - var password = $form.find('[name=password]').val(); - var $submit = $form.find('[type=submit]'); - $submit.val(t('files_external', 'Saving …')); - $.ajax({ - type: 'POST', - contentType: 'application/json', - data: JSON.stringify({ - uid: uid, - user: user, - password: password - }), - url: OC.generateUrl('apps/files_external/globalcredentials'), - dataType: 'json', - success: function() { - $submit.val(t('files_external', 'Saved')); - setTimeout(function(){ - $submit.val(t('files_external', 'Save')); - }, 2500); - } - }); - return false; - }); - - // global instance - OCA.Files_External.Settings.mountConfig = mountConfigListView; - - /** - * Legacy - * - * @namespace - * @deprecated use OCA.Files_External.Settings.mountConfig instead - */ - OC.MountConfig = { - saveStorage: _.bind(mountConfigListView.saveStorageConfig, mountConfigListView) - }; -}); - -// export - -OCA.Files_External = OCA.Files_External || {}; -/** - * @namespace - */ -OCA.Files_External.Settings = OCA.Files_External.Settings || {}; - -OCA.Files_External.Settings.GlobalStorageConfig = GlobalStorageConfig; -OCA.Files_External.Settings.UserStorageConfig = UserStorageConfig; -OCA.Files_External.Settings.MountConfigListView = MountConfigListView; - -})(); diff --git a/apps/files_external/js/statusmanager.js b/apps/files_external/js/statusmanager.js deleted file mode 100644 index 5f94192ea35..00000000000 --- a/apps/files_external/js/statusmanager.js +++ /dev/null @@ -1,613 +0,0 @@ -/** - * ownCloud - * - * @author Juan Pablo Villafañez Ramos <jvillafanez@owncloud.com> - * @author Jesus Macias Portela <jesus@owncloud.com> - * @copyright (C) 2014 ownCloud, Inc. - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/** @global Handlebars */ - -if (!OCA.Files_External) { - OCA.Files_External = {}; -} - -if (!OCA.Files_External.StatusManager) { - OCA.Files_External.StatusManager = {}; -} - -OCA.Files_External.StatusManager = { - - mountStatus: null, - mountPointList: null, - - /** - * Function - * @param {callback} afterCallback - */ - - getMountStatus: function (afterCallback) { - var self = this; - if (typeof afterCallback !== 'function' || self.isGetMountStatusRunning) { - return; - } - - if (self.mountStatus) { - afterCallback(self.mountStatus); - } - }, - - /** - * Function Check mount point status from cache - * @param {string} mount_point - */ - - getMountPointListElement: function (mount_point) { - var element; - $.each(this.mountPointList, function (key, value) { - if (value.mount_point === mount_point) { - element = value; - return false; - } - }); - return element; - }, - - /** - * Function Check mount point status from cache - * @param {string} mount_point - * @param {string} mount_point - */ - - getMountStatusForMount: function (mountData, afterCallback) { - var self = this; - if (typeof afterCallback !== 'function' || self.isGetMountStatusRunning) { - return $.Deferred().resolve(); - } - - var defObj; - if (self.mountStatus[mountData.mount_point]) { - defObj = $.Deferred(); - afterCallback(mountData, self.mountStatus[mountData.mount_point]); - defObj.resolve(); // not really useful, but it'll keep the same behaviour - } else { - defObj = $.ajax({ - type: 'GET', - url: OC.getRootPath() + '/index.php/apps/files_external/' + ((mountData.type === 'personal') ? 'userstorages' : 'userglobalstorages') + '/' + mountData.id, - data: {'testOnly' : false}, - success: function (response) { - if (response && response.status === 0) { - self.mountStatus[mountData.mount_point] = response; - } else { - var statusCode = response.status ? response.status : 1; - var statusMessage = response.statusMessage ? response.statusMessage : t('files_external', 'Empty response from the server') - // failure response with error message - self.mountStatus[mountData.mount_point] = { - type: mountData.type, - status: statusCode, - id: mountData.id, - error: statusMessage, - userProvided: response.userProvided, - authMechanism: response.authMechanism, - canEdit: response.can_edit, - }; - } - afterCallback(mountData, self.mountStatus[mountData.mount_point]); - }, - error: function (jqxhr, state, error) { - var message; - if (mountData.location === 3) { - // In this case the error is because mount point use Login credentials and don't exist in the session - message = t('files_external', 'Couldn\'t access. Please log out and in again to activate this mount point'); - } else { - message = t('files_external', 'Couldn\'t get the information from the remote server: {code} {type}', { - code: jqxhr.status, - type: error - }); - } - self.mountStatus[mountData.mount_point] = { - type: mountData.type, - status: 1, - location: mountData.location, - error: message - }; - afterCallback(mountData, self.mountStatus[mountData.mount_point]); - } - }); - } - return defObj; - }, - - /** - * Function to get external mount point list from the files_external API - * @param {Function} afterCallback function to be executed - */ - - getMountPointList: function (afterCallback) { - var self = this; - if (typeof afterCallback !== 'function' || self.isGetMountPointListRunning) { - return; - } - - if (self.mountPointList) { - afterCallback(self.mountPointList); - } else { - self.isGetMountPointListRunning = true; - $.ajax({ - type: 'GET', - url: OC.linkToOCS('apps/files_external/api/v1') + 'mounts?format=json', - success: function (response) { - self.mountPointList = []; - _.each(response.ocs.data, function (mount) { - var element = {}; - element.mount_point = mount.name; - element.type = mount.scope; - element.location = ""; - element.id = mount.id; - element.backendText = mount.backend; - element.backend = mount.class; - - self.mountPointList.push(element); - }); - afterCallback(self.mountPointList); - }, - error: function (jqxhr, state, error) { - self.mountPointList = []; - OC.Notification.show(t('files_external', 'Couldn\'t get the list of external mount points: {type}', - {type: error}), {type: 'error'} - ); - }, - complete: function () { - self.isGetMountPointListRunning = false; - } - }); - } - }, - - /** - * Function to manage action when a mountpoint status = 1 (Errored). Show a dialog to be redirected to settings page. - * @param {string} name MountPoint Name - */ - - manageMountPointError: function (name) { - this.getMountStatus($.proxy(function (allMountStatus) { - if (allMountStatus.hasOwnProperty(name) && allMountStatus[name].status > 0 && allMountStatus[name].status < 7) { - var mountData = allMountStatus[name]; - if (mountData.type === "system") { - if (mountData.userProvided || mountData.authMechanism === 'password::global::user') { - // personal mount whit credentials problems - this.showCredentialsDialog(name, mountData); - } else if (mountData.canEdit) { - OC.dialogs.confirm(t('files_external', 'There was an error with message: ') + mountData.error + '. Do you want to review mount point config in admin settings page?', t('files_external', 'External mount error'), function (e) { - if (e === true) { - OC.redirect(OC.generateUrl('/settings/admin/externalstorages')); - } - }); - } else { - OC.dialogs.info(t('files_external', 'There was an error with message: ') + mountData.error + '. Please contact your system administrator.', t('files_external', 'External mount error'), () => {}); - } - } else { - OC.dialogs.confirm(t('files_external', 'There was an error with message: ') + mountData.error + '. Do you want to review mount point config in personal settings page?', t('files_external', 'External mount error'), function (e) { - if (e === true) { - OC.redirect(OC.generateUrl('/settings/personal#' + t('files_external', 'external-storage'))); - } - }); - } - } - }, this)); - }, - - /** - * Function to process a mount point in relation with their status, Called from Async Queue. - * @param {object} mountData - * @param {object} mountStatus - */ - - processMountStatusIndividual: function (mountData, mountStatus) { - - var mountPoint = mountData.mount_point; - if (mountStatus.status > 0) { - var trElement = FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(mountPoint)); - - var route = OCA.Files_External.StatusManager.Utils.getIconRoute(trElement) + '-error'; - - if (OCA.Files_External.StatusManager.Utils.isCorrectViewAndRootFolder()) { - OCA.Files_External.StatusManager.Utils.showIconError(mountPoint, $.proxy(OCA.Files_External.StatusManager.manageMountPointError, OCA.Files_External.StatusManager), route); - } - return false; - } else { - if (OCA.Files_External.StatusManager.Utils.isCorrectViewAndRootFolder()) { - OCA.Files_External.StatusManager.Utils.restoreFolder(mountPoint); - OCA.Files_External.StatusManager.Utils.toggleLink(mountPoint, true, true); - } - return true; - } - }, - - /** - * Function to process a mount point in relation with their status - * @param {object} mountData - * @param {object} mountStatus - */ - - processMountList: function (mountList) { - var elementList = null; - $.each(mountList, function (name, value) { - var trElement = $('.files-fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(value.mount_point) + '\"]'); //FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(value.mount_point)); - trElement.attr('data-external-backend', value.backend); - if (elementList) { - elementList = elementList.add(trElement); - } else { - elementList = trElement; - } - }); - - if (elementList instanceof $) { - if (OCA.Files_External.StatusManager.Utils.isCorrectViewAndRootFolder()) { - // Put their custom icon - OCA.Files_External.StatusManager.Utils.changeFolderIcon(elementList); - // Save default view - OCA.Files_External.StatusManager.Utils.storeDefaultFolderIconAndBgcolor(elementList); - OCA.Files_External.StatusManager.Utils.toggleLink(elementList.find('a.name'), false, false); - } - } - }, - - /** - * Function to process the whole mount point list in relation with their status (Async queue) - */ - - launchFullConnectivityCheckOneByOne: function () { - var self = this; - this.getMountPointList(function (list) { - // check if we have a list first - if (list === undefined && !self.emptyWarningShown) { - self.emptyWarningShown = true; - OC.Notification.show(t('files_external', 'Couldn\'t fetch list of Windows network drive mount points: Empty response from server'), - {type: 'error'} - ); - return; - } - if (list && list.length > 0) { - self.processMountList(list); - - if (!self.mountStatus) { - self.mountStatus = {}; - } - - var ajaxQueue = []; - $.each(list, function (key, value) { - var queueElement = { - funcName: $.proxy(self.getMountStatusForMount, self), - funcArgs: [value, - $.proxy(self.processMountStatusIndividual, self)] - }; - ajaxQueue.push(queueElement); - }); - - var rolQueue = new OCA.Files_External.StatusManager.RollingQueue(ajaxQueue, 4, function () { - if (!self.notificationHasShown) { - $.each(self.mountStatus, function (key, value) { - if (value.status === 1) { - self.notificationHasShown = true; - } - }); - } - }); - rolQueue.runQueue(); - } - }); - }, - - - /** - * Function to process a mount point list in relation with their status (Async queue) - * @param {object} mountListData - * @param {boolean} recheck delete cached info and force api call to check mount point status - */ - - launchPartialConnectivityCheck: function (mountListData, recheck) { - if (mountListData.length === 0) { - return; - } - - var self = this; - var ajaxQueue = []; - $.each(mountListData, function (key, value) { - if (recheck && value.mount_point in self.mountStatus) { - delete self.mountStatus[value.mount_point]; - } - var queueElement = { - funcName: $.proxy(self.getMountStatusForMount, self), - funcArgs: [value, - $.proxy(self.processMountStatusIndividual, self)] - }; - ajaxQueue.push(queueElement); - }); - new OCA.Files_External.StatusManager.RollingQueue(ajaxQueue, 4).runQueue(); - }, - - - /** - * Function to relaunch some mount point status check - * @param {string} mountListNames - * @param {boolean} recheck delete cached info and force api call to check mount point status - */ - - recheckConnectivityForMount: function (mountListNames, recheck) { - if (mountListNames.length === 0) { - return; - } - - var self = this; - var mountListData = []; - - if (!self.mountStatus) { - self.mountStatus = {}; - } - - $.each(mountListNames, function (key, value) { - var mountData = self.getMountPointListElement(value); - if (mountData) { - mountListData.push(mountData); - } - }); - - // for all mounts in the list, delete the cached status values - if (recheck) { - $.each(mountListData, function (key, value) { - if (value.mount_point in self.mountStatus) { - delete self.mountStatus[value.mount_point]; - } - }); - } - - self.processMountList(mountListData); - self.launchPartialConnectivityCheck(mountListData, recheck); - }, - - credentialsDialogTemplate: - '<div id="files_external_div_form"><div>' + - '<div>{{credentials_text}}</div>' + - '<form>' + - '<input type="text" name="username" placeholder="{{placeholder_username}}"/>' + - '<input type="password" name="password" placeholder="{{placeholder_password}}"/>' + - '</form>' + - '</div></div>', - - /** - * Function to display custom dialog to enter credentials - * @param {any} mountPoint - - * @param {any} mountData - - */ - showCredentialsDialog: function (mountPoint, mountData) { - var dialog = $(OCA.Files_External.Templates.credentialsDialog({ - credentials_text: t('files_external', 'Please enter the credentials for the {mount} mount', { - 'mount': mountPoint - }), - placeholder_username: t('files_external', 'Username'), - placeholder_password: t('files_external', 'Password') - })); - - $('body').append(dialog); - - var apply = function () { - var username = dialog.find('[name=username]').val(); - var password = dialog.find('[name=password]').val(); - var endpoint = OC.generateUrl('apps/files_external/userglobalstorages/{id}', { - id: mountData.id - }); - $('.oc-dialog-close').hide(); - $.ajax({ - type: 'PUT', - url: endpoint, - data: { - backendOptions: { - user: username, - password: password - } - }, - success: function (data) { - OC.Notification.show(t('files_external', 'Credentials saved'), {type: 'success'}); - dialog.ocdialog('close'); - /* Trigger status check again */ - OCA.Files_External.StatusManager.recheckConnectivityForMount([OC.basename(data.mountPoint)], true); - }, - error: function () { - $('.oc-dialog-close').show(); - OC.Notification.show(t('files_external', 'Credentials saving failed'), {type: 'error'}); - } - }); - return false; - }; - - var ocdialogParams = { - modal: true, - title: t('files_external', 'Credentials required'), - buttons: [{ - text: t('files_external', 'Save'), - click: apply, - closeOnEscape: true - }], - closeOnExcape: true - }; - - dialog.ocdialog(ocdialogParams) - .bind('ocdialogclose', function () { - dialog.ocdialog('destroy').remove(); - }); - - dialog.find('form').on('submit', apply); - dialog.find('form input:first').focus(); - dialog.find('form input').keyup(function (e) { - if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) { - $(e.target).closest('form').submit(); - return false; - } else { - return true; - } - }); - } -}; - -OCA.Files_External.StatusManager.Utils = { - - showIconError: function (folder, clickAction, errorImageUrl) { - var imageUrl = "url(" + errorImageUrl + ")"; - var trFolder = $('.files-fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(folder)); - this.changeFolderIcon(folder, imageUrl); - this.toggleLink(folder, false, clickAction); - trFolder.addClass('externalErroredRow'); - }, - - /** - * @param folder string with the folder or jQuery element pointing to the tr element - */ - storeDefaultFolderIconAndBgcolor: function (folder) { - var trFolder; - if (folder instanceof $) { - trFolder = folder; - } else { - trFolder = $('.files-fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(folder)); //$('.files-fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); - } - trFolder.each(function () { - var thisElement = $(this); - if (thisElement.data('oldbgcolor') === undefined) { - thisElement.data('oldbgcolor', thisElement.css('background-color')); - } - }); - - var icon = trFolder.find('td.filename div.thumbnail'); - icon.each(function () { - var thisElement = $(this); - if (thisElement.data('oldImage') === undefined) { - thisElement.data('oldImage', thisElement.css('background-image')); - } - }); - }, - - /** - * @param folder string with the folder or jQuery element pointing to the tr element - */ - restoreFolder: function (folder) { - var trFolder; - if (folder instanceof $) { - trFolder = folder; - } else { - // can't use here FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(folder)); return incorrect instance of filelist - trFolder = $('.files-fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); - } - var tdChilds = trFolder.find("td.filename div.thumbnail"); - tdChilds.each(function () { - var thisElement = $(this); - thisElement.css('background-image', thisElement.data('oldImage')); - }); - }, - - /** - * @param folder string with the folder or jQuery element pointing to the first td element - * of the tr matching the folder name - */ - changeFolderIcon: function (filename) { - var file; - var route; - if (filename instanceof $) { - //trElementList - $.each(filename, function (index) { - route = OCA.Files_External.StatusManager.Utils.getIconRoute($(this)); - $(this).attr("data-icon", route); - $(this).find('td.filename div.thumbnail').css('background-image', "url(" + route + ")").css('display', 'none').css('display', 'inline'); - }); - } else { - file = $(".files-fileList tr[data-file=\"" + this.jqSelEscape(filename) + "\"] > td.filename div.thumbnail"); - var parentTr = file.parents('tr:first'); - route = OCA.Files_External.StatusManager.Utils.getIconRoute(parentTr); - parentTr.attr("data-icon", route); - file.css('background-image', "url(" + route + ")").css('display', 'none').css('display', 'inline'); - } - }, - - /** - * @param backend string with the name of the external storage backend - * of the tr matching the folder name - */ - getIconRoute: function (tr) { - if (OCA.Theming) { - var icon = OC.generateUrl('/apps/theming/img/core/filetypes/folder-external.svg?v=' + OCA.Theming.cacheBuster); - } else { - var icon = OC.imagePath('core', 'filetypes/folder-external'); - } - var backend = null; - - if (tr instanceof $) { - backend = tr.attr('data-external-backend'); - } - - switch (backend) { - case 'windows_network_drive': - icon = OC.imagePath('windows_network_drive', 'folder-windows'); - break; - } - - return icon; - }, - - toggleLink: function (filename, active, action) { - var link; - if (filename instanceof $) { - link = filename; - } else { - link = $(".files-fileList tr[data-file=\"" + this.jqSelEscape(filename) + "\"] > td.filename a.name"); - } - if (active) { - link.off('click.connectivity'); - OCA.Files.App.fileList.fileActions.display(link.parent(), true, OCA.Files.App.fileList); - } else { - link.find('.fileactions, .nametext .action').remove(); // from files/js/fileactions (display) - link.off('click.connectivity'); - link.on('click.connectivity', function (e) { - if (action && $.isFunction(action)) { - action(filename); - } - e.preventDefault(); - return false; - }); - } - }, - - isCorrectViewAndRootFolder: function () { - // correct views = files & extstoragemounts - if (OCA.Files.App.getActiveView() === 'files' || OCA.Files.App.getActiveView() === 'extstoragemounts') { - return OCA.Files.App.currentFileList.getCurrentDirectory() === '/'; - } - return false; - }, - - /* escape a selector expression for jQuery */ - jqSelEscape: function (expression) { - if (expression) { - return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&'); - } - return null; - }, - - /* Copied from http://stackoverflow.com/questions/2631001/javascript-test-for-existence-of-nested-object-key */ - checkNested: function (cobj /*, level1, level2, ... levelN*/) { - var args = Array.prototype.slice.call(arguments), - obj = args.shift(); - - for (var i = 0; i < args.length; i++) { - if (!obj || !obj.hasOwnProperty(args[i])) { - return false; - } - obj = obj[args[i]]; - } - return true; - } -}; |