From d1b0b0da109e052e56dd517c6d7b51a17b35c220 Mon Sep 17 00:00:00 2001 From: boojack Date: Thu, 3 Aug 2023 23:28:38 +0800 Subject: [PATCH] chore: remove shortcuts in frontend (#2071) --- web/src/components/CreateShortcutDialog.tsx | 293 -------------------- web/src/components/HomeSidebar.tsx | 2 - web/src/components/MemoFilter.tsx | 17 +- web/src/components/MemoList.tsx | 17 +- web/src/components/MobileHeader.tsx | 22 +- web/src/components/ShortcutList.tsx | 169 ----------- web/src/helpers/api.ts | 20 -- web/src/less/create-shortcut-dialog.less | 101 ------- web/src/locales/de.json | 12 +- web/src/locales/en.json | 10 - web/src/locales/es.json | 10 - web/src/locales/fr.json | 10 - web/src/locales/hi.json | 12 +- web/src/locales/hr.json | 10 - web/src/locales/it.json | 10 - web/src/locales/ja.json | 10 - web/src/locales/ko.json | 10 - web/src/locales/nl.json | 10 - web/src/locales/pl.json | 10 - web/src/locales/pt-BR.json | 12 +- web/src/locales/ru.json | 12 +- web/src/locales/sl.json | 12 +- web/src/locales/sv.json | 10 - web/src/locales/tr.json | 10 - web/src/locales/uk.json | 10 - web/src/locales/vi.json | 10 - web/src/locales/zh-Hans.json | 10 - web/src/locales/zh-Hant.json | 12 +- web/src/store/index.ts | 2 - web/src/store/module/filter.ts | 8 - web/src/store/module/index.ts | 1 - web/src/store/module/shortcut.ts | 49 ---- web/src/store/reducer/filter.ts | 1 - web/src/store/reducer/shortcut.ts | 51 ---- web/src/types/modules/shortcut.d.ts | 28 -- 35 files changed, 16 insertions(+), 977 deletions(-) delete mode 100644 web/src/components/CreateShortcutDialog.tsx delete mode 100644 web/src/components/ShortcutList.tsx delete mode 100644 web/src/less/create-shortcut-dialog.less delete mode 100644 web/src/store/module/shortcut.ts delete mode 100644 web/src/store/reducer/shortcut.ts delete mode 100644 web/src/types/modules/shortcut.d.ts diff --git a/web/src/components/CreateShortcutDialog.tsx b/web/src/components/CreateShortcutDialog.tsx deleted file mode 100644 index 362373e7..00000000 --- a/web/src/components/CreateShortcutDialog.tsx +++ /dev/null @@ -1,293 +0,0 @@ -import { useCallback, useEffect, useState } from "react"; -import { toast } from "react-hot-toast"; -import { getNormalizedTimeString } from "@/helpers/datetime"; -import { filterConsts, getDefaultFilter, relationConsts } from "@/helpers/filter"; -import useLoading from "@/hooks/useLoading"; -import { useShortcutStore, useTagStore } from "@/store/module"; -import { useTranslate } from "@/utils/i18n"; -import { generateDialog } from "./Dialog"; -import Icon from "./Icon"; -import Selector from "./kit/Selector"; -import "@/less/create-shortcut-dialog.less"; - -interface Props extends DialogProps { - shortcutId?: ShortcutId; -} - -const CreateShortcutDialog: React.FC = (props: Props) => { - const { destroy, shortcutId } = props; - const shortcutStore = useShortcutStore(); - const [title, setTitle] = useState(""); - const [filters, setFilters] = useState([]); - const requestState = useLoading(false); - const t = useTranslate(); - - useEffect(() => { - if (shortcutId) { - const shortcutTemp = shortcutStore.getShortcutById(shortcutId); - if (shortcutTemp) { - setTitle(shortcutTemp.title); - const temp = JSON.parse(shortcutTemp.payload); - if (Array.isArray(temp)) { - setFilters(temp); - } - } - } - }, [shortcutId]); - - const handleTitleInputChange = (e: React.ChangeEvent) => { - const text = e.target.value as string; - setTitle(text); - }; - - const handleSaveBtnClick = async () => { - if (!title) { - toast.error(t("shortcut-list.title-required")); - return; - } - for (const filter of filters) { - if (!filter.value.value) { - toast.error(t("shortcut-list.value-required")); - return; - } - } - try { - if (shortcutId) { - await shortcutStore.patchShortcut({ - id: shortcutId, - title, - payload: JSON.stringify(filters), - }); - } else { - await shortcutStore.createShortcut({ - title, - payload: JSON.stringify(filters), - }); - } - } catch (error: any) { - console.error(error); - toast.error(error.response.data.message); - } - destroy(); - }; - - const handleAddFilterBtnClick = () => { - if (filters.length > 0) { - const lastFilter = filters[filters.length - 1]; - if (lastFilter.value.value === "") { - toast(t("shortcut-list.fill-previous")); - return; - } - } - - setFilters([...filters, getDefaultFilter()]); - }; - - const handleFilterChange = useCallback((index: number, filter: Filter) => { - setFilters((filters) => { - const temp = [...filters]; - temp[index] = filter; - return temp; - }); - }, []); - - const handleFilterRemove = useCallback((index: number) => { - setFilters((filters) => { - const temp = filters.filter((_, i) => i !== index); - return temp; - }); - }, []); - - return ( - <> -
-

{shortcutId ? t("shortcut-list.edit-shortcut") : t("shortcut-list.create-shortcut")}

- -
-
-
- {t("common.title")} - -
-
- {t("common.filter")} -
- {filters.map((f, index) => { - return ( - - ); - })} -
- {t("filter.new-filter")} -
-
-
-
-
-
-
- -
-
- - ); -}; - -interface MemoFilterInputerProps { - index: number; - filter: Filter; - handleFilterChange: (index: number, filter: Filter) => void; - handleFilterRemove: (index: number) => void; -} - -const MemoFilterInputer: React.FC = (props: MemoFilterInputerProps) => { - const { index, filter, handleFilterChange, handleFilterRemove } = props; - const t = useTranslate(); - const tagStore = useTagStore(); - const [value, setValue] = useState(filter.value.value); - const tags = Array.from(tagStore.getState().tags); - const { type } = filter; - - const typeDataSource = Object.values(filterConsts).map(({ text, value }) => ({ text: t(text), value })); - const operatorDataSource = Object.values(filterConsts[type as FilterType].operators).map(({ text, value }) => ({ text: t(text), value })); - const relationDataSource = Object.values(relationConsts).map(({ text, value }) => ({ text: t(text), value })); - - const valueDataSource = - type === "TYPE" - ? filterConsts["TYPE"].values.map(({ text, value }) => ({ text: t(text), value })) - : type === "VISIBILITY" - ? filterConsts["VISIBILITY"].values.map(({ text, value }) => ({ text: t(text), value })) - : tags.sort().map((t) => { - return { text: t, value: t }; - }); - - const maxDatetimeValue = getNormalizedTimeString("9999-12-31T23:59"); - - useEffect(() => { - if (type === "DISPLAY_TIME") { - const nowDatetimeValue = getNormalizedTimeString(); - handleValueChange(nowDatetimeValue); - } else { - setValue(filter.value.value); - } - }, [type]); - - const handleRelationChange = (value: string) => { - if (["AND", "OR"].includes(value)) { - handleFilterChange(index, { - ...filter, - relation: value as MemoFilterRelation, - }); - } - }; - - const handleTypeChange = (value: string) => { - if (filter.type !== value) { - const ops = Object.values(filterConsts[value as FilterType].operators); - handleFilterChange(index, { - ...filter, - type: value as FilterType, - value: { - operator: ops[0].value, - value: "", - }, - }); - } - }; - - const handleOperatorChange = (value: string) => { - handleFilterChange(index, { - ...filter, - value: { - ...filter.value, - operator: value, - }, - }); - }; - - const handleValueChange = (value: string) => { - setValue(value); - handleFilterChange(index, { - ...filter, - value: { - ...filter.value, - value, - }, - }); - }; - - const handleRemoveBtnClick = () => { - handleFilterRemove(index); - }; - - return ( -
- {index > 0 ? ( - - ) : null} - - - {type === "TEXT" ? ( - { - handleValueChange(event.target.value); - }} - placeholder={t("filter.text-placeholder")} - /> - ) : type === "DISPLAY_TIME" ? ( - { - handleValueChange(event.target.value); - }} - /> - ) : ( - - )} - -
- ); -}; - -export default function showCreateShortcutDialog(shortcutId?: ShortcutId): void { - generateDialog( - { - className: "create-shortcut-dialog", - dialogName: "create-shortcut-dialog", - }, - CreateShortcutDialog, - { shortcutId } - ); -} diff --git a/web/src/components/HomeSidebar.tsx b/web/src/components/HomeSidebar.tsx index c7d4cfb9..b75e77f4 100644 --- a/web/src/components/HomeSidebar.tsx +++ b/web/src/components/HomeSidebar.tsx @@ -1,6 +1,5 @@ import { useLayoutStore, useUserStore } from "../store/module"; import SearchBar from "./SearchBar"; -import ShortcutList from "./ShortcutList"; import TagList from "./TagList"; import UsageHeatMap from "./UsageHeatMap"; @@ -32,7 +31,6 @@ const HomeSidebar = () => { {!userStore.isVisitorMode() && ( <> - )} diff --git a/web/src/components/MemoFilter.tsx b/web/src/components/MemoFilter.tsx index 5c846624..6ca8844f 100644 --- a/web/src/components/MemoFilter.tsx +++ b/web/src/components/MemoFilter.tsx @@ -2,7 +2,7 @@ import { useEffect } from "react"; import { useLocation } from "react-router-dom"; import { getDateString } from "@/helpers/datetime"; import { getTextWithMemoType } from "@/helpers/filter"; -import { useFilterStore, useShortcutStore } from "@/store/module"; +import { useFilterStore } from "@/store/module"; import { useTranslate } from "@/utils/i18n"; import Icon from "./Icon"; import "@/less/memo-filter.less"; @@ -11,11 +11,9 @@ const MemoFilter = () => { const t = useTranslate(); const location = useLocation(); const filterStore = useFilterStore(); - const shortcutStore = useShortcutStore(); const filter = filterStore.state; - const { tag: tagQuery, duration, type: memoType, text: textQuery, shortcutId, visibility } = filter; - const shortcut = shortcutId ? shortcutStore.getShortcutById(shortcutId) : null; - const showFilter = Boolean(tagQuery || (duration && duration.from < duration.to) || memoType || textQuery || shortcut || visibility); + const { tag: tagQuery, duration, type: memoType, text: textQuery, visibility } = filter; + const showFilter = Boolean(tagQuery || (duration && duration.from < duration.to) || memoType || textQuery || visibility); useEffect(() => { filterStore.clearFilter(); @@ -24,15 +22,6 @@ const MemoFilter = () => { return (
{t("common.filter")}: -
{ - filterStore.setMemoShortcut(undefined); - }} - > - {shortcut?.title} - -
{ diff --git a/web/src/components/MemoList.tsx b/web/src/components/MemoList.tsx index 50a52d46..e26c5c68 100644 --- a/web/src/components/MemoList.tsx +++ b/web/src/components/MemoList.tsx @@ -2,9 +2,8 @@ import { useEffect, useRef, useState } from "react"; import { toast } from "react-hot-toast"; import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; import { getTimeStampByDate } from "@/helpers/datetime"; -import { checkShouldShowMemoWithFilters } from "@/helpers/filter"; import { LINK_REG, PLAIN_LINK_REG, TAG_REG } from "@/labs/marked/parser"; -import { useFilterStore, useMemoStore, useShortcutStore, useUserStore } from "@/store/module"; +import { useFilterStore, useMemoStore, useUserStore } from "@/store/module"; import { useTranslate } from "@/utils/i18n"; import Empty from "./Empty"; import Memo from "./Memo"; @@ -19,28 +18,20 @@ const MemoList: React.FC = (props: Props) => { const t = useTranslate(); const memoStore = useMemoStore(); const userStore = useUserStore(); - const shortcutStore = useShortcutStore(); const filterStore = useFilterStore(); const filter = filterStore.state; const { memos, isFetching } = memoStore.state; const [isComplete, setIsComplete] = useState(false); const currentUsername = userStore.getCurrentUsername(); - const { tag: tagQuery, duration, type: memoType, text: textQuery, shortcutId, visibility } = filter; - const shortcut = shortcutId ? shortcutStore.getShortcutById(shortcutId) : null; - const showMemoFilter = Boolean(tagQuery || (duration && duration.from < duration.to) || memoType || textQuery || shortcut || visibility); + const { tag: tagQuery, duration, type: memoType, text: textQuery, visibility } = filter; + const showMemoFilter = Boolean(tagQuery || (duration && duration.from < duration.to) || memoType || textQuery || visibility); const shownMemos = ( - showMemoFilter || shortcut + showMemoFilter ? memos.filter((memo) => { let shouldShow = true; - if (shortcut) { - const filters = JSON.parse(shortcut.payload) as Filter[]; - if (Array.isArray(filters)) { - shouldShow = checkShouldShowMemoWithFilters(memo, filters); - } - } if (tagQuery) { const tagsSet = new Set(); for (const t of Array.from(memo.content.match(new RegExp(TAG_REG, "gu")) ?? [])) { diff --git a/web/src/components/MobileHeader.tsx b/web/src/components/MobileHeader.tsx index 8f978413..43680b17 100644 --- a/web/src/components/MobileHeader.tsx +++ b/web/src/components/MobileHeader.tsx @@ -1,5 +1,5 @@ -import { useEffect, useState } from "react"; -import { useFilterStore, useLayoutStore, useShortcutStore } from "@/store/module"; +import { useState } from "react"; +import { useLayoutStore } from "@/store/module"; import Icon from "./Icon"; interface Props { @@ -8,24 +8,8 @@ interface Props { const MobileHeader = (props: Props) => { const { showSearch = true } = props; - const filterStore = useFilterStore(); - const shortcutStore = useShortcutStore(); const layoutStore = useLayoutStore(); - const filter = filterStore.state; - const shortcuts = shortcutStore.state.shortcuts; - const [titleText, setTitleText] = useState("MEMOS"); - - useEffect(() => { - if (!filter.shortcutId) { - setTitleText("MEMOS"); - return; - } - - const shortcut = shortcutStore.getShortcutById(filter.shortcutId); - if (shortcut) { - setTitleText(shortcut.title); - } - }, [filter, shortcuts]); + const [titleText] = useState("MEMOS"); return (
diff --git a/web/src/components/ShortcutList.tsx b/web/src/components/ShortcutList.tsx deleted file mode 100644 index 39921e91..00000000 --- a/web/src/components/ShortcutList.tsx +++ /dev/null @@ -1,169 +0,0 @@ -import { useEffect } from "react"; -import { toast } from "react-hot-toast"; -import { getTimeStampByDate } from "@/helpers/datetime"; -import useLoading from "@/hooks/useLoading"; -import useToggle from "@/hooks/useToggle"; -import { useFilterStore, useShortcutStore } from "@/store/module"; -import { useTranslate } from "@/utils/i18n"; -import showCreateShortcutDialog from "./CreateShortcutDialog"; -import Icon from "./Icon"; - -const ShortcutList = () => { - const t = useTranslate(); - const filterStore = useFilterStore(); - const shortcutStore = useShortcutStore(); - const filter = filterStore.state; - const shortcuts = shortcutStore.state.shortcuts; - const loadingState = useLoading(); - - const pinnedShortcuts = shortcuts - .filter((s) => s.rowStatus === "ARCHIVED") - .sort((a, b) => getTimeStampByDate(b.createdTs) - getTimeStampByDate(a.createdTs)); - const unpinnedShortcuts = shortcuts - .filter((s) => s.rowStatus === "NORMAL") - .sort((a, b) => getTimeStampByDate(b.createdTs) - getTimeStampByDate(a.createdTs)); - const sortedShortcuts = pinnedShortcuts.concat(unpinnedShortcuts); - - useEffect(() => { - shortcutStore - .getMyAllShortcuts() - .catch(() => { - // do nth - }) - .finally(() => { - loadingState.setFinish(); - }); - }, []); - - return ( -
-
- {t("common.shortcuts")} - -
-
- {sortedShortcuts.map((s) => { - return ; - })} -
-
- ); -}; - -interface ShortcutContainerProps { - shortcut: Shortcut; - isActive: boolean; -} - -const ShortcutContainer: React.FC = (props: ShortcutContainerProps) => { - const { shortcut, isActive } = props; - const t = useTranslate(); - const filterStore = useFilterStore(); - const shortcutStore = useShortcutStore(); - const [showConfirmDeleteBtn, toggleConfirmDeleteBtn] = useToggle(false); - - const handleShortcutClick = () => { - if (isActive) { - filterStore.setMemoShortcut(undefined); - } else { - filterStore.setMemoShortcut(shortcut.id); - } - }; - - const handleDeleteMemoClick = async (event: React.MouseEvent) => { - event.stopPropagation(); - - if (showConfirmDeleteBtn) { - try { - await shortcutStore.deleteShortcutById(shortcut.id); - if (filterStore.getState().shortcutId === shortcut.id) { - // need clear shortcut filter - filterStore.setMemoShortcut(undefined); - } - } catch (error: any) { - console.error(error); - toast.error(error.response.data.message); - } - } else { - toggleConfirmDeleteBtn(); - } - }; - - const handleEditShortcutBtnClick = (event: React.MouseEvent) => { - event.stopPropagation(); - showCreateShortcutDialog(shortcut.id); - }; - - const handlePinShortcutBtnClick = async (event: React.MouseEvent) => { - event.stopPropagation(); - - try { - const shortcutPatch: ShortcutPatch = { - id: shortcut.id, - rowStatus: shortcut.rowStatus === "ARCHIVED" ? "NORMAL" : "ARCHIVED", - }; - await shortcutStore.patchShortcut(shortcutPatch); - } catch (error) { - // do nth - } - }; - - const handleDeleteBtnMouseLeave = () => { - toggleConfirmDeleteBtn(false); - }; - - return ( - <> -
-
- {shortcut.title} -
-
- - - -
-
- - {shortcut.rowStatus === "ARCHIVED" ? t("common.unpin") : t("common.pin")} - - - {t("common.edit")} - - - {t("common.delete")} - {showConfirmDeleteBtn ? "!" : ""} - -
-
-
-
- - ); -}; - -export default ShortcutList; diff --git a/web/src/helpers/api.ts b/web/src/helpers/api.ts index 3dc30552..469c3ae7 100644 --- a/web/src/helpers/api.ts +++ b/web/src/helpers/api.ts @@ -142,26 +142,6 @@ export function checkOpenAIEnabled() { return axios.get(`/api/openai/enabled`); } -export function getShortcutList(shortcutFind?: ShortcutFind) { - const queryList = []; - if (shortcutFind?.creatorUsername) { - queryList.push(`creatorUsername=${shortcutFind.creatorUsername}`); - } - return axios.get(`/api/v1/shortcut?${queryList.join("&")}`); -} - -export function createShortcut(shortcutCreate: ShortcutCreate) { - return axios.post("/api/v1/shortcut", shortcutCreate); -} - -export function patchShortcut(shortcutPatch: ShortcutPatch) { - return axios.patch(`/api/v1/shortcut/${shortcutPatch.id}`, shortcutPatch); -} - -export function deleteShortcutById(shortcutId: ShortcutId) { - return axios.delete(`/api/v1/shortcut/${shortcutId}`); -} - export function getResourceList() { return axios.get("/api/v1/resource"); } diff --git a/web/src/less/create-shortcut-dialog.less b/web/src/less/create-shortcut-dialog.less deleted file mode 100644 index 68593b90..00000000 --- a/web/src/less/create-shortcut-dialog.less +++ /dev/null @@ -1,101 +0,0 @@ -.create-shortcut-dialog { - @apply px-4; - - > .dialog-container { - @apply w-180 max-w-full; - - > .dialog-content-container { - @apply flex flex-col justify-start items-start; - - > .form-item-container { - @apply w-full mt-2 py-1 flex sm:flex-row flex-col justify-start items-start; - - > .normal-text { - @apply block shrink-0 w-12 mr-8 sm:text-right text-left text-sm leading-8; - color: gray; - } - - > .title-input { - @apply w-full py-1 px-2 h-9 text-sm rounded border dark:border-zinc-700 dark:bg-zinc-800 shadow-inner; - } - - > .filters-wrapper { - @apply w-full flex flex-col justify-start items-start; - - > .create-filter-btn { - @apply text-sm py-1 px-2 rounded shadow flex flex-row sm:justify-start justify-center items-center border dark:border-zinc-700 cursor-pointer text-blue-500 hover:opacity-80 sm:min-w-0 min-w-full sm:mb-0 mb-1; - } - } - } - } - - > .dialog-footer-container { - @apply w-full mt-0 flex flex-row justify-between items-center; - - > .btns-container { - @apply flex flex-row justify-start items-center; - - > .tip-text { - @apply text-sm text-gray-400 mr-2; - } - - > .btn { - @apply text-base px-4 py-1 leading-7 rounded shadow hover:opacity-80; - - &.save-btn { - @apply bg-green-600 text-white; - - &.requesting { - @apply cursor-wait opacity-80; - } - } - } - } - } - } -} - -.memo-filter-input-wrapper { - @apply w-full mb-3 shrink-0 flex flex-row sm:justify-start justify-center items-center sm:flex-nowrap flex-wrap sm:gap-0 gap-3; - - > .selector-wrapper { - @apply mr-1 h-9 grow-0 shrink-0 sm:min-w-0 min-w-full; - - &.relation-selector { - @apply w-16; - @media only screen and (min-width: 640px) { - margin-left: -68px; - } - } - - &.type-selector { - @apply w-1/4; - } - - &.operator-selector { - @apply w-1/5; - } - - &.value-selector { - @apply grow; - } - } - - > input.value-inputer { - @media only screen and (min-width: 640px) { - max-width: calc(100% - 152px); - } - @apply h-9 px-2 shrink-0 grow mr-1 text-sm rounded border bg-transparent hover:bg-gray-50 sm:min-w-0 min-w-full; - } - - > input.datetime-selector { - @media only screen and (min-width: 640px) { - max-width: calc(100% - 152px); - } - @apply h-9 px-2 shrink-0 grow mr-1 text-sm rounded border bg-transparent sm:min-w-0 min-w-full; - } - - > .remove-btn { - @apply w-4 h-auto ml-1 cursor-pointer opacity-60 hover:opacity-80; - } -} diff --git a/web/src/locales/de.json b/web/src/locales/de.json index fe5746dc..a1680a29 100644 --- a/web/src/locales/de.json +++ b/web/src/locales/de.json @@ -34,7 +34,6 @@ "sign-out": "Abmelden", "back-to-home": "Zurück zur Startseite", "type": "Typ", - "shortcuts": "Verknüpfungen", "title": "Titel", "filter": "Filter", "tags": "Tags", @@ -97,7 +96,7 @@ "memo": { "view-detail": "Details anzeigen", "copy": "Kopieren", - "copy-link":"Link Kopieren", + "copy-link": "Link Kopieren", "visibility": { "private": "Nur für dich sichtbar", "protected": "Für Mitglieder sichtbar", @@ -109,15 +108,6 @@ "fetching-data": "Lade Daten...", "fetch-more": "Klicke hier, um mehr zu laden" }, - "shortcut-list": { - "shortcut-title": "Titel der Verknüpfung", - "create-shortcut": "Verknüpfung erstellen", - "edit-shortcut": "Verknüpfung bearbeiten", - "fill-previous": "Bitte vorherigen Filterwert ausfüllen", - "title-required": "Titel wird benötigt", - "value-required": "Filterwert wird benötigt", - "eligible-memo": "eligible memo" - }, "filter": { "new-filter": "Neuer Filter", "type": { diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 6eb3f853..d8b8a10e 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -38,7 +38,6 @@ "sign-up": "Sign up", "sign-out": "Sign out", "type": "Type", - "shortcuts": "Shortcuts", "title": "Title", "filter": "Filter", "filter-period": "{{from}} to {{to}}", @@ -148,15 +147,6 @@ } } }, - "shortcut-list": { - "shortcut-title": "shortcut title", - "create-shortcut": "Create Shortcut", - "edit-shortcut": "Edit Shortcut", - "eligible-memo": "eligible memo", - "fill-previous": "Please fill in previous filter value", - "title-required": "Title is required", - "value-required": "Filter value is required" - }, "tag-list": { "tip-text": "Input `#tag` to create", "create-tag": "Create Tag", diff --git a/web/src/locales/es.json b/web/src/locales/es.json index cd80fd0e..801b9761 100644 --- a/web/src/locales/es.json +++ b/web/src/locales/es.json @@ -34,7 +34,6 @@ "sign-out": "Cerrar sesión", "back-to-home": "Volver al Inicio", "type": "Tipo", - "shortcuts": "Atajos", "title": "Título", "filter": "Filtros", "tags": "Etiquetas", @@ -109,15 +108,6 @@ "fetching-data": "obteniendo datos...", "fetch-more": "Click aqui para obtener más información" }, - "shortcut-list": { - "shortcut-title": "título del atajo", - "create-shortcut": "Crear Atajo", - "edit-shortcut": "Editar Atajo", - "eligible-memo": "nota elegible", - "fill-previous": "Introduce el valor del filtro anterior", - "title-required": "El título es obligatorio", - "value-required": "El valor del filtro es obligatorio" - }, "filter": { "new-filter": "Nuevo Filtro", "type": { diff --git a/web/src/locales/fr.json b/web/src/locales/fr.json index 65d94b3e..9f4ef970 100644 --- a/web/src/locales/fr.json +++ b/web/src/locales/fr.json @@ -34,7 +34,6 @@ "sign-out": "Se déconnecter", "back-to-home": "Retour à l'accueil", "type": "Type", - "shortcuts": "Raccourcis", "title": "Titre", "filter": "Filtre", "tags": "Étiquettes", @@ -109,15 +108,6 @@ "fetching-data": "récupération des données...", "fetch-more": "Cliquez ici pour en savoir plus" }, - "shortcut-list": { - "shortcut-title": "titre du raccourci", - "create-shortcut": "Créer un raccourci", - "edit-shortcut": "Editer un raccourci", - "eligible-memo": "mémo admissible", - "fill-previous": "Veuillez remplir la valeur du filtre précédent", - "title-required": "Le titre est requis", - "value-required": "La valeur du filtre est requise" - }, "filter": { "new-filter": "Nouveau filtre", "type": { diff --git a/web/src/locales/hi.json b/web/src/locales/hi.json index 0db06c19..c4818c5b 100644 --- a/web/src/locales/hi.json +++ b/web/src/locales/hi.json @@ -38,7 +38,6 @@ "sign-up": "साइन अप करें", "sign-out": "साइन आउट करें", "type": "प्रकार", - "shortcuts": "शॉर्टकट", "title": "शीर्षक", "filter": "फ़िल्टर", "filter-period": "{{from}} से {{to}} तक", @@ -148,15 +147,6 @@ } } }, - "shortcut-list": { - "shortcut-title": "शॉर्टकट शीर्षक", - "create-shortcut": "शॉर्टकट बनाएँ", - "edit-shortcut": "शॉर्टकट संपादित करें", - "eligible-memo": "उपयुक्त मेमो", - "fill-previous": "कृपया पिछले फ़िल्टर मान को भरें", - "title-required": "शीर्षक आवश्यक है", - "value-required": "फ़िल्टर मान आवश्यक है" - }, "tag-list": { "tip-text": "बनाने के लिए `#tag` इनपुट करें", "create-tag": "टैग बनाएँ", @@ -428,4 +418,4 @@ "powered-by": "द्वारा संचालित", "other-projects": "अन्य प्रोजेक्ट्स" } -} \ No newline at end of file +} diff --git a/web/src/locales/hr.json b/web/src/locales/hr.json index b0962e36..cd2b5f3e 100644 --- a/web/src/locales/hr.json +++ b/web/src/locales/hr.json @@ -38,7 +38,6 @@ "sign-up": "Registriraj se", "sign-out": "Odjavi se", "type": "Tip", - "shortcuts": "Prečaci", "title": "Naslov", "filter": "Filtriraj", "filter-period": "{{from}} do {{to}}", @@ -148,15 +147,6 @@ } } }, - "shortcut-list": { - "shortcut-title": "ime prečaca", - "create-shortcut": "Stvori prečac", - "edit-shortcut": "Uredi prečac", - "eligible-memo": "eligible memo", - "fill-previous": "Please fill in previous filter value", - "title-required": "Naslov je obavezan", - "value-required": "Filter value je tražena" - }, "tag-list": { "tip-text": "Unesi `#tag` kako bi stvorio", "create-tag": "Stvori Tag", diff --git a/web/src/locales/it.json b/web/src/locales/it.json index 24b2340a..97aa24dc 100644 --- a/web/src/locales/it.json +++ b/web/src/locales/it.json @@ -34,7 +34,6 @@ "sign-out": "Esci", "back-to-home": "Ritorna alla Home", "type": "Tipo", - "shortcuts": "Scorciatoie", "title": "Titolo", "filter": "Filtro", "tags": "Etichette", @@ -109,15 +108,6 @@ "fetching-data": "recupero i dati...", "fetch-more": "Clicca per caricare più dati" }, - "shortcut-list": { - "shortcut-title": "titolo Scorciatoia", - "create-shortcut": "Crea Scorciatoia", - "edit-shortcut": "Modifica Scorciatoia", - "eligible-memo": "eligible memo", - "fill-previous": "Compila il valore del filtro precedente", - "title-required": "Il titolo è obbligatorio", - "value-required": "Il valore del filtro è obbligatorio" - }, "filter": { "new-filter": "Nuovo Filtro", "type": { diff --git a/web/src/locales/ja.json b/web/src/locales/ja.json index 7bdb35e2..8e6876d9 100644 --- a/web/src/locales/ja.json +++ b/web/src/locales/ja.json @@ -38,7 +38,6 @@ "sign-up": "登録", "sign-out": "ログアウト", "type": "タイプ", - "shortcuts": "ショートカット", "title": "タイトル", "filter": "フィルター", "filter-period": "{{from}}から{{to}}", @@ -145,15 +144,6 @@ } } }, - "shortcut-list": { - "shortcut-title": "ショートカットの名前", - "create-shortcut": "ショートカットを作成", - "edit-shortcut": "ショートカットを編集", - "eligible-memo": "的確なメモ", - "fill-previous": "前回のフィルターの値を入力してください。", - "title-required": "タイトルは必須です", - "value-required": "フィルターの値は必須です。" - }, "tag-list": { "tip-text": "作成するには`#tag`のように入力してください", "create-tag": "タグを作成する", diff --git a/web/src/locales/ko.json b/web/src/locales/ko.json index 4e66926e..1709c0ac 100644 --- a/web/src/locales/ko.json +++ b/web/src/locales/ko.json @@ -38,7 +38,6 @@ "sign-up": "회원등록", "sign-out": "로그아웃", "type": "타입", - "shortcuts": "바로가기", "title": "제목", "filter": "필터", "filter-period": "{{from}} 부터 {{to}}", @@ -145,15 +144,6 @@ } } }, - "shortcut-list": { - "shortcut-title": "바로가기 이름", - "create-shortcut": "바로가기 생성", - "edit-shortcut": "바로가기 변경", - "eligible-memo": "해당하는 메모", - "fill-previous": "위의 필터 값을 채워주세요", - "title-required": "제목이 있어야 합니다", - "value-required": "필터 값이 있어야 합니다" - }, "tag-list": { "tip-text": "`#태그명`을 입력하세요", "create-tag": "태그 생성", diff --git a/web/src/locales/nl.json b/web/src/locales/nl.json index 2645b88d..95098aa1 100644 --- a/web/src/locales/nl.json +++ b/web/src/locales/nl.json @@ -32,7 +32,6 @@ "sign-out": "Uitloggen", "back-to-home": "Terug naar homepagina", "type": "Type", - "shortcuts": "Snelkoppelingen", "title": "Titel", "filter": "Filter", "tags": "Labels", @@ -109,15 +108,6 @@ "fetching-data": "data aan het ophalen...", "fetch-more": "Klik hier om meer op te halen" }, - "shortcut-list": { - "shortcut-title": "snelkoppelingstitel", - "create-shortcut": "Maak Snelkoppeling", - "edit-shortcut": "Wijzig Shortcut", - "eligible-memo": "geschikte memo", - "fill-previous": "Vul alsjeblieft het vorige filter in", - "title-required": "Titel is verplicht", - "value-required": "Filter is verplicht" - }, "filter": { "new-filter": "Nieuw Filter", "type": { diff --git a/web/src/locales/pl.json b/web/src/locales/pl.json index af097b8c..ccd00db6 100644 --- a/web/src/locales/pl.json +++ b/web/src/locales/pl.json @@ -35,7 +35,6 @@ "sign-out": "Wyloguj", "back-to-home": "Powrót do Strony Głównej", "type": "Typ", - "shortcuts": "Skróty", "title": "Tytuł", "filter": "Filtruj", "tags": "Tagi", @@ -109,15 +108,6 @@ "fetching-data": "pobieranie danych...", "fetch-more": "Kliknij, aby pobrać więcej" }, - "shortcut-list": { - "shortcut-title": "krótki tytuł", - "create-shortcut": "Utwórz skrót", - "edit-shortcut": "Edytuj skrót", - "eligible-memo": "kwalifikująca się notatka", - "fill-previous": "Proszę uzupełnij poprzednią wartość filtra", - "title-required": "Tytuł jest wymagany", - "value-required": "Wartość filtra jest wymagana" - }, "filter": { "new-filter": "Nowy filtr", "type": { diff --git a/web/src/locales/pt-BR.json b/web/src/locales/pt-BR.json index 7cc2d2f7..223ad885 100644 --- a/web/src/locales/pt-BR.json +++ b/web/src/locales/pt-BR.json @@ -38,7 +38,6 @@ "sign-up": "Registrar", "sign-out": "Sair", "type": "Tipo", - "shortcuts": "Atalhos", "title": "Título", "filter": "Filtro", "filter-period": "{{from}} até {{to}}", @@ -145,15 +144,6 @@ } } }, - "shortcut-list": { - "shortcut-title": "título do atalho", - "create-shortcut": "Criar atalho", - "edit-shortcut": "Editar atalho", - "eligible-memo": "memo elegível", - "fill-previous": "Por favor, preencha o valor do filtro anterior", - "title-required": "O título do atalho é obrigatório", - "value-required": "O valor do filtro é obrigatório" - }, "tag-list": { "tip-text": "Insira `#tag` para criar uma nova", "create-tag": "Criar Tag", @@ -401,4 +391,4 @@ "powered-by": "Provido por", "other-projects": "Outros projetos" } -} \ No newline at end of file +} diff --git a/web/src/locales/ru.json b/web/src/locales/ru.json index 49a38dd1..652f7ec7 100644 --- a/web/src/locales/ru.json +++ b/web/src/locales/ru.json @@ -43,7 +43,6 @@ "sign-out": "Выйти", "back-to-home": "Вернуться на главную", "type": "Тип", - "shortcuts": "Фильтры", "title": "Заголовок", "filter": "Фильтр", "filter-period": "{{from}} по {{to}}", @@ -179,15 +178,6 @@ "fetching-data": "загрузка данных...", "fetch-more": "Загрузить больше" }, - "shortcut-list": { - "shortcut-title": "Название фильтра", - "create-shortcut": "Создать фильтр", - "edit-shortcut": "Редактировать фильтр", - "eligible-memo": "связанные записи", - "fill-previous": "Пожалуйста, заполните значение фильтра", - "title-required": "Название обязательно", - "value-required": "Значение фильтра обязательно" - }, "filter": { "new-filter": "Новый фильтр", "type": { @@ -469,4 +459,4 @@ "other-projects": "Другие проекты", "powered-by": "Создано" } -} \ No newline at end of file +} diff --git a/web/src/locales/sl.json b/web/src/locales/sl.json index ff45d08e..e51f6df7 100644 --- a/web/src/locales/sl.json +++ b/web/src/locales/sl.json @@ -39,7 +39,6 @@ "sign-out": "Odjavi se", "back-to-home": "Nazaj domov", "type": "Tip", - "shortcuts": "Bližnjice", "title": "Naslov", "filter": "Filter", "tags": "Značke", @@ -130,15 +129,6 @@ "fetching-data": "pridobivam podatke...", "fetch-more": "Kliknite tu da pridobite še več" }, - "shortcut-list": { - "shortcut-title": "naslov bližnjice", - "create-shortcut": "Kreiraj bližnjico", - "edit-shortcut": "Uredi bližnjico", - "eligible-memo": "upravičene beležke", - "fill-previous": "Prosim izpolnite prejšnje vrednosti filtra", - "title-required": "Naslov je obvezen", - "value-required": "Vrednost filtra je obvezna" - }, "filter": { "new-filter": "Nov filter", "type": { @@ -200,7 +190,7 @@ "created_ts": "Čas ustvarjanja", "updated_ts": "Čas posodobitve", "daily-review-time-offset": "Časovni odmik dnevnega pregleda", - "auto-collapse":"Samodejno strni" + "auto-collapse": "Samodejno strni" }, "storage-section": { "storage-services-list": "Seznam storitev shramb", diff --git a/web/src/locales/sv.json b/web/src/locales/sv.json index a1d67361..7fd4ac51 100644 --- a/web/src/locales/sv.json +++ b/web/src/locales/sv.json @@ -34,7 +34,6 @@ "sign-out": "Logga ut", "back-to-home": "Tillbaka hem", "type": "Typ", - "shortcuts": "Genvägar", "title": "Titel", "filter": "Filter", "tags": "Taggar", @@ -109,15 +108,6 @@ "fetching-data": "hämtar data...", "fetch-more": "Klicka här för att hämta mer" }, - "shortcut-list": { - "shortcut-title": "Genvägs titel", - "create-shortcut": "Skapa genväg", - "edit-shortcut": "Ändra genväg", - "eligible-memo": "kvalificerad anteckning", - "fill-previous": "Vänligen fyll i tidigare filtervärde", - "title-required": "Titel krävs", - "value-required": "Filtervärde krävs" - }, "filter": { "new-filter": "Nytt filter", "type": { diff --git a/web/src/locales/tr.json b/web/src/locales/tr.json index 42a2672b..431d7f92 100644 --- a/web/src/locales/tr.json +++ b/web/src/locales/tr.json @@ -34,7 +34,6 @@ "sign-out": "Çıkış yap", "back-to-home": "Ana sayfaya dön", "type": "Tip", - "shortcuts": "Kısayollar", "title": "Başlık", "filter": "Filtre", "tags": "Etiketler", @@ -99,15 +98,6 @@ "fetching-data": "Veriler yükleniyor...", "fetch-more": "Daha fazla yükle" }, - "shortcut-list": { - "shortcut-title": "Kısayol adı", - "create-shortcut": "Kısayol oluştur", - "edit-shortcut": "Kısayolu düzenle", - "eligible-memo": "İlgili notlar", - "fill-previous": "Lütfen filtre değerini doldurun", - "title-required": "Başlık gerekli", - "value-required": "Filtre değeri gerekli" - }, "filter": { "new-filter": "Yeni filtre", "type": { diff --git a/web/src/locales/uk.json b/web/src/locales/uk.json index 380cc5c7..646305b1 100644 --- a/web/src/locales/uk.json +++ b/web/src/locales/uk.json @@ -34,7 +34,6 @@ "sign-out": "Вийти", "back-to-home": "Повернутися на головну", "type": "Типу", - "shortcuts": "Ярлики", "title": "Заголовок", "filter": "Фільтр", "tags": "Теги", @@ -109,15 +108,6 @@ "fetching-data": "завантаження даних...", "fetch-more": "Завантажити більше" }, - "shortcut-list": { - "shortcut-title": "назва ярлика", - "create-shortcut": "Створити ярлик", - "edit-shortcut": "Редагувати ярлик", - "eligible-memo": "пов'язані нотатки", - "fill-previous": "Будь ласка заповніть значення фільтра", - "title-required": "Назва обов'язкова", - "value-required": "Значення фільтра обов'язкове" - }, "filter": { "new-filter": "Новий фільтр", "type": { diff --git a/web/src/locales/vi.json b/web/src/locales/vi.json index dbe82234..505c1246 100644 --- a/web/src/locales/vi.json +++ b/web/src/locales/vi.json @@ -34,7 +34,6 @@ "sign-out": "Đăng xuất", "back-to-home": "Về trang chủ", "type": "Kiểu", - "shortcuts": "Lối tắt", "title": "Tiêu đề", "filter": "Bộ lọc", "tags": "Thẻ", @@ -109,15 +108,6 @@ "fetching-data": "đang tải dữ liệu...", "fetch-more": "Nhấp vào đây để tải thêm dữ liệu" }, - "shortcut-list": { - "shortcut-title": "Tên lối tắt", - "create-shortcut": "Tạo lối tắt", - "edit-shortcut": "Chỉnh sửa lối tắt", - "eligible-memo": "ghi chú đạt chuẩn", - "fill-previous": "Vui lòng nhập vào giá trị của bộ lọc trước đó", - "title-required": "Tiêu đề là bắt buộc", - "value-required": "Giá trị bộ lọc là bắt buộc" - }, "filter": { "new-filter": "Bộ Lọc Mới", "type": { diff --git a/web/src/locales/zh-Hans.json b/web/src/locales/zh-Hans.json index bc3c58f7..1abb6087 100644 --- a/web/src/locales/zh-Hans.json +++ b/web/src/locales/zh-Hans.json @@ -49,7 +49,6 @@ "select": "选择", "settings": "设置", "share": "分享", - "shortcuts": "捷径", "sign-in": "登录", "sign-in-with": "使用{{provider}}登录", "sign-out": "注销", @@ -440,15 +439,6 @@ "display-with-updated-time": "显示最后修改时间" } }, - "shortcut-list": { - "create-shortcut": "创建捷径", - "edit-shortcut": "编辑捷径", - "eligible-memo": "符合条件的备忘录", - "fill-previous": "请填写之前的过滤值", - "shortcut-title": "捷径标题", - "title-required": "标题是必填项", - "value-required": "过滤值是必填项" - }, "tag-list": { "all-tags": "全部标签", "create-tag": "创建标签", diff --git a/web/src/locales/zh-Hant.json b/web/src/locales/zh-Hant.json index e128ce70..90baa3d1 100644 --- a/web/src/locales/zh-Hant.json +++ b/web/src/locales/zh-Hant.json @@ -38,7 +38,6 @@ "sign-up": "註冊", "sign-out": "登出", "type": "類型", - "shortcuts": "捷徑", "title": "標題", "filter": "過濾器", "filter-period": "{{from}} 至 {{to}}", @@ -148,15 +147,6 @@ } } }, - "shortcut-list": { - "shortcut-title": "捷徑標題", - "create-shortcut": "新增捷徑", - "edit-shortcut": "編輯捷徑", - "eligible-memo": "符合條件的備忘錄", - "fill-previous": "請填入前一個過濾器的值", - "title-required": "標題為必填", - "value-required": "過濾器值為必填" - }, "tag-list": { "tip-text": "輸入 `#tag` 以新增標籤", "create-tag": "建立標籤", @@ -419,4 +409,4 @@ "powered-by": "威力本源", "other-projects": "其他專案" } -} \ No newline at end of file +} diff --git a/web/src/store/index.ts b/web/src/store/index.ts index 36402987..7853c4f7 100644 --- a/web/src/store/index.ts +++ b/web/src/store/index.ts @@ -6,7 +6,6 @@ import globalReducer from "./reducer/global"; import layoutReducer from "./reducer/layout"; import memoReducer from "./reducer/memo"; import resourceReducer from "./reducer/resource"; -import shortcutReducer from "./reducer/shortcut"; import tagReducer from "./reducer/tag"; import userReducer from "./reducer/user"; @@ -16,7 +15,6 @@ const store = configureStore({ user: userReducer, memo: memoReducer, tag: tagReducer, - shortcut: shortcutReducer, filter: filterReducer, resource: resourceReducer, dialog: dialogReducer, diff --git a/web/src/store/module/filter.ts b/web/src/store/module/filter.ts index 72fe6b86..9a4f208f 100644 --- a/web/src/store/module/filter.ts +++ b/web/src/store/module/filter.ts @@ -19,7 +19,6 @@ export const useFilterStore = () => { type: undefined, duration: undefined, text: undefined, - shortcutId: undefined, visibility: undefined, }) ); @@ -31,13 +30,6 @@ export const useFilterStore = () => { }) ); }, - setMemoShortcut: (shortcutId?: ShortcutId) => { - store.dispatch( - setFilter({ - shortcutId: shortcutId, - }) - ); - }, setTextFilter: (text?: string) => { store.dispatch( setFilter({ diff --git a/web/src/store/module/index.ts b/web/src/store/module/index.ts index 6510f116..0604c7b7 100644 --- a/web/src/store/module/index.ts +++ b/web/src/store/module/index.ts @@ -3,7 +3,6 @@ export * from "./filter"; export * from "./memo"; export * from "./tag"; export * from "./resource"; -export * from "./shortcut"; export * from "./user"; export * from "./dialog"; export * from "./layout"; diff --git a/web/src/store/module/shortcut.ts b/web/src/store/module/shortcut.ts deleted file mode 100644 index 05a875cf..00000000 --- a/web/src/store/module/shortcut.ts +++ /dev/null @@ -1,49 +0,0 @@ -import * as api from "@/helpers/api"; -import store, { useAppSelector } from "../"; -import { createShortcut, deleteShortcut, patchShortcut, setShortcuts } from "../reducer/shortcut"; - -const convertResponseModelShortcut = (shortcut: Shortcut): Shortcut => { - return { - ...shortcut, - createdTs: shortcut.createdTs * 1000, - updatedTs: shortcut.updatedTs * 1000, - }; -}; - -export const useShortcutStore = () => { - const state = useAppSelector((state) => state.shortcut); - return { - state, - getState: () => { - return store.getState().shortcut; - }, - getMyAllShortcuts: async () => { - const { data } = await api.getShortcutList(); - const shortcuts = data.map((s) => convertResponseModelShortcut(s)); - store.dispatch(setShortcuts(shortcuts)); - }, - getShortcutById: (id: ShortcutId) => { - for (const s of state.shortcuts) { - if (s.id === id) { - return s; - } - } - - return null; - }, - createShortcut: async (shortcutCreate: ShortcutCreate) => { - const { data } = await api.createShortcut(shortcutCreate); - const shortcut = convertResponseModelShortcut(data); - store.dispatch(createShortcut(shortcut)); - }, - patchShortcut: async (shortcutPatch: ShortcutPatch) => { - const { data } = await api.patchShortcut(shortcutPatch); - const shortcut = convertResponseModelShortcut(data); - store.dispatch(patchShortcut(shortcut)); - }, - deleteShortcutById: async (shortcutId: ShortcutId) => { - await api.deleteShortcutById(shortcutId); - store.dispatch(deleteShortcut(shortcutId)); - }, - }; -}; diff --git a/web/src/store/reducer/filter.ts b/web/src/store/reducer/filter.ts index 9606b7f7..acbe6843 100644 --- a/web/src/store/reducer/filter.ts +++ b/web/src/store/reducer/filter.ts @@ -10,7 +10,6 @@ interface State { duration?: Duration; type?: MemoSpecType; text?: string; - shortcutId?: ShortcutId; visibility?: Visibility; } diff --git a/web/src/store/reducer/shortcut.ts b/web/src/store/reducer/shortcut.ts deleted file mode 100644 index e8277296..00000000 --- a/web/src/store/reducer/shortcut.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { createSlice, PayloadAction } from "@reduxjs/toolkit"; - -interface State { - shortcuts: Shortcut[]; -} - -const shortcutSlice = createSlice({ - name: "memo", - initialState: { - shortcuts: [], - } as State, - reducers: { - setShortcuts: (state, action: PayloadAction) => { - return { - ...state, - shortcuts: action.payload, - }; - }, - createShortcut: (state, action: PayloadAction) => { - return { - ...state, - shortcuts: state.shortcuts.concat(action.payload).sort((a, b) => b.createdTs - a.createdTs), - }; - }, - patchShortcut: (state, action: PayloadAction>) => { - return { - ...state, - shortcuts: state.shortcuts.map((s) => { - if (s.id === action.payload.id) { - return { - ...s, - ...action.payload, - }; - } else { - return s; - } - }), - }; - }, - deleteShortcut: (state, action: PayloadAction) => { - return { - ...state, - shortcuts: [...state.shortcuts].filter((shortcut) => shortcut.id !== action.payload), - }; - }, - }, -}); - -export const { setShortcuts, createShortcut, patchShortcut, deleteShortcut } = shortcutSlice.actions; - -export default shortcutSlice.reducer; diff --git a/web/src/types/modules/shortcut.d.ts b/web/src/types/modules/shortcut.d.ts deleted file mode 100644 index 078a9e28..00000000 --- a/web/src/types/modules/shortcut.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -type ShortcutId = number; - -interface Shortcut { - id: ShortcutId; - - rowStatus: RowStatus; - createdTs: TimeStamp; - updatedTs: TimeStamp; - - title: string; - payload: string; -} - -interface ShortcutCreate { - title: string; - payload: string; -} - -interface ShortcutPatch { - id: ShortcutId; - title?: string; - payload?: string; - rowStatus?: RowStatus; -} - -interface ShortcutFind { - creatorUsername?: string; -}