diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2319abb..4728d8b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,3 +18,10 @@ repos: rev: v0.19.1 hooks: - id: gitlint + - repo: local + hooks: + - id: prettify + name: prettify + entry: bash ./prettify-pre-commit.sh + language: system + files: \.(js|ts|jsx|tsx|css|html)$ diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 8c23962..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "editor.tabSize": 2, - "editor.insertSpaces": true, - "workbench.editor.customLabels.patterns": { - "{**/index.*,**/route.*,**/layout.*,**/page.*}": "${dirname}.${extname} (${filename})" - }, - "cSpell.words": [ - "hie", - "nextjs", - "openapi", - "tailwindcss", - "Topbar", - "zustand" - ] -} diff --git a/CHANGELOG.md b/CHANGELOG.md index ad27f00..c88ca32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ Types of changes: ### Changed +- Updated the API of items/{id}, items/relation, tags/relation +- Updated the layout of explorer showcase - Move "New Tag/Item/Folder" button from database page to sidebar ### Security diff --git a/app/api/folders/[id]/route.ts b/app/api/folders/[id]/route.ts index b4e7eae..c751899 100644 --- a/app/api/folders/[id]/route.ts +++ b/app/api/folders/[id]/route.ts @@ -27,18 +27,33 @@ export async function PATCH( request: Request, { params }: { params: { id: string } } ) { + let name: string | undefined; + let path: string | undefined; try { - const { name, path } = await request.json(); + const json = await request.json(); + name = json.name; + let rawPath = json.path; - // Normalization - let fmtPath = path.replace(/\\/g, "/").trim(); // Replace backslashes with forward - if (!fmtPath.endsWith("/")) { - fmtPath += "/"; // Always add trailing slash + if (rawPath === undefined) { + path = undefined; + } else { + // Normalization + path = rawPath.replace(/\\/g, "/").trim(); // Replace backslashes with forward + if (path !== undefined && !path.endsWith("/")) { + path += "/"; // Always add trailing slash + } } + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + try { const updated = await prisma.folder.update({ where: { id: Number(params.id) }, - data: { name, path: fmtPath }, + data: { name, path }, }); return NextResponse.json(updated); diff --git a/app/api/folders/route.ts b/app/api/folders/route.ts index a189303..e536cf7 100644 --- a/app/api/folders/route.ts +++ b/app/api/folders/route.ts @@ -4,18 +4,27 @@ import { StatusCodes } from "http-status-codes"; // Create a folder export async function POST(request: Request) { + let name: string; + let path: string; try { - const { name, path } = await request.json(); - console.debug("Received data:", { name, path }); + const json = await request.json(); + name = json.name; // Normalization - let fmtPath = path.replace(/\\/g, "/").trim(); // Replace backslashes with forward - if (!fmtPath.endsWith("/")) { - fmtPath += "/"; // Always add trailing slash + path = json.path.replace(/\\/g, "/").trim(); // Replace backslashes with forward + if (!path.endsWith("/")) { + path += "/"; // Always add trailing slash } + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + try { const created = await prisma.folder.create({ - data: { name, path: fmtPath }, + data: { name, path }, }); return NextResponse.json(created); diff --git a/app/api/items/[id]/route.ts b/app/api/items/[id]/route.ts index 18831e6..bee9e07 100644 --- a/app/api/items/[id]/route.ts +++ b/app/api/items/[id]/route.ts @@ -39,11 +39,15 @@ export async function DELETE( { params }: { params: { id: string } } ) { try { + await prisma.itemRelation.deleteMany({ + where: { itemId: Number(params.id) }, + }); + const deleted = await prisma.item.delete({ where: { id: Number(params.id) }, }); - return NextResponse.json(deleted); + return NextResponse.json(deleted); // TODO change to 204? } catch (error) { console.error("Error deleting item:", error); return NextResponse.json( @@ -58,22 +62,36 @@ export async function PATCH( request: Request, { params }: { params: { id: string } } ) { + let path: string | undefined; + let folderId: number | undefined; + let name: string | undefined; + let starred: boolean | undefined; try { - const { folderId, path, name, starred } = await request.json(); + const json = await request.json(); + let rawPath = json.path; + folderId = json.folderId; + name = json.name; + starred = json.starred; - // Normalization - const fmtPath = path.replace(/\\/g, "/"); // Replace backslashes with forward + path = rawPath === undefined ? undefined : rawPath.replace(/\\/g, "/"); // Replace backslashes with forward + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + try { const item = await prisma.item.update({ where: { id: Number(params.id) }, - data: { path: fmtPath, folderId, name, starred }, + data: { path, folderId, name, starred }, }); return NextResponse.json(item); } catch (error) { console.error("Error update item:", error); return NextResponse.json( - { error: "Error deleting item" }, + { error: "Error update item" }, { status: StatusCodes.INTERNAL_SERVER_ERROR } ); } diff --git a/app/api/items/relation/[id]/route.ts b/app/api/items/relation/[id]/route.ts new file mode 100644 index 0000000..dbcc200 --- /dev/null +++ b/app/api/items/relation/[id]/route.ts @@ -0,0 +1,81 @@ +import { NextResponse } from "next/server"; +import { prisma } from "@/app/lib/config/prisma"; +import { StatusCodes } from "http-status-codes"; + +export async function PATCH( + request: Request, + { params }: { params: { id: string } } +) { + let tagId: number | undefined; + let itemId: number | undefined; + try { + const json = await request.json(); + tagId = json.tagId; + itemId = json.itemId; + + console.debug("Received data:", { tagId, itemId }); + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + + try { + if (tagId !== undefined) { + const tag = await prisma.tag.findUnique({ + where: { id: tagId }, + }); + if (tag === null) { + return NextResponse.json( + { error: "Tag not found" }, + { status: StatusCodes.NOT_FOUND } + ); + } + } + + if (itemId !== undefined) { + const item = await prisma.item.findUnique({ + where: { id: itemId }, + }); + if (item === null) { + return NextResponse.json( + { error: "Item not found" }, + { status: StatusCodes.NOT_FOUND } + ); + } + } + + const updated = await prisma.itemRelation.update({ + where: { id: Number(params.id) }, + data: { tagId, itemId }, + }); + + return NextResponse.json(updated); + } catch (error) { + console.error("Error update item relation:", error); + return NextResponse.json( + { error: "Error updating item relation" }, + { status: StatusCodes.INTERNAL_SERVER_ERROR } + ); + } +} + +export async function DELETE( + _request: Request, + { params }: { params: { id: string } } +) { + try { + const deleted = await prisma.tagRelation.delete({ + where: { id: Number(params.id) }, + }); + + return NextResponse.json(deleted); + } catch (error) { + console.error("Error deleting item relation:", error); + return NextResponse.json( + { error: "Error deleting item relation" }, + { status: StatusCodes.INTERNAL_SERVER_ERROR } + ); + } +} diff --git a/app/api/items/relation/route.ts b/app/api/items/relation/route.ts index db3cf28..fba6b49 100644 --- a/app/api/items/relation/route.ts +++ b/app/api/items/relation/route.ts @@ -3,38 +3,51 @@ import { prisma } from "@/app/lib/config/prisma"; import { StatusCodes } from "http-status-codes"; export async function POST(request: Request) { + let tagId: number; + let itemId: number; try { - const { tagId, itemId } = await request.json(); - console.debug("Received data:", { tagId, itemId }); - - const created = await prisma.itemRelation.create({ - data: { tagId, itemId }, - }); + const json = await request.json(); + tagId = json.tagId; + itemId = json.itemId; - return NextResponse.json(created); + console.debug("Received data:", { tagId, itemId }); } catch (error) { - console.error("Error creating item relation:", error); return NextResponse.json( - { error: "Error creating item relation" }, - { status: StatusCodes.INTERNAL_SERVER_ERROR } + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } ); } -} -export async function PATCH(request: Request) { try { - const { id, tagId, itemId } = await request.json(); + const tag = await prisma.tag.findUnique({ + where: { id: tagId }, + }); + if (tag === null) { + return NextResponse.json( + { error: "Tag not found" }, + { status: StatusCodes.NOT_FOUND } + ); + } + + const item = await prisma.item.findUnique({ + where: { id: itemId }, + }); + if (item === null) { + return NextResponse.json( + { error: "Item not found" }, + { status: StatusCodes.NOT_FOUND } + ); + } - const updated = await prisma.itemRelation.update({ - where: { id }, + const created = await prisma.itemRelation.create({ data: { tagId, itemId }, }); - return NextResponse.json(updated); + return NextResponse.json(created); } catch (error) { - console.error("Error update item relation:", error); + console.error("Error creating item relation:", error); return NextResponse.json( - { error: "Error updating item relation" }, + { error: "Error creating item relation" }, { status: StatusCodes.INTERNAL_SERVER_ERROR } ); } @@ -52,28 +65,3 @@ export async function GET() { ); } } - -export async function DELETE(request: Request) { - try { - const { id } = await request.json(); - - if (!id) { - return NextResponse.json( - { error: "ID is required" }, - { status: StatusCodes.BAD_REQUEST } - ); - } - - const deleted = await prisma.tagRelation.delete({ - where: { id }, - }); - - return NextResponse.json(deleted); - } catch (error) { - console.error("Error deleting tag:", error); - return NextResponse.json( - { error: "Error deleting tag" }, - { status: StatusCodes.INTERNAL_SERVER_ERROR } - ); - } -} diff --git a/app/api/items/route.ts b/app/api/items/route.ts index a9a87eb..49dafef 100644 --- a/app/api/items/route.ts +++ b/app/api/items/route.ts @@ -4,15 +4,29 @@ import { StatusCodes } from "http-status-codes"; // Create a new item export async function POST(request: Request) { + let path: string; + let folderId: number; + let name: string; + let starred: boolean; try { - const { path, folderId, name, starred } = await request.json(); - console.debug("Received data:", { path, name, starred }); + const json = await request.json(); + let rawPath = json.path; + folderId = json.folderId; + name = json.name; + starred = json.starred; // Normalization - const fmtPath = path.replace(/\\/g, "/").trim(); // Replace backslashes with forward + path = rawPath.replace(/\\/g, "/").trim(); // Replace backslashes with forward + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + try { const item = await prisma.item.create({ - data: { path: fmtPath, folderId, name, starred }, + data: { path, folderId, name, starred }, }); return NextResponse.json(item); diff --git a/app/api/tags/[id]/route.ts b/app/api/tags/[id]/route.ts index 1a18b7b..0f19c6c 100644 --- a/app/api/tags/[id]/route.ts +++ b/app/api/tags/[id]/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from "next/server"; import { prisma } from "@/app/lib/config/prisma"; import { StatusCodes } from "http-status-codes"; +import { TagType } from "@/app/lib/types"; // Get a tag export async function GET( @@ -63,9 +64,45 @@ export async function PATCH( request: Request, { params }: { params: { id: string } } ) { + let name: string | undefined; + let type: string | undefined; + let starred: boolean | undefined; + let backColor: string | undefined; + let textColor: string | undefined; try { - const { name, type, starred, backColor, textColor } = await request.json(); + const json = await request.json(); + name = json.name; + type = json.type; + starred = json.starred; + backColor = json.backColor; + textColor = json.textColor; + if ( + type !== undefined && + type !== TagType.Normal && + type !== TagType.Category + ) { + return NextResponse.json( + { error: "Invalid tag type" }, + { status: StatusCodes.BAD_REQUEST } + ); + } + + console.debug("Received data:", { + name, + type, + starred, + backColor, + textColor, + }); + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + + try { const tag = await prisma.tag.update({ where: { id: Number(params.id) }, data: { diff --git a/app/api/tags/relation/[id]/route.ts b/app/api/tags/relation/[id]/route.ts new file mode 100644 index 0000000..2aa0941 --- /dev/null +++ b/app/api/tags/relation/[id]/route.ts @@ -0,0 +1,88 @@ +import { NextResponse } from "next/server"; +import { prisma } from "@/app/lib/config/prisma"; +import { StatusCodes } from "http-status-codes"; + +export async function PATCH( + request: Request, + { params }: { params: { id: string } } +) { + let parentId: number | undefined; + let childId: number | undefined; + try { + const json = await request.json(); + parentId = json.parentId; + childId = json.childId; + + console.debug("Received data:", { parentId, childId }); + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + + if (parentId === childId) { + return NextResponse.json( + { error: "Parent cannot be equal to Child" }, + { status: StatusCodes.BAD_REQUEST } + ); + } + + try { + if (parentId !== undefined) { + const parentTag = await prisma.tag.findUnique({ + where: { id: parentId }, + }); + if (parentTag === null) { + return NextResponse.json( + { error: "Parent or child tag not found" }, + { status: StatusCodes.NOT_FOUND } + ); + } + } + + if (childId !== undefined) { + const childTag = await prisma.tag.findUnique({ + where: { id: childId }, + }); + if (childTag === null) { + return NextResponse.json( + { error: "Parent or child tag not found" }, + { status: StatusCodes.NOT_FOUND } + ); + } + } + + const updated = await prisma.tagRelation.update({ + where: { id: Number(params.id) }, + data: { parentId, childId }, + }); + + return NextResponse.json(updated); + } catch (error) { + console.error("Error update tag relation:", error); + return NextResponse.json( + { error: "Error updating tag relation" }, + { status: StatusCodes.INTERNAL_SERVER_ERROR } + ); + } +} + +export async function DELETE( + _request: Request, + { params }: { params: { id: string } } +) { + try { + const deleted = await prisma.tagRelation.delete({ + where: { id: Number(params.id) }, + }); + + return NextResponse.json(deleted); + } catch (error) { + console.error("Error deleting tag relation:", error); + return NextResponse.json( + { error: "Error deleting tag relation" }, + { status: StatusCodes.INTERNAL_SERVER_ERROR } + ); + } +} diff --git a/app/api/tags/relation/route.ts b/app/api/tags/relation/route.ts index 92af231..c1ab074 100644 --- a/app/api/tags/relation/route.ts +++ b/app/api/tags/relation/route.ts @@ -3,52 +3,58 @@ import { prisma } from "@/app/lib/config/prisma"; import { StatusCodes } from "http-status-codes"; export async function POST(request: Request) { + let parentId: number; + let childId: number; try { - const { parentId, childId } = await request.json(); - console.debug("Received data:", { parentId, childId }); - - if (parentId === childId) { - return NextResponse.json( - { error: "Parent cannot be equal to Child" }, - { status: StatusCodes.BAD_REQUEST } - ); - } + const json = await request.json(); + parentId = json.parentId; + childId = json.childId; - const created = await prisma.tagRelation.create({ - data: { parentId, childId }, - }); - - return NextResponse.json(created); + console.debug("Received data:", { parentId, childId }); } catch (error) { - console.error("Error creating tag relation:", error); return NextResponse.json( - { error: "Error creating tag relation" }, - { status: StatusCodes.INTERNAL_SERVER_ERROR } + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + + if (parentId === childId) { + return NextResponse.json( + { error: "Parent cannot be equal to Child" }, + { status: StatusCodes.BAD_REQUEST } ); } -} -export async function PATCH(request: Request) { try { - const { id, parentId, childId } = await request.json(); + const parentTag = await prisma.tag.findUnique({ + where: { id: parentId }, + }); + if (parentTag === null) { + return NextResponse.json( + { error: "Parent tag not found" }, + { status: StatusCodes.NOT_FOUND } + ); + } - if (parentId === childId) { + const childTag = await prisma.tag.findUnique({ + where: { id: childId }, + }); + if (childTag === null) { return NextResponse.json( - { error: "Parent cannot be equal to Child" }, - { status: StatusCodes.BAD_REQUEST } + { error: "Child tag not found" }, + { status: StatusCodes.NOT_FOUND } ); } - const updated = await prisma.tagRelation.update({ - where: { id }, + const created = await prisma.tagRelation.create({ data: { parentId, childId }, }); - return NextResponse.json(updated); + return NextResponse.json(created); } catch (error) { - console.error("Error update tag relation:", error); + console.error("Error creating tag relation:", error); return NextResponse.json( - { error: "Error updating tag relation" }, + { error: "Error creating tag relation" }, { status: StatusCodes.INTERNAL_SERVER_ERROR } ); } @@ -66,28 +72,3 @@ export async function GET() { ); } } - -export async function DELETE(request: Request) { - try { - const { id } = await request.json(); - - if (!id) { - return NextResponse.json( - { error: "ID is required" }, - { status: StatusCodes.BAD_REQUEST } - ); - } - - const deleted = await prisma.tagRelation.delete({ - where: { id }, - }); - - return NextResponse.json(deleted); - } catch (error) { - console.error("Error deleting tag:", error); - return NextResponse.json( - { error: "Error deleting tag" }, - { status: StatusCodes.INTERNAL_SERVER_ERROR } - ); - } -} diff --git a/app/api/tags/route.ts b/app/api/tags/route.ts index fb23398..ca089bc 100644 --- a/app/api/tags/route.ts +++ b/app/api/tags/route.ts @@ -5,8 +5,26 @@ import { TagType } from "@/app/lib/types"; // Create a new tag export async function POST(request: Request) { + let name: string; + let type: string; + let starred: boolean; + let backColor: string; + let textColor: string; try { - const { name, type, starred, backColor, textColor } = await request.json(); + const json = await request.json(); + name = json.name; + type = json.type; + starred = json.starred; + backColor = json.backColor; + textColor = json.textColor; + + if (type !== TagType.Normal && type !== TagType.Category) { + return NextResponse.json( + { error: "Invalid tag type" }, + { status: StatusCodes.BAD_REQUEST } + ); + } + console.debug("Received data:", { name, type, @@ -14,7 +32,14 @@ export async function POST(request: Request) { backColor, textColor, }); + } catch (error) { + return NextResponse.json( + { error: `Error parsing request body, ${error}` }, + { status: StatusCodes.BAD_REQUEST } + ); + } + try { const tag = await prisma.tag.create({ data: { name, type, starred, backColor, textColor }, }); diff --git a/app/explorer/[tag]/itemGrid/index.tsx b/app/explorer/[tag]/itemGrid/index.tsx index e3d2390..2b25b3b 100644 --- a/app/explorer/[tag]/itemGrid/index.tsx +++ b/app/explorer/[tag]/itemGrid/index.tsx @@ -7,6 +7,8 @@ import { getTag } from "@/app/lib/tags"; import { Backdrop, Button, ImageList, ImageListItem } from "@mui/material"; import Showcase from "./showcase"; +const SHOW_CASE_QUANTITY = 85; + interface Props { tagId: number; } @@ -111,7 +113,7 @@ export default function ItemGrid(props: Props) { ))} diff --git a/app/explorer/[tag]/itemGrid/showcase/index.tsx b/app/explorer/[tag]/itemGrid/showcase/index.tsx index dd0db5d..532f898 100644 --- a/app/explorer/[tag]/itemGrid/showcase/index.tsx +++ b/app/explorer/[tag]/itemGrid/showcase/index.tsx @@ -25,30 +25,18 @@ export default function Showcase(props: Props) { open={open} onClick={onClick} > - - {/* - - - - - - - */} - - ? - - + ? ); } diff --git a/hie.code-workspace b/hie.code-workspace new file mode 100644 index 0000000..995e287 --- /dev/null +++ b/hie.code-workspace @@ -0,0 +1,47 @@ +{ + "folders": [ + { + "name": "Page: Database", + "path": "app/database" + }, + { + "name": "Page: Explorer", + "path": "app/explorer" + }, + { + "name": "Components", + "path": "app/components" + }, + { + "name": "Lib", + "path": "app/lib" + }, + { + "name": "API: Server", + "path": "app/api" + }, + { + "name": "API: OpenAPI", + "path": "public/openapi" + }, + { + "name": "Root", + "path": "." + } + ], + "settings": { + "editor.tabSize": 2, + "editor.insertSpaces": true, + "workbench.editor.customLabels.patterns": { + "{**/index.*,**/route.*,**/layout.*,**/page.*}": "${dirname}.${extname} (${filename})" + }, + "cSpell.words": [ + "hie", + "nextjs", + "openapi", + "tailwindcss", + "Topbar", + "zustand" + ] + } +} diff --git a/prettify-pre-commit.sh b/prettify-pre-commit.sh new file mode 100644 index 0000000..396c029 --- /dev/null +++ b/prettify-pre-commit.sh @@ -0,0 +1,11 @@ +#!/bin/bash +FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') +[ -z "$FILES" ] && exit 0 + +# Prettify all selected files +echo "$FILES" | xargs ./node_modules/.bin/prettier --ignore-unknown --write + +# Add back the modified/prettified files to staging +echo "$FILES" | xargs git add + +exit 0 diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7c86d80..b0b97fd 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -30,7 +30,7 @@ model Tag { model Item { id Int @id @default(autoincrement()) path String - folder Folder @relation(fields: [folderId], references: [id]) + folder Folder @relation(fields: [folderId], references: [id], onDelete: Cascade) folderId Int name String? starred Boolean @default(false) diff --git a/public/openapi/document.yaml b/public/openapi/document.yaml index 1a8bed9..e89393d 100644 --- a/public/openapi/document.yaml +++ b/public/openapi/document.yaml @@ -21,14 +21,18 @@ paths: /api/tags/{id}: $ref: "./tags/id.yaml" /api/tags/relation: - $ref: "./tags/relation.yaml" + $ref: "./tags/relation/index.yaml" + /api/tags/relation/{id}: + $ref: "./tags/relation/id.yaml" /api/items: $ref: "./items/index.yaml" - /api/items{id}: + /api/items/{id}: $ref: "./items/id.yaml" /api/items/relation: - $ref: "./items/relation.yaml" + $ref: "./items/relation/index.yaml" + /api/items/relation/{id}: + $ref: "./items/relation/id.yaml" /api/folders: $ref: "./folders/index.yaml" diff --git a/public/openapi/folders/id.yaml b/public/openapi/folders/id.yaml index 9c42e4d..b07b6c0 100644 --- a/public/openapi/folders/id.yaml +++ b/public/openapi/folders/id.yaml @@ -2,6 +2,14 @@ patch: summary: Update a folder tags: - Folders + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + description: ID of the folder to update requestBody: required: true content: @@ -21,12 +29,14 @@ delete: summary: Delete a folder tags: - Folders - requestBody: - required: true - content: - application/json: - schema: - type: object + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + description: ID of the folder to delete responses: "204": description: Folder deleted successfully diff --git a/public/openapi/items/id.yaml b/public/openapi/items/id.yaml index fc8ce83..0e27179 100644 --- a/public/openapi/items/id.yaml +++ b/public/openapi/items/id.yaml @@ -2,6 +2,14 @@ patch: summary: Update item tags: - Items + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + description: ID of the item to update requestBody: required: true content: @@ -11,26 +19,35 @@ patch: properties: path: type: string + description: Optional path, omit to leave unchanged + example: "my-img.jpg" folderId: type: integer + description: Optional folder ID, omit to leave unchanged + example: 1 name: type: string + description: Optional name, omit to leave unchanged + example: "MyImage" starred: type: boolean + description: Optional starred status, omit to leave unchanged responses: "200": description: Item updated successfully delete: - summary: Delete a item + summary: Delete an item tags: - Items - requestBody: - required: true - content: - application/json: - schema: - type: object + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + description: ID of the item to delete responses: - "204": + "200": description: Item deleted successfully diff --git a/public/openapi/items/relation/id.yaml b/public/openapi/items/relation/id.yaml new file mode 100644 index 0000000..dc46f8f --- /dev/null +++ b/public/openapi/items/relation/id.yaml @@ -0,0 +1,39 @@ +patch: + summary: Update item relation + tags: + - Items relation + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + tagId: + type: number + itemId: + type: number + responses: + "200": + description: Item relation updated successfully +delete: + summary: Delete a item relation + tags: + - Items relation + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + responses: + "204": + description: Item relation deleted successfully diff --git a/public/openapi/items/relation.yaml b/public/openapi/items/relation/index.yaml similarity index 52% rename from public/openapi/items/relation.yaml rename to public/openapi/items/relation/index.yaml index 9ac0424..bb246d0 100644 --- a/public/openapi/items/relation.yaml +++ b/public/openapi/items/relation/index.yaml @@ -16,42 +16,7 @@ post: responses: "200": description: Item relation created successfully -patch: - summary: Update item relation - tags: - - Items relation - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - id: - type: integer - tagId: - type: number - itemId: - type: number - responses: - "200": - description: Item relation updated successfully -delete: - summary: Delete a item relation - tags: - - Items relation - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - id: - type: integer - responses: - "204": - description: Item relation deleted successfully + get: summary: List all item relations tags: diff --git a/public/openapi/tags/id.yaml b/public/openapi/tags/id.yaml index 69a7b97..b6c0a70 100644 --- a/public/openapi/tags/id.yaml +++ b/public/openapi/tags/id.yaml @@ -2,6 +2,14 @@ patch: summary: Update a tag tags: - Tags + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + description: ID of the tag to update requestBody: required: true content: @@ -11,36 +19,49 @@ patch: properties: name: type: string + description: Optional name, omit to leave unchanged + example: "MyTag" type: type: string + enum: [normal, category] + description: Optional type, omit to leave unchanged + example: "normal" starred: type: boolean + description: Optional starred state, omit to leave unchanged + example: true backColor: type: string + description: Optional background color, omit to leave unchanged textColor: type: string + description: Optional text color, omit to leave unchanged responses: "200": description: Tag updated successfully + delete: summary: Delete a tag tags: - Tags - requestBody: - required: true - content: - application/json: - schema: - type: object + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + description: ID of the tag to delete responses: - "204": + "200": description: Tag deleted successfully + get: summary: Get a specific tag by ID tags: - Tags parameters: - - name: tagId + - name: id in: path required: true schema: diff --git a/public/openapi/tags/relation/id.yaml b/public/openapi/tags/relation/id.yaml new file mode 100644 index 0000000..3e6f55d --- /dev/null +++ b/public/openapi/tags/relation/id.yaml @@ -0,0 +1,40 @@ +patch: + summary: Update tag relation + tags: + - Tags relation + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + parentId: + type: number + childId: + type: number + responses: + "200": + description: Tag relation updated successfully + +delete: + summary: Delete a tag relation + tags: + - Tags relation + parameters: + - name: id + in: path + required: true + schema: + type: integer + example: 1 + responses: + "200": + description: Tag relation deleted successfully diff --git a/public/openapi/tags/relation.yaml b/public/openapi/tags/relation/index.yaml similarity index 52% rename from public/openapi/tags/relation.yaml rename to public/openapi/tags/relation/index.yaml index 651455e..828321a 100644 --- a/public/openapi/tags/relation.yaml +++ b/public/openapi/tags/relation/index.yaml @@ -16,42 +16,7 @@ post: responses: "400": description: Parent cannot be equal to Child -patch: - summary: Update tag relation - tags: - - Tags relation - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - id: - type: integer - parentId: - type: number - childId: - type: number - responses: - "200": - description: Tag relation updated successfully -delete: - summary: Delete a tag relation - tags: - - Tags relation - requestBody: - required: true - content: - application/json: - schema: - type: object - properties: - id: - type: integer - responses: - "204": - description: Tag relation deleted successfully + get: summary: List all tag relations tags: