mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
⚡ Add tags to GET /workflows
This commit is contained in:
parent
be7ec2d3e7
commit
ffea0a01f6
|
@ -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 {
|
||||
|
|
|
@ -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> = {
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in a new issue