diff --git a/src/components/filetree.html b/src/components/filetree.html
index 5550464c1..321fc1bd0 100644
--- a/src/components/filetree.html
+++ b/src/components/filetree.html
@@ -214,7 +214,7 @@
{{ 'filemanager.list.empty' | tr }} |
- |
+ |
|
@@ -222,7 +222,7 @@
{{ entry.uid | prettyOwner }} |
{{ entry.size | prettyByteSize }} |
{{ entry.mtime | prettyDate }} |
-
+ |
|
diff --git a/src/components/filetree.js b/src/components/filetree.js
index fa553fbd7..44c393456 100644
--- a/src/components/filetree.js
+++ b/src/components/filetree.js
@@ -6,7 +6,8 @@
angular.module('Application').component('filetree', {
bindings: {
backendId: '<',
- backendType: '<'
+ backendType: '<',
+ view: '<'
},
templateUrl: 'components/filetree.html?<%= revision %>',
controller: [ '$scope', '$translate', '$timeout', 'Client', FileTreeController ]
@@ -15,6 +16,7 @@ angular.module('Application').component('filetree', {
function FileTreeController($scope, $translate, $timeout, Client) {
$scope.backendId = this.backendId;
$scope.backendType = this.backendType;
+ $scope.view = this.view;
$scope.busy = true;
$scope.client = Client;
@@ -26,7 +28,6 @@ function FileTreeController($scope, $translate, $timeout, Client) {
$scope.clipboard = []; // holds cut or copied entries
$scope.clipboardCut = false; // if action is cut or copy
$scope.dropToBody = false;
- $scope.view = 'fileTree';
$scope.applicationLink = '';
$scope.owners = [
@@ -968,4 +969,19 @@ function FileTreeController($scope, $translate, $timeout, Client) {
}
openPath('.');
+
+ // handle save shortcuts
+ window.addEventListener('keydown', function (event) {
+ if ($scope.$parent.activeView !== $scope.view || $scope.$parent.viewerOpen) return;
+
+ if (event.key === 'ArrowDown') {
+ $scope.$apply(selectNext);
+ } else if (event.key === 'ArrowUp') {
+ $scope.$apply(selectPrev);
+ } else if (event.key === 'Enter') {
+ $scope.$apply(openSelected);
+ } else if (event.key === 'Backspace') {
+ if ($scope.view === 'fileTree') $scope.goDirectoryUp();
+ }
+ });
}
diff --git a/src/filemanager.html b/src/filemanager.html
index 8aecd3ab1..fb2f29200 100644
--- a/src/filemanager.html
+++ b/src/filemanager.html
@@ -144,20 +144,20 @@
{{ volume.name }}
-
+
diff --git a/src/js/filemanager.js b/src/js/filemanager.js
index e7acb9057..3be90e081 100644
--- a/src/js/filemanager.js
+++ b/src/js/filemanager.js
@@ -74,22 +74,35 @@ function isModalVisible() {
return !!document.getElementsByClassName('modal in').length;
}
+var VIEW = {
+ LEFT: 'left',
+ RIGHT: 'right'
+};
+
app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Client', function ($scope, $translate, $timeout, Client) {
var search = decodeURIComponent(window.location.search).slice(1).split('&').map(function (item) { return item.split('='); }).reduce(function (o, k) { o[k[0]] = k[1]; return o; }, {});
+ $scope.VIEW = VIEW;
+
$scope.initialized = false;
$scope.status = null;
$scope.client = Client;
$scope.title = '';
- $scope.id = search.id;
- $scope.type = search.type;
-
- // move to this instead of above
$scope.backendId = search.id;
$scope.backendType = search.type;
-
$scope.volumes = [];
$scope.splitView = false;
+ $scope.activeView = VIEW.LEFT;
+ $scope.viewerOpen = false;
+
+ $scope.toggleSplitView = function () {
+ $scope.splitView = !$scope.splitView;
+ if (!$scope.splitView) $scope.activeView = VIEW.LEFT;
+ };
+
+ $scope.setActiveView = function (view) {
+ $scope.activeView = view;
+ };
// for monaco editor
var LANGUAGES = [];
@@ -124,13 +137,13 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
// clear model if any
if ($scope.textEditor.editor && $scope.textEditor.editor.getModel()) $scope.textEditor.editor.setModel(null);
- $scope.view = 'textEditor';
+ $scope.viewerOpen = true;
// document.getElementById('textEditorModal').style['display'] = 'flex';
var filePath = sanitize($scope.textEditor.cwd + '/' + entry.fileName);
var language = getLanguage(entry.fileName);
- Client.filesGet($scope.id, $scope.type, filePath, 'data', function (error, result) {
+ Client.filesGet($scope.backendId, $scope.backendType, filePath, 'data', function (error, result) {
if (error) return Client.error(error);
if (!$scope.textEditor.editor) {
@@ -156,7 +169,7 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
var filePath = sanitize($scope.textEditor.cwd + '/' + $scope.textEditor.entry.fileName);
var file = new File([newContent], 'file');
- Client.filesUpload($scope.id, $scope.type, filePath, file, true, function () {}, function (error) {
+ Client.filesUpload($scope.backendId, $scope.backendType, filePath, file, true, function () {}, function (error) {
if (error) return Client.error(error);
// update size immediately for the list view to avoid reloading the whole list
@@ -172,11 +185,13 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
close: function () {
$scope.textEditor.visible = false;
+ $scope.viewerOpen = false;
$('#textEditorCloseModal').modal('hide');
},
onClose: function () {
$scope.textEditor.visible = false;
+ $scope.viewerOpen = false;
$('#textEditorCloseModal').modal('hide');
},
@@ -236,11 +251,11 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
if (error) return Client.initError(error, init);
var getter;
- if ($scope.type === 'app') {
- getter = Client.getApp.bind(Client, $scope.id);
- } else if ($scope.type === 'volume') {
- getter = Client.getVolume.bind(Client, $scope.id);
- } else if ($scope.type === 'mail') {
+ if ($scope.backendType === 'app') {
+ getter = Client.getApp.bind(Client, $scope.backendId);
+ } else if ($scope.backendType === 'volume') {
+ getter = Client.getVolume.bind(Client, $scope.backendId);
+ } else if ($scope.backendType === 'mail') {
getter = function (next) { next(null, null); };
}
@@ -251,9 +266,9 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
}
// fine to do async
- if ($scope.type === 'app') fetchVolumesInfo(result.mounts || []);
+ if ($scope.backendType === 'app') fetchVolumesInfo(result.mounts || []);
- switch ($scope.type) {
+ switch ($scope.backendType) {
case 'app':
$scope.title = result.label || result.fqdn;
$scope.rootDirLabel = '/app/data/';
@@ -286,15 +301,7 @@ app.controller('FileManagerController', ['$scope', '$translate', '$timeout', 'Cl
// handle save shortcuts
window.addEventListener('keydown', function (event) {
- if (event.key === 'ArrowDown') {
- $scope.$apply(selectNext);
- } else if (event.key === 'ArrowUp') {
- $scope.$apply(selectPrev);
- // } else if (event.key === 'Enter') {
- // $scope.$apply(openSelected);
- // } else if (event.key === 'Backspace') {
- // if ($scope.view === 'fileTree') $scope.goDirectoryUp();
- } else if((navigator.platform.match('Mac') ? event.metaKey : event.ctrlKey) && event.key === 's') {
+ if((navigator.platform.match('Mac') ? event.metaKey : event.ctrlKey) && event.key === 's') {
if ($scope.view !== 'textEditor') return;
event.preventDefault();
diff --git a/src/theme.scss b/src/theme.scss
index f17cd2111..7d87cb384 100644
--- a/src/theme.scss
+++ b/src/theme.scss
@@ -1837,17 +1837,21 @@ tag-input {
.file-trees {
display: flex;
- }
-
- .spacer {
- width: 2px;
- background-color: #d3d3d3;
- margin: 0 10px;
+ overflow: hidden;
}
filetree {
- // flex-basis: 50%;
width: 100%;
+
+ &.two-pane {
+ width: 50%;
+
+ &:first-of-type {
+ margin-right: 5px;
+ padding-right: 5px;
+ border-right: 1px solid #d3d3d3;
+ }
+ }
}
.toolbar {
@@ -1918,12 +1922,13 @@ tag-input {
.table td {
vertical-align: middle;
+ padding: 0;
}
}
.file-list-header {
th {
- padding: 2px 8px;
+ padding: 0;
}
}
@@ -1932,11 +1937,13 @@ tag-input {
}
.context-menu-action {
- display: none;
+ display: inline-block;
+ visibility: hidden;
}
tr:hover .context-menu-action {
- display: inline-block;
+ // display: inline-block;
+ visibility: visible;
}
tr.entry-selected .context-menu-action {