refactor(app): convert tag-selector to react [EE-2983] (#6783)

pull/6997/head
Chaim Lev-Ari 2022-05-29 09:14:14 +03:00 committed by GitHub
parent 75d854e6ad
commit d52417c14f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 103 additions and 288 deletions

View File

@ -3,6 +3,7 @@ import '../app/assets/css';
import { pushStateLocationPlugin, UIRouter } from '@uirouter/react';
import { initialize as initMSW, mswDecorator } from 'msw-storybook-addon';
import { handlers } from '@/setup-tests/server-handlers';
import { QueryClient, QueryClientProvider } from 'react-query';
// Initialize MSW
initMSW({
@ -31,11 +32,17 @@ export const parameters = {
},
};
const testQueryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
export const decorators = [
(Story) => (
<UIRouter plugins={[pushStateLocationPlugin]}>
<Story />
</UIRouter>
<QueryClientProvider client={testQueryClient}>
<UIRouter plugins={[pushStateLocationPlugin]}>
<Story />
</UIRouter>
</QueryClientProvider>
),
mswDecorator,
];

View File

@ -807,13 +807,6 @@ json-tree .branch-preview {
}
/* !spinkit override */
/* uib-typeahead override */
#scrollable-dropdown-menu .dropdown-menu {
max-height: 300px;
overflow-y: auto;
}
/* !uib-typeahead override */
.kubectl-shell {
display: block;
text-align: center;

View File

@ -93,12 +93,9 @@
</div>
</div>
</div>
<div class="form-group">
<tag-selector ng-if="$ctrl.tags.length" tags="$ctrl.tags" model="$ctrl.model.TagIds"></tag-selector>
<div ng-if="$ctrl.tags && !$ctrl.tags.length" class="col-sm-12 small text-muted">
No tags available. Head over to the <a ui-sref="portainer.tags">Tags view</a> to add tags
</div>
</div>
<tag-selector ng-if="$ctrl.model.TagIds" value="$ctrl.model.TagIds" on-change="($ctrl.onChangeTags)"> </tag-selector>
<div class="col-sm-12 form-section-title"> Associated environments by tags </div>
<div class="col-sm-12 form-group">
<group-association-table

View File

@ -6,6 +6,7 @@ export class EdgeGroupFormController {
constructor(EndpointService, $async, $scope) {
this.EndpointService = EndpointService;
this.$async = $async;
this.$scope = $scope;
this.endpoints = {
state: {
@ -22,6 +23,7 @@ export class EdgeGroupFormController {
this.dissociateEndpoint = this.dissociateEndpoint.bind(this);
this.getDynamicEndpointsAsync = this.getDynamicEndpointsAsync.bind(this);
this.getDynamicEndpoints = this.getDynamicEndpoints.bind(this);
this.onChangeTags = this.onChangeTags.bind(this);
$scope.$watch(
() => this.model,
@ -34,6 +36,12 @@ export class EdgeGroupFormController {
);
}
onChangeTags(value) {
return this.$scope.$evalAsync(() => {
this.model.TagIds = value;
});
}
associateEndpoint(endpoint) {
if (!_.includes(this.model.Endpoints, endpoint.Id)) {
this.model.Endpoints = [...this.model.Endpoints, endpoint.Id];

View File

@ -8,7 +8,6 @@ angular.module('portainer.edge').component('edgeGroupForm', {
bindings: {
model: '<',
groups: '<',
tags: '<',
formActionLabel: '@',
formAction: '<',
actionInProgress: '<',

View File

@ -13,9 +13,7 @@
form-action-label="Add edge group"
form-action="$ctrl.createGroup"
groups="$ctrl.endpointGroups"
tags="$ctrl.tags"
model="$ctrl.model"
on-change-tags="($ctrl.onChangeTags)"
></edge-group-form>
</rd-widget-body>
</rd-widget>

View File

@ -1,9 +1,8 @@
export class CreateEdgeGroupController {
/* @ngInject */
constructor(EdgeGroupService, GroupService, TagService, Notifications, $state, $async) {
constructor(EdgeGroupService, GroupService, Notifications, $state, $async) {
this.EdgeGroupService = EdgeGroupService;
this.GroupService = GroupService;
this.TagService = TagService;
this.Notifications = Notifications;
this.$state = $state;
this.$async = $async;
@ -26,8 +25,8 @@ export class CreateEdgeGroupController {
}
async $onInit() {
const [tags, endpointGroups] = await Promise.all([this.TagService.tags(), this.GroupService.groups()]);
this.tags = tags;
const endpointGroups = await this.GroupService.groups();
this.endpointGroups = endpointGroups;
this.state.loaded = true;
}

View File

@ -14,7 +14,6 @@
form-action="$ctrl.updateGroup"
endpoints="$ctrl.endpoints"
groups="$ctrl.endpointGroups"
tags="$ctrl.tags"
model="$ctrl.model"
></edge-group-form>
</rd-widget-body>

View File

@ -1,9 +1,8 @@
export class EditEdgeGroupController {
/* @ngInject */
constructor(EdgeGroupService, GroupService, TagService, Notifications, $state, $async) {
constructor(EdgeGroupService, GroupService, Notifications, $state, $async) {
this.EdgeGroupService = EdgeGroupService;
this.GroupService = GroupService;
this.TagService = TagService;
this.Notifications = Notifications;
this.$state = $state;
this.$async = $async;
@ -18,13 +17,12 @@ export class EditEdgeGroupController {
}
async $onInit() {
const [tags, endpointGroups, group] = await Promise.all([this.TagService.tags(), this.GroupService.groups(), this.EdgeGroupService.group(this.$state.params.groupId)]);
const [endpointGroups, group] = await Promise.all([this.GroupService.groups(), this.EdgeGroupService.group(this.$state.params.groupId)]);
if (!group) {
this.Notifications.error('Failed to find edge group', {});
this.$state.go('edge.groups');
}
this.tags = tags;
this.endpointGroups = endpointGroups;
this.model = group;
this.state.loaded = true;

View File

@ -9,13 +9,11 @@ angular.module('portainer.app').component('groupForm', {
pageType: '@',
model: '=',
availableEndpoints: '=',
availableTags: '<',
associatedEndpoints: '=',
addLabelAction: '<',
removeLabelAction: '<',
formAction: '<',
formActionLabel: '@',
actionInProgress: '<',
onCreateTag: '<',
},
});

View File

@ -23,17 +23,9 @@
</div>
<!-- !description-input -->
<div class="col-sm-12 form-section-title"> Metadata </div>
<!-- tags -->
<div class="form-group">
<tag-selector
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 -->
<tag-selector ng-if="$ctrl.model.TagIds" value="$ctrl.model.TagIds" on-change="($ctrl.onChangeTags)" allow-create="$ctrl.state.allowCreateTag"> </tag-selector>
<!-- environments -->
<div ng-if="$ctrl.model.Id !== 1">
<div class="col-sm-12 form-section-title"> Associated environments </div>

View File

@ -3,8 +3,9 @@ import angular from 'angular';
class GroupFormController {
/* @ngInject */
constructor($q, EndpointService, GroupService, Notifications, Authentication) {
constructor($q, $scope, EndpointService, GroupService, Notifications, Authentication) {
this.$q = $q;
this.$scope = $scope;
this.EndpointService = EndpointService;
this.GroupService = GroupService;
this.Notifications = Notifications;
@ -13,6 +14,13 @@ class GroupFormController {
this.associateEndpoint = this.associateEndpoint.bind(this);
this.dissociateEndpoint = this.dissociateEndpoint.bind(this);
this.getPaginatedEndpointsByGroup = this.getPaginatedEndpointsByGroup.bind(this);
this.onChangeTags = this.onChangeTags.bind(this);
}
onChangeTags(value) {
return this.$scope.$evalAsync(() => {
this.model.TagIds = value;
});
}
$onInit() {

View File

@ -1,10 +0,0 @@
angular.module('portainer.app').component('tagSelector', {
templateUrl: './tagSelector.html',
controller: 'TagSelectorController',
bindings: {
tags: '<',
model: '=',
onCreate: '<',
allowCreate: '<',
},
});

View File

@ -1,35 +0,0 @@
<div ng-show="$ctrl.model.length > 0" class="col-sm-12" style="padding: 0; margin-bottom: 15px">
<label class="col-sm-3 col-lg-2 control-label text-left"> Selected tags </label>
<div class="col-sm-9 col-lg-10" style="padding-top: 4px">
<span class="tag space-right interactive" ng-repeat="tag in $ctrl.state.selectedTags" ng-click="$ctrl.removeTag(tag)">
{{ tag.Name }}
<a title="Remove tag" ng-click="$ctrl.removeTag(tag)" style="margin-left: 2px">
<span class="fa fa-trash-alt white-icon" aria-hidden="true"></span>
</a>
</span>
</div>
</div>
<div class="col-sm-12" style="padding: 0">
<label for="tags" class="col-sm-3 col-lg-2 control-label text-left"> Tags </label>
<div class="col-sm-9 col-lg-10" id="scrollable-dropdown-menu" 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.filterTags($viewValue)"
typeahead-on-select="$ctrl.selectTag($item, $model, $label)"
typeahead-no-results="$ctrl.state.noResult"
typeahead-show-hint="true"
typeahead-min-length="0"
data-cy="tags-tagInput"
/>
</div>
<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.allowCreate && $ctrl.state.noResult" style="margin-top: 2px">
<span class="small text-muted"> No tags matching your filter. </span>
</div>

View File

@ -1,62 +0,0 @@
import angular from 'angular';
import _ from 'lodash-es';
class TagSelectorController {
/* @ngInject */
constructor() {
this.state = {
selectedValue: '',
selectedTags: [],
noResult: false,
};
}
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;
}
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;
}
return filteredTags.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);

View File

@ -1,6 +1,11 @@
import angular from 'angular';
export const componentsModule = angular.module(
'portainer.app.react.components',
[]
).name;
import { r2a } from '@/react-tools/react2angular';
import { TagSelector } from '@/react/components/TagSelector';
export const componentsModule = angular
.module('portainer.app.react.components', [])
.component(
'tagSelector',
r2a(TagSelector, ['allowCreate', 'onChange', 'value'])
).name;

View File

@ -13,7 +13,7 @@ export async function getTags() {
export async function createTag(name: string) {
try {
const { data: tag } = await axios.post(buildUrl(), { name });
const { data: tag } = await axios.post<Tag>(buildUrl(), { name });
return tag;
} catch (err) {
throw parseAxiosError(err as Error, 'Unable to create tag');

View File

@ -188,12 +188,9 @@
</div>
</div>
<!-- !group -->
<!-- tags -->
<div class="form-group">
<tag-selector ng-if="formValues && availableTags" tags="availableTags" model="formValues.TagIds" allow-create="state.allowCreateTag" on-create="(onCreateTag)">
</tag-selector>
</div>
<!-- !tags -->
<tag-selector ng-if="formValues" value="formValues.TagIds" allow-create="state.allowCreateTag" on-change="(onChangeTags)"> </tag-selector>
<!-- actions -->
<div class="form-group">
<div class="col-sm-12">

View File

@ -28,6 +28,12 @@ angular
$scope.profiles = [];
$scope.onChangeTags = function onChangeTags(value) {
return $scope.$evalAsync(() => {
$scope.formValues.TagIds = value;
});
};
$scope.onVoucherFilesChange = function () {
if ($scope.formValues.VoucherFiles.length < 1) {
return;
@ -53,20 +59,6 @@ angular
});
};
$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('Failure', err, 'Unable to create tag');
}
}
$scope.createEndpointAndConfigureDevice = function () {
return $async(async () => {
$scope.state.actionInProgress = true;
@ -133,11 +125,9 @@ angular
$q.all({
groups: GroupService.groups(),
tags: TagService.tags(),
})
.then(function success(data) {
$scope.groups = data.groups;
$scope.availableTags = data.tags;
})
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to load groups');

View File

@ -17,7 +17,6 @@ angular
clipboard,
EndpointService,
GroupService,
TagService,
SettingsService,
Notifications,
Authentication,
@ -91,20 +90,12 @@ angular
$scope.formValues.URL = '';
};
$scope.onCreateTag = function onCreateTag(tagName) {
return $async(onCreateTagAsync, tagName);
$scope.onChangeTags = function onChangeTags(value) {
return $scope.$evalAsync(() => {
$scope.formValues.TagIds = value;
});
};
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('Failure', err, 'Unable to create tag');
}
}
function onChangeCheckInInterval(value) {
setFieldValue('EdgeCheckinInterval', value);
}
@ -310,12 +301,10 @@ angular
function initView() {
$q.all({
groups: GroupService.groups(),
tags: TagService.tags(),
settings: SettingsService.settings(),
})
.then(function success(data) {
$scope.groups = data.groups;
$scope.availableTags = data.tags;
const settings = data.settings;

View File

@ -436,12 +436,9 @@
</div>
</div>
<!-- !group -->
<!-- tags -->
<div class="form-group">
<tag-selector ng-if="formValues && availableTags" tags="availableTags" model="formValues.TagIds" allow-create="state.allowCreateTag" on-create="(onCreateTag)">
</tag-selector>
</div>
<!-- !tags -->
<tag-selector ng-if="formValues" value="formValues.TagIds" allow-create="state.allowCreateTag" on-change="(onChangeTags)"> </tag-selector>
<div class="col-sm-12 form-section-title"> Actions </div>
<!-- actions -->
<div class="form-group">

View File

@ -60,7 +60,7 @@
<div class="col-sm-12 form-section-title" style="margin-top: 25px"> Join token </div>
<p>
<i class="fa fa-info-circle blue-icon" aria-hidden="true" style="margin-right: 2px"></i>
For those prestaging the edge agent, use the following join token to associate the Edge agent with this environment.
For those pre-staging the edge agent, use the following join token to associate the Edge agent with this environment.
</p>
<p> You can read more about pre-staging in the userguide available <a href="https://downloads.portainer.io/edge_agent_guide.pdf">here.</a> </p>
<div style="margin-top: 10px; overflow-wrap: break-word">
@ -159,11 +159,9 @@
</div>
</div>
<!-- !group -->
<!-- tags -->
<div class="form-group">
<tag-selector ng-if="endpoint && availableTags" tags="availableTags" model="endpoint.TagIds" on-create="(onCreateTag)" allow-create="state.allowCreate"></tag-selector>
</div>
<!-- !tags -->
<tag-selector ng-if="endpoint" value="endpoint.TagIds" allow-create="state.allowCreate" on-change="(onChangeTags)"></tag-selector>
<!-- endpoint-security -->
<div ng-if="endpointType === 'remote' && !state.azureEndpoint && !state.kubernetesEndpoint && !state.edgeEndpoint && endpoint.Type !== 6">
<div class="col-sm-12 form-section-title"> Security </div>

View File

@ -20,7 +20,7 @@ function EndpointController(
clipboard,
EndpointService,
GroupService,
TagService,
Notifications,
Authentication,
SettingsService,
@ -28,6 +28,7 @@ function EndpointController(
) {
$scope.onChangeCheckInInterval = onChangeCheckInInterval;
$scope.setFieldValue = setFieldValue;
$scope.onChangeTags = onChangeTags;
$scope.state = {
uploadInProgress: false,
@ -51,26 +52,12 @@ function EndpointController(
$('#copyNotificationEdgeKey').show().fadeOut(2500);
};
$scope.onCreateTag = function onCreateTag(tagName) {
return $async(onCreateTagAsync, tagName);
};
$scope.onToggleAllowSelfSignedCerts = function onToggleAllowSelfSignedCerts(checked) {
return $scope.$evalAsync(() => {
$scope.state.allowSelfSignedCerts = checked;
});
};
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.onDisassociateEndpoint = async function () {
ModalService.confirmDisassociate((confirmed) => {
if (confirmed) {
@ -98,6 +85,10 @@ function EndpointController(
setFieldValue('EdgeCheckinInterval', value);
}
function onChangeTags(value) {
setFieldValue('TagIds', value);
}
function setFieldValue(name, value) {
return $scope.$evalAsync(() => {
$scope.endpoint = {
@ -229,12 +220,7 @@ function EndpointController(
async function initView() {
return $async(async () => {
try {
const [endpoint, groups, tags, settings] = await Promise.all([
EndpointService.endpoint($transition$.params().id),
GroupService.groups(),
TagService.tags(),
SettingsService.settings(),
]);
const [endpoint, groups, settings] = await Promise.all([EndpointService.endpoint($transition$.params().id), GroupService.groups(), SettingsService.settings()]);
if (endpoint.URL.indexOf('unix://') === 0 || endpoint.URL.indexOf('npipe://') === 0) {
$scope.endpointType = 'local';
@ -254,7 +240,6 @@ function EndpointController(
$scope.endpoint = endpoint;
$scope.initialTagIds = endpoint.TagIds.slice();
$scope.groups = groups;
$scope.availableTags = tags;
configureState();

View File

@ -1,6 +1,6 @@
import { EndpointGroupDefaultModel } from '../../../models/group';
angular.module('portainer.app').controller('CreateGroupController', function CreateGroupController($async, $scope, $state, GroupService, TagService, Notifications) {
angular.module('portainer.app').controller('CreateGroupController', function CreateGroupController($async, $scope, $state, GroupService, Notifications) {
$scope.state = {
actionInProgress: false,
};
@ -28,31 +28,10 @@ angular.module('portainer.app').controller('CreateGroupController', function Cre
});
};
$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) => {
$scope.availableTags = tags;
$scope.associatedEndpoints = [];
$scope.model = new EndpointGroupDefaultModel();
$scope.loaded = true;
})
.catch((err) => {
Notifications.error('Failure', err, 'Unable to retrieve tags');
});
$scope.associatedEndpoints = [];
$scope.model = new EndpointGroupDefaultModel();
$scope.loaded = true;
}
initView();

View File

@ -12,14 +12,12 @@
page-type="create"
model="model"
available-endpoints="availableEndpoints"
available-tags="availableTags"
associated-endpoints="associatedEndpoints"
add-label-action="addLabel"
remove-label-action="removeLabel"
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>

View File

@ -12,14 +12,12 @@
page-type="edit"
model="group"
available-endpoints="availableEndpoints"
available-tags="availableTags"
associated-endpoints="associatedEndpoints"
add-label-action="addLabel"
remove-label-action="removeLabel"
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>

View File

@ -1,4 +1,4 @@
angular.module('portainer.app').controller('GroupController', function GroupController($q, $async, $scope, $state, $transition$, GroupService, TagService, Notifications) {
angular.module('portainer.app').controller('GroupController', function GroupController($q, $scope, $state, $transition$, GroupService, Notifications) {
$scope.state = {
actionInProgress: false,
};
@ -20,30 +20,14 @@ angular.module('portainer.app').controller('GroupController', function GroupCont
});
};
$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;
$q.all({
group: GroupService.group(groupId),
tags: TagService.tags(),
})
.then(function success(data) {
$scope.group = data.group;
$scope.availableTags = data.tags;
$scope.loaded = true;
})
.catch(function error(err) {

View File

@ -62,18 +62,19 @@ export function TagSelector({ value, allowCreate = false, onChange }: Props) {
{value.length > 0 && (
<FormControl label="Selected tags">
{selectedTags.map((tag) => (
<span className="tag space-right interactive" key={tag.value}>
<button
type="button"
title="Remove tag"
className={clsx(styles.removeTagBtn, 'space-left', 'tag')}
onClick={() => handleRemove(tag.value)}
key={tag.value}
>
{tag.label}
<button
type="button"
title="Remove tag"
className={clsx(styles.removeTagBtn, 'space-left')}
onClick={() => handleRemove(tag.value)}
>
<i className="fa fa-trash-alt white-icon" aria-hidden="true" />
</button>
</span>
<i
className="fa fa-trash-alt white-icon space-left"
aria-hidden="true"
/>
</button>
))}
</FormControl>
)}

View File

@ -12,6 +12,11 @@ import { createMockTeams, createMockUsers } from '../react-tools/test-mocks';
import { azureHandlers } from './setup-handlers/azure';
const tags: Tag[] = [
{ ID: 1, Name: 'tag1' },
{ ID: 2, Name: 'tag2' },
];
const licenseInfo: LicenseInfo = {
nodes: 1000,
type: LicenseType.Subscription,
@ -48,11 +53,11 @@ export const handlers = [
};
return res(ctx.json(group));
}),
rest.get('/api/tags', (req, res, ctx) => {
const tags: Tag[] = [
{ ID: 1, Name: 'tag1' },
{ ID: 2, Name: 'tag2' },
];
return res(ctx.json(tags));
rest.get('/api/tags', (req, res, ctx) => res(ctx.json(tags))),
rest.post<{ name: string }>('/api/tags', (req, res, ctx) => {
const tagName = req.body.name;
const tag = { ID: tags.length + 1, Name: tagName };
tags.push(tag);
return res(ctx.json(tag));
}),
];