Add tags to GET /workflows

This commit is contained in:
Iván Ovejero 2021-04-13 12:00:49 +02:00
parent be7ec2d3e7
commit ffea0a01f6
3 changed files with 49 additions and 16 deletions

View file

@ -23,6 +23,7 @@ import { Repository } from 'typeorm';
import { ChildProcess } from 'child_process';
import { Url } from 'url';
import { Request } from 'express';
import { TagEntity } from './databases/entities/TagEntity';
export interface IActivationError {
time: number;
@ -80,13 +81,13 @@ export interface ITagBase {
}
export interface ITagDb extends ITagBase {
id: number;
id: string | number;
}
// Almost identical to editor-ui.Interfaces.ts
export interface IWorkflowDb extends IWorkflowBase {
id: number | string;
tags: Array<{ id: number; name: string }>;
tags: TagEntity[] | Array<{ id: string; name: string }>; // TODO: Unify
}
export interface IWorkflowResponse extends IWorkflowBase {

View file

@ -502,7 +502,7 @@ class App {
const { tags } = req.body as { tags: string };
if (tags) {
const tagIds = tags.split(',').map(Number);
const tagIds = tags.split(',');
await TagHelpers.createTagWorkflowRelations(result.id as string, tagIds);
result.tags = await TagHelpers.getTagsForResponseData(tagIds);
}
@ -554,6 +554,19 @@ class App {
const results = await Db.collections.Workflow!.find(findQuery);
const tagsPerWorkflow = await TagHelpers.getTagsByWorkflowIds(results.map(({ id }) => id.toString()));
// TODO: Improve
tagsPerWorkflow.forEach(({ workflowId, id, name }) => {
results.forEach(result => {
if (result.id !== workflowId) return;
// @ts-ignore
result.tags = result.tags
? [...result.tags, { id, name }]
: [{ id, name }];
});
});
for (const entry of results) {
(entry as unknown as IWorkflowShortResponse).id = entry.id.toString();
}
@ -654,7 +667,7 @@ class App {
if (tags) {
await TagHelpers.deleteAllTagsForWorkflow(id);
const tagIds = tags.split(',').map(Number);
const tagIds = tags.split(',');
for (const tagId of tagIds) {
await TagHelpers.validateId(tagId);
@ -745,7 +758,7 @@ class App {
}));
// Creates a tag
this.app.post(`/${this.restEndpoint}/tags`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<{ id: number, name: string }> => {
this.app.post(`/${this.restEndpoint}/tags`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<{ id: string, name: string }> => {
TagHelpers.validateRequestBody(req.body);
const { name } = req.body;
@ -758,28 +771,28 @@ class App {
updatedAt: this.getCurrentDate(),
};
const { id } = await Db.collections.Tag!.save(newTag);
const { id } = await Db.collections.Tag!.save(newTag) as { id: string };
return { id, name };
}));
// Deletes a tag
this.app.delete(`/${this.restEndpoint}/tags/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<boolean> => {
const id = Number(req.params.id);
const { id } = req.params;
await TagHelpers.validateId(id);
await Db.collections.Tag!.delete({ id });
return true;
}));
// Updates an existing tag
this.app.patch(`/${this.restEndpoint}/tags/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<{ id: number, name: string }> => {
this.app.patch(`/${this.restEndpoint}/tags/:id`, ResponseHelper.send(async (req: express.Request, res: express.Response): Promise<{ id: string, name: string }> => {
TagHelpers.validateRequestBody(req.body);
const { name } = req.body;
await TagHelpers.validateName(name);
TagHelpers.validateLength(name);
const id = Number(req.params.id);
const { id } = req.params;
await TagHelpers.validateId(id);
const updatedTag: Partial<ITagDb> = {

View file

@ -17,7 +17,7 @@ import {
/**
* Validate whether a tag ID exists so that it can be used for a workflow create or tag update operation.
*/
export async function validateId(id: number): Promise<void> | never {
export async function validateId(id: string): Promise<void> | never {
const findQuery = { where: { id } } as FindOneOptions;
const tag = await Db.collections.Tag!.findOne(findQuery);
@ -116,15 +116,34 @@ export async function getAllTagsWithUsageCount(): Promise<Array<{
}
/**
* Retrieve tag IDs and names, to be used in an API response.
* Retrieve tag IDs and names, to be used in an API response
* for a workflow create/update operation.
*/
export async function getTagsByWorkflowIds(
workflowIds: string[]
): Promise<Array<{ workflowId: number; id: string; name: string }>> {
return await getConnection().createQueryBuilder()
.select('workflows_tags.workflowId', 'workflowId')
.addSelect('tag_entity.id', 'id')
.addSelect('tag_entity.name', 'name')
.from('workflows_tags', 'workflows_tags')
.leftJoin('tag_entity', 'tag_entity', 'tag_entity.id = workflows_tags.tagId')
.where('workflows_tags.workflowId IN (:...workflowIds)', { workflowIds })
.getRawMany();
}
/**
* Retrieve tag IDs and names, to be used in an API response
* for a workflow create/update operation.
*/
export async function getTagsForResponseData(
tagIds: number[]
): Promise<Array<{ id: number; name: string }>> {
tagIds: string[]
): Promise<Array<{ id: string; name: string }>> {
return await Db.collections.Tag!.find({
select: ['id', 'name'],
where: { id: In(tagIds) },
});
}) as Array<{ id: string; name: string }>;
}
/**
@ -146,7 +165,7 @@ async function findRelations(
*/
export async function getWorkflowTags(
workflowId: string
): Promise<Array<{ id: number; name: string }>> {
): Promise<Array<{ id: string; name: string }>> {
return await getConnection().createQueryBuilder()
.select('tag_entity.id', 'id')
.addSelect('tag_entity.name', 'name')
@ -170,7 +189,7 @@ export async function getWorkflowTags(
/**
* Link a workflow to one or more tags.
*/
export async function createTagWorkflowRelations(workflowId: string, tagIds: number[]) {
export async function createTagWorkflowRelations(workflowId: string, tagIds: string[]) {
await getConnection().createQueryBuilder()
.insert()
.into('workflows_tags')