diff --git a/app/extensions/storidge/views/profiles/edit/profileController.js b/app/extensions/storidge/views/profiles/edit/profileController.js
index ff6aecfc0..ecafae46f 100644
--- a/app/extensions/storidge/views/profiles/edit/profileController.js
+++ b/app/extensions/storidge/views/profiles/edit/profileController.js
@@ -2,21 +2,49 @@ angular.module('extension.storidge')
.controller('StoridgeProfileController', ['$scope', '$state', '$transition$', 'Notifications', 'StoridgeProfileService', 'ModalService',
function ($scope, $state, $transition$, Notifications, StoridgeProfileService, ModalService) {
+ $scope.formValues = {
+ Labels: []
+ };
+
$scope.state = {
NoLimit: false,
LimitIOPS: false,
LimitBandwidth: false,
updateInProgress: false,
- deleteInProgress: false
+ deleteInProgress: false,
+ RecurringSnapshotEnabled: false
};
+ $scope.addLabel = function() {
+ $scope.formValues.Labels.push({ name: '', value: ''});
+ };
+
+ $scope.removeLabel = function(index) {
+ $scope.formValues.Labels.splice(index, 1);
+ };
+
+ function prepareLabels(profile) {
+ var labels = {};
+ $scope.formValues.Labels.forEach(function (label) {
+ if (label.name && label.value) {
+ labels[label.name] = label.value;
+ }
+ });
+ profile.Labels = labels;
+ }
+
+ function initLabels(labels) {
+ $scope.formValues.Labels = Object.keys(labels).map(function(key) {
+ return { name:key, value:labels[key] };
+ });
+ }
+
$scope.RedundancyOptions = [
{ value: 2, label: '2-copy' },
{ value: 3, label: '3-copy' }
];
$scope.update = function() {
-
var profile = $scope.profile;
if (!$scope.state.LimitIOPS) {
@@ -29,6 +57,23 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService, M
delete profile.MaxBandwidth;
}
+ if (profile.SnapshotEnabled) {
+ if (!profile.SnapshotMax || profile.SnapshotMax <= 0) {
+ profile.SnapshotMax = 1;
+ }
+ if (!$scope.state.RecurringSnapshotEnabled) {
+ delete profile.SnapshotInterval;
+ }
+ if ($scope.state.RecurringSnapshotEnabled && (!profile.SnapshotInterval || profile.SnapshotInterval <= 0)) {
+ profile.SnapshotInterval = 1440;
+ }
+ } else {
+ delete profile.SnapshotMax;
+ delete profile.SnapshotInterval;
+ }
+
+ prepareLabels(profile);
+
$scope.state.updateInProgress = true;
StoridgeProfileService.update(profile)
.then(function success() {
@@ -81,6 +126,10 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService, M
} else {
$scope.state.NoLimit = true;
}
+ if (profile.SnapshotEnabled && profile.SnapshotInterval !== 0) {
+ $scope.state.RecurringSnapshotEnabled = true;
+ }
+ initLabels(profile.Labels);
$scope.profile = profile;
})
.catch(function error(err) {
diff --git a/app/extensions/storidge/views/profiles/profilesController.js b/app/extensions/storidge/views/profiles/profilesController.js
index 2214739c7..f60d5c6d5 100644
--- a/app/extensions/storidge/views/profiles/profilesController.js
+++ b/app/extensions/storidge/views/profiles/profilesController.js
@@ -1,3 +1,4 @@
+import _ from 'lodash-es';
import { StoridgeProfileDefaultModel } from '../../models/profile';
angular.module('extension.storidge')
@@ -35,8 +36,13 @@ function ($q, $scope, $state, Notifications, StoridgeProfileService) {
$scope.create = function() {
var model = new StoridgeProfileDefaultModel();
+ model.Labels = {};
model.Name = $scope.formValues.Name;
- model.Directory = model.Directory + model.Name;
+ model.Directory = model.Directory + _.toLower(model.Name);
+ delete model.MinBandwidth;
+ delete model.MaxBandwidth;
+ delete model.MinIOPS;
+ delete model.MaxIOPS;
$scope.state.actionInProgress = true;
StoridgeProfileService.create(model)
diff --git a/app/extensions/storidge/views/snapshots/inspect/snapshot.html b/app/extensions/storidge/views/snapshots/inspect/snapshot.html
new file mode 100644
index 000000000..fb9d1afa4
--- /dev/null
+++ b/app/extensions/storidge/views/snapshots/inspect/snapshot.html
@@ -0,0 +1,53 @@
+
+
+
+ Volumes > {{ volumeId }} > Snapshots > {{ snapshot.Id }}
+
+
+
+
+
+
+
+
+
+
+
+ ID |
+
+ {{ snapshot.Id }}
+
+ |
+
+
+ Date |
+ {{ snapshot.Date }} |
+
+
+ Description |
+ {{ snapshot.Description }} |
+
+
+ SourceID |
+ {{ snapshot.SourceID }} |
+
+
+ Type |
+ {{ snapshot.Type }} |
+
+
+ Directory |
+ {{ snapshot.Directory }} |
+
+
+ Source |
+ {{ snapshot.Source }} |
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/extensions/storidge/views/snapshots/inspect/snapshotController.js b/app/extensions/storidge/views/snapshots/inspect/snapshotController.js
new file mode 100644
index 000000000..1534087cd
--- /dev/null
+++ b/app/extensions/storidge/views/snapshots/inspect/snapshotController.js
@@ -0,0 +1,44 @@
+angular.module('extension.storidge')
+.controller('StoridgeSnapshotController', ['$scope', '$state', '$transition$', 'Notifications', 'ModalService', 'StoridgeSnapshotService',
+function ($scope, $state, $transition$, Notifications, ModalService, StoridgeSnapshotService) {
+
+ $scope.removeSnapshot = function () {
+ ModalService.confirm({
+ title: 'Are you sure?',
+ message: 'Do you want really want to remove this snapshot?',
+ buttons: {
+ confirm: {
+ label: 'Remove',
+ className: 'btn-danger'
+ }
+ },
+ callback: function onConfirm(confirmed) {
+ if(!confirmed) { return; }
+ StoridgeSnapshotService.remove($scope.snapshot.Id)
+ .then(function () {
+ Notifications.success('Success', 'Snapshot removed');
+ $state.go('portainer.volumes.volume', {id: $scope.volumeId});
+ })
+ .catch(function error(err) {
+ Notifications.error('Failure', err, 'Unable to remove snapshot');
+ });
+ }
+ });
+ };
+
+ function initView() {
+ $scope.volumeId = $transition$.params().id;
+ $scope.snapshotId = $transition$.params().snapshotId;
+
+ StoridgeSnapshotService.snapshot($scope.snapshotId)
+ .then(function success(data) {
+ $scope.snapshot = data;
+ })
+ .catch(function error(err) {
+ Notifications.error('Failure', err, 'Unable to retrieve snapshot details');
+ });
+ }
+
+ initView();
+
+}]);
diff --git a/app/portainer/components/datatables/genericDatatableController.js b/app/portainer/components/datatables/genericDatatableController.js
index 15fe1a8d0..3fb1db1c8 100644
--- a/app/portainer/components/datatables/genericDatatableController.js
+++ b/app/portainer/components/datatables/genericDatatableController.js
@@ -1,13 +1,13 @@
import './datatable.css';
angular.module('portainer.app')
-.controller('GenericDatatableController', ['PaginationService', 'DatatableService',
-function (PaginationService, DatatableService) {
+.controller('GenericDatatableController', ['PaginationService', 'DatatableService', 'PAGINATION_MAX_ITEMS',
+function (PaginationService, DatatableService, PAGINATION_MAX_ITEMS) {
this.state = {
selectAll: false,
orderBy: this.orderBy,
- paginatedItemLimit: PaginationService.getPaginationLimit(this.tableKey),
+ paginatedItemLimit: PAGINATION_MAX_ITEMS,
displayTextFilter: false,
selectedItemCount: 0,
selectedItems: []
@@ -67,5 +67,6 @@ function (PaginationService, DatatableService) {
function setDefaults(ctrl) {
ctrl.showTextFilter = ctrl.showTextFilter ? ctrl.showTextFilter : false;
ctrl.state.reverseOrder = ctrl.reverseOrder ? ctrl.reverseOrder : false;
+ ctrl.state.paginatedItemLimit = PaginationService.getPaginationLimit(ctrl.tableKey);
}
}]);
diff --git a/app/portainer/components/slider/sliderController.js b/app/portainer/components/slider/sliderController.js
index 21175579d..8755097cb 100644
--- a/app/portainer/components/slider/sliderController.js
+++ b/app/portainer/components/slider/sliderController.js
@@ -10,7 +10,7 @@ angular.module('portainer.app')
showSelectionBar: true,
enforceStep: false,
translate: function(value, sliderId, label) {
- if (label === 'floor' || value === 0) {
+ if ((label === 'floor' && ctrl.floor === 0) || value === 0) {
return 'unlimited';
}
return value;
diff --git a/app/portainer/filters/filters.js b/app/portainer/filters/filters.js
index f6b6d881f..30ef37384 100644
--- a/app/portainer/filters/filters.js
+++ b/app/portainer/filters/filters.js
@@ -38,7 +38,7 @@ angular.module('portainer.app')
.filter('capitalize', function () {
'use strict';
return function (text) {
- return _.capitalize(text);
+ return text ? _.capitalize(text) : '';
};
})
.filter('stripprotocol', function() {
diff --git a/app/portainer/services/legacyExtensionManager.js b/app/portainer/services/legacyExtensionManager.js
index 580457b14..8b0aa783a 100644
--- a/app/portainer/services/legacyExtensionManager.js
+++ b/app/portainer/services/legacyExtensionManager.js
@@ -2,8 +2,8 @@ import _ from 'lodash-es';
// TODO: legacy extension management
angular.module('portainer.app')
-.factory('LegacyExtensionManager', ['$q', 'PluginService', 'SystemService', 'LegacyExtensionService',
-function ExtensionManagerFactory($q, PluginService, SystemService, LegacyExtensionService) {
+.factory('LegacyExtensionManager', ['$q', 'PluginService', 'SystemService', 'NodeService', 'LegacyExtensionService',
+function ExtensionManagerFactory($q, PluginService, SystemService, NodeService, LegacyExtensionService) {
'use strict';
var service = {};
@@ -59,9 +59,9 @@ function ExtensionManagerFactory($q, PluginService, SystemService, LegacyExtensi
function registerStoridgeUsingSwarmManagerIP() {
var deferred = $q.defer();
- SystemService.info()
+ NodeService.getActiveManager()
.then(function success(data) {
- var managerIP = data.Swarm.NodeAddr;
+ var managerIP = data.Addr;
var storidgeAPIURL = 'tcp://' + managerIP + ':8282';
return LegacyExtensionService.registerStoridgeExtension(storidgeAPIURL);
})
diff --git a/app/portainer/services/localStorage.js b/app/portainer/services/localStorage.js
index f23f0ba50..31754881d 100644
--- a/app/portainer/services/localStorage.js
+++ b/app/portainer/services/localStorage.js
@@ -60,10 +60,10 @@ angular.module('portainer.app')
localStorageService.remove('JWT');
},
storePaginationLimit: function(key, count) {
- localStorageService.cookie.set('pagination_' + key, count);
+ localStorageService.set('datatable_pagination_' + key, count);
},
getPaginationLimit: function(key) {
- return localStorageService.cookie.get('pagination_' + key);
+ return localStorageService.get('datatable_pagination_' + key);
},
getDataTableOrder: function(key) {
return localStorageService.get('datatable_order_' + key);
diff --git a/app/portainer/services/notifications.js b/app/portainer/services/notifications.js
index cff57364e..010c27079 100644
--- a/app/portainer/services/notifications.js
+++ b/app/portainer/services/notifications.js
@@ -21,6 +21,8 @@ angular.module('portainer.app')
msg = e.data.details;
} else if (e.data && e.data.message) {
msg = e.data.message;
+ } else if (e.data && e.data.content) {
+ msg = e.data.content;
} else if (e.message) {
msg = e.message;
} else if (e.err && e.err.data && e.err.data.message) {
diff --git a/app/portainer/views/sidebar/sidebar.html b/app/portainer/views/sidebar/sidebar.html
index 6193f73ef..0f833f739 100644
--- a/app/portainer/views/sidebar/sidebar.html
+++ b/app/portainer/views/sidebar/sidebar.html
@@ -25,16 +25,19 @@
offline-mode="endpointState.OfflineMode"
>