diff --git a/ui/src/RecentFilesDrawer/AddTagToWorkflowPopover.tsx b/ui/src/RecentFilesDrawer/AddTagToWorkflowPopover.tsx index 7b27d2f..6726889 100644 --- a/ui/src/RecentFilesDrawer/AddTagToWorkflowPopover.tsx +++ b/ui/src/RecentFilesDrawer/AddTagToWorkflowPopover.tsx @@ -10,6 +10,8 @@ import { Input, HStack, IconButton, + Alert, + AlertIcon, } from "@chakra-ui/react"; import { useEffect, useState, useContext } from "react"; import { tagsTable, workflowsTable } from "../db-tables/WorkspaceDB"; @@ -25,6 +27,7 @@ export default function AddTagToWorkflowPopover({ workflow }: Props) { const { onRefreshFilesList } = useContext(RecentFilesContext); const [allTags, setAllTags] = useState([]); const [newTagName, setNewTagName] = useState(""); + const [submitError, setSubmitError] = useState(false); const initialTags = workflow.tags?.map((t) => ({ value: t, @@ -34,6 +37,21 @@ export default function AddTagToWorkflowPopover({ workflow }: Props) { const [selectedTags, setSelectedTags] = useState>(initialTags); + const addTag = async () => { + const tagNameList = + (await tagsTable?.listAll().then((list) => list.map((f) => f.name))) ?? + []; + if (tagNameList.includes(newTagName)) { + console.log(1111); + setSubmitError(true); + } else { + await tagsTable?.create(newTagName); + tagsTable?.listAll().then((tags) => setAllTags(tags ?? [])); + setNewTagName(""); + setSubmitError(false); + } + }; + useEffect(() => { const loadTags = async () => { const tags = await tagsTable?.listAll(); @@ -119,7 +137,7 @@ export default function AddTagToWorkflowPopover({ workflow }: Props) { variant={"flushed"} value={newTagName} onChange={(e) => { - setNewTagName(e.target.value); + setNewTagName(e.target.value.trim()); }} /> + {submitError ? ( + + + The name is duplicated, please modify it and submit again. + + ) : ( + "" + )} diff --git a/ui/src/db-tables/WorkspaceDB.ts b/ui/src/db-tables/WorkspaceDB.ts index 7cf7c5f..21a82c6 100644 --- a/ui/src/db-tables/WorkspaceDB.ts +++ b/ui/src/db-tables/WorkspaceDB.ts @@ -6,6 +6,7 @@ import { UserSettingsTable } from "./UserSettingsTable"; import { TagsTable } from "./tagsTable"; import { indexdb } from "./indexdb"; import { Folder, Workflow } from "../types/dbTypes"; +import { v4 as uuidv4 } from "uuid"; export type Table = | "workflows" @@ -97,7 +98,14 @@ export async function backfillIndexdb() { const backfillTags = async () => { try { const all = await tagsTable?.getRecords(); - all && (await indexdb.tags.bulkAdd(Object.values(all))); + const tagList = all ? Object.values(all) : []; + if (tagList.length > 0 && !tagList[0].id) { + tagList.forEach((tag) => { + tag.id = uuidv4(); + }); + } + + tagList.length > 0 && (await indexdb.tags.bulkAdd(tagList)); } catch (error) { console.error(error); } diff --git a/ui/src/db-tables/indexdb.ts b/ui/src/db-tables/indexdb.ts index c7a87fd..c65d7ee 100644 --- a/ui/src/db-tables/indexdb.ts +++ b/ui/src/db-tables/indexdb.ts @@ -24,13 +24,13 @@ class ManagerDB extends Dexie { constructor() { super(WORKSPACE_INDEXDB_NAME); - this.version(1) + this.version(2) .stores({ workflows: "&id, name, parentFolderID", // Primary key and indexed props changelogs: "&id, workflowID", media: "&id, workflowID", folders: "&id, name, parentFolderID", - tags: "&name", + tags: "&id, name", userSettings: "&id", models: "&id, fileName, fileHash", cache: "&id", diff --git a/ui/src/db-tables/tagsTable.ts b/ui/src/db-tables/tagsTable.ts index 2d38d02..5ffce0c 100644 --- a/ui/src/db-tables/tagsTable.ts +++ b/ui/src/db-tables/tagsTable.ts @@ -1,32 +1,27 @@ -import { saveDB } from "../Api"; import { Tag } from "../types/dbTypes"; import { Table } from "./WorkspaceDB"; import { TableBase } from "./TableBase"; -import { indexdb } from "./indexdb"; +import { v4 as uuidv4 } from "uuid"; export class TagsTable extends TableBase { static readonly TABLE_NAME: Table = "tags"; + constructor() { super("tags"); } + static async load(): Promise { const instance = new TagsTable(); return instance; } - public async upsert(name: string) { + public async create(name: string) { const newTag = { + id: uuidv4(), name, workflowIDs: [], updateTime: Date.now(), }; - indexdb.tags.put(newTag); - const tags = await this.getRecords(); - if (tags[name] == null) { - tags[name] = newTag; - } - tags[name].updateTime = Date.now(); - saveDB("tags", JSON.stringify(tags)); - return tags[name]; + await this.add(newTag); } } diff --git a/ui/src/types/dbTypes.ts b/ui/src/types/dbTypes.ts index c0e0eed..52f2592 100644 --- a/ui/src/types/dbTypes.ts +++ b/ui/src/types/dbTypes.ts @@ -24,6 +24,7 @@ export type Tags = { [name: string]: Tag; }; export type Tag = { + id: string; name: string; workflowIDs: string[]; updateTime: number;