From 8a4e07120f534b1008b9eeb6fa221ae84a665f65 Mon Sep 17 00:00:00 2001 From: Steven Date: Sun, 12 Nov 2023 12:57:39 +0800 Subject: [PATCH] chore: update collection details --- .../web/src/components/CollectionView.tsx | 24 ++++++++++--- .../src/components/CreateCollectionDialog.tsx | 36 ++++++++++++------- .../src/components/CreateShortcutDialog.tsx | 14 +++++--- frontend/web/src/components/Header.tsx | 14 ++++---- frontend/web/src/components/ShortcutView.tsx | 4 +-- .../web/src/components/ShortcutsContainer.tsx | 7 +++- .../web/src/pages/CollectionDashboard.tsx | 13 +++++++ frontend/web/src/pages/CollectionSpace.tsx | 28 +++++++++------ 8 files changed, 97 insertions(+), 43 deletions(-) diff --git a/frontend/web/src/components/CollectionView.tsx b/frontend/web/src/components/CollectionView.tsx index 20e6f20..fffecc6 100644 --- a/frontend/web/src/components/CollectionView.tsx +++ b/frontend/web/src/components/CollectionView.tsx @@ -1,7 +1,10 @@ import classNames from "classnames"; +import copy from "copy-to-clipboard"; import { useState } from "react"; +import toast from "react-hot-toast"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; +import { absolutifyLink } from "@/helpers/utils"; import useNavigateTo from "@/hooks/useNavigateTo"; import useResponsiveWidth from "@/hooks/useResponsiveWidth"; import { useAppSelector } from "@/stores"; @@ -30,6 +33,11 @@ const CollectionView = (props: Props) => { .map((shortcutId) => shortcutList.find((shortcut) => shortcut?.id === shortcutId)) .filter(Boolean) as any as Shortcut[]; + const handleCopyCollectionLink = () => { + copy(absolutifyLink(`/c/${collection.name}`)); + toast.success("Collection link copied to clipboard."); + }; + const handleDeleteCollectionButtonClick = () => { showCommonDialog({ title: "Delete Collection", @@ -49,10 +57,12 @@ const CollectionView = (props: Props) => { <>
-
-
- {collection.title} +
+
+ {collection.title} + (c/{collection.name})
+

{collection.description}

{collection.visibility !== Visibility.PRIVATE && ( @@ -86,7 +96,13 @@ const CollectionView = (props: Props) => {
{shortcuts.map((shortcut) => { return ( - handleShortcutClick(shortcut)} /> + handleShortcutClick(shortcut)} + /> ); })}
diff --git a/frontend/web/src/components/CreateCollectionDialog.tsx b/frontend/web/src/components/CreateCollectionDialog.tsx index ae130cb..c0cea77 100644 --- a/frontend/web/src/components/CreateCollectionDialog.tsx +++ b/frontend/web/src/components/CreateCollectionDialog.tsx @@ -35,9 +35,9 @@ const CreateCollectionDialog: React.FC = (props: Props) => { const [selectedShortcuts, setSelectedShortcuts] = useState([]); const requestState = useLoading(false); const isCreating = isUndefined(collectionId); - const unselectedShortcuts = shortcutList.filter( - (shortcut) => !selectedShortcuts.find((selectedShortcut) => selectedShortcut.id === shortcut.id) - ); + const unselectedShortcuts = shortcutList + .filter((shortcut) => (state.collectionCreate.visibility === Visibility.PUBLIC ? shortcut.visibility === "PUBLIC" : true)) + .filter((shortcut) => !selectedShortcuts.find((selectedShortcut) => selectedShortcut.id === shortcut.id)); useEffect(() => { (async () => { @@ -100,8 +100,8 @@ const CreateCollectionDialog: React.FC = (props: Props) => { }; const handleSaveBtnClick = async () => { - if (!state.collectionCreate.name) { - toast.error("Name is required"); + if (!state.collectionCreate.name || !state.collectionCreate.title) { + toast.error("Please fill in required fields."); return; } @@ -147,24 +147,28 @@ const CreateCollectionDialog: React.FC = (props: Props) => {
- Name + + Name * +
- Title + + Title * +
@@ -176,7 +180,7 @@ const CreateCollectionDialog: React.FC = (props: Props) => { @@ -200,12 +204,12 @@ const CreateCollectionDialog: React.FC = (props: Props) => { ({selectedShortcuts.length}) {selectedShortcuts.length === 0 && Select a shortcut first}

-
+
{selectedShortcuts.map((shortcut) => { return ( { setSelectedShortcuts([...selectedShortcuts.filter((selectedShortcut) => selectedShortcut.id !== shortcut.id)]); @@ -217,7 +221,7 @@ const CreateCollectionDialog: React.FC = (props: Props) => { return ( { setSelectedShortcuts([...selectedShortcuts, shortcut]); @@ -225,6 +229,12 @@ const CreateCollectionDialog: React.FC = (props: Props) => { /> ); })} + {selectedShortcuts.length + unselectedShortcuts.length === 0 && ( +
+ +

No shortcuts found.

+
+ )}
diff --git a/frontend/web/src/components/CreateShortcutDialog.tsx b/frontend/web/src/components/CreateShortcutDialog.tsx index 424897e..5bbe542 100644 --- a/frontend/web/src/components/CreateShortcutDialog.tsx +++ b/frontend/web/src/components/CreateShortcutDialog.tsx @@ -163,8 +163,8 @@ const CreateShortcutDialog: React.FC = (props: Props) => { }; const handleSaveBtnClick = async () => { - if (!state.shortcutCreate.name) { - toast.error("Name is required"); + if (!state.shortcutCreate.name || !state.shortcutCreate.link) { + toast.error("Please fill in required fields."); return; } @@ -209,19 +209,23 @@ const CreateShortcutDialog: React.FC = (props: Props) => {
- Name + + Name * +
- Destination URL + + Destination URL * + { return ( <>
-
+
- - + + Slash {profile.plan === PlanType.PRO && ( @@ -41,10 +41,10 @@ const Header: React.FC = () => { )} {shouldShowRouterSwitch && ( <> - / + / + @@ -56,13 +56,13 @@ const Header: React.FC = () => { to="/" className="w-full px-2 flex flex-row justify-start items-center text-left dark:text-gray-400 leading-8 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-800 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60" > - Shortcuts + Shortcuts - Collections + Collections } diff --git a/frontend/web/src/components/ShortcutView.tsx b/frontend/web/src/components/ShortcutView.tsx index f55ff90..b4f5a6c 100644 --- a/frontend/web/src/components/ShortcutView.tsx +++ b/frontend/web/src/components/ShortcutView.tsx @@ -24,13 +24,13 @@ const ShortcutView = (props: Props) => { )} onClick={onClick} > - +
{favicon ? ( ) : ( )} - +
{shortcut.title ? ( <> diff --git a/frontend/web/src/components/ShortcutsContainer.tsx b/frontend/web/src/components/ShortcutsContainer.tsx index 417820b..37bb45c 100644 --- a/frontend/web/src/components/ShortcutsContainer.tsx +++ b/frontend/web/src/components/ShortcutsContainer.tsx @@ -1,4 +1,5 @@ import classNames from "classnames"; +import { absolutifyLink } from "@/helpers/utils"; import useViewStore from "../stores/v1/view"; import ShortcutCard from "./ShortcutCard"; import ShortcutView from "./ShortcutView"; @@ -13,6 +14,10 @@ const ShortcutsContainer: React.FC = (props: Props) => { const displayStyle = viewStore.displayStyle || "full"; const ShortcutItemView = viewStore.displayStyle === "compact" ? ShortcutView : ShortcutCard; + const handleShortcutClick = (shortcut: Shortcut) => { + window.open(absolutifyLink(`/s/${shortcut.id}`)); + }; + return (
= (props: Props) => { )} > {shortcutList.map((shortcut) => { - return ; + return handleShortcutClick(shortcut)} />; })}
); diff --git a/frontend/web/src/pages/CollectionDashboard.tsx b/frontend/web/src/pages/CollectionDashboard.tsx index fb67b07..c1ec805 100644 --- a/frontend/web/src/pages/CollectionDashboard.tsx +++ b/frontend/web/src/pages/CollectionDashboard.tsx @@ -38,6 +38,19 @@ const CollectionDashboard: React.FC = () => { return ( <>
+