create tag from tag selector (#3640)
* feat(tags): add button to save tag when doesn't exist * feat(endpoints): allow the creating of tags in endpoint edit * feat(groups): allow user to create tags in create group * feat(groups): allow user to create tags in edit group * feat(endpoint): allow user to create tags from endpoint create * feat(tags): allow the creation of a new tag from dropdown * feat(tag): replace "add" with "create" * feat(tags): show tags input when not tags * feat(tags): hide create message when not allowed * refactor(tags): replace component controller with class * refactor(tags): replace native methods with lodash * refactor(tags): remove unused onChangeTags function * refactor(tags): remove on-change binding * style(tags): remove white space * refactor(endpoint-groups): move controller to separate file * fix(groups): allow admin to create tag in group form * refactor(endpoints): wrap async function with try catch and $async * style(tags): wrap arrow function args with parenthesis * refactor(endpoints): return $async functions * refactor(tags): throw error in the format Notification expectspull/3691/head
parent
dd6262cf69
commit
db8b3d6e5a
|
@ -1,92 +1,5 @@
|
|||
import _ from 'lodash-es';
|
||||
import angular from 'angular';
|
||||
|
||||
class GroupFormController {
|
||||
/* @ngInject */
|
||||
constructor($q, EndpointService, GroupService, Notifications) {
|
||||
this.$q = $q;
|
||||
this.EndpointService = EndpointService;
|
||||
this.GroupService = GroupService;
|
||||
this.Notifications = Notifications;
|
||||
|
||||
this.associateEndpoint = this.associateEndpoint.bind(this);
|
||||
this.dissociateEndpoint = this.dissociateEndpoint.bind(this);
|
||||
this.getPaginatedEndpointsByGroup = this.getPaginatedEndpointsByGroup.bind(this);
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
this.state = {
|
||||
available: {
|
||||
limit: '10',
|
||||
filter: '',
|
||||
pageNumber: 1,
|
||||
totalCount: 0
|
||||
},
|
||||
associated: {
|
||||
limit: '10',
|
||||
filter: '',
|
||||
pageNumber: 1,
|
||||
totalCount: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
associateEndpoint(endpoint) {
|
||||
if (this.pageType === 'create' && !_.includes(this.associatedEndpoints, endpoint)) {
|
||||
this.associatedEndpoints.push(endpoint);
|
||||
} else if (this.pageType === 'edit') {
|
||||
this.GroupService.addEndpoint(this.model.Id, endpoint)
|
||||
.then(() => {
|
||||
this.Notifications.success('Success', 'Endpoint successfully added to group');
|
||||
this.reloadTablesContent();
|
||||
})
|
||||
.catch((err) => this.Notifications.error('Error', err, 'Unable to add endpoint to group'));
|
||||
}
|
||||
}
|
||||
|
||||
dissociateEndpoint(endpoint) {
|
||||
if (this.pageType === 'create') {
|
||||
_.remove(this.associatedEndpoints, (item) => item.Id === endpoint.Id);
|
||||
} else if (this.pageType === 'edit') {
|
||||
this.GroupService.removeEndpoint(this.model.Id, endpoint.Id)
|
||||
.then(() => {
|
||||
this.Notifications.success('Success', 'Endpoint successfully removed from group');
|
||||
this.reloadTablesContent();
|
||||
})
|
||||
.catch((err) => this.Notifications.error('Error', err, 'Unable to remove endpoint from group'));
|
||||
}
|
||||
}
|
||||
|
||||
reloadTablesContent() {
|
||||
this.getPaginatedEndpointsByGroup(this.pageType, 'available');
|
||||
this.getPaginatedEndpointsByGroup(this.pageType, 'associated');
|
||||
this.GroupService.group(this.model.Id)
|
||||
.then((data) => {
|
||||
this.model = data;
|
||||
})
|
||||
}
|
||||
|
||||
getPaginatedEndpointsByGroup(pageType, tableType) {
|
||||
if (tableType === 'available') {
|
||||
const context = this.state.available;
|
||||
const start = (context.pageNumber - 1) * context.limit + 1;
|
||||
this.EndpointService.endpointsByGroup(start, context.limit, context.filter, 1)
|
||||
.then((data) => {
|
||||
this.availableEndpoints = data.value;
|
||||
this.state.available.totalCount = data.totalCount;
|
||||
});
|
||||
} else if (tableType === 'associated' && pageType === 'edit') {
|
||||
const groupId = this.model.Id ? this.model.Id : 1;
|
||||
const context = this.state.associated;
|
||||
const start = (context.pageNumber - 1) * context.limit + 1;
|
||||
this.EndpointService.endpointsByGroup(start, context.limit, context.filter, groupId)
|
||||
.then((data) => {
|
||||
this.associatedEndpoints = data.value;
|
||||
this.state.associated.totalCount = data.totalCount;
|
||||
});
|
||||
}
|
||||
// ignore (associated + create) group as there is no backend pagination for this table
|
||||
}
|
||||
}
|
||||
import GroupFormController from './groupFormController';
|
||||
|
||||
angular.module('portainer.app').component('groupForm', {
|
||||
templateUrl: './groupForm.html',
|
||||
|
@ -102,6 +15,7 @@ angular.module('portainer.app').component('groupForm', {
|
|||
removeLabelAction: '<',
|
||||
formAction: '<',
|
||||
formActionLabel: '@',
|
||||
actionInProgress: '<'
|
||||
actionInProgress: '<',
|
||||
onCreateTag: '<'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
<!-- tags -->
|
||||
<div class="form-group">
|
||||
<tag-selector
|
||||
ng-if="$ctrl.availableTags && $ctrl.model.TagIds"
|
||||
ng-if="$ctrl.model && $ctrl.availableTags"
|
||||
tags="$ctrl.availableTags"
|
||||
model="$ctrl.model.TagIds"
|
||||
allow-create="$ctrl.state.allowCreateTag"
|
||||
on-create="$ctrl.onCreateTag"
|
||||
></tag-selector>
|
||||
</div>
|
||||
<!-- !tags -->
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
import _ from 'lodash-es';
|
||||
import angular from 'angular';
|
||||
|
||||
class GroupFormController {
|
||||
/* @ngInject */
|
||||
constructor($q, EndpointService, GroupService, Notifications, Authentication) {
|
||||
this.$q = $q;
|
||||
this.EndpointService = EndpointService;
|
||||
this.GroupService = GroupService;
|
||||
this.Notifications = Notifications;
|
||||
this.Authentication = Authentication;
|
||||
|
||||
this.associateEndpoint = this.associateEndpoint.bind(this);
|
||||
this.dissociateEndpoint = this.dissociateEndpoint.bind(this);
|
||||
this.getPaginatedEndpointsByGroup = this.getPaginatedEndpointsByGroup.bind(this);
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
this.state = {
|
||||
available: {
|
||||
limit: '10',
|
||||
filter: '',
|
||||
pageNumber: 1,
|
||||
totalCount: 0
|
||||
},
|
||||
associated: {
|
||||
limit: '10',
|
||||
filter: '',
|
||||
pageNumber: 1,
|
||||
totalCount: 0
|
||||
},
|
||||
allowCreateTag: this.Authentication.isAdmin()
|
||||
};
|
||||
}
|
||||
associateEndpoint(endpoint) {
|
||||
if (this.pageType === 'create' && !_.includes(this.associatedEndpoints, endpoint)) {
|
||||
this.associatedEndpoints.push(endpoint);
|
||||
} else if (this.pageType === 'edit') {
|
||||
this.GroupService.addEndpoint(this.model.Id, endpoint)
|
||||
.then(() => {
|
||||
this.Notifications.success('Success', 'Endpoint successfully added to group');
|
||||
this.reloadTablesContent();
|
||||
})
|
||||
.catch((err) => this.Notifications.error('Error', err, 'Unable to add endpoint to group'));
|
||||
}
|
||||
}
|
||||
|
||||
dissociateEndpoint(endpoint) {
|
||||
if (this.pageType === 'create') {
|
||||
_.remove(this.associatedEndpoints, (item) => item.Id === endpoint.Id);
|
||||
} else if (this.pageType === 'edit') {
|
||||
this.GroupService.removeEndpoint(this.model.Id, endpoint.Id)
|
||||
.then(() => {
|
||||
this.Notifications.success('Success', 'Endpoint successfully removed from group');
|
||||
this.reloadTablesContent();
|
||||
})
|
||||
.catch((err) => this.Notifications.error('Error', err, 'Unable to remove endpoint from group'));
|
||||
}
|
||||
}
|
||||
|
||||
reloadTablesContent() {
|
||||
this.getPaginatedEndpointsByGroup(this.pageType, 'available');
|
||||
this.getPaginatedEndpointsByGroup(this.pageType, 'associated');
|
||||
this.GroupService.group(this.model.Id)
|
||||
.then((data) => {
|
||||
this.model = data;
|
||||
})
|
||||
}
|
||||
|
||||
getPaginatedEndpointsByGroup(pageType, tableType) {
|
||||
if (tableType === 'available') {
|
||||
const context = this.state.available;
|
||||
const start = (context.pageNumber - 1) * context.limit + 1;
|
||||
this.EndpointService.endpointsByGroup(start, context.limit, context.filter, 1)
|
||||
.then((data) => {
|
||||
this.availableEndpoints = data.value;
|
||||
this.state.available.totalCount = data.totalCount;
|
||||
});
|
||||
} else if (tableType === 'associated' && pageType === 'edit') {
|
||||
const groupId = this.model.Id ? this.model.Id : 1;
|
||||
const context = this.state.associated;
|
||||
const start = (context.pageNumber - 1) * context.limit + 1;
|
||||
this.EndpointService.endpointsByGroup(start, context.limit, context.filter, groupId)
|
||||
.then((data) => {
|
||||
this.associatedEndpoints = data.value;
|
||||
this.state.associated.totalCount = data.totalCount;
|
||||
});
|
||||
}
|
||||
// ignore (associated + create) group as there is no backend pagination for this table
|
||||
}
|
||||
}
|
||||
|
||||
angular.module('portainer.app').controller('GroupFormController', GroupFormController);
|
||||
export default GroupFormController;
|
|
@ -4,5 +4,7 @@ angular.module('portainer.app').component('tagSelector', {
|
|||
bindings: {
|
||||
tags: '<',
|
||||
model: '=',
|
||||
onCreate: '<',
|
||||
allowCreate: '<'
|
||||
},
|
||||
});
|
||||
|
|
|
@ -15,24 +15,24 @@
|
|||
<label for="tags" class="col-sm-3 col-lg-2 control-label text-left">
|
||||
Tags
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10" ng-if="$ctrl.tags.length > 0">
|
||||
<div class="col-sm-9 col-lg-10" ng-if="$ctrl.allowCreate || $ctrl.tags.length > 0">
|
||||
<input
|
||||
type="text" ng-model="$ctrl.state.selectedValue"
|
||||
id="tags" class="form-control"
|
||||
placeholder="Select tags..."
|
||||
uib-typeahead="tag.Id as tag.Name for tag in $ctrl.tags | filter: $ctrl.filterSelected | filter:$viewValue | limitTo:7"
|
||||
uib-typeahead="tag.Id as tag.Name for tag in $ctrl.filterTags($viewValue)"
|
||||
typeahead-on-select="$ctrl.selectTag($item, $model, $label)"
|
||||
typeahead-no-results="$ctrl.state.noResult"
|
||||
typeahead-show-hint="true" typeahead-min-length="0"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-9 col-lg-10" ng-if="$ctrl.tags.length === 0">
|
||||
<div class="col-sm-9 col-lg-10" ng-if="!$ctrl.allowCreate && $ctrl.tags.length === 0">
|
||||
<span class="small text-muted">
|
||||
No tags available.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-offset-3 col-lg-offset-2 col-sm-12" ng-if="$ctrl.state.noResult" style="margin-top: 2px;">
|
||||
<div class="col-sm-offset-3 col-lg-offset-2 col-sm-12" ng-if="!$ctrl.allowCreate && $ctrl.state.noResult" style="margin-top: 2px;">
|
||||
<span class="small text-muted">
|
||||
No tags matching your filter.
|
||||
</span>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}]);
|
||||
});
|
||||
|
|
|
@ -259,10 +259,12 @@
|
|||
<!-- tags -->
|
||||
<div class="form-group">
|
||||
<tag-selector
|
||||
ng-if="availableTags"
|
||||
ng-if="formValues && availableTags"
|
||||
tags="availableTags"
|
||||
model="formValues.TagIds"
|
||||
></tag-selector>
|
||||
allow-create="state.allowCreateTag"
|
||||
on-create="onCreateTag"
|
||||
></tag-selector>
|
||||
</div>
|
||||
<!-- !tags -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
|
|
|
@ -165,9 +165,11 @@
|
|||
<!-- tags -->
|
||||
<div class="form-group">
|
||||
<tag-selector
|
||||
ng-if="availableTags && endpoint.TagIds"
|
||||
ng-if="endpoint && availableTags"
|
||||
tags="availableTags"
|
||||
model="endpoint.TagIds"
|
||||
on-create="onCreateTag"
|
||||
allow-create="state.allowCreate"
|
||||
></tag-selector>
|
||||
</div>
|
||||
<!-- !tags -->
|
||||
|
|
|
@ -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();
|
||||
}]);
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
}]);
|
||||
});
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
form-action="create"
|
||||
form-action-label="Create the group"
|
||||
action-in-progress="state.actionInProgress"
|
||||
on-create-tag="onCreateTag"
|
||||
></group-form>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
form-action="update"
|
||||
form-action-label="Update the group"
|
||||
action-in-progress="state.actionInProgress"
|
||||
on-create-tag="onCreateTag"
|
||||
></group-form>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
|
|
@ -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();
|
||||
}]);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue