No tags matching your filter.
diff --git a/app/portainer/components/tag-selector/tagSelectorController.js b/app/portainer/components/tag-selector/tagSelectorController.js
index 3d64485e3..40b99d3e5 100644
--- a/app/portainer/components/tag-selector/tagSelectorController.js
+++ b/app/portainer/components/tag-selector/tagSelectorController.js
@@ -1,35 +1,62 @@
+import angular from 'angular';
import _ from 'lodash-es';
-angular.module('portainer.app').controller('TagSelectorController', function() {
- this.$onInit = function() {
- this.state.selectedTags = _.map(this.model, (id) => _.find(this.tags, (t) => t.Id === id));
- };
-
- this.state = {
- selectedValue: '',
- selectedTags: [],
- noResult: false,
- };
-
- this.selectTag = function($item) {
- this.state.selectedValue = '';
- this.model.push($item.Id);
- this.state.selectedTags.push($item);
- };
-
- this.removeTag = function removeTag(tag) {
- _.remove(this.state.selectedTags, { Id: tag.Id });
- _.remove(this.model, (id) => id === tag.Id);
- };
-
- this.filterSelected = filterSelected.bind(this);
-
- function filterSelected($item) {
- if (!this.model) {
- return true;
- }
- return !_.includes(this.model, $item.Id);
+class TagSelectorController {
+ /* @ngInject */
+ constructor() {
+ this.state = {
+ selectedValue: '',
+ selectedTags: [],
+ noResult: false,
+ };
}
- window._remove = _.remove;
-});
+ removeTag(tag) {
+ _.remove(this.model, (id) => tag.Id === id);
+ _.remove(this.state.selectedTags, { Id: tag.Id });
+ }
+
+ selectTag($item) {
+ this.state.selectedValue = '';
+ if ($item.create && this.allowCreate) {
+ this.onCreate($item.value);
+ return;
+ }
+ this.state.selectedTags.push($item);
+ this.model.push($item.Id);
+ }
+
+ filterTags(searchValue) {
+ let filteredTags = _.filter(this.tags, (tag) => !_.includes(this.model, tag.Id));
+ if (!searchValue) {
+ return filteredTags.slice(0, 7);
+ }
+
+ const exactTag = _.find(this.tags, (tag) => tag.Name === searchValue);
+ filteredTags = _.filter(filteredTags, (tag) => _.includes(tag.Name.toLowerCase(), searchValue.toLowerCase()));
+ if (exactTag || !this.allowCreate) {
+ return filteredTags.slice(0, 7);
+ }
+
+ return filteredTags.slice(0, 6).concat({ Name: `Create "${searchValue}"`, create: true, value: searchValue });
+ }
+
+ generateSelectedTags(model, tags) {
+ this.state.selectedTags = _.map(model, (id) => _.find(tags, (t) => t.Id === id));
+ }
+
+ $onInit() {
+ this.generateSelectedTags(this.model, this.tags);
+ }
+
+ $onChanges({ tags, model }) {
+ const tagsValue = tags && tags.currentValue ? tags.currentValue : this.tags;
+ const modelValue = model && model.currentValue ? model.currentValue : this.model;
+ if (modelValue && tagsValue) {
+ this.generateSelectedTags(modelValue, tagsValue);
+ }
+ }
+}
+
+export default TagSelectorController;
+angular.module('portainer.app').controller('TagSelectorController', TagSelectorController);
diff --git a/app/portainer/services/api/tagService.js b/app/portainer/services/api/tagService.js
index b8c6e3918..d7c952dd2 100644
--- a/app/portainer/services/api/tagService.js
+++ b/app/portainer/services/api/tagService.js
@@ -35,12 +35,16 @@ angular.module('portainer.app')
return deferred.promise;
};
- service.createTag = function(name) {
+ service.createTag = async function(name) {
var payload = {
Name: name
};
-
- return Tags.create({}, payload).$promise;
+ try {
+ const tag = await Tags.create({}, payload).$promise;
+ return new TagViewModel(tag);
+ } catch(err) {
+ throw { msg: 'Unable to create tag', err };
+ }
};
service.deleteTag = function(id) {
diff --git a/app/portainer/views/endpoints/create/createEndpointController.js b/app/portainer/views/endpoints/create/createEndpointController.js
index 968aa041b..3bb7a989f 100644
--- a/app/portainer/views/endpoints/create/createEndpointController.js
+++ b/app/portainer/views/endpoints/create/createEndpointController.js
@@ -1,12 +1,12 @@
import {EndpointSecurityFormData} from '../../../components/endpointSecurity/porEndpointSecurityModel';
-angular.module('portainer.app')
-.controller('CreateEndpointController', ['$q', '$scope', '$state', '$filter', 'clipboard', 'EndpointService', 'GroupService', 'TagService', 'Notifications',
-function ($q, $scope, $state, $filter, clipboard, EndpointService, GroupService, TagService, Notifications) {
+angular.module('portainer.app').controller('CreateEndpointController',
+function CreateEndpointController($async, $q, $scope, $state, $filter, clipboard, EndpointService, GroupService, TagService, Notifications, Authentication) {
$scope.state = {
EnvironmentType: 'agent',
- actionInProgress: false
+ actionInProgress: false,
+ allowCreateTag: Authentication.isAdmin()
};
$scope.formValues = {
@@ -84,6 +84,20 @@ function ($q, $scope, $state, $filter, clipboard, EndpointService, GroupService,
createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tagIds);
};
+ $scope.onCreateTag = function onCreateTag(tagName) {
+ return $async(onCreateTagAsync, tagName);
+ }
+
+ async function onCreateTagAsync(tagName) {
+ try {
+ const tag = await TagService.createTag(tagName);
+ $scope.availableTags = $scope.availableTags.concat(tag);
+ $scope.formValues.TagIds = $scope.formValues.TagIds.concat(tag.Id);
+ } catch(err) {
+ Notifications.error('Failue', err, 'Unable to create tag');
+ }
+ }
+
function createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tagIds) {
$scope.state.actionInProgress = true;
EndpointService.createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tagIds)
@@ -133,4 +147,4 @@ function ($q, $scope, $state, $filter, clipboard, EndpointService, GroupService,
}
initView();
-}]);
+});
diff --git a/app/portainer/views/endpoints/create/createendpoint.html b/app/portainer/views/endpoints/create/createendpoint.html
index 89308e179..955453464 100644
--- a/app/portainer/views/endpoints/create/createendpoint.html
+++ b/app/portainer/views/endpoints/create/createendpoint.html
@@ -259,10 +259,12 @@
+ allow-create="state.allowCreateTag"
+ on-create="onCreateTag"
+ >
diff --git a/app/portainer/views/endpoints/edit/endpoint.html b/app/portainer/views/endpoints/edit/endpoint.html
index d33e8bd7a..827a9aa97 100644
--- a/app/portainer/views/endpoints/edit/endpoint.html
+++ b/app/portainer/views/endpoints/edit/endpoint.html
@@ -165,9 +165,11 @@
diff --git a/app/portainer/views/endpoints/edit/endpointController.js b/app/portainer/views/endpoints/edit/endpointController.js
index b01a5f1ad..451b6955f 100644
--- a/app/portainer/views/endpoints/edit/endpointController.js
+++ b/app/portainer/views/endpoints/edit/endpointController.js
@@ -3,8 +3,8 @@ import uuidv4 from 'uuid/v4';
import {EndpointSecurityFormData} from '../../../components/endpointSecurity/porEndpointSecurityModel';
angular.module('portainer.app')
-.controller('EndpointController', ['$q', '$scope', '$state', '$transition$', '$filter', 'clipboard', 'EndpointService', 'GroupService', 'TagService', 'EndpointProvider', 'Notifications',
-function ($q, $scope, $state, $transition$, $filter, clipboard, EndpointService, GroupService, TagService, EndpointProvider, Notifications) {
+.controller('EndpointController',
+function EndpointController($async, $q, $scope, $state, $transition$, $filter, clipboard, EndpointService, GroupService, TagService, EndpointProvider, Notifications, Authentication) {
if (!$scope.applicationState.application.endpointManagement) {
$state.go('portainer.endpoints');
@@ -13,13 +13,16 @@ function ($q, $scope, $state, $transition$, $filter, clipboard, EndpointService,
$scope.state = {
uploadInProgress: false,
actionInProgress: false,
- deploymentTab: 0
+ deploymentTab: 0,
+ allowCreate: Authentication.isAdmin()
};
$scope.formValues = {
SecurityFormData: new EndpointSecurityFormData()
};
+
+
$scope.copyEdgeAgentDeploymentCommand = function() {
if ($scope.state.deploymentTab === 0) {
clipboard.copyText('docker run -d -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker/volumes:/var/lib/docker/volumes -v /:/host --restart always -e EDGE=1 -e EDGE_ID=' + $scope.randomEdgeID + ' -e EDGE_KEY=' + $scope.endpoint.EdgeKey +' -e CAP_HOST_MANAGEMENT=1 -v portainer_agent_data:/data --name portainer_edge_agent portainer/agent');
@@ -34,6 +37,20 @@ function ($q, $scope, $state, $transition$, $filter, clipboard, EndpointService,
$('#copyNotificationEdgeKey').show().fadeOut(2500);
};
+ $scope.onCreateTag = function onCreateTag(tagName) {
+ return $async(onCreateTagAsync, tagName);
+ }
+
+ async function onCreateTagAsync(tagName) {
+ try {
+ const tag = await TagService.createTag(tagName);
+ $scope.availableTags = $scope.availableTags.concat(tag);
+ $scope.endpoint.TagIds = $scope.endpoint.TagIds.concat(tag.Id);
+ } catch(err) {
+ Notifications.error('Failue', err, 'Unable to create tag');
+ }
+ }
+
$scope.updateEndpoint = function() {
var endpoint = $scope.endpoint;
var securityData = $scope.formValues.SecurityFormData;
@@ -120,4 +137,4 @@ function ($q, $scope, $state, $transition$, $filter, clipboard, EndpointService,
}
initView();
-}]);
+});
diff --git a/app/portainer/views/groups/create/createGroupController.js b/app/portainer/views/groups/create/createGroupController.js
index 109e70ca1..9308c93b0 100644
--- a/app/portainer/views/groups/create/createGroupController.js
+++ b/app/portainer/views/groups/create/createGroupController.js
@@ -1,8 +1,7 @@
import {EndpointGroupDefaultModel} from '../../../models/group';
angular.module('portainer.app')
-.controller('CreateGroupController', ['$q', '$scope', '$state', 'GroupService', 'EndpointService', 'TagService', 'Notifications',
-function ($q, $scope, $state, GroupService, EndpointService, TagService, Notifications) {
+.controller('CreateGroupController', function CreateGroupController($async, $scope, $state, GroupService, TagService, Notifications) {
$scope.state = {
actionInProgress: false
@@ -31,6 +30,20 @@ function ($q, $scope, $state, GroupService, EndpointService, TagService, Notific
});
};
+ $scope.onCreateTag = function onCreateTag(tagName) {
+ return $async(onCreateTagAsync, tagName);
+ }
+
+ async function onCreateTagAsync(tagName) {
+ try {
+ const tag = await TagService.createTag(tagName);
+ $scope.availableTags = $scope.availableTags.concat(tag);
+ $scope.model.TagIds = $scope.model.TagIds.concat(tag.Id);
+ } catch(err) {
+ Notifications.error('Failue', err, 'Unable to create tag');
+ }
+ }
+
function initView() {
TagService.tags()
.then((tags) => {
@@ -45,4 +58,4 @@ function ($q, $scope, $state, GroupService, EndpointService, TagService, Notific
}
initView();
-}]);
+});
diff --git a/app/portainer/views/groups/create/creategroup.html b/app/portainer/views/groups/create/creategroup.html
index 480d04f81..e89b01e08 100644
--- a/app/portainer/views/groups/create/creategroup.html
+++ b/app/portainer/views/groups/create/creategroup.html
@@ -21,6 +21,7 @@
form-action="create"
form-action-label="Create the group"
action-in-progress="state.actionInProgress"
+ on-create-tag="onCreateTag"
>
diff --git a/app/portainer/views/groups/edit/group.html b/app/portainer/views/groups/edit/group.html
index 7dca1c807..25b8f19a0 100644
--- a/app/portainer/views/groups/edit/group.html
+++ b/app/portainer/views/groups/edit/group.html
@@ -21,6 +21,7 @@
form-action="update"
form-action-label="Update the group"
action-in-progress="state.actionInProgress"
+ on-create-tag="onCreateTag"
>
diff --git a/app/portainer/views/groups/edit/groupController.js b/app/portainer/views/groups/edit/groupController.js
index d173e40b1..a9bcf1812 100644
--- a/app/portainer/views/groups/edit/groupController.js
+++ b/app/portainer/views/groups/edit/groupController.js
@@ -1,6 +1,5 @@
-angular.module('portainer.app')
-.controller('GroupController', ['$q', '$scope', '$state', '$transition$', 'GroupService', 'TagService', 'Notifications',
-function ($q, $scope, $state, $transition$, GroupService, TagService, Notifications) {
+angular.module('portainer.app').controller('GroupController',
+function GroupController($q, $async, $scope, $state, $transition$, GroupService, TagService, Notifications) {
$scope.state = {
actionInProgress: false
@@ -23,6 +22,20 @@ function ($q, $scope, $state, $transition$, GroupService, TagService, Notificati
});
};
+ $scope.onCreateTag = function onCreateTag(tagName) {
+ return $async(onCreateTagAsync, tagName);
+ }
+
+ async function onCreateTagAsync(tagName) {
+ try {
+ const tag = await TagService.createTag(tagName);
+ $scope.availableTags = $scope.availableTags.concat(tag);
+ $scope.group.TagIds = $scope.group.TagIds.concat(tag.Id);
+ } catch(err) {
+ Notifications.error('Failue', err, 'Unable to create tag');
+ }
+ }
+
function initView() {
var groupId = $transition$.params().id;
@@ -41,4 +54,4 @@ function ($q, $scope, $state, $transition$, GroupService, TagService, Notificati
}
initView();
-}]);
+});