diff --git a/store/db/db.go b/store/db/db.go index 71b72383..5ab544b7 100644 --- a/store/db/db.go +++ b/store/db/db.go @@ -43,7 +43,7 @@ func (db *DB) Open(ctx context.Context) (err error) { } // Connect to the database without foreign_key. - sqliteDB, err := sql.Open("sqlite3", db.profile.DSN+"?cache=shared&_foreign_keys=0&_busy_timeout=9999999") + sqliteDB, err := sql.Open("sqlite3", db.profile.DSN+"?cache=shared&_foreign_keys=0&_journal_mode=WAL") if err != nil { return fmt.Errorf("failed to open db with dsn: %s, err: %w", db.profile.DSN, err) } diff --git a/store/db/seed/10006__tag.sql b/store/db/seed/10006__tag.sql new file mode 100644 index 00000000..5db2cfb6 --- /dev/null +++ b/store/db/seed/10006__tag.sql @@ -0,0 +1,32 @@ +INSERT INTO + tag ( + `name`, + `creator_id` + ) +VALUES + ( + 'Hello', + 101 + ); + +INSERT INTO + tag ( + `name`, + `creator_id` + ) +VALUES + ( + 'TODO', + 101 + ); + +INSERT INTO + tag ( + `name`, + `creator_id` + ) +VALUES + ( + 'TODO', + 102 + ); diff --git a/web/src/components/CreateTagDialog.tsx b/web/src/components/CreateTagDialog.tsx index 81c050c5..460b9ff1 100644 --- a/web/src/components/CreateTagDialog.tsx +++ b/web/src/components/CreateTagDialog.tsx @@ -23,20 +23,21 @@ const CreateTagDialog: React.FC = (props: Props) => { const [tagName, setTagName] = useState(""); const [suggestTagNameList, setSuggestTagNameList] = useState([]); const tagNameList = tagStore.state.tags; + const shownSuggestTagNameList = suggestTagNameList.filter((tag) => !tagNameList.includes(tag)); useEffect(() => { getTagSuggestionList().then(({ data }) => { - setSuggestTagNameList(data.data.filter((tag) => !tagNameList.includes(tag) && validateTagName(tag))); + setSuggestTagNameList(data.data.filter((tag) => validateTagName(tag))); }); - }, [tagNameList]); + }, []); const handleTagNameChanged = (e: React.ChangeEvent) => { const tagName = e.target.value as string; setTagName(tagName.trim()); }; - const handleRemoveSuggestTag = (tag: string) => { - setSuggestTagNameList(suggestTagNameList.filter((item) => item !== tag)); + const handleUpsertSuggestTag = async (tagName: string) => { + await tagStore.upsertTag(tagName); }; const handleSaveBtnClick = async () => { @@ -100,15 +101,15 @@ const CreateTagDialog: React.FC = (props: Props) => { )} - {suggestTagNameList.length > 0 && ( + {shownSuggestTagNameList.length > 0 && ( <>

Tag suggestions

- {suggestTagNameList.map((tag) => ( + {shownSuggestTagNameList.map((tag) => ( handleRemoveSuggestTag(tag)} + onClick={() => handleUpsertSuggestTag(tag)} > #{tag} diff --git a/web/src/components/MemoEditor.tsx b/web/src/components/MemoEditor.tsx index 4281ab82..a505d95d 100644 --- a/web/src/components/MemoEditor.tsx +++ b/web/src/components/MemoEditor.tsx @@ -327,7 +327,7 @@ const MemoEditor = () => { toastHelper.error(error.response.data.message); } - // Upsert tag based with content. + // Upsert tag with the content. const matchedNodes = getMatchedNodes(content); const tagNameList = uniq(matchedNodes.filter((node) => node.parserName === "tag").map((node) => node.matchedContent.slice(1))); for (const tagName of tagNameList) {