From 06fc29aecd64eb02e08cadc6a8c7f969cc49ee85 Mon Sep 17 00:00:00 2001 From: boojack Date: Sat, 2 Jul 2022 14:14:18 +0800 Subject: [PATCH] chore: rename delete to archive --- .../{DeletedMemo.tsx => ArchivedMemo.tsx} | 17 ++-- web/src/components/ArchivedMemoDialog.tsx | 73 ++++++++++++++++++ web/src/components/Memo.tsx | 38 ++++----- web/src/components/MemoTrashDialog.tsx | 77 ------------------- web/src/components/Sidebar.tsx | 10 +-- web/src/components/TagList.tsx | 2 +- ...-dialog.less => archived-memo-dialog.less} | 4 +- web/src/less/memo.less | 12 +-- web/src/less/shortcut-list.less | 46 ++++------- web/src/less/tag-list.less | 30 +++----- web/src/services/memoService.ts | 6 +- 11 files changed, 135 insertions(+), 180 deletions(-) rename web/src/components/{DeletedMemo.tsx => ArchivedMemo.tsx} (79%) create mode 100644 web/src/components/ArchivedMemoDialog.tsx delete mode 100644 web/src/components/MemoTrashDialog.tsx rename web/src/less/{memo-trash-dialog.less => archived-memo-dialog.less} (87%) diff --git a/web/src/components/DeletedMemo.tsx b/web/src/components/ArchivedMemo.tsx similarity index 79% rename from web/src/components/DeletedMemo.tsx rename to web/src/components/ArchivedMemo.tsx index 954c93e9..776b19d8 100644 --- a/web/src/components/DeletedMemo.tsx +++ b/web/src/components/ArchivedMemo.tsx @@ -10,15 +10,14 @@ import "../less/memo.less"; interface Props { memo: Memo; - handleDeletedMemoAction: (memoId: MemoId) => void; } -const DeletedMemo: React.FC = (props: Props) => { - const { memo: propsMemo, handleDeletedMemoAction } = props; +const ArchivedMemo: React.FC = (props: Props) => { + const { memo: propsMemo } = props; const memo = { ...propsMemo, createdAtStr: utils.getDateTimeString(propsMemo.createdTs), - deletedAtStr: utils.getDateTimeString(propsMemo.updatedTs ?? Date.now()), + archivedAtStr: utils.getDateTimeString(propsMemo.updatedTs ?? Date.now()), }; const [showConfirmDeleteBtn, toggleConfirmDeleteBtn] = useToggle(false); const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1")); @@ -27,7 +26,7 @@ const DeletedMemo: React.FC = (props: Props) => { if (showConfirmDeleteBtn) { try { await memoService.deleteMemoById(memo.id); - handleDeletedMemoAction(memo.id); + await memoService.fetchAllMemos(); } catch (error: any) { toastHelper.error(error.message); } @@ -42,7 +41,7 @@ const DeletedMemo: React.FC = (props: Props) => { id: memo.id, rowStatus: "NORMAL", }); - handleDeletedMemoAction(memo.id); + await memoService.fetchAllMemos(); toastHelper.info("Restored successfully"); } catch (error: any) { toastHelper.error(error.message); @@ -56,9 +55,9 @@ const DeletedMemo: React.FC = (props: Props) => { }; return ( -
+
- Deleted at {memo.deletedAtStr} + Archived at {memo.archivedAtStr}
Restore @@ -80,4 +79,4 @@ const DeletedMemo: React.FC = (props: Props) => { ); }; -export default DeletedMemo; +export default ArchivedMemo; diff --git a/web/src/components/ArchivedMemoDialog.tsx b/web/src/components/ArchivedMemoDialog.tsx new file mode 100644 index 00000000..a485a5fe --- /dev/null +++ b/web/src/components/ArchivedMemoDialog.tsx @@ -0,0 +1,73 @@ +import { useEffect, useState } from "react"; +import useLoading from "../hooks/useLoading"; +import { memoService } from "../services"; +import { useAppSelector } from "../store"; +import { showDialog } from "./Dialog"; +import toastHelper from "./Toast"; +import ArchivedMemo from "./ArchivedMemo"; +import "../less/archived-memo-dialog.less"; + +interface Props extends DialogProps {} + +const ArchivedMemoDialog: React.FC = (props: Props) => { + const { destroy } = props; + const memos = useAppSelector((state) => state.memo.memos); + const loadingState = useLoading(); + const [archivedMemos, setArchivedMemos] = useState([]); + + useEffect(() => { + memoService + .fetchArchivedMemos() + .then((result) => { + setArchivedMemos(result); + }) + .catch((error) => { + toastHelper.error("Failed to fetch archived memos: ", error); + }) + .finally(() => { + loadingState.setFinish(); + }); + }, [memos]); + + return ( + <> +
+

+ 🗂 + Archived Memos +

+ +
+
+ {loadingState.isLoading ? ( +
+

fetching data...

+
+ ) : archivedMemos.length === 0 ? ( +
+

Here is No Zettels.

+
+ ) : ( +
+ {archivedMemos.map((memo) => ( + + ))} +
+ )} +
+ + ); +}; + +export default function showArchivedMemo(): void { + showDialog( + { + className: "archived-memo-dialog", + useAppContext: true, + }, + ArchivedMemoDialog, + {} + ); +} diff --git a/web/src/components/Memo.tsx b/web/src/components/Memo.tsx index 6f72e334..c1dd5acf 100644 --- a/web/src/components/Memo.tsx +++ b/web/src/components/Memo.tsx @@ -3,7 +3,6 @@ import { escape, indexOf } from "lodash-es"; import { IMAGE_URL_REG, LINK_REG, MEMO_LINK_REG, TAG_REG, UNKNOWN_ID } from "../helpers/consts"; import { DONE_BLOCK_REG, parseMarkedToHtml, TODO_BLOCK_REG } from "../helpers/marked"; import * as utils from "../helpers/utils"; -import useToggle from "../hooks/useToggle"; import { editorStateService, locationService, memoService } from "../services"; import Only from "./common/OnlyWhen"; import Image from "./Image"; @@ -34,7 +33,6 @@ const Memo: React.FC = (props: Props) => { expandButtonStatus: -1, }); const memoContainerRef = useRef(null); - const [showConfirmDeleteBtn, toggleConfirmDeleteBtn] = useToggle(false); const imageUrls = Array.from(memo.content.match(IMAGE_URL_REG) ?? []).map((s) => s.replace(IMAGE_URL_REG, "$1")); useEffect(() => { @@ -74,28 +72,18 @@ const Memo: React.FC = (props: Props) => { editorStateService.setEditMemoWithId(memo.id); }; - const handleDeleteMemoClick = async () => { - if (showConfirmDeleteBtn) { - try { - await memoService.patchMemo({ - id: memo.id, - rowStatus: "ARCHIVED", - }); - } catch (error: any) { - toastHelper.error(error.message); - } - - if (editorStateService.getState().editMemoId === memo.id) { - editorStateService.clearEditMemo(); - } - } else { - toggleConfirmDeleteBtn(); + const handleArchiveMemoClick = async () => { + try { + await memoService.patchMemo({ + id: memo.id, + rowStatus: "ARCHIVED", + }); + } catch (error: any) { + toastHelper.error(error.message); } - }; - const handleMouseLeaveMemoWrapper = () => { - if (showConfirmDeleteBtn) { - toggleConfirmDeleteBtn(false); + if (editorStateService.getState().editMemoId === memo.id) { + editorStateService.clearEditMemo(); } }; @@ -162,7 +150,7 @@ const Memo: React.FC = (props: Props) => { }; return ( -
+
{memo.createdAtStr} @@ -196,8 +184,8 @@ const Memo: React.FC = (props: Props) => { View Story - - {showConfirmDeleteBtn ? "Delete!" : "Delete"} + + Archive
diff --git a/web/src/components/MemoTrashDialog.tsx b/web/src/components/MemoTrashDialog.tsx deleted file mode 100644 index 8597a7f9..00000000 --- a/web/src/components/MemoTrashDialog.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { useCallback, useEffect, useState } from "react"; -import useLoading from "../hooks/useLoading"; -import { locationService, memoService } from "../services"; -import { showDialog } from "./Dialog"; -import toastHelper from "./Toast"; -import DeletedMemo from "./DeletedMemo"; -import "../less/memo-trash-dialog.less"; - -interface Props extends DialogProps {} - -const MemoTrashDialog: React.FC = (props: Props) => { - const { destroy } = props; - const loadingState = useLoading(); - const [deletedMemos, setDeletedMemos] = useState([]); - - useEffect(() => { - memoService - .fetchDeletedMemos() - .then((result) => { - setDeletedMemos(result); - }) - .catch((error) => { - toastHelper.error("Failed to fetch deleted memos: ", error); - }) - .finally(() => { - loadingState.setFinish(); - }); - locationService.clearQuery(); - }, []); - - const handleDeletedMemoAction = useCallback(async (memoId: MemoId) => { - setDeletedMemos((deletedMemos) => deletedMemos.filter((memo) => memo.id !== memoId)); - await memoService.fetchAllMemos(); - }, []); - - return ( - <> -
-

- 🗑️ - Recycle Bin -

- -
-
- {loadingState.isLoading ? ( -
-

fetching data...

-
- ) : deletedMemos.length === 0 ? ( -
-

Here is No Zettels.

-
- ) : ( -
- {deletedMemos.map((memo) => ( - - ))} -
- )} -
- - ); -}; - -export default function showMemoTrashDialog(): void { - showDialog( - { - className: "memo-trash-dialog", - useAppContext: true, - }, - MemoTrashDialog, - {} - ); -} diff --git a/web/src/components/Sidebar.tsx b/web/src/components/Sidebar.tsx index b566361c..9c406d24 100644 --- a/web/src/components/Sidebar.tsx +++ b/web/src/components/Sidebar.tsx @@ -2,7 +2,7 @@ import { useAppSelector } from "../store"; import * as utils from "../helpers/utils"; import showDailyReviewDialog from "./DailyReviewDialog"; import showSettingDialog from "./SettingDialog"; -import showMemoTrashDialog from "./MemoTrashDialog"; +import showArchivedMemoDialog from "./ArchivedMemoDialog"; import UserBanner from "./UserBanner"; import UsageHeatMap from "./UsageHeatMap"; import ShortcutList from "./ShortcutList"; @@ -21,8 +21,8 @@ const Sidebar: React.FC = () => { showSettingDialog(); }; - const handleMemosTrashBtnClick = () => { - showMemoTrashDialog(); + const handleArchivedBtnClick = () => { + showArchivedMemoDialog(); }; return ( @@ -55,8 +55,8 @@ const Sidebar: React.FC = () => { -
diff --git a/web/src/components/TagList.tsx b/web/src/components/TagList.tsx index 6c40451e..32506c44 100644 --- a/web/src/components/TagList.tsx +++ b/web/src/components/TagList.tsx @@ -126,7 +126,7 @@ const TagItemContainer: React.FC = (props: TagItemContain
{hasSubTags ? ( -
+
{tag.subTags.map((st, idx) => ( ))} diff --git a/web/src/less/memo-trash-dialog.less b/web/src/less/archived-memo-dialog.less similarity index 87% rename from web/src/less/memo-trash-dialog.less rename to web/src/less/archived-memo-dialog.less index 96155897..131c2ee4 100644 --- a/web/src/less/memo-trash-dialog.less +++ b/web/src/less/archived-memo-dialog.less @@ -1,6 +1,6 @@ @import "./mixin.less"; -.memo-trash-dialog { +.archived-memo-dialog { @apply px-4; > .dialog-container { @@ -15,7 +15,7 @@ .flex(column, center, center); } - > .deleted-memos-container { + > .archived-memos-container { .flex(column, flex-start, flex-start); @apply w-full; } diff --git a/web/src/less/memo.less b/web/src/less/memo.less index 22ec1b1c..6821e437 100644 --- a/web/src/less/memo.less +++ b/web/src/less/memo.less @@ -4,7 +4,7 @@ .memo-wrapper { @apply flex flex-col justify-start items-start w-full max-w-full p-4 pt-3 mt-2 bg-white rounded-lg border border-white hover:border-gray-200; - &.deleted-memo { + &.archived-memo { @apply border-gray-200; } @@ -50,14 +50,10 @@ } > .btn { - @apply w-full py-2 px-3 rounded justify-start; + @apply w-full text-sm leading-6 py-1 px-3 rounded justify-start; - &.delete-btn { - @apply text-red-600; - - &.final-confirm { - @apply font-bold; - } + &.archive-btn { + @apply text-orange-600; } } } diff --git a/web/src/less/shortcut-list.less b/web/src/less/shortcut-list.less index 674c995c..94c25957 100644 --- a/web/src/less/shortcut-list.less +++ b/web/src/less/shortcut-list.less @@ -1,21 +1,18 @@ @import "./mixin.less"; .shortcuts-wrapper { - .flex(column, flex-start, flex-start); - @apply w-full py-0 px-2 mt-2 h-auto shrink-0 flex-nowrap; + @apply flex flex-col justify-start items-start w-full py-0 px-2 mt-2 h-auto shrink-0 flex-nowrap; .hide-scroll-bar(); > .title-text { - .flex(row, flex-start, center); - @apply w-full px-4; + @apply flex flex-row justify-start items-center w-full px-4; > .normal-text { - @apply text-xs leading-6 font-mono text-gray-400; + @apply text-sm leading-6 font-mono text-gray-400; } > .btn { - .flex(column, center, center); - @apply w-5 h-5 bg-gray-200 rounded ml-2 shadow hover:opacity-80; + @apply flex flex-col justify-center items-center w-5 h-5 bg-gray-200 rounded ml-2 shadow hover:opacity-80; > img { @apply w-4 h-4 opacity-80; @@ -24,8 +21,7 @@ } > .create-shortcut-btn-container { - .flex(row, flex-start, center); - @apply w-full mt-4 mb-2 ml-4; + @apply flex flex-row justify-start items-center w-full mt-4 mb-2 ml-4; > .btn { @apply flex p-2 px-4 rounded-lg text-sm border border-dashed border-blue-600; @@ -37,23 +33,19 @@ } > .shortcuts-container { - .flex(column, flex-start, flex-start); - @apply relative w-full h-auto flex-nowrap mb-2; + @apply flex flex-col justify-start items-start relative w-full h-auto flex-nowrap mb-2; > .shortcut-container { - .flex(row, space-between, center); - @apply w-full h-10 py-0 px-4 mt-px first:mt-2 rounded-lg text-base cursor-pointer select-none shrink-0; + @apply flex flex-row justify-between items-center w-full h-10 py-0 px-4 mt-px first:mt-2 rounded-lg text-base cursor-pointer select-none shrink-0 hover:bg-gray-200; &:hover { - background-color: @bg-gray; - > .btns-container { @apply flex; } } &.active { - background-color: @text-green !important; + @apply bg-green-600; > .shortcut-text-container { > * { @@ -63,8 +55,7 @@ } > .shortcut-text-container { - .flex(row, flex-start, center); - @apply truncate shrink leading-5 mr-1; + @apply flex flex-row justify-start items-center truncate shrink leading-5 mr-1; color: @text-black; > .icon-text { @@ -77,8 +68,7 @@ } > .btns-container { - .flex(row, flex-end, center); - @apply hidden shrink-0; + @apply flex-row justify-end items-center hidden shrink-0; > .action-btn { .flex(row, center, center); @@ -91,35 +81,33 @@ &.toggle-btn { &:hover { & + .action-btns-wrapper { - display: flex; + @apply flex; } } } } > .action-btns-wrapper { - .flex(column, flex-start, flex-start); - @apply absolute right-0 w-auto h-auto px-4 pt-3 translate-y-16 hidden z-10; + @apply flex-col justify-start items-start absolute top-6 right-0 w-auto h-auto px-4 pt-3 hidden z-10; > .action-btns-container { - .flex(column, flex-start, flex-start); - @apply w-24 h-auto p-1 whitespace-nowrap rounded-md bg-white shadow; + @apply flex flex-col justify-start items-start w-24 h-auto p-1 whitespace-nowrap rounded-md bg-white shadow; > .btn { - @apply w-full py-2 px-3 rounded text-sm text-left hover:bg-gray-100; + @apply w-full text-sm leading-6 py-1 px-3 rounded text-left hover:bg-gray-100; &.delete-btn { - color: @text-red; + @apply text-orange-600; &.final-confirm { - font-weight: bold; + @apply font-black; } } } } &:hover { - display: flex; + @apply flex; } } } diff --git a/web/src/less/tag-list.less b/web/src/less/tag-list.less index 759642c4..953bf21e 100644 --- a/web/src/less/tag-list.less +++ b/web/src/less/tag-list.less @@ -1,21 +1,18 @@ @import "./mixin.less"; .tags-wrapper { - .flex(column, flex-start, flex-start); - @apply px-2 w-full h-auto flex-nowrap pb-4 mt-2 grow; + @apply flex flex-col justify-start items-start px-2 w-full h-auto flex-nowrap pb-4 mt-2 grow; .hide-scroll-bar(); > .title-text { - @apply w-full py-1 px-4 text-xs font-mono text-gray-400; + @apply w-full px-4 text-sm leading-6 font-mono text-gray-400; } > .tags-container { - .flex(column, flex-start, flex-start); - @apply relative w-full h-auto flex-nowrap mb-2 mt-1; + @apply flex flex-col justify-start items-start relative w-full h-auto flex-nowrap mb-2 mt-1; .subtags-container { - .flex(column, flex-start, flex-start); - @apply h-auto mt-1 ml-4 pl-1; + @apply flex flex-col justify-start items-start h-auto mt-1 ml-4 pl-1; width: calc(100% - 18px); min-width: 80px; border-left: 2px solid @bg-gray; @@ -26,27 +23,19 @@ } .tag-item-container { - .flex(row, space-between, center); - @apply w-full h-10 py-0 px-4 rounded-lg text-base shrink-0 select-none cursor-pointer; - - &:hover { - background-color: @bg-gray; - } + @apply flex flex-row justify-between items-center w-full h-10 py-0 px-4 rounded-lg text-base shrink-0 select-none cursor-pointer hover:bg-gray-200; &.active { > .tag-text-container { > * { - @apply font-bold; - color: @text-green; + @apply text-green-600; } } } > .tag-text-container { - .flex(row, flex-start, center); - @apply overflow-hidden text-ellipsis shrink-0 leading-5; + @apply flex flex-row justify-start items-center overflow-hidden text-ellipsis shrink-0 leading-5 text-black; max-width: calc(100% - 24px); - color: @text-black; > .icon-text { @apply block w-4 shrink-0; @@ -58,11 +47,10 @@ } > .btns-container { - .flex(row, flex-end, center); + @apply flex flex-row justify-end items-center; > .action-btn { - .flex(row, center, center); - @apply w-6 h-6 shrink-0 transition-all rotate-0; + @apply flex flex-row justify-center items-center w-6 h-6 shrink-0 transition-all rotate-0; > .icon-img { @apply w-5 h-5 opacity-80; diff --git a/web/src/services/memoService.ts b/web/src/services/memoService.ts index c268a05e..9243c670 100644 --- a/web/src/services/memoService.ts +++ b/web/src/services/memoService.ts @@ -23,12 +23,12 @@ const memoService = { return memos; }, - fetchDeletedMemos: async () => { + fetchArchivedMemos: async () => { const { data } = (await api.getArchivedMemoList()).data; - const deletedMemos = data.map((m) => { + const archivedMemos = data.map((m) => { return convertResponseModelMemo(m); }); - return deletedMemos; + return archivedMemos; }, getMemoById: (memoId: MemoId) => {