mirror of
https://github.com/usememos/memos.git
synced 2025-02-21 05:40:57 +01:00
perf: reduce bundle size by 21% with direct icon imports (#3844)
This commit is contained in:
parent
d11bd30ec6
commit
2dbf92f7f1
@ -1,7 +1,7 @@
|
||||
import { Option, Select } from "@mui/joy";
|
||||
import { SunIcon, MoonIcon, SmileIcon } from "lucide-react";
|
||||
import { FC } from "react";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
value: Appearance;
|
||||
@ -18,11 +18,11 @@ const AppearanceSelect: FC<Props> = (props: Props) => {
|
||||
const getPrefixIcon = (appearance: Appearance) => {
|
||||
const className = "w-4 h-auto";
|
||||
if (appearance === "light") {
|
||||
return <Icon.Sun className={className} />;
|
||||
return <SunIcon className={className} />;
|
||||
} else if (appearance === "dark") {
|
||||
return <Icon.Moon className={className} />;
|
||||
return <MoonIcon className={className} />;
|
||||
} else {
|
||||
return <Icon.Smile className={className} />;
|
||||
return <SmileIcon className={className} />;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Button, IconButton, Input } from "@mui/joy";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { useUserStore } from "@/store/v1";
|
||||
import { User } from "@/types/proto/api/v1/user_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props extends DialogProps {
|
||||
user: User;
|
||||
@ -71,7 +71,7 @@ const ChangeMemberPasswordDialog: React.FC<Props> = (props: Props) => {
|
||||
{t("setting.account-section.change-password")} ({user.nickname})
|
||||
</p>
|
||||
<IconButton size="sm" onClick={handleCloseBtnClick}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, IconButton, Input } from "@mui/joy";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
@ -6,7 +7,6 @@ import { useCommonContext } from "@/layouts/CommonContextProvider";
|
||||
import { useUserStore } from "@/store/v1";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
|
||||
type Props = DialogProps;
|
||||
|
||||
@ -70,7 +70,7 @@ const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
|
||||
<div className="dialog-header-container !w-64">
|
||||
<p className="title-text">{t("setting.account-section.change-password")}</p>
|
||||
<IconButton size="sm" onClick={handleCloseBtnClick}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, IconButton, Input, Radio, RadioGroup } from "@mui/joy";
|
||||
import { XIcon } from "lucide-react";
|
||||
import React, { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { userServiceClient } from "@/grpcweb";
|
||||
@ -6,7 +7,6 @@ import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props extends DialogProps {
|
||||
onConfirm: () => void;
|
||||
@ -87,7 +87,7 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
|
||||
<div className="dialog-header-container">
|
||||
<p className="title-text">Create access token</p>
|
||||
<IconButton size="sm" onClick={() => destroy()}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container !w-80">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, Divider, IconButton, Input, Option, Select, Typography } from "@mui/joy";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { identityProviderServiceClient } from "@/grpcweb";
|
||||
@ -6,7 +7,6 @@ import { absolutifyLink } from "@/helpers/utils";
|
||||
import { FieldMapping, IdentityProvider, IdentityProvider_Type, OAuth2Config } from "@/types/proto/api/v1/idp_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
|
||||
const templateList: IdentityProvider[] = [
|
||||
{
|
||||
@ -245,7 +245,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||
<div className="dialog-header-container">
|
||||
<p>{t(isCreating ? "setting.sso-section.create-sso" : "setting.sso-section.update-sso")}</p>
|
||||
<IconButton size="sm" onClick={handleCloseBtnClick}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container min-w-[19rem]">
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Button, IconButton, Input } from "@mui/joy";
|
||||
import { XIcon } from "lucide-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { webhookServiceClient } from "@/grpcweb";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props extends DialogProps {
|
||||
webhookId?: number;
|
||||
@ -97,7 +97,7 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
|
||||
<div className="dialog-header-container">
|
||||
<p className="title-text">{isCreating ? "Create webhook" : "Edit webhook"}</p>
|
||||
<IconButton size="sm" onClick={() => destroy()}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container !w-80">
|
||||
|
@ -1,9 +1,9 @@
|
||||
import Icon from "./Icon";
|
||||
import { BirdIcon } from "lucide-react";
|
||||
|
||||
const Empty = () => {
|
||||
return (
|
||||
<div className="mx-auto">
|
||||
<Icon.Bird strokeWidth={1} className="w-24 h-auto text-gray-500 dark:text-gray-400" />
|
||||
<BirdIcon strokeWidth={1} className="w-24 h-auto text-gray-500 dark:text-gray-400" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Drawer, IconButton } from "@mui/joy";
|
||||
import { SearchIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import Icon from "../Icon";
|
||||
import ExploreSidebar from "./ExploreSidebar";
|
||||
|
||||
const ExploreSidebarDrawer = () => {
|
||||
@ -23,7 +23,7 @@ const ExploreSidebarDrawer = () => {
|
||||
return (
|
||||
<>
|
||||
<IconButton onClick={toggleDrawer(true)}>
|
||||
<Icon.Search className="w-5 h-auto dark:text-gray-400" />
|
||||
<SearchIcon className="w-5 h-auto dark:text-gray-400" />
|
||||
</IconButton>
|
||||
<Drawer anchor="right" size="sm" open={open} onClose={toggleDrawer(false)}>
|
||||
<div className="w-full h-full px-4 bg-zinc-100 dark:bg-zinc-900">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Drawer, IconButton } from "@mui/joy";
|
||||
import { SearchIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import Icon from "../Icon";
|
||||
import HomeSidebar from "./HomeSidebar";
|
||||
|
||||
const HomeSidebarDrawer = () => {
|
||||
@ -23,7 +23,7 @@ const HomeSidebarDrawer = () => {
|
||||
return (
|
||||
<>
|
||||
<IconButton onClick={toggleDrawer(true)}>
|
||||
<Icon.Search className="w-5 h-auto dark:text-gray-400" />
|
||||
<SearchIcon className="w-5 h-auto dark:text-gray-400" />
|
||||
</IconButton>
|
||||
<Drawer anchor="right" size="sm" open={open} onClose={toggleDrawer(false)}>
|
||||
<div className="w-full h-full px-4 bg-zinc-100 dark:bg-zinc-900">
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Dropdown, Menu, MenuButton, MenuItem, Switch } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { Edit3Icon, HashIcon, MoreVerticalIcon, TagsIcon, TrashIcon } from "lucide-react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import useDebounce from "react-use/lib/useDebounce";
|
||||
@ -8,7 +9,6 @@ import { memoServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useMemoFilterStore, useMemoList, useTagStore } from "@/store/v1";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "../Icon";
|
||||
import showRenameTagDialog from "../RenameTagDialog";
|
||||
import TagTree from "../TagTree";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "../ui/Popover";
|
||||
@ -66,7 +66,7 @@ const TagsSection = (props: Props) => {
|
||||
{tagAmounts.length > 0 && (
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<Icon.MoreVertical className="w-4 h-auto shrink-0 opacity-60" />
|
||||
<MoreVerticalIcon className="w-4 h-auto shrink-0 opacity-60" />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" alignOffset={-12}>
|
||||
<div className="w-auto flex flex-row justify-between items-center gap-2">
|
||||
@ -90,17 +90,17 @@ const TagsSection = (props: Props) => {
|
||||
<Dropdown>
|
||||
<MenuButton slots={{ root: "div" }}>
|
||||
<div className="shrink-0 group">
|
||||
<Icon.Hash className="group-hover:hidden w-4 h-auto shrink-0 opacity-40" />
|
||||
<Icon.MoreVertical className="hidden group-hover:block w-4 h-auto shrink-0 opacity-60" />
|
||||
<HashIcon className="group-hover:hidden w-4 h-auto shrink-0 opacity-40" />
|
||||
<MoreVerticalIcon className="hidden group-hover:block w-4 h-auto shrink-0 opacity-60" />
|
||||
</div>
|
||||
</MenuButton>
|
||||
<Menu size="sm" placement="bottom-start">
|
||||
<MenuItem onClick={() => showRenameTagDialog({ tag: tag })}>
|
||||
<Icon.Edit3 className="w-4 h-auto" />
|
||||
<Edit3Icon className="w-4 h-auto" />
|
||||
{t("common.rename")}
|
||||
</MenuItem>
|
||||
<MenuItem color="danger" onClick={() => handleDeleteTag(tag)}>
|
||||
<Icon.Trash className="w-4 h-auto" />
|
||||
<TrashIcon className="w-4 h-auto" />
|
||||
{t("common.delete")}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
@ -119,7 +119,7 @@ const TagsSection = (props: Props) => {
|
||||
) : (
|
||||
!props.readonly && (
|
||||
<div className="p-2 border border-dashed dark:border-zinc-800 rounded-md flex flex-row justify-start items-start gap-1 text-gray-400 dark:text-gray-500">
|
||||
<Icon.Tags />
|
||||
<TagsIcon />
|
||||
<p className="mt-0.5 text-sm leading-snug italic">{t("tag.create-tags-guide")}</p>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,3 +0,0 @@
|
||||
import * as Icon from "lucide-react";
|
||||
|
||||
export default Icon;
|
@ -1,5 +1,6 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { InboxIcon, MessageCircleIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { activityServiceClient } from "@/grpcweb";
|
||||
@ -9,7 +10,6 @@ import { Inbox, Inbox_Status } from "@/types/proto/api/v1/inbox_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { User } from "@/types/proto/api/v1/user_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "../Icon";
|
||||
|
||||
interface Props {
|
||||
inbox: Inbox;
|
||||
@ -81,7 +81,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
|
||||
)}
|
||||
>
|
||||
<Tooltip title={"Comment"} placement="bottom">
|
||||
<Icon.MessageCircle className="w-4 sm:w-5 h-auto" />
|
||||
<MessageCircleIcon className="w-4 sm:w-5 h-auto" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
@ -95,10 +95,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
|
||||
<div>
|
||||
{inbox.status === Inbox_Status.UNREAD && (
|
||||
<Tooltip title={t("common.archive")} placement="top">
|
||||
<Icon.Inbox
|
||||
className="w-4 h-auto cursor-pointer text-gray-400 hover:text-blue-600"
|
||||
onClick={() => handleArchiveMessage()}
|
||||
/>
|
||||
<InboxIcon className="w-4 h-auto cursor-pointer text-gray-400 hover:text-blue-600" onClick={() => handleArchiveMessage()} />
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { ArrowUpIcon, InboxIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { activityServiceClient } from "@/grpcweb";
|
||||
@ -7,7 +8,6 @@ import { activityNamePrefix, useInboxStore } from "@/store/v1";
|
||||
import { Activity } from "@/types/proto/api/v1/activity_service";
|
||||
import { Inbox, Inbox_Status } from "@/types/proto/api/v1/inbox_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "../Icon";
|
||||
|
||||
interface Props {
|
||||
inbox: Inbox;
|
||||
@ -66,7 +66,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
|
||||
)}
|
||||
>
|
||||
<Tooltip title={"Update"} placement="bottom">
|
||||
<Icon.ArrowUp className="w-4 sm:w-5 h-auto" />
|
||||
<ArrowUpIcon className="w-4 sm:w-5 h-auto" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
@ -80,10 +80,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
|
||||
<div>
|
||||
{inbox.status === Inbox_Status.UNREAD && (
|
||||
<Tooltip title={t("common.archive")} placement="top">
|
||||
<Icon.Inbox
|
||||
className="w-4 h-auto cursor-pointer text-gray-400 hover:text-blue-600"
|
||||
onClick={() => handleArchiveMessage()}
|
||||
/>
|
||||
<InboxIcon className="w-4 h-auto cursor-pointer text-gray-400 hover:text-blue-600" onClick={() => handleArchiveMessage()} />
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import { ExternalLinkIcon } from "lucide-react";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
@ -15,7 +15,7 @@ const LearnMore: React.FC<Props> = (props: Props) => {
|
||||
return (
|
||||
<Tooltip title={title ?? t("common.learn-more")} placement="top">
|
||||
<a className={`text-gray-500 dark:text-gray-400 hover:text-blue-600 ${className}`} href={url} target="_blank">
|
||||
<Icon.ExternalLink className="w-4 h-auto" />
|
||||
<ExternalLinkIcon className="w-4 h-auto" />
|
||||
</a>
|
||||
</Tooltip>
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Option, Select } from "@mui/joy";
|
||||
import { GlobeIcon } from "lucide-react";
|
||||
import { FC } from "react";
|
||||
import { locales } from "@/i18n";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
value: Locale;
|
||||
@ -19,7 +19,7 @@ const LocaleSelect: FC<Props> = (props: Props) => {
|
||||
return (
|
||||
<Select
|
||||
className={`!min-w-[10rem] w-auto whitespace-nowrap ${className ?? ""}`}
|
||||
startDecorator={<Icon.Globe className="w-4 h-auto" />}
|
||||
startDecorator={<GlobeIcon className="w-4 h-auto" />}
|
||||
value={value}
|
||||
onChange={(_, value) => handleSelectChange(value as Locale)}
|
||||
>
|
||||
|
@ -1,9 +1,18 @@
|
||||
import { Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import copy from "copy-to-clipboard";
|
||||
import {
|
||||
ArchiveIcon,
|
||||
ArchiveRestoreIcon,
|
||||
BookmarkMinusIcon,
|
||||
BookmarkPlusIcon,
|
||||
CopyIcon,
|
||||
Edit3Icon,
|
||||
MoreVerticalIcon,
|
||||
TrashIcon,
|
||||
} from "lucide-react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import Icon from "@/components/Icon";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
import { RowStatus } from "@/types/proto/api/v1/common";
|
||||
@ -108,34 +117,34 @@ const MemoActionMenu = (props: Props) => {
|
||||
<Dropdown>
|
||||
<MenuButton slots={{ root: "div" }}>
|
||||
<span className={clsx("flex justify-center items-center rounded-full hover:opacity-70", props.className)}>
|
||||
<Icon.MoreVertical className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
<MoreVerticalIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
</span>
|
||||
</MenuButton>
|
||||
<Menu className="text-sm" size="sm" placement="bottom-end">
|
||||
{!hiddenActions?.includes("pin") && (
|
||||
<MenuItem onClick={handleTogglePinMemoBtnClick}>
|
||||
{memo.pinned ? <Icon.BookmarkMinus className="w-4 h-auto" /> : <Icon.BookmarkPlus className="w-4 h-auto" />}
|
||||
{memo.pinned ? <BookmarkMinusIcon className="w-4 h-auto" /> : <BookmarkPlusIcon className="w-4 h-auto" />}
|
||||
{memo.pinned ? t("common.unpin") : t("common.pin")}
|
||||
</MenuItem>
|
||||
)}
|
||||
{!hiddenActions?.includes("edit") && props.onEdit && (
|
||||
<MenuItem onClick={handleEditMemoClick}>
|
||||
<Icon.Edit3 className="w-4 h-auto" />
|
||||
<Edit3Icon className="w-4 h-auto" />
|
||||
{t("common.edit")}
|
||||
</MenuItem>
|
||||
)}
|
||||
{!hiddenActions?.includes("share") && (
|
||||
<MenuItem onClick={handleCopyLink}>
|
||||
<Icon.Copy className="w-4 h-auto" />
|
||||
<CopyIcon className="w-4 h-auto" />
|
||||
{t("memo.copy-link")}
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem color="warning" onClick={handleToggleMemoStatusClick}>
|
||||
{memo.rowStatus === RowStatus.ARCHIVED ? <Icon.ArchiveRestore className="w-4 h-auto" /> : <Icon.Archive className="w-4 h-auto" />}
|
||||
{memo.rowStatus === RowStatus.ARCHIVED ? <ArchiveRestoreIcon className="w-4 h-auto" /> : <ArchiveIcon className="w-4 h-auto" />}
|
||||
{memo.rowStatus === RowStatus.ARCHIVED ? t("common.restore") : t("common.archive")}
|
||||
</MenuItem>
|
||||
<MenuItem color="danger" onClick={handleDeleteMemoClick}>
|
||||
<Icon.Trash className="w-4 h-auto" />
|
||||
<TrashIcon className="w-4 h-auto" />
|
||||
{t("common.delete")}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
@ -2,9 +2,9 @@ import clsx from "clsx";
|
||||
import copy from "copy-to-clipboard";
|
||||
import DOMPurify from "dompurify";
|
||||
import hljs from "highlight.js";
|
||||
import { CopyIcon } from "lucide-react";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import Icon from "../Icon";
|
||||
import MermaidBlock from "./MermaidBlock";
|
||||
import { BaseProps } from "./types";
|
||||
|
||||
@ -57,7 +57,7 @@ const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
|
||||
<div className="w-full my-1 bg-amber-100 border-l-4 border-amber-400 rounded hover:shadow dark:bg-zinc-600 dark:border-zinc-400 relative">
|
||||
<div className="w-full px-2 py-1 flex flex-row justify-between items-center text-amber-500 dark:text-zinc-400">
|
||||
<span className="text-sm font-mono">{formatedLanguage}</span>
|
||||
<Icon.Copy className="w-4 h-auto cursor-pointer hover:opacity-80" onClick={handleCopyButtonClick} />
|
||||
<CopyIcon className="w-4 h-auto cursor-pointer hover:opacity-80" onClick={handleCopyButtonClick} />
|
||||
</div>
|
||||
|
||||
<div className="overflow-auto">
|
||||
|
@ -1,9 +1,9 @@
|
||||
import clsx from "clsx";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { ArrowUpRightIcon } from "lucide-react";
|
||||
import { useContext, useEffect } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
import Icon from "@/components/Icon";
|
||||
import MemoResourceListView from "@/components/MemoResourceListView";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
@ -76,7 +76,7 @@ const EmbeddedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
|
||||
{memo.uid.slice(0, 8)}
|
||||
</span>
|
||||
<Link className="opacity-60 hover:opacity-80" to={`/m/${memo.uid}`} unstable_viewTransition>
|
||||
<Icon.ArrowUpRight className="w-5 h-auto" />
|
||||
<ArrowUpRightIcon className="w-5 h-auto" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import clsx from "clsx";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { CheckCircleIcon, Code2Icon, HashIcon, LinkIcon } from "lucide-react";
|
||||
import { Memo, MemoProperty } from "@/types/proto/api/v1/memo_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "../Icon";
|
||||
|
||||
interface Props {
|
||||
memo: Memo;
|
||||
@ -45,7 +45,7 @@ const MemoDetailSidebar = ({ memo, className }: Props) => {
|
||||
{property.hasLink && (
|
||||
<div className="w-auto border dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
<Icon.Link className="w-4 h-auto mr-1" />
|
||||
<LinkIcon className="w-4 h-auto mr-1" />
|
||||
<span className="block text-sm">{t("memo.links")}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -53,7 +53,7 @@ const MemoDetailSidebar = ({ memo, className }: Props) => {
|
||||
{property.hasTaskList && (
|
||||
<div className="w-auto border dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
<Icon.CheckCircle className="w-4 h-auto mr-1" />
|
||||
<CheckCircleIcon className="w-4 h-auto mr-1" />
|
||||
<span className="block text-sm">{t("memo.to-do")}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -61,7 +61,7 @@ const MemoDetailSidebar = ({ memo, className }: Props) => {
|
||||
{property.hasCode && (
|
||||
<div className="w-auto border dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
<Icon.Code2 className="w-4 h-auto mr-1" />
|
||||
<Code2Icon className="w-4 h-auto mr-1" />
|
||||
<span className="block text-sm">{t("memo.code")}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -81,7 +81,7 @@ const MemoDetailSidebar = ({ memo, className }: Props) => {
|
||||
key={tag}
|
||||
className="shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-gray-600 dark:text-gray-400 dark:border-zinc-800"
|
||||
>
|
||||
<Icon.Hash className="group-hover:hidden w-4 h-auto shrink-0 opacity-40" />
|
||||
<HashIcon className="group-hover:hidden w-4 h-auto shrink-0 opacity-40" />
|
||||
<div className={clsx("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}>
|
||||
<span className="truncate dark:opacity-80">{tag}</span>
|
||||
</div>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Drawer, IconButton } from "@mui/joy";
|
||||
import { GanttChartIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import Icon from "../Icon";
|
||||
import MemoDetailSidebar from "./MemoDetailSidebar";
|
||||
|
||||
interface Props {
|
||||
@ -27,7 +27,7 @@ const MemoDetailSidebarDrawer = ({ memo }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<IconButton onClick={toggleDrawer(true)}>
|
||||
<Icon.GanttChart className="w-5 h-auto dark:text-gray-400" />
|
||||
<GanttChartIcon className="w-5 h-auto dark:text-gray-400" />
|
||||
</IconButton>
|
||||
<Drawer anchor="right" size="sm" open={open} onClose={toggleDrawer(false)}>
|
||||
<div className="w-full h-full px-4 bg-zinc-100 dark:bg-zinc-900">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Option, Select } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { Settings2Icon } from "lucide-react";
|
||||
import { useMemoFilterStore } from "@/store/v1";
|
||||
import Icon from "./Icon";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "./ui/Popover";
|
||||
|
||||
interface Props {
|
||||
@ -17,7 +17,7 @@ const MemoDisplaySettingMenu = ({ className }: Props) => {
|
||||
<PopoverTrigger
|
||||
className={clsx(className, isApplying ? "text-teal-600 bg-teal-50 dark:text-teal-500 dark:bg-teal-900 rounded-sm" : "opacity-40")}
|
||||
>
|
||||
<Icon.Settings2 className="w-4 h-auto shrink-0" />
|
||||
<Settings2Icon className="w-4 h-auto shrink-0" />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" alignOffset={-12} sideOffset={14}>
|
||||
<div className="flex flex-col gap-2">
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Autocomplete, AutocompleteOption, Button, Checkbox, Chip, IconButton } from "@mui/joy";
|
||||
import { uniqBy } from "lodash-es";
|
||||
import { LinkIcon } from "lucide-react";
|
||||
import React, { useContext, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import useDebounce from "react-use/lib/useDebounce";
|
||||
import Icon from "@/components/Icon";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/Popover";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
import { DEFAULT_LIST_MEMOS_PAGE_SIZE } from "@/helpers/consts";
|
||||
@ -127,7 +127,7 @@ const AddMemoRelationPopover = (props: Props) => {
|
||||
<Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
|
||||
<PopoverTrigger>
|
||||
<IconButton size="sm" component="div">
|
||||
<Icon.Link className="w-5 h-5 mx-auto" />
|
||||
<LinkIcon className="w-5 h-5 mx-auto" />
|
||||
</IconButton>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="center">
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Dropdown, IconButton, Menu, MenuButton, MenuItem } from "@mui/joy";
|
||||
import { Link } from "@mui/joy";
|
||||
import Icon from "@/components/Icon";
|
||||
import { CheckSquareIcon, Code2Icon, SquareSlashIcon } from "lucide-react";
|
||||
import { EditorRefActions } from "../Editor";
|
||||
|
||||
interface Props {
|
||||
@ -67,15 +67,15 @@ const MarkdownMenu = (props: Props) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Icon.SquareSlash className="w-5 h-5 mx-auto" />
|
||||
<SquareSlashIcon className="w-5 h-5 mx-auto" />
|
||||
</MenuButton>
|
||||
<Menu className="text-sm" size="sm" placement="bottom-start">
|
||||
<MenuItem onClick={handleCodeBlockClick}>
|
||||
<Icon.Code2 className="w-4 h-auto" />
|
||||
<Code2Icon className="w-4 h-auto" />
|
||||
<span>Code block</span>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleCheckboxClick}>
|
||||
<Icon.CheckSquare className="w-4 h-auto" />
|
||||
<CheckSquareIcon className="w-4 h-auto" />
|
||||
<span>Checkbox</span>
|
||||
</MenuItem>
|
||||
<div className="-mt-0.5 pl-2">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Dropdown, IconButton, Menu, MenuButton } from "@mui/joy";
|
||||
import { HashIcon } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import useClickAway from "react-use/lib/useClickAway";
|
||||
import Icon from "@/components/Icon";
|
||||
import OverflowTip from "@/components/kit/OverflowTip";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useTagStore } from "@/store/v1";
|
||||
@ -58,7 +58,7 @@ const TagSelector = (props: Props) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Icon.Hash className="w-5 h-5 mx-auto" />
|
||||
<HashIcon className="w-5 h-5 mx-auto" />
|
||||
</MenuButton>
|
||||
<Menu className="relative text-sm" component="div" size="sm" placement="bottom-start">
|
||||
<div ref={containerRef}>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IconButton } from "@mui/joy";
|
||||
import { PaperclipIcon } from "lucide-react";
|
||||
import { useContext, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import Icon from "@/components/Icon";
|
||||
import { useResourceStore } from "@/store/v1";
|
||||
import { Resource } from "@/types/proto/api/v1/resource_service";
|
||||
import { MemoEditorContext } from "../types";
|
||||
@ -67,7 +67,7 @@ const UploadResourceButton = () => {
|
||||
|
||||
return (
|
||||
<IconButton size="sm" disabled={state.uploadingFlag}>
|
||||
<Icon.Paperclip className="w-5 h-5 mx-auto" />
|
||||
<PaperclipIcon className="w-5 h-5 mx-auto" />
|
||||
<input
|
||||
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
|
||||
ref={fileInputRef}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { LinkIcon, XIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
import { MemoRelation, MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import Icon from "../Icon";
|
||||
|
||||
interface Props {
|
||||
relationList: MemoRelation[];
|
||||
@ -41,9 +41,9 @@ const RelationListView = (props: Props) => {
|
||||
className="w-auto max-w-xs overflow-hidden flex flex-row justify-start items-center bg-zinc-100 dark:bg-zinc-900 hover:opacity-80 rounded-md text-sm p-1 px-2 text-gray-500 dark:text-gray-400 cursor-pointer hover:line-through"
|
||||
onClick={() => handleDeleteRelation(memo)}
|
||||
>
|
||||
<Icon.Link className="w-4 h-auto shrink-0 opacity-80" />
|
||||
<LinkIcon className="w-4 h-auto shrink-0 opacity-80" />
|
||||
<span className="mx-1 max-w-full text-ellipsis whitespace-nowrap overflow-hidden">{memo.snippet}</span>
|
||||
<Icon.X className="w-4 h-auto cursor-pointer shrink-0 opacity-60 hover:opacity-100" />
|
||||
<XIcon className="w-4 h-auto cursor-pointer shrink-0 opacity-60 hover:opacity-100" />
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { DndContext, closestCenter, MouseSensor, TouchSensor, useSensor, useSensors, DragEndEvent } from "@dnd-kit/core";
|
||||
import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { Resource } from "@/types/proto/api/v1/resource_service";
|
||||
import Icon from "../Icon";
|
||||
import ResourceIcon from "../ResourceIcon";
|
||||
import SortableItem from "./SortableItem";
|
||||
|
||||
@ -45,7 +45,7 @@ const ResourceListView = (props: Props) => {
|
||||
<span className="text-sm max-w-[8rem] truncate">{resource.filename}</span>
|
||||
</SortableItem>
|
||||
<button className="shrink-0" onClick={() => handleDeleteResource(resource.name)}>
|
||||
<Icon.X className="w-4 h-auto cursor-pointer opacity-60 hover:opacity-100" />
|
||||
<XIcon className="w-4 h-auto cursor-pointer opacity-60 hover:opacity-100" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Select, Option, Button, Divider } from "@mui/joy";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { SendIcon } from "lucide-react";
|
||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@ -18,7 +19,6 @@ import { WorkspaceMemoRelatedSetting } from "@/types/proto/api/v1/workspace_sett
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { convertVisibilityFromString, convertVisibilityToString } from "@/utils/memo";
|
||||
import Icon from "../Icon";
|
||||
import VisibilityIcon from "../VisibilityIcon";
|
||||
import AddMemoRelationPopover from "./ActionButton/AddMemoRelationPopover";
|
||||
import MarkdownMenu from "./ActionButton/MarkdownMenu";
|
||||
@ -473,7 +473,7 @@ const MemoEditor = (props: Props) => {
|
||||
className="!font-normal"
|
||||
disabled={!allowSave}
|
||||
loading={state.isRequesting}
|
||||
endDecorator={<Icon.Send className="w-4 h-auto" />}
|
||||
endDecorator={<SendIcon className="w-4 h-auto" />}
|
||||
onClick={handleSaveBtnClick}
|
||||
>
|
||||
{t("editor.save")}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { isEqual } from "lodash-es";
|
||||
import { CalendarIcon, CheckCircleIcon, CodeIcon, EyeIcon, FilterIcon, LinkIcon, SearchIcon, TagIcon, XIcon } from "lucide-react";
|
||||
import { FilterFactor, getMemoFilterKey, MemoFilter, useMemoFilterStore } from "@/store/v1";
|
||||
import Icon from "./Icon";
|
||||
|
||||
const MemoFilters = () => {
|
||||
const memoFilterStore = useMemoFilterStore();
|
||||
@ -23,7 +23,7 @@ const MemoFilters = () => {
|
||||
return (
|
||||
<div className="w-full mb-2 flex flex-row justify-start items-start gap-2">
|
||||
<span className="flex flex-row items-center gap-0.5 text-gray-500 text-sm leading-6 border border-transparent">
|
||||
<Icon.Filter className="w-4 h-auto opacity-60 inline" />
|
||||
<FilterIcon className="w-4 h-auto opacity-60 inline" />
|
||||
Filters
|
||||
</span>
|
||||
<div className="flex flex-row justify-start items-center flex-wrap gap-2 leading-6 h-6">
|
||||
@ -36,7 +36,7 @@ const MemoFilters = () => {
|
||||
<FactorIcon className="w-4 h-auto text-gray-500 dark:text-gray-400 opacity-60" factor={filter.factor} />
|
||||
<span className="text-gray-500 dark:text-gray-400 text-sm max-w-32 truncate">{getFilterDisplayText(filter)}</span>
|
||||
<button className="text-gray-500 dark:text-gray-300 opacity-60 hover:opacity-100">
|
||||
<Icon.X className="w-4 h-auto" />
|
||||
<XIcon className="w-4 h-auto" />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
@ -47,13 +47,13 @@ const MemoFilters = () => {
|
||||
|
||||
const FactorIcon = ({ factor, className }: { factor: FilterFactor; className?: string }) => {
|
||||
const iconMap = {
|
||||
tagSearch: <Icon.Tag className={className} />,
|
||||
visibility: <Icon.Eye className={className} />,
|
||||
contentSearch: <Icon.Search className={className} />,
|
||||
displayTime: <Icon.Calendar className={className} />,
|
||||
"property.hasLink": <Icon.Link className={className} />,
|
||||
"property.hasTaskList": <Icon.CheckCircle className={className} />,
|
||||
"property.hasCode": <Icon.Code className={className} />,
|
||||
tagSearch: <TagIcon className={className} />,
|
||||
visibility: <EyeIcon className={className} />,
|
||||
contentSearch: <SearchIcon className={className} />,
|
||||
displayTime: <CalendarIcon className={className} />,
|
||||
"property.hasLink": <LinkIcon className={className} />,
|
||||
"property.hasTaskList": <CheckCircleIcon className={className} />,
|
||||
"property.hasCode": <CodeIcon className={className} />,
|
||||
};
|
||||
return iconMap[factor as keyof typeof iconMap] || <></>;
|
||||
};
|
||||
|
@ -1,11 +1,11 @@
|
||||
import clsx from "clsx";
|
||||
import { DotIcon, LinkIcon, MilestoneIcon } from "lucide-react";
|
||||
import { memo, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import useAsyncEffect from "@/hooks/useAsyncEffect";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
import { MemoRelation } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
memo: Memo;
|
||||
@ -54,7 +54,7 @@ const MemoRelationListView = (props: Props) => {
|
||||
)}
|
||||
onClick={() => setSelectedTab("referencing")}
|
||||
>
|
||||
<Icon.Link className="w-3 h-auto shrink-0 opacity-70" />
|
||||
<LinkIcon className="w-3 h-auto shrink-0 opacity-70" />
|
||||
<span>Referencing</span>
|
||||
<span className="opacity-80">({referencingMemoList.length})</span>
|
||||
</button>
|
||||
@ -67,7 +67,7 @@ const MemoRelationListView = (props: Props) => {
|
||||
)}
|
||||
onClick={() => setSelectedTab("referenced")}
|
||||
>
|
||||
<Icon.Milestone className="w-3 h-auto shrink-0 opacity-70" />
|
||||
<MilestoneIcon className="w-3 h-auto shrink-0 opacity-70" />
|
||||
<span>Referenced by</span>
|
||||
<span className="opacity-80">({referencedMemoList.length})</span>
|
||||
</button>
|
||||
@ -83,7 +83,7 @@ const MemoRelationListView = (props: Props) => {
|
||||
to={`/m/${memo.uid}`}
|
||||
unstable_viewTransition
|
||||
>
|
||||
<Icon.Dot className="shrink-0 w-4 h-auto opacity-40" />
|
||||
<DotIcon className="shrink-0 w-4 h-auto opacity-40" />
|
||||
<span className="truncate">{memo.snippet}</span>
|
||||
</Link>
|
||||
);
|
||||
@ -100,7 +100,7 @@ const MemoRelationListView = (props: Props) => {
|
||||
to={`/m/${memo.uid}`}
|
||||
unstable_viewTransition
|
||||
>
|
||||
<Icon.Dot className="shrink-0 w-4 h-auto opacity-40" />
|
||||
<DotIcon className="shrink-0 w-4 h-auto opacity-40" />
|
||||
<span className="truncate">{memo.snippet}</span>
|
||||
</Link>
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { BookmarkIcon, MessageCircleMoreIcon } from "lucide-react";
|
||||
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
@ -11,7 +12,6 @@ import { WorkspaceMemoRelatedSetting } from "@/types/proto/api/v1/workspace_sett
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { convertVisibilityToString } from "@/utils/memo";
|
||||
import Icon from "./Icon";
|
||||
import MemoActionMenu from "./MemoActionMenu";
|
||||
import MemoContent from "./MemoContent";
|
||||
import MemoEditor from "./MemoEditor";
|
||||
@ -169,13 +169,13 @@ const MemoView: React.FC<Props> = (props: Props) => {
|
||||
to={`/m/${memo.uid}#comments`}
|
||||
unstable_viewTransition
|
||||
>
|
||||
<Icon.MessageCircleMore className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
<MessageCircleMoreIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
{commentAmount > 0 && <span className="text-xs text-gray-500 dark:text-gray-400">{commentAmount}</span>}
|
||||
</Link>
|
||||
)}
|
||||
{props.showPinned && memo.pinned && (
|
||||
<Tooltip title={t("common.pinned")} placement="top">
|
||||
<Icon.Bookmark className="w-4 h-auto text-amber-500" />
|
||||
<BookmarkIcon className="w-4 h-auto text-amber-500" />
|
||||
</Tooltip>
|
||||
)}
|
||||
{!readonly && (
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { ArchiveIcon, BellIcon, Globe2Icon, HomeIcon, LogInIcon, PaperclipIcon, SettingsIcon, SmileIcon, User2Icon } from "lucide-react";
|
||||
import { useEffect } from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
@ -7,7 +8,6 @@ import { Routes } from "@/router";
|
||||
import { useInboxStore } from "@/store/v1";
|
||||
import { Inbox_Status } from "@/types/proto/api/v1/inbox_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "./Icon";
|
||||
import UserBanner from "./UserBanner";
|
||||
|
||||
interface NavLinkItem {
|
||||
@ -52,25 +52,25 @@ const Navigation = (props: Props) => {
|
||||
id: "header-home",
|
||||
path: Routes.ROOT,
|
||||
title: t("common.home"),
|
||||
icon: <Icon.Home className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <HomeIcon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
const resourcesNavLink: NavLinkItem = {
|
||||
id: "header-resources",
|
||||
path: Routes.RESOURCES,
|
||||
title: t("common.resources"),
|
||||
icon: <Icon.Paperclip className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <PaperclipIcon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
const exploreNavLink: NavLinkItem = {
|
||||
id: "header-explore",
|
||||
path: Routes.EXPLORE,
|
||||
title: t("common.explore"),
|
||||
icon: <Icon.Globe2 className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <Globe2Icon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
const profileNavLink: NavLinkItem = {
|
||||
id: "header-profile",
|
||||
path: user ? `/u/${encodeURIComponent(user.username)}` : "",
|
||||
title: t("common.profile"),
|
||||
icon: <Icon.User2 className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <User2Icon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
const inboxNavLink: NavLinkItem = {
|
||||
id: "header-inbox",
|
||||
@ -79,7 +79,7 @@ const Navigation = (props: Props) => {
|
||||
icon: (
|
||||
<>
|
||||
<div className="relative">
|
||||
<Icon.Bell className="w-6 h-auto opacity-70 shrink-0" />
|
||||
<BellIcon className="w-6 h-auto opacity-70 shrink-0" />
|
||||
{hasUnreadInbox && <div className="absolute top-0 left-5 w-2 h-2 rounded-full bg-blue-500"></div>}
|
||||
</div>
|
||||
</>
|
||||
@ -89,25 +89,25 @@ const Navigation = (props: Props) => {
|
||||
id: "header-archived",
|
||||
path: Routes.ARCHIVED,
|
||||
title: t("common.archived"),
|
||||
icon: <Icon.Archive className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <ArchiveIcon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
const settingNavLink: NavLinkItem = {
|
||||
id: "header-setting",
|
||||
path: Routes.SETTING,
|
||||
title: t("common.settings"),
|
||||
icon: <Icon.Settings className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <SettingsIcon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
const signInNavLink: NavLinkItem = {
|
||||
id: "header-auth",
|
||||
path: Routes.AUTH,
|
||||
title: t("common.sign-in"),
|
||||
icon: <Icon.LogIn className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <LogInIcon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
const aboutNavLink: NavLinkItem = {
|
||||
id: "header-about",
|
||||
path: Routes.ABOUT,
|
||||
title: t("common.about"),
|
||||
icon: <Icon.Smile className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
icon: <SmileIcon className="w-6 h-auto opacity-70 shrink-0" />,
|
||||
};
|
||||
|
||||
const navLinks: NavLinkItem[] = user
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Drawer, IconButton } from "@mui/joy";
|
||||
import { MenuIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import Icon from "./Icon";
|
||||
import Navigation from "./Navigation";
|
||||
|
||||
const NavigationDrawer = () => {
|
||||
@ -23,7 +23,7 @@ const NavigationDrawer = () => {
|
||||
return (
|
||||
<>
|
||||
<IconButton onClick={toggleDrawer(true)}>
|
||||
<Icon.Menu className="w-5 h-auto dark:text-gray-400" />
|
||||
<MenuIcon className="w-5 h-auto dark:text-gray-400" />
|
||||
</IconButton>
|
||||
<Drawer anchor="left" size="sm" open={open} onClose={toggleDrawer(false)}>
|
||||
<div className="w-full h-full overflow-auto px-4 bg-zinc-100 dark:bg-zinc-900">
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { XIcon } from "lucide-react";
|
||||
import React, { useState } from "react";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
import "@/less/preview-image-dialog.less";
|
||||
|
||||
const MIN_SCALE = 0.5;
|
||||
@ -116,7 +116,7 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
|
||||
<>
|
||||
<div className="btns-container">
|
||||
<button className="btn" onClick={handleCloseBtnClick}>
|
||||
<Icon.X className="icon-img" />
|
||||
<XIcon className="icon-img" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="img-container" onClick={handleImgContainerClick}>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Dropdown, Menu, MenuButton } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { SmilePlusIcon } from "lucide-react";
|
||||
import { useRef, useState } from "react";
|
||||
import useClickAway from "react-use/lib/useClickAway";
|
||||
import Icon from "@/components/Icon";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
@ -76,7 +76,7 @@ const ReactionSelector = (props: Props) => {
|
||||
<span
|
||||
className={clsx("h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70", className)}
|
||||
>
|
||||
<Icon.SmilePlus className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
<SmilePlusIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
</span>
|
||||
</MenuButton>
|
||||
<Menu className="relative text-sm" component="div" size="sm" placement="bottom-start">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, IconButton, Input, List, ListItem } from "@mui/joy";
|
||||
import { XIcon } from "lucide-react";
|
||||
import React, { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
@ -7,7 +8,6 @@ import useLoading from "@/hooks/useLoading";
|
||||
import { useTagStore } from "@/store/v1";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props extends DialogProps {
|
||||
tag: string;
|
||||
@ -55,7 +55,7 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
|
||||
<div className="dialog-header-container">
|
||||
<p className="title-text">{"Rename tag"}</p>
|
||||
<IconButton size="sm" onClick={() => destroy()}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container max-w-xs">
|
||||
|
@ -1,8 +1,18 @@
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
BinaryIcon,
|
||||
BookIcon,
|
||||
FileArchiveIcon,
|
||||
FileAudioIcon,
|
||||
FileEditIcon,
|
||||
FileIcon,
|
||||
FileTextIcon,
|
||||
FileVideo2Icon,
|
||||
SheetIcon,
|
||||
} from "lucide-react";
|
||||
import React from "react";
|
||||
import { Resource } from "@/types/proto/api/v1/resource_service";
|
||||
import { getResourceType, getResourceUrl } from "@/utils/resource";
|
||||
import Icon from "./Icon";
|
||||
import showPreviewImageDialog from "./PreviewImageDialog";
|
||||
import SquareDiv from "./kit/SquareDiv";
|
||||
|
||||
@ -40,25 +50,25 @@ const ResourceIcon = (props: Props) => {
|
||||
const getResourceIcon = () => {
|
||||
switch (resourceType) {
|
||||
case "video/*":
|
||||
return <Icon.FileVideo2 strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <FileVideo2Icon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "audio/*":
|
||||
return <Icon.FileAudio strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <FileAudioIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "text/*":
|
||||
return <Icon.FileText strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <FileTextIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "application/epub+zip":
|
||||
return <Icon.Book strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <BookIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "application/pdf":
|
||||
return <Icon.Book strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <BookIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "application/msword":
|
||||
return <Icon.FileEdit strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <FileEditIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "application/msexcel":
|
||||
return <Icon.SheetIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <SheetIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "application/zip":
|
||||
return <Icon.FileArchiveIcon onClick={previewResource} strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <FileArchiveIcon onClick={previewResource} strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
case "application/x-java-archive":
|
||||
return <Icon.BinaryIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <BinaryIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
default:
|
||||
return <Icon.File strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
return <FileIcon strokeWidth={strokeWidth} className="w-full h-auto" />;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { SearchIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useMemoFilterStore } from "@/store/v1";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "./Icon";
|
||||
import MemoDisplaySettingMenu from "./MemoDisplaySettingMenu";
|
||||
|
||||
const SearchBar = () => {
|
||||
@ -29,7 +29,7 @@ const SearchBar = () => {
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-auto flex flex-row justify-start items-center">
|
||||
<Icon.Search className="absolute left-3 w-4 h-auto opacity-40" />
|
||||
<SearchIcon className="absolute left-3 w-4 h-auto opacity-40" />
|
||||
<input
|
||||
className="w-full text-gray-500 dark:text-gray-400 bg-zinc-50 dark:bg-zinc-900 border dark:border-zinc-800 text-sm leading-7 rounded-lg p-1 pl-8 outline-none"
|
||||
placeholder={t("memo.search-placeholder")}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, IconButton } from "@mui/joy";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { ClipboardIcon, TrashIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { userServiceClient } from "@/grpcweb";
|
||||
@ -7,7 +8,6 @@ import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { UserAccessToken } from "@/types/proto/api/v1/user_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import showCreateAccessTokenDialog from "../CreateAccessTokenDialog";
|
||||
import Icon from "../Icon";
|
||||
import LearnMore from "../LearnMore";
|
||||
|
||||
const listAccessTokens = async (name: string) => {
|
||||
@ -102,7 +102,7 @@ const AccessTokenSection = () => {
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400 flex flex-row justify-start items-center gap-x-1">
|
||||
<span className="font-mono">{getFormatedAccessToken(userAccessToken.accessToken)}</span>
|
||||
<IconButton color="neutral" variant="plain" size="sm" onClick={() => copyAccessToken(userAccessToken.accessToken)}>
|
||||
<Icon.Clipboard className="w-4 h-auto text-gray-400" />
|
||||
<ClipboardIcon className="w-4 h-auto text-gray-400" />
|
||||
</IconButton>
|
||||
</td>
|
||||
<td className="whitespace-nowrap py-2 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-400">
|
||||
@ -123,7 +123,7 @@ const AccessTokenSection = () => {
|
||||
handleDeleteAccessToken(userAccessToken.accessToken);
|
||||
}}
|
||||
>
|
||||
<Icon.Trash className="w-4 h-auto" />
|
||||
<TrashIcon className="w-4 h-auto" />
|
||||
</IconButton>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, Dropdown, Input, Menu, MenuButton, MenuItem, Radio, RadioGroup } from "@mui/joy";
|
||||
import { sortBy } from "lodash-es";
|
||||
import { MoreVerticalIcon } from "lucide-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { userServiceClient } from "@/grpcweb";
|
||||
@ -9,7 +10,6 @@ import { RowStatus } from "@/types/proto/api/v1/common";
|
||||
import { User, User_Role } from "@/types/proto/api/v1/user_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import showChangeMemberPasswordDialog from "../ChangeMemberPasswordDialog";
|
||||
import Icon from "../Icon";
|
||||
|
||||
interface State {
|
||||
creatingUser: User;
|
||||
@ -204,7 +204,7 @@ const MemberSection = () => {
|
||||
) : (
|
||||
<Dropdown>
|
||||
<MenuButton size="sm">
|
||||
<Icon.MoreVertical className="w-4 h-auto" />
|
||||
<MoreVerticalIcon className="w-4 h-auto" />
|
||||
</MenuButton>
|
||||
<Menu placement="bottom-end" size="sm">
|
||||
<MenuItem onClick={() => handleChangePasswordClick(user)}>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Button, Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy";
|
||||
import { MoreVerticalIcon, PenLineIcon } from "lucide-react";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
import { downloadFileFromUrl } from "@/helpers/utils";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import showChangePasswordDialog from "../ChangePasswordDialog";
|
||||
import Icon from "../Icon";
|
||||
import showUpdateAccountDialog from "../UpdateAccountDialog";
|
||||
import UserAvatar from "../UserAvatar";
|
||||
import AccessTokenSection from "./AccessTokenSection";
|
||||
@ -35,13 +35,13 @@ const MyAccountSection = () => {
|
||||
</div>
|
||||
<div className="w-full flex flex-row justify-start items-center mt-2 space-x-2">
|
||||
<Button variant="outlined" color="neutral" size="sm" onClick={showUpdateAccountDialog}>
|
||||
<Icon.PenLine className="w-4 h-4 mx-auto mr-1" />
|
||||
<PenLineIcon className="w-4 h-4 mx-auto mr-1" />
|
||||
{t("common.edit")}
|
||||
</Button>
|
||||
<Dropdown>
|
||||
<MenuButton slots={{ root: "div" }}>
|
||||
<Button variant="outlined" color="neutral" size="sm">
|
||||
<Icon.MoreVertical className="w-4 h-4 mx-auto" />
|
||||
<MoreVerticalIcon className="w-4 h-4 mx-auto" />
|
||||
</Button>
|
||||
</MenuButton>
|
||||
<Menu className="text-sm" size="sm" placement="bottom">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, Divider, Dropdown, List, ListItem, Menu, MenuButton, MenuItem } from "@mui/joy";
|
||||
import { MoreVerticalIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
@ -6,7 +7,6 @@ import { identityProviderServiceClient } from "@/grpcweb";
|
||||
import { IdentityProvider } from "@/types/proto/api/v1/idp_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import showCreateIdentityProviderDialog from "../CreateIdentityProviderDialog";
|
||||
import Icon from "../Icon";
|
||||
import LearnMore from "../LearnMore";
|
||||
|
||||
const SSOSection = () => {
|
||||
@ -59,7 +59,7 @@ const SSOSection = () => {
|
||||
<div className="flex flex-row items-center">
|
||||
<Dropdown>
|
||||
<MenuButton size="sm">
|
||||
<Icon.MoreVertical className="w-4 h-auto" />
|
||||
<MoreVerticalIcon className="w-4 h-auto" />
|
||||
</MenuButton>
|
||||
<Menu placement="bottom-end" size="sm">
|
||||
<MenuItem onClick={() => showCreateIdentityProviderDialog(identityProvider, fetchIdentityProviderList)}>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, Divider, Input, List, ListItem, Radio, RadioGroup, Tooltip } from "@mui/joy";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { HelpCircleIcon } from "lucide-react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
@ -11,7 +12,6 @@ import {
|
||||
} from "@/types/proto/api/v1/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "../Icon";
|
||||
|
||||
const StorageSection = () => {
|
||||
const t = useTranslate();
|
||||
@ -132,7 +132,7 @@ const StorageSection = () => {
|
||||
<div className="flex flex-row items-center">
|
||||
<span className="text-gray-700 dark:text-gray-500 mr-1">{t("setting.system-section.max-upload-size")}</span>
|
||||
<Tooltip title={t("setting.system-section.max-upload-size-hint")} placement="top">
|
||||
<Icon.HelpCircle className="w-4 h-auto" />
|
||||
<HelpCircleIcon className="w-4 h-auto" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Input
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, IconButton } from "@mui/joy";
|
||||
import { ExternalLinkIcon, TrashIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { webhookServiceClient } from "@/grpcweb";
|
||||
@ -6,7 +7,6 @@ import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { Webhook } from "@/types/proto/api/v1/webhook_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import showCreateWebhookDialog from "../CreateWebhookDialog";
|
||||
import Icon from "../Icon";
|
||||
|
||||
const listWebhooks = async (userId: number) => {
|
||||
const { webhooks } = await webhookServiceClient.listWebhooks({
|
||||
@ -88,7 +88,7 @@ const WebhookSection = () => {
|
||||
handleDeleteWebhook(webhook);
|
||||
}}
|
||||
>
|
||||
<Icon.Trash className="w-4 h-auto" />
|
||||
<TrashIcon className="w-4 h-auto" />
|
||||
</IconButton>
|
||||
</td>
|
||||
</tr>
|
||||
@ -113,7 +113,7 @@ const WebhookSection = () => {
|
||||
target="_blank"
|
||||
>
|
||||
{t("common.learn-more")}
|
||||
<Icon.ExternalLink className="inline w-4 h-auto ml-1" />
|
||||
<ExternalLinkIcon className="inline w-4 h-auto ml-1" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, Select, Textarea, Option, Divider } from "@mui/joy";
|
||||
import { ExternalLinkIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
@ -7,7 +8,6 @@ import { workspaceSettingNamePrefix, useWorkspaceSettingStore } from "@/store/v1
|
||||
import { WorkspaceGeneralSetting } from "@/types/proto/api/v1/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "../Icon";
|
||||
import showUpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog";
|
||||
|
||||
const WorkspaceSection = () => {
|
||||
@ -101,7 +101,7 @@ const WorkspaceSection = () => {
|
||||
target="_blank"
|
||||
>
|
||||
{t("common.learn-more")}
|
||||
<Icon.ExternalLink className="inline w-4 h-auto ml-1" />
|
||||
<ExternalLinkIcon className="inline w-4 h-auto ml-1" />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ChevronRightIcon, HashIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import useToggle from "react-use/lib/useToggle";
|
||||
import { useMemoFilterStore } from "@/store/v1";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Tag {
|
||||
key: string;
|
||||
@ -108,7 +108,7 @@ const TagItemContainer: React.FC<TagItemContainerProps> = (props: TagItemContain
|
||||
}`}
|
||||
>
|
||||
<div className="shrink-0">
|
||||
<Icon.Hash className="w-4 h-auto shrink-0 mr-1 text-gray-400 dark:text-gray-500" />
|
||||
<HashIcon className="w-4 h-auto shrink-0 mr-1 text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
<span className="truncate cursor-pointer hover:opacity-80" onClick={handleTagClick}>
|
||||
{tag.key}
|
||||
@ -120,7 +120,7 @@ const TagItemContainer: React.FC<TagItemContainerProps> = (props: TagItemContain
|
||||
className={`flex flex-row justify-center items-center w-6 h-6 shrink-0 transition-all rotate-0 ${showSubTags && "rotate-90"}`}
|
||||
onClick={handleToggleBtnClick}
|
||||
>
|
||||
<Icon.ChevronRight className="w-5 h-5 cursor-pointer text-gray-400 dark:text-gray-500" />
|
||||
<ChevronRightIcon className="w-5 h-5 cursor-pointer text-gray-400 dark:text-gray-500" />
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, IconButton, Input, Textarea } from "@mui/joy";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { convertFileToBase64 } from "@/helpers/utils";
|
||||
@ -8,7 +9,6 @@ import { userNamePrefix, useUserStore } from "@/store/v1";
|
||||
import { User as UserPb } from "@/types/proto/api/v1/user_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
import UserAvatar from "./UserAvatar";
|
||||
|
||||
type Props = DialogProps;
|
||||
@ -143,7 +143,7 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
|
||||
<div className="dialog-header-container !w-64">
|
||||
<p className="title-text">{t("setting.account-section.update-information")}</p>
|
||||
<IconButton size="sm" onClick={handleCloseBtnClick}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container space-y-2">
|
||||
@ -154,7 +154,7 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
|
||||
<input type="file" accept="image/*" className="absolute invisible w-full h-full inset-0" onChange={handleAvatarChanged} />
|
||||
</label>
|
||||
{state.avatarUrl && (
|
||||
<Icon.X
|
||||
<XIcon
|
||||
className="w-4 h-auto ml-1 cursor-pointer opacity-60 hover:opacity-80"
|
||||
onClick={() =>
|
||||
setPartialState({
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Button, IconButton, Input } from "@mui/joy";
|
||||
import Textarea from "@mui/joy/Textarea/Textarea";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { workspaceSettingNamePrefix, useWorkspaceSettingStore } from "@/store/v1";
|
||||
@ -8,7 +9,6 @@ import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import AppearanceSelect from "./AppearanceSelect";
|
||||
import { generateDialog } from "./Dialog";
|
||||
import Icon from "./Icon";
|
||||
import LocaleSelect from "./LocaleSelect";
|
||||
|
||||
type Props = DialogProps;
|
||||
@ -103,7 +103,7 @@ const UpdateCustomizedProfileDialog: React.FC<Props> = ({ destroy }: Props) => {
|
||||
<div className="dialog-header-container">
|
||||
<p className="title-text">{t("setting.system-section.customize-server.title")}</p>
|
||||
<IconButton size="sm" onClick={handleCloseButtonClick}>
|
||||
<Icon.X className="w-5 h-auto" />
|
||||
<XIcon className="w-5 h-auto" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="dialog-content-container min-w-[16rem]">
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { LogOutIcon, SmileIcon } from "lucide-react";
|
||||
import { authServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { Routes } from "@/router";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Icon from "./Icon";
|
||||
import UserAvatar from "./UserAvatar";
|
||||
|
||||
interface Props {
|
||||
@ -41,11 +41,11 @@ const UserBanner = (props: Props) => {
|
||||
</MenuButton>
|
||||
<Menu placement="bottom-start" style={{ zIndex: "9999" }}>
|
||||
<MenuItem onClick={handleSignOut}>
|
||||
<Icon.LogOut className="w-4 h-auto opacity-60" />
|
||||
<LogOutIcon className="w-4 h-auto opacity-60" />
|
||||
<span className="truncate">{t("common.sign-out")}</span>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => navigateTo(Routes.ABOUT)}>
|
||||
<Icon.Smile className="w-4 h-auto opacity-60" />
|
||||
<SmileIcon className="w-4 h-auto opacity-60" />
|
||||
<span className="truncate">{t("common.about")}</span>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
@ -2,6 +2,7 @@ import { Divider, Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
import { countBy } from "lodash-es";
|
||||
import { CalendarDaysIcon, CheckCircleIcon, Code2Icon, LinkIcon, ListTodoIcon, MoreVerticalIcon, RefreshCcwIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
@ -11,7 +12,6 @@ import i18n from "@/i18n";
|
||||
import { useMemoFilterStore, useMemoStore } from "@/store/v1";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import ActivityCalendar from "./ActivityCalendar";
|
||||
import Icon from "./Icon";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "./ui/Popover";
|
||||
|
||||
interface UserMemoStats {
|
||||
@ -75,7 +75,7 @@ const UserStatisticsView = () => {
|
||||
<div className="group w-full border mt-2 py-2 px-3 rounded-lg space-y-0.5 text-gray-500 dark:text-gray-400 bg-zinc-50 dark:bg-zinc-900 dark:border-zinc-800">
|
||||
<div className="w-full mb-1 flex flex-row justify-between items-center">
|
||||
<div className="relative text-base font-medium leading-6 flex flex-row items-center dark:text-gray-400">
|
||||
<Icon.CalendarDays className="w-5 h-auto mr-1 opacity-60" strokeWidth={1.5} />
|
||||
<CalendarDaysIcon className="w-5 h-auto mr-1 opacity-60" strokeWidth={1.5} />
|
||||
<span>{dayjs(monthString).toDate().toLocaleString(i18n.language, { year: "numeric", month: "long" })}</span>
|
||||
<input
|
||||
className="inset-0 absolute z-1 opacity-0"
|
||||
@ -88,11 +88,11 @@ const UserStatisticsView = () => {
|
||||
<div className="invisible group-hover:visible flex justify-end items-center">
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<Icon.MoreVertical className="w-4 h-auto shrink-0 opacity-60" />
|
||||
<MoreVerticalIcon className="w-4 h-auto shrink-0 opacity-60" />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" alignOffset={-12}>
|
||||
<button className="w-auto flex flex-row justify-between items-center gap-2 hover:opacity-80" onClick={rebuildMemoTags}>
|
||||
<Icon.RefreshCcw className="text-gray-400 w-4 h-auto cursor-pointer opacity-60" />
|
||||
<RefreshCcwIcon className="text-gray-400 w-4 h-auto cursor-pointer opacity-60" />
|
||||
<span className="text-sm shrink-0 text-gray-500 dark:text-gray-400">Refresh</span>
|
||||
</button>
|
||||
</PopoverContent>
|
||||
@ -114,7 +114,7 @@ const UserStatisticsView = () => {
|
||||
onClick={() => memoFilterStore.addFilter({ factor: "property.hasLink", value: "" })}
|
||||
>
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
<Icon.Link className="w-4 h-auto mr-1" />
|
||||
<LinkIcon className="w-4 h-auto mr-1" />
|
||||
<span className="block text-sm">{t("memo.links")}</span>
|
||||
</div>
|
||||
<span className="text-sm truncate">{memoStats.link}</span>
|
||||
@ -124,11 +124,7 @@ const UserStatisticsView = () => {
|
||||
onClick={() => memoFilterStore.addFilter({ factor: "property.hasTaskList", value: "" })}
|
||||
>
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
{memoStats.incompleteTasks > 0 ? (
|
||||
<Icon.ListTodo className="w-4 h-auto mr-1" />
|
||||
) : (
|
||||
<Icon.CheckCircle className="w-4 h-auto mr-1" />
|
||||
)}
|
||||
{memoStats.incompleteTasks > 0 ? <ListTodoIcon className="w-4 h-auto mr-1" /> : <CheckCircleIcon className="w-4 h-auto mr-1" />}
|
||||
<span className="block text-sm">{t("memo.to-do")}</span>
|
||||
</div>
|
||||
{memoStats.incompleteTasks > 0 ? (
|
||||
@ -148,7 +144,7 @@ const UserStatisticsView = () => {
|
||||
onClick={() => memoFilterStore.addFilter({ factor: "property.hasCode", value: "" })}
|
||||
>
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
<Icon.Code2 className="w-4 h-auto mr-1" />
|
||||
<Code2Icon className="w-4 h-auto mr-1" />
|
||||
<span className="block text-sm">{t("memo.code")}</span>
|
||||
</div>
|
||||
<span className="text-sm truncate">{memoStats.code}</span>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import { Globe2Icon, LockIcon, UsersIcon } from "lucide-react";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
visibility: Visibility;
|
||||
@ -11,11 +11,11 @@ const VisibilityIcon = (props: Props) => {
|
||||
|
||||
let VIcon = null;
|
||||
if (visibility === Visibility.PRIVATE) {
|
||||
VIcon = Icon.Lock;
|
||||
VIcon = LockIcon;
|
||||
} else if (visibility === Visibility.PROTECTED) {
|
||||
VIcon = Icon.Users;
|
||||
VIcon = UsersIcon;
|
||||
} else if (visibility === Visibility.PUBLIC) {
|
||||
VIcon = Icon.Globe2;
|
||||
VIcon = Globe2Icon;
|
||||
}
|
||||
if (!VIcon) {
|
||||
return null;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Button, IconButton, Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
||||
import { Suspense, useEffect, useState } from "react";
|
||||
import { Outlet, useLocation } from "react-router-dom";
|
||||
import useLocalStorage from "react-use/lib/useLocalStorage";
|
||||
import Icon from "@/components/Icon";
|
||||
import Navigation from "@/components/Navigation";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||
@ -55,13 +55,13 @@ const RootLayout = () => {
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
>
|
||||
{!collapsed ? (
|
||||
<Button variant="plain" color="neutral" startDecorator={<Icon.ChevronLeft className="w-5 h-auto opacity-70" />}>
|
||||
<Button variant="plain" color="neutral" startDecorator={<ChevronLeftIcon className="w-5 h-auto opacity-70" />}>
|
||||
{t("common.collapse")}
|
||||
</Button>
|
||||
) : (
|
||||
<Tooltip title={t("common.expand")} placement="right" arrow>
|
||||
<IconButton>
|
||||
<Icon.ChevronRight className="w-5 h-auto opacity-70" />
|
||||
<ChevronRightIcon className="w-5 h-auto opacity-70" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Link } from "@mui/joy";
|
||||
import Icon from "@/components/Icon";
|
||||
import { DotIcon } from "lucide-react";
|
||||
import MobileHeader from "@/components/MobileHeader";
|
||||
|
||||
const About = () => {
|
||||
@ -16,15 +16,15 @@ const About = () => {
|
||||
<Link underline="always" href="https://www.github.com/usememos/memos" target="_blank">
|
||||
GitHub Repo
|
||||
</Link>
|
||||
<Icon.Dot className="w-4 h-auto opacity-60" />
|
||||
<DotIcon className="w-4 h-auto opacity-60" />
|
||||
<Link underline="always" href="https://www.usememos.com/" target="_blank">
|
||||
Official Website
|
||||
</Link>
|
||||
<Icon.Dot className="w-4 h-auto opacity-60" />
|
||||
<DotIcon className="w-4 h-auto opacity-60" />
|
||||
<Link underline="always" href="https://www.usememos.com/blog" target="_blank">
|
||||
Blogs
|
||||
</Link>
|
||||
<Icon.Dot className="w-4 h-auto opacity-60" />
|
||||
<DotIcon className="w-4 h-auto opacity-60" />
|
||||
<Link underline="always" href="https://www.usememos.com/docs" target="_blank">
|
||||
Documents
|
||||
</Link>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Button, Tooltip } from "@mui/joy";
|
||||
import dayjs from "dayjs";
|
||||
import { ArchiveIcon, ArchiveRestoreIcon, ArrowDownIcon, TrashIcon } from "lucide-react";
|
||||
import { ClientError } from "nice-grpc-web";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import Empty from "@/components/Empty";
|
||||
import Icon from "@/components/Icon";
|
||||
import MemoContent from "@/components/MemoContent";
|
||||
import MemoFilters from "@/components/MemoFilters";
|
||||
import MobileHeader from "@/components/MobileHeader";
|
||||
@ -97,7 +97,7 @@ const Archived = () => {
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<div className="w-full flex flex-row justify-between items-center mb-2">
|
||||
<div className="flex flex-row justify-start items-center gap-1">
|
||||
<Icon.Archive className="w-5 h-auto opacity-70 shrink-0" />
|
||||
<ArchiveIcon className="w-5 h-auto opacity-70 shrink-0" />
|
||||
<span>{t("common.archived")}</span>
|
||||
</div>
|
||||
<div className="w-44">
|
||||
@ -119,12 +119,12 @@ const Archived = () => {
|
||||
<div className="flex flex-row justify-end items-center gap-x-2">
|
||||
<Tooltip title={t("common.restore")} placement="top">
|
||||
<button onClick={() => handleRestoreMemoClick(memo)}>
|
||||
<Icon.ArchiveRestore className="w-4 h-auto cursor-pointer text-gray-500 dark:text-gray-400" />
|
||||
<ArchiveRestoreIcon className="w-4 h-auto cursor-pointer text-gray-500 dark:text-gray-400" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip title={t("common.delete")} placement="top">
|
||||
<button onClick={() => handleDeleteMemoClick(memo)} className="text-gray-500 dark:text-gray-400">
|
||||
<Icon.Trash className="w-4 h-auto cursor-pointer" />
|
||||
<TrashIcon className="w-4 h-auto cursor-pointer" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@ -138,7 +138,7 @@ const Archived = () => {
|
||||
variant="plain"
|
||||
color="neutral"
|
||||
loading={isRequesting}
|
||||
endDecorator={<Icon.ArrowDown className="w-4 h-auto" />}
|
||||
endDecorator={<ArrowDownIcon className="w-4 h-auto" />}
|
||||
onClick={() => fetchMemos(nextPageToken)}
|
||||
>
|
||||
{t("memo.load-more")}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { last } from "lodash-es";
|
||||
import { LoaderIcon } from "lucide-react";
|
||||
import { ClientError } from "nice-grpc-web";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import Icon from "@/components/Icon";
|
||||
import { authServiceClient } from "@/grpcweb";
|
||||
import { absolutifyLink } from "@/helpers/utils";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
@ -70,7 +70,7 @@ const AuthCallback = () => {
|
||||
return (
|
||||
<div className="p-4 py-24 w-full h-full flex justify-center items-center">
|
||||
{state.loading ? (
|
||||
<Icon.Loader className="animate-spin dark:text-gray-200" />
|
||||
<LoaderIcon className="animate-spin dark:text-gray-200" />
|
||||
) : (
|
||||
<div className="max-w-lg font-mono whitespace-pre-wrap opacity-80">{state.errorMessage}</div>
|
||||
)}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
import { ArrowDownIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import Empty from "@/components/Empty";
|
||||
import { ExploreSidebar, ExploreSidebarDrawer } from "@/components/ExploreSidebar";
|
||||
import Icon from "@/components/Icon";
|
||||
import MemoFilters from "@/components/MemoFilters";
|
||||
import MemoView from "@/components/MemoView";
|
||||
import MobileHeader from "@/components/MobileHeader";
|
||||
@ -84,7 +84,7 @@ const Explore = () => {
|
||||
variant="plain"
|
||||
color="neutral"
|
||||
loading={isRequesting}
|
||||
endDecorator={<Icon.ArrowDown className="w-4 h-auto" />}
|
||||
endDecorator={<ArrowDownIcon className="w-4 h-auto" />}
|
||||
onClick={() => fetchMemos(nextPageToken)}
|
||||
>
|
||||
{t("memo.load-more")}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
import { ArrowDownIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import Empty from "@/components/Empty";
|
||||
import { HomeSidebar, HomeSidebarDrawer } from "@/components/HomeSidebar";
|
||||
import Icon from "@/components/Icon";
|
||||
import MemoEditor from "@/components/MemoEditor";
|
||||
import MemoFilters from "@/components/MemoFilters";
|
||||
import MemoView from "@/components/MemoView";
|
||||
@ -100,7 +100,7 @@ const Home = () => {
|
||||
variant="plain"
|
||||
color="neutral"
|
||||
loading={isRequesting}
|
||||
endDecorator={<Icon.ArrowDown className="w-4 h-auto" />}
|
||||
endDecorator={<ArrowDownIcon className="w-4 h-auto" />}
|
||||
onClick={() => fetchMemos(nextPageToken)}
|
||||
>
|
||||
{t("memo.load-more")}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { BellIcon } from "lucide-react";
|
||||
import { useEffect } from "react";
|
||||
import Empty from "@/components/Empty";
|
||||
import Icon from "@/components/Icon";
|
||||
import MemoCommentMessage from "@/components/Inbox/MemoCommentMessage";
|
||||
import VersionUpdateMessage from "@/components/Inbox/VersionUpdateMessage";
|
||||
import MobileHeader from "@/components/MobileHeader";
|
||||
@ -29,7 +29,7 @@ const Inboxes = () => {
|
||||
<div className="w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-800 text-black dark:text-gray-300">
|
||||
<div className="relative w-full flex flex-row justify-between items-center">
|
||||
<p className="py-1 flex flex-row justify-start items-center select-none opacity-80">
|
||||
<Icon.Bell className="w-6 h-auto mr-1 opacity-80" />
|
||||
<BellIcon className="w-6 h-auto mr-1 opacity-80" />
|
||||
<span className="text-lg">{t("common.inbox")}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import Icon from "@/components/Icon";
|
||||
import { LoaderIcon } from "lucide-react";
|
||||
|
||||
function Loading() {
|
||||
return (
|
||||
<div className="fixed w-full h-full flex flex-row justify-center items-center">
|
||||
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-center items-center">
|
||||
<Icon.Loader className="animate-spin dark:text-gray-200" />
|
||||
<LoaderIcon className="animate-spin dark:text-gray-200" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { ArrowUpLeftFromCircleIcon, MessageCircleIcon } from "lucide-react";
|
||||
import { ClientError } from "nice-grpc-web";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import Icon from "@/components/Icon";
|
||||
import { MemoDetailSidebar, MemoDetailSidebarDrawer } from "@/components/MemoDetailSidebar";
|
||||
import MemoEditor from "@/components/MemoEditor";
|
||||
import MemoView from "@/components/MemoView";
|
||||
@ -98,7 +98,7 @@ const MemoDetail = () => {
|
||||
to={`/m/${parentMemo.uid}`}
|
||||
unstable_viewTransition
|
||||
>
|
||||
<Icon.ArrowUpLeftFromCircle className="w-4 h-auto shrink-0 opacity-60 mr-2" />
|
||||
<ArrowUpLeftFromCircleIcon className="w-4 h-auto shrink-0 opacity-60 mr-2" />
|
||||
<span className="truncate">{parentMemo.content}</span>
|
||||
</Link>
|
||||
</div>
|
||||
@ -123,7 +123,7 @@ const MemoDetail = () => {
|
||||
<Button
|
||||
variant="plain"
|
||||
color="neutral"
|
||||
endDecorator={<Icon.MessageCircle className="w-5 h-auto text-gray-500" />}
|
||||
endDecorator={<MessageCircleIcon className="w-5 h-auto text-gray-500" />}
|
||||
onClick={handleShowCommentEditor}
|
||||
>
|
||||
<span className="font-normal text-gray-500">{t("memo.comment.write-a-comment")}</span>
|
||||
@ -134,7 +134,7 @@ const MemoDetail = () => {
|
||||
<>
|
||||
<div className="w-full flex flex-row justify-between items-center px-3 mb-2">
|
||||
<div className="flex flex-row justify-start items-center">
|
||||
<Icon.MessageCircle className="w-5 h-auto text-gray-400 mr-1" />
|
||||
<MessageCircleIcon className="w-5 h-auto text-gray-400 mr-1" />
|
||||
<span className="text-gray-400 text-sm">{t("memo.comment.self")}</span>
|
||||
<span className="text-gray-400 text-sm ml-1">({comments.length})</span>
|
||||
</div>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Divider, IconButton, Input, Tooltip } from "@mui/joy";
|
||||
import dayjs from "dayjs";
|
||||
import { includes } from "lodash-es";
|
||||
import { PaperclipIcon, SearchIcon, TrashIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import Empty from "@/components/Empty";
|
||||
import Icon from "@/components/Icon";
|
||||
import MobileHeader from "@/components/MobileHeader";
|
||||
import ResourceIcon from "@/components/ResourceIcon";
|
||||
import { resourceServiceClient } from "@/grpcweb";
|
||||
@ -68,14 +68,14 @@ const Resources = () => {
|
||||
<div className="w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-800 text-black dark:text-gray-300">
|
||||
<div className="relative w-full flex flex-row justify-between items-center">
|
||||
<p className="py-1 flex flex-row justify-start items-center select-none opacity-80">
|
||||
<Icon.Paperclip className="w-6 h-auto mr-1 opacity-80" />
|
||||
<PaperclipIcon className="w-6 h-auto mr-1 opacity-80" />
|
||||
<span className="text-lg">{t("common.resources")}</span>
|
||||
</p>
|
||||
<div>
|
||||
<Input
|
||||
className="max-w-[8rem]"
|
||||
placeholder={t("common.search")}
|
||||
startDecorator={<Icon.Search className="w-4 h-auto" />}
|
||||
startDecorator={<SearchIcon className="w-4 h-auto" />}
|
||||
value={state.searchQuery}
|
||||
onChange={(e) => setState({ ...state, searchQuery: e.target.value })}
|
||||
/>
|
||||
@ -133,7 +133,7 @@ const Resources = () => {
|
||||
<span className="text-gray-500 dark:text-gray-500 opacity-80">({unusedResources.length})</span>
|
||||
<Tooltip title="Delete all" placement="top">
|
||||
<IconButton size="sm" onClick={handleDeleteUnusedResources}>
|
||||
<Icon.Trash className="w-4 h-auto opacity-60" />
|
||||
<TrashIcon className="w-4 h-auto opacity-60" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Option, Select } from "@mui/joy";
|
||||
import { LucideIcon } from "lucide-react";
|
||||
import { CogIcon, DatabaseIcon, KeyIcon, LibraryIcon, LucideIcon, Settings2Icon, UserIcon, UsersIcon } from "lucide-react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import Icon from "@/components/Icon";
|
||||
import MobileHeader from "@/components/MobileHeader";
|
||||
import MemberSection from "@/components/Settings/MemberSection";
|
||||
import MemoRelatedSettings from "@/components/Settings/MemoRelatedSettings";
|
||||
@ -27,13 +26,13 @@ interface State {
|
||||
const BASIC_SECTIONS: SettingSection[] = ["my-account", "preference"];
|
||||
const ADMIN_SECTIONS: SettingSection[] = ["member", "system", "memo-related", "storage", "sso"];
|
||||
const SECTION_ICON_MAP: Record<SettingSection, LucideIcon> = {
|
||||
"my-account": Icon.User,
|
||||
preference: Icon.Cog,
|
||||
member: Icon.Users,
|
||||
system: Icon.Settings2,
|
||||
"memo-related": Icon.Library,
|
||||
storage: Icon.Database,
|
||||
sso: Icon.Key,
|
||||
"my-account": UserIcon,
|
||||
preference: CogIcon,
|
||||
member: UsersIcon,
|
||||
system: Settings2Icon,
|
||||
"memo-related": LibraryIcon,
|
||||
storage: DatabaseIcon,
|
||||
sso: KeyIcon,
|
||||
};
|
||||
|
||||
const Setting = () => {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import copy from "copy-to-clipboard";
|
||||
import dayjs from "dayjs";
|
||||
import { ArrowDownIcon, ExternalLinkIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { useParams } from "react-router-dom";
|
||||
import Empty from "@/components/Empty";
|
||||
import Icon from "@/components/Icon";
|
||||
import MemoFilters from "@/components/MemoFilters";
|
||||
import MemoView from "@/components/MemoView";
|
||||
import MobileHeader from "@/components/MobileHeader";
|
||||
@ -113,7 +113,7 @@ const UserProfile = () => {
|
||||
<Button
|
||||
color="neutral"
|
||||
variant="outlined"
|
||||
endDecorator={<Icon.ExternalLink className="w-4 h-auto opacity-60" />}
|
||||
endDecorator={<ExternalLinkIcon className="w-4 h-auto opacity-60" />}
|
||||
onClick={handleCopyProfileLink}
|
||||
>
|
||||
{t("common.share")}
|
||||
@ -140,7 +140,7 @@ const UserProfile = () => {
|
||||
variant="plain"
|
||||
color="neutral"
|
||||
loading={isRequesting}
|
||||
endDecorator={<Icon.ArrowDown className="w-4 h-auto" />}
|
||||
endDecorator={<ArrowDownIcon className="w-4 h-auto" />}
|
||||
onClick={() => fetchMemos(nextPageToken)}
|
||||
>
|
||||
{t("memo.load-more")}
|
||||
|
Loading…
x
Reference in New Issue
Block a user