Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
963706ae
Commit
963706ae
authored
Oct 26, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: update button source
parent
8635aed1
Changes
44
Show whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
209 additions
and
417 deletions
+209
-417
index.html
web/index.html
+2
-2
package.json
web/package.json
+1
-1
pnpm-lock.yaml
web/pnpm-lock.yaml
+11
-5
ChangeMemberPasswordDialog.tsx
web/src/components/ChangeMemberPasswordDialog.tsx
+5
-4
ChangePasswordDialog.tsx
web/src/components/ChangePasswordDialog.tsx
+0
-116
CreateAccessTokenDialog.tsx
web/src/components/CreateAccessTokenDialog.tsx
+6
-5
CreateIdentityProviderDialog.tsx
web/src/components/CreateIdentityProviderDialog.tsx
+6
-5
CreateWebhookDialog.tsx
web/src/components/CreateWebhookDialog.tsx
+6
-5
ExploreSidebarDrawer.tsx
web/src/components/ExploreSidebar/ExploreSidebarDrawer.tsx
+4
-3
HomeSidebarDrawer.tsx
web/src/components/HomeSidebar/HomeSidebarDrawer.tsx
+4
-3
MemoDetailSidebarDrawer.tsx
.../components/MemoDetailSidebar/MemoDetailSidebarDrawer.tsx
+4
-3
AddMemoRelationPopover.tsx
...onents/MemoEditor/ActionButton/AddMemoRelationPopover.tsx
+5
-4
LocationSelector.tsx
...c/components/MemoEditor/ActionButton/LocationSelector.tsx
+5
-4
MarkdownMenu.tsx
web/src/components/MemoEditor/ActionButton/MarkdownMenu.tsx
+5
-3
TagSelector.tsx
web/src/components/MemoEditor/ActionButton/TagSelector.tsx
+5
-2
UploadResourceButton.tsx
...mponents/MemoEditor/ActionButton/UploadResourceButton.tsx
+3
-3
index.tsx
web/src/components/MemoEditor/index.tsx
+7
-11
NavigationDrawer.tsx
web/src/components/NavigationDrawer.tsx
+4
-3
PagedMemoList.tsx
web/src/components/PagedMemoList/PagedMemoList.tsx
+3
-8
PasswordSignInForm.tsx
web/src/components/PasswordSignInForm.tsx
+7
-4
RenameTagDialog.tsx
web/src/components/RenameTagDialog.tsx
+6
-5
AccessTokenSection.tsx
web/src/components/Settings/AccessTokenSection.tsx
+7
-9
MemberSection.tsx
web/src/components/Settings/MemberSection.tsx
+5
-2
MemoRelatedSettings.tsx
web/src/components/Settings/MemoRelatedSettings.tsx
+3
-2
MyAccountSection.tsx
web/src/components/Settings/MyAccountSection.tsx
+6
-5
SSOSection.tsx
web/src/components/Settings/SSOSection.tsx
+5
-2
StorageSection.tsx
web/src/components/Settings/StorageSection.tsx
+3
-2
WebhookSection.tsx
web/src/components/Settings/WebhookSection.tsx
+5
-7
WorkspaceSection.tsx
web/src/components/Settings/WorkspaceSection.tsx
+4
-3
UpdateAccountDialog.tsx
web/src/components/UpdateAccountDialog.tsx
+5
-4
UpdateCustomizedProfileDialog.tsx
web/src/components/UpdateCustomizedProfileDialog.tsx
+8
-5
UserBanner.tsx
web/src/components/UserBanner.tsx
+3
-3
UserStatisticsView.tsx
web/src/components/UserStatisticsView.tsx
+14
-5
Popover.tsx
web/src/components/ui/Popover.tsx
+1
-1
global.css
web/src/css/global.css
+0
-14
tailwind.css
web/src/css/tailwind.css
+7
-57
RootLayout.tsx
web/src/layouts/RootLayout.tsx
+6
-4
main.tsx
web/src/main.tsx
+1
-1
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+8
-12
Resources.tsx
web/src/pages/Resources.tsx
+4
-3
SignIn.tsx
web/src/pages/SignIn.tsx
+4
-4
SignUp.tsx
web/src/pages/SignUp.tsx
+7
-4
UserProfile.tsx
web/src/pages/UserProfile.tsx
+3
-7
tailwind.config.js
web/tailwind.config.js
+1
-62
No files found.
web/index.html
View file @
963706ae
...
@@ -18,8 +18,8 @@
...
@@ -18,8 +18,8 @@
}
}
</script>
</script>
</head>
</head>
<body>
<body
class=
"text-base w-full min-h-[100svh] bg-zinc-100 dark:bg-zinc-900"
>
<div
id=
"root"
></div>
<div
id=
"root"
class=
"relative w-full min-h-full"
></div>
<script
type=
"module"
src=
"/src/main.tsx"
></script>
<script
type=
"module"
src=
"/src/main.tsx"
></script>
<!-- memos.metadata.body -->
<!-- memos.metadata.body -->
</body>
</body>
...
...
web/package.json
View file @
963706ae
...
@@ -19,7 +19,7 @@
...
@@ -19,7 +19,7 @@
"@mui/joy"
:
"5.0.0-beta.48"
,
"@mui/joy"
:
"5.0.0-beta.48"
,
"@radix-ui/react-popover"
:
"^1.1.2"
,
"@radix-ui/react-popover"
:
"^1.1.2"
,
"@reduxjs/toolkit"
:
"^2.3.0"
,
"@reduxjs/toolkit"
:
"^2.3.0"
,
"@usememos/mui"
:
"0.0.1-alpha.
6
"
,
"@usememos/mui"
:
"0.0.1-alpha.
10
"
,
"class-variance-authority"
:
"^0.7.0"
,
"class-variance-authority"
:
"^0.7.0"
,
"clsx"
:
"^2.1.1"
,
"clsx"
:
"^2.1.1"
,
"copy-to-clipboard"
:
"^3.3.3"
,
"copy-to-clipboard"
:
"^3.3.3"
,
...
...
web/pnpm-lock.yaml
View file @
963706ae
...
@@ -39,8 +39,8 @@ importers:
...
@@ -39,8 +39,8 @@ importers:
specifier
:
^2.3.0
specifier
:
^2.3.0
version
:
2.3.0(react-redux@9.1.2(@types/react@18.3.12)(react@18.3.1)(redux@5.0.1))(react@18.3.1)
version
:
2.3.0(react-redux@9.1.2(@types/react@18.3.12)(react@18.3.1)(redux@5.0.1))(react@18.3.1)
'
@usememos/mui'
:
'
@usememos/mui'
:
specifier
:
0.0.1-alpha.
6
specifier
:
0.0.1-alpha.
10
version
:
0.0.1-alpha.
6(lucide-react@0.453.0(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1
)
version
:
0.0.1-alpha.
10(lucide-react@0.453.0(react@18.3.1))(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwind-merge@2.5.4)(tailwindcss@3.4.14
)
class-variance-authority
:
class-variance-authority
:
specifier
:
^0.7.0
specifier
:
^0.7.0
version
:
0.7.0
version
:
0.7.0
...
@@ -1409,12 +1409,15 @@ packages:
...
@@ -1409,12 +1409,15 @@ packages:
'
@ungap/structured-clone@1.2.0'
:
'
@ungap/structured-clone@1.2.0'
:
resolution
:
{
integrity
:
sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
}
resolution
:
{
integrity
:
sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==
}
'
@usememos/mui@0.0.1-alpha.
6
'
:
'
@usememos/mui@0.0.1-alpha.
10
'
:
resolution
:
{
integrity
:
sha512-
CVE3kQ/Uk+T3Zp8jcEOWR4syS6hIxVrQ9UgwpnOiR8d3OEghRFbZBQ6hs4C0sEefIPWS5xsZiEKa0E4BIZezBw
==
}
resolution
:
{
integrity
:
sha512-
jyEQ4sgmYCxOWEyuUat7MqQN7Gy4PohQxnLvIje0upqu2zT2AaI0GhOPs/t2HkYK09tFXLAVnhp2I+6jBBhfIg
==
}
peerDependencies
:
peerDependencies
:
lucide-react
:
^0.453.0
lucide-react
:
^0.453.0
postcss
:
^8.4.47
react
:
'
>=17.0.0'
react
:
'
>=17.0.0'
react-dom
:
'
>=17.0.0'
react-dom
:
'
>=17.0.0'
tailwind-merge
:
^2.5.4
tailwindcss
:
^3.4.14
'
@vitejs/plugin-react@4.3.3'
:
'
@vitejs/plugin-react@4.3.3'
:
resolution
:
{
integrity
:
sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==
}
resolution
:
{
integrity
:
sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==
}
...
@@ -4639,11 +4642,14 @@ snapshots:
...
@@ -4639,11 +4642,14 @@ snapshots:
'
@ungap/structured-clone@1.2.0'
:
{}
'
@ungap/structured-clone@1.2.0'
:
{}
'
@usememos/mui@0.0.1-alpha.
6(lucide-react@0.453.0(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1
)'
:
'
@usememos/mui@0.0.1-alpha.
10(lucide-react@0.453.0(react@18.3.1))(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwind-merge@2.5.4)(tailwindcss@3.4.14
)'
:
dependencies
:
dependencies
:
lucide-react
:
0.453.0(react@18.3.1)
lucide-react
:
0.453.0(react@18.3.1)
postcss
:
8.4.47
react
:
18.3.1
react
:
18.3.1
react-dom
:
18.3.1(react@18.3.1)
react-dom
:
18.3.1(react@18.3.1)
tailwind-merge
:
2.5.4
tailwindcss
:
3.4.14
'
@vitejs/plugin-react@4.3.3(vite@5.4.10(@types/node@22.8.0)(less@4.2.0))'
:
'
@vitejs/plugin-react@4.3.3(vite@5.4.10(@types/node@22.8.0)(less@4.2.0))'
:
dependencies
:
dependencies
:
...
...
web/src/components/ChangeMemberPasswordDialog.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Input
}
from
"@mui/joy"
;
import
{
Input
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -70,9 +71,9 @@ const ChangeMemberPasswordDialog: React.FC<Props> = (props: Props) => {
...
@@ -70,9 +71,9 @@ const ChangeMemberPasswordDialog: React.FC<Props> = (props: Props) => {
<
p
className=
"title-text"
>
<
p
className=
"title-text"
>
{
t
(
"setting.account-section.change-password"
)
}
(
{
user
.
nickname
}
)
{
t
(
"setting.account-section.change-password"
)
}
(
{
user
.
nickname
}
)
</
p
>
</
p
>
<
IconButton
size=
"sm
"
onClick=
{
handleCloseBtnClick
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
handleCloseBtnClick
}
>
<
XIcon
className=
"w-5 h-auto"
/>
<
XIcon
className=
"w-5 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container"
>
<
div
className=
"dialog-content-container"
>
<
p
className=
"text-sm mb-1"
>
{
t
(
"auth.new-password"
)
}
</
p
>
<
p
className=
"text-sm mb-1"
>
{
t
(
"auth.new-password"
)
}
</
p
>
...
@@ -92,7 +93,7 @@ const ChangeMemberPasswordDialog: React.FC<Props> = (props: Props) => {
...
@@ -92,7 +93,7 @@ const ChangeMemberPasswordDialog: React.FC<Props> = (props: Props) => {
onChange=
{
handleNewPasswordAgainChanged
}
onChange=
{
handleNewPasswordAgainChanged
}
/>
/>
<
div
className=
"flex flex-row justify-end items-center mt-4 w-full gap-x-2"
>
<
div
className=
"flex flex-row justify-end items-center mt-4 w-full gap-x-2"
>
<
Button
color=
"neutral"
variant=
"plain"
onClick=
{
handleCloseBtnClick
}
>
<
Button
variant=
"plain"
onClick=
{
handleCloseBtnClick
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
<
Button
color=
"primary"
onClick=
{
handleSaveBtnClick
}
>
<
Button
color=
"primary"
onClick=
{
handleSaveBtnClick
}
>
...
...
web/src/components/ChangePasswordDialog.tsx
deleted
100644 → 0
View file @
8635aed1
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"
;
import
{
useCommonContext
}
from
"@/layouts/CommonContextProvider"
;
import
{
useUserStore
}
from
"@/store/v1"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
generateDialog
}
from
"./Dialog"
;
type
Props
=
DialogProps
;
const
ChangePasswordDialog
:
React
.
FC
<
Props
>
=
({
destroy
}:
Props
)
=>
{
const
t
=
useTranslate
();
const
commonContext
=
useCommonContext
();
const
currentUser
=
useCurrentUser
();
const
userStore
=
useUserStore
();
const
[
newPassword
,
setNewPassword
]
=
useState
(
""
);
const
[
newPasswordAgain
,
setNewPasswordAgain
]
=
useState
(
""
);
useEffect
(()
=>
{
if
(
commonContext
.
profile
.
mode
===
"demo"
)
{
toast
.
error
(
"Demo mode does not support this operation."
);
destroy
();
}
},
[]);
const
handleCloseBtnClick
=
()
=>
{
destroy
();
};
const
handleNewPasswordChanged
=
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
setNewPassword
(
e
.
target
.
value
);
};
const
handleNewPasswordAgainChanged
=
(
e
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
setNewPasswordAgain
(
e
.
target
.
value
);
};
const
handleSaveBtnClick
=
async
()
=>
{
if
(
newPassword
===
""
||
newPasswordAgain
===
""
)
{
toast
.
error
(
t
(
"message.fill-all"
));
return
;
}
if
(
newPassword
!==
newPasswordAgain
)
{
toast
.
error
(
t
(
"message.new-password-not-match"
));
setNewPasswordAgain
(
""
);
return
;
}
try
{
await
userStore
.
updateUser
(
{
name
:
currentUser
.
name
,
password
:
newPassword
,
},
[
"password"
],
);
toast
.
success
(
t
(
"message.password-changed"
));
handleCloseBtnClick
();
}
catch
(
error
:
any
)
{
toast
.
error
(
error
.
details
);
console
.
error
(
error
);
}
};
return
(
<>
<
div
className=
"dialog-header-container !w-64"
>
<
p
className=
"title-text"
>
{
t
(
"setting.account-section.change-password"
)
}
</
p
>
<
IconButton
size=
"sm"
onClick=
{
handleCloseBtnClick
}
>
<
XIcon
className=
"w-5 h-auto"
/>
</
IconButton
>
</
div
>
<
div
className=
"dialog-content-container"
>
<
p
className=
"text-sm mb-1"
>
{
t
(
"auth.new-password"
)
}
</
p
>
<
Input
className=
"w-full"
type=
"password"
placeholder=
{
t
(
"auth.new-password"
)
}
value=
{
newPassword
}
onChange=
{
handleNewPasswordChanged
}
/>
<
p
className=
"text-sm mb-1 mt-2"
>
{
t
(
"auth.repeat-new-password"
)
}
</
p
>
<
Input
className=
"w-full"
type=
"password"
placeholder=
{
t
(
"auth.repeat-new-password"
)
}
value=
{
newPasswordAgain
}
onChange=
{
handleNewPasswordAgainChanged
}
/>
<
div
className=
"w-full flex flex-row justify-end items-center pt-4 space-x-2"
>
<
Button
color=
"neutral"
variant=
"plain"
onClick=
{
handleCloseBtnClick
}
>
{
t
(
"common.cancel"
)
}
</
Button
>
<
Button
color=
"primary"
onClick=
{
handleSaveBtnClick
}
>
{
t
(
"common.save"
)
}
</
Button
>
</
div
>
</
div
>
</>
);
};
function
showChangePasswordDialog
()
{
generateDialog
(
{
className
:
"change-password-dialog"
,
dialogName
:
"change-password-dialog"
,
},
ChangePasswordDialog
,
);
}
export
default
showChangePasswordDialog
;
web/src/components/CreateAccessTokenDialog.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Input
,
Radio
,
RadioGroup
}
from
"@mui/joy"
;
import
{
Input
,
Radio
,
RadioGroup
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
XIcon
}
from
"lucide-react"
;
import
React
,
{
useState
}
from
"react"
;
import
React
,
{
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -86,9 +87,9 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
...
@@ -86,9 +87,9 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
<>
<>
<
div
className=
"dialog-header-container"
>
<
div
className=
"dialog-header-container"
>
<
p
className=
"title-text"
>
Create access token
</
p
>
<
p
className=
"title-text"
>
Create access token
</
p
>
<
IconButton
size=
"sm
"
onClick=
{
()
=>
destroy
()
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
()
=>
destroy
()
}
>
<
XIcon
className=
"w-5 h-auto"
/>
<
XIcon
className=
"w-5 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container !w-80"
>
<
div
className=
"dialog-content-container !w-80"
>
<
div
className=
"w-full flex flex-col justify-start items-start mb-3"
>
<
div
className=
"w-full flex flex-col justify-start items-start mb-3"
>
...
@@ -118,10 +119,10 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
...
@@ -118,10 +119,10 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"w-full flex flex-row justify-end items-center mt-4 space-x-2"
>
<
div
className=
"w-full flex flex-row justify-end items-center mt-4 space-x-2"
>
<
Button
color=
"neutral"
variant=
"plain"
disabled=
{
requestState
.
isLoading
}
loading
=
{
requestState
.
isLoading
}
onClick=
{
destroy
}
>
<
Button
variant=
"plain"
disabled
=
{
requestState
.
isLoading
}
onClick=
{
destroy
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
<
Button
color=
"primary"
disabled=
{
requestState
.
isLoading
}
loading=
{
requestState
.
isLoading
}
onClick=
{
handleSaveBtnClick
}
>
<
Button
color=
"primary"
disabled=
{
requestState
.
isLoading
}
onClick=
{
handleSaveBtnClick
}
>
{
t
(
"common.create"
)
}
{
t
(
"common.create"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/CreateIdentityProviderDialog.tsx
View file @
963706ae
import
{
Button
,
Divider
,
IconButton
,
Input
,
Option
,
Select
,
Typography
}
from
"@mui/joy"
;
import
{
Divider
,
Input
,
Option
,
Select
,
Typography
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -244,9 +245,9 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
...
@@ -244,9 +245,9 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
<>
<>
<
div
className=
"dialog-header-container"
>
<
div
className=
"dialog-header-container"
>
<
p
>
{
t
(
isCreating
?
"setting.sso-section.create-sso"
:
"setting.sso-section.update-sso"
)
}
</
p
>
<
p
>
{
t
(
isCreating
?
"setting.sso-section.create-sso"
:
"setting.sso-section.update-sso"
)
}
</
p
>
<
IconButton
size=
"sm
"
onClick=
{
handleCloseBtnClick
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
handleCloseBtnClick
}
>
<
XIcon
className=
"w-5 h-auto"
/>
<
XIcon
className=
"w-5 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container min-w-[19rem]"
>
<
div
className=
"dialog-content-container min-w-[19rem]"
>
{
isCreating
&&
(
{
isCreating
&&
(
...
@@ -420,10 +421,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
...
@@ -420,10 +421,10 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
</>
</>
)
}
)
}
<
div
className=
"mt-2 w-full flex flex-row justify-end items-center space-x-1"
>
<
div
className=
"mt-2 w-full flex flex-row justify-end items-center space-x-1"
>
<
Button
variant=
"plain"
color=
"neutral"
onClick=
{
handleCloseBtnClick
}
>
<
Button
variant=
"plain"
onClick=
{
handleCloseBtnClick
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
<
Button
onClick=
{
handleConfirmBtnClick
}
disabled=
{
!
allowConfirmAction
()
}
>
<
Button
color=
"primary"
onClick=
{
handleConfirmBtnClick
}
disabled=
{
!
allowConfirmAction
()
}
>
{
t
(
isCreating
?
"common.create"
:
"common.update"
)
}
{
t
(
isCreating
?
"common.create"
:
"common.update"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/CreateWebhookDialog.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Input
}
from
"@mui/joy"
;
import
{
Input
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
XIcon
}
from
"lucide-react"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -96,9 +97,9 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
...
@@ -96,9 +97,9 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
<>
<>
<
div
className=
"dialog-header-container"
>
<
div
className=
"dialog-header-container"
>
<
p
className=
"title-text"
>
{
isCreating
?
"Create webhook"
:
"Edit webhook"
}
</
p
>
<
p
className=
"title-text"
>
{
isCreating
?
"Create webhook"
:
"Edit webhook"
}
</
p
>
<
IconButton
size=
"sm
"
onClick=
{
()
=>
destroy
()
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
()
=>
destroy
()
}
>
<
XIcon
className=
"w-5 h-auto"
/>
<
XIcon
className=
"w-5 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container !w-80"
>
<
div
className=
"dialog-content-container !w-80"
>
<
div
className=
"w-full flex flex-col justify-start items-start mb-3"
>
<
div
className=
"w-full flex flex-col justify-start items-start mb-3"
>
...
@@ -130,10 +131,10 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
...
@@ -130,10 +131,10 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"w-full flex flex-row justify-end items-center mt-2 space-x-2"
>
<
div
className=
"w-full flex flex-row justify-end items-center mt-2 space-x-2"
>
<
Button
color=
"neutral"
variant=
"plain"
disabled=
{
requestState
.
isLoading
}
loading
=
{
requestState
.
isLoading
}
onClick=
{
destroy
}
>
<
Button
variant=
"plain"
disabled
=
{
requestState
.
isLoading
}
onClick=
{
destroy
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
<
Button
color=
"primary"
disabled=
{
requestState
.
isLoading
}
loading=
{
requestState
.
isLoading
}
onClick=
{
handleSaveBtnClick
}
>
<
Button
color=
"primary"
disabled=
{
requestState
.
isLoading
}
onClick=
{
handleSaveBtnClick
}
>
{
t
(
"common.create"
)
}
{
t
(
"common.create"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/ExploreSidebar/ExploreSidebarDrawer.tsx
View file @
963706ae
import
{
Drawer
,
IconButton
}
from
"@mui/joy"
;
import
{
Drawer
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
SearchIcon
}
from
"lucide-react"
;
import
{
SearchIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useLocation
}
from
"react-router-dom"
;
...
@@ -22,9 +23,9 @@ const ExploreSidebarDrawer = () => {
...
@@ -22,9 +23,9 @@ const ExploreSidebarDrawer = () => {
return
(
return
(
<>
<>
<
IconButton
onClick=
{
toggleDrawer
(
true
)
}
>
<
Button
variant=
"plain"
className=
"!bg-transparent px-2"
onClick=
{
toggleDrawer
(
true
)
}
>
<
SearchIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
<
SearchIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
</
Icon
Button
>
</
Button
>
<
Drawer
anchor=
"right"
size=
"sm"
open=
{
open
}
onClose=
{
toggleDrawer
(
false
)
}
>
<
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"
>
<
div
className=
"w-full h-full px-4 bg-zinc-100 dark:bg-zinc-900"
>
<
ExploreSidebar
className=
"py-4"
/>
<
ExploreSidebar
className=
"py-4"
/>
...
...
web/src/components/HomeSidebar/HomeSidebarDrawer.tsx
View file @
963706ae
import
{
Drawer
,
IconButton
}
from
"@mui/joy"
;
import
{
Drawer
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
SearchIcon
}
from
"lucide-react"
;
import
{
SearchIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useLocation
}
from
"react-router-dom"
;
...
@@ -22,9 +23,9 @@ const HomeSidebarDrawer = () => {
...
@@ -22,9 +23,9 @@ const HomeSidebarDrawer = () => {
return
(
return
(
<>
<>
<
IconButton
onClick=
{
toggleDrawer
(
true
)
}
>
<
Button
variant=
"plain"
className=
"!bg-transparent px-2"
onClick=
{
toggleDrawer
(
true
)
}
>
<
SearchIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
<
SearchIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
</
Icon
Button
>
</
Button
>
<
Drawer
anchor=
"right"
size=
"sm"
open=
{
open
}
onClose=
{
toggleDrawer
(
false
)
}
>
<
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"
>
<
div
className=
"w-full h-full px-4 bg-zinc-100 dark:bg-zinc-900"
>
<
HomeSidebar
className=
"py-4"
/>
<
HomeSidebar
className=
"py-4"
/>
...
...
web/src/components/MemoDetailSidebar/MemoDetailSidebarDrawer.tsx
View file @
963706ae
import
{
Drawer
,
IconButton
}
from
"@mui/joy"
;
import
{
Drawer
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
GanttChartIcon
}
from
"lucide-react"
;
import
{
GanttChartIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useLocation
}
from
"react-router-dom"
;
...
@@ -26,9 +27,9 @@ const MemoDetailSidebarDrawer = ({ memo }: Props) => {
...
@@ -26,9 +27,9 @@ const MemoDetailSidebarDrawer = ({ memo }: Props) => {
return
(
return
(
<>
<>
<
IconButton
onClick=
{
toggleDrawer
(
true
)
}
>
<
Button
variant=
"plain"
className=
"!bg-transparent px-2"
onClick=
{
toggleDrawer
(
true
)
}
>
<
GanttChartIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
<
GanttChartIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
</
Icon
Button
>
</
Button
>
<
Drawer
anchor=
"right"
size=
"sm"
open=
{
open
}
onClose=
{
toggleDrawer
(
false
)
}
>
<
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"
>
<
div
className=
"w-full h-full px-4 bg-zinc-100 dark:bg-zinc-900"
>
<
MemoDetailSidebar
className=
"py-4"
memo=
{
memo
}
/>
<
MemoDetailSidebar
className=
"py-4"
memo=
{
memo
}
/>
...
...
web/src/components/MemoEditor/ActionButton/AddMemoRelationPopover.tsx
View file @
963706ae
import
{
Autocomplete
,
AutocompleteOption
,
Button
,
Checkbox
,
Chip
,
IconButton
}
from
"@mui/joy"
;
import
{
Autocomplete
,
AutocompleteOption
,
Checkbox
,
Chip
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
uniqBy
}
from
"lodash-es"
;
import
{
uniqBy
}
from
"lodash-es"
;
import
{
LinkIcon
}
from
"lucide-react"
;
import
{
LinkIcon
}
from
"lucide-react"
;
import
React
,
{
useContext
,
useState
}
from
"react"
;
import
React
,
{
useContext
,
useState
}
from
"react"
;
...
@@ -129,9 +130,9 @@ const AddMemoRelationPopover = (props: Props) => {
...
@@ -129,9 +130,9 @@ const AddMemoRelationPopover = (props: Props) => {
return
(
return
(
<
Popover
open=
{
popoverOpen
}
onOpenChange=
{
setPopoverOpen
}
>
<
Popover
open=
{
popoverOpen
}
onOpenChange=
{
setPopoverOpen
}
>
<
PopoverTrigger
>
<
PopoverTrigger
>
<
IconButton
size=
"sm"
component=
"div
"
>
<
Button
className=
"px-2"
variant=
"plain
"
>
<
LinkIcon
className=
"w-5 h-5 mx-auto"
/>
<
LinkIcon
className=
"w-5 h-5 mx-auto"
/>
</
Icon
Button
>
</
Button
>
</
PopoverTrigger
>
</
PopoverTrigger
>
<
PopoverContent
align=
"center"
>
<
PopoverContent
align=
"center"
>
<
div
className=
"w-[16rem] flex flex-col justify-start items-start"
>
<
div
className=
"w-[16rem] flex flex-col justify-start items-start"
>
...
@@ -173,7 +174,7 @@ const AddMemoRelationPopover = (props: Props) => {
...
@@ -173,7 +174,7 @@ const AddMemoRelationPopover = (props: Props) => {
/>
/>
<
div
className=
"mt-2 w-full flex flex-row justify-end items-center gap-2"
>
<
div
className=
"mt-2 w-full flex flex-row justify-end items-center gap-2"
>
<
Checkbox
size=
"sm"
label=
{
"Embed"
}
checked=
{
embedded
}
onChange=
{
(
e
)
=>
setEmbedded
(
e
.
target
.
checked
)
}
/>
<
Checkbox
size=
"sm"
label=
{
"Embed"
}
checked=
{
embedded
}
onChange=
{
(
e
)
=>
setEmbedded
(
e
.
target
.
checked
)
}
/>
<
Button
size=
"sm"
onClick=
{
addMemoRelations
}
disabled=
{
selectedMemos
.
length
===
0
}
>
<
Button
size=
"sm"
color=
"primary"
onClick=
{
addMemoRelations
}
disabled=
{
selectedMemos
.
length
===
0
}
>
{
t
(
"common.add"
)
}
{
t
(
"common.add"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/MemoEditor/ActionButton/LocationSelector.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Input
}
from
"@mui/joy"
;
import
{
Input
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
LatLng
}
from
"leaflet"
;
import
{
LatLng
}
from
"leaflet"
;
import
{
MapPinIcon
,
XIcon
}
from
"lucide-react"
;
import
{
MapPinIcon
,
XIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
...
@@ -94,7 +95,7 @@ const LocationSelector = (props: Props) => {
...
@@ -94,7 +95,7 @@ const LocationSelector = (props: Props) => {
return
(
return
(
<
Popover
open=
{
popoverOpen
}
onOpenChange=
{
setPopoverOpen
}
>
<
Popover
open=
{
popoverOpen
}
onOpenChange=
{
setPopoverOpen
}
>
<
PopoverTrigger
>
<
PopoverTrigger
>
<
IconButton
className=
"group"
size=
"sm"
component=
"div
"
>
<
Button
className=
"group px-2"
variant=
"plain
"
>
<
MapPinIcon
className=
"w-5 h-5 mx-auto shrink-0"
/>
<
MapPinIcon
className=
"w-5 h-5 mx-auto shrink-0"
/>
{
props
.
location
&&
(
{
props
.
location
&&
(
<>
<>
...
@@ -104,7 +105,7 @@ const LocationSelector = (props: Props) => {
...
@@ -104,7 +105,7 @@ const LocationSelector = (props: Props) => {
<
XIcon
className=
"w-5 h-5 mx-auto shrink-0 hidden group-hover:block opacity-60 hover:opacity-80"
onClick=
{
removeLocation
}
/>
<
XIcon
className=
"w-5 h-5 mx-auto shrink-0 hidden group-hover:block opacity-60 hover:opacity-80"
onClick=
{
removeLocation
}
/>
</>
</>
)
}
)
}
</
Icon
Button
>
</
Button
>
</
PopoverTrigger
>
</
PopoverTrigger
>
<
PopoverContent
align=
"center"
>
<
PopoverContent
align=
"center"
>
<
div
className=
"min-w-80 sm:w-128 flex flex-col justify-start items-start"
>
<
div
className=
"min-w-80 sm:w-128 flex flex-col justify-start items-start"
>
...
@@ -125,7 +126,7 @@ const LocationSelector = (props: Props) => {
...
@@ -125,7 +126,7 @@ const LocationSelector = (props: Props) => {
/>
/>
<
Button
<
Button
className=
"shrink-0"
className=
"shrink-0"
size=
"sm
"
color=
"primary
"
onClick=
{
()
=>
{
onClick=
{
()
=>
{
props
.
onChange
(
props
.
onChange
(
Location
.
fromPartial
({
Location
.
fromPartial
({
...
...
web/src/components/MemoEditor/ActionButton/MarkdownMenu.tsx
View file @
963706ae
import
{
Dropdown
,
IconButton
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
,
Link
}
from
"@mui/joy"
;
import
{
Link
}
from
"@mui/joy
"
;
import
{
Button
}
from
"@usememos/mui
"
;
import
{
CheckSquareIcon
,
Code2Icon
,
SquareSlashIcon
}
from
"lucide-react"
;
import
{
CheckSquareIcon
,
Code2Icon
,
SquareSlashIcon
}
from
"lucide-react"
;
import
{
EditorRefActions
}
from
"../Editor"
;
import
{
EditorRefActions
}
from
"../Editor"
;
...
@@ -60,10 +60,12 @@ const MarkdownMenu = (props: Props) => {
...
@@ -60,10 +60,12 @@ const MarkdownMenu = (props: Props) => {
return
(
return
(
<
Dropdown
>
<
Dropdown
>
<
MenuButton
<
MenuButton
slots=
{
{
root
:
Icon
Button
}
}
slots=
{
{
root
:
Button
}
}
slotProps=
{
{
slotProps=
{
{
root
:
{
root
:
{
size
:
"sm"
,
size
:
"sm"
,
variant
:
"plain"
,
className
:
"px-2"
,
},
},
}
}
}
}
>
>
...
...
web/src/components/MemoEditor/ActionButton/TagSelector.tsx
View file @
963706ae
import
{
Dropdown
,
IconButton
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
HashIcon
}
from
"lucide-react"
;
import
{
HashIcon
}
from
"lucide-react"
;
import
{
useRef
,
useState
}
from
"react"
;
import
{
useRef
,
useState
}
from
"react"
;
import
useClickAway
from
"react-use/lib/useClickAway"
;
import
useClickAway
from
"react-use/lib/useClickAway"
;
...
@@ -41,10 +42,12 @@ const TagSelector = (props: Props) => {
...
@@ -41,10 +42,12 @@ const TagSelector = (props: Props) => {
return
(
return
(
<
Dropdown
open=
{
open
}
onOpenChange=
{
(
_
,
isOpen
)
=>
setOpen
(
isOpen
)
}
>
<
Dropdown
open=
{
open
}
onOpenChange=
{
(
_
,
isOpen
)
=>
setOpen
(
isOpen
)
}
>
<
MenuButton
<
MenuButton
slots=
{
{
root
:
Icon
Button
}
}
slots=
{
{
root
:
Button
}
}
slotProps=
{
{
slotProps=
{
{
root
:
{
root
:
{
size
:
"sm"
,
size
:
"sm"
,
variant
:
"plain"
,
className
:
"px-2"
,
},
},
}
}
}
}
>
>
...
...
web/src/components/MemoEditor/ActionButton/UploadResourceButton.tsx
View file @
963706ae
import
{
IconButton
}
from
"@mui/joy
"
;
import
{
Button
}
from
"@usememos/mui
"
;
import
{
PaperclipIcon
}
from
"lucide-react"
;
import
{
PaperclipIcon
}
from
"lucide-react"
;
import
{
useContext
,
useRef
,
useState
}
from
"react"
;
import
{
useContext
,
useRef
,
useState
}
from
"react"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
...
@@ -66,7 +66,7 @@ const UploadResourceButton = () => {
...
@@ -66,7 +66,7 @@ const UploadResourceButton = () => {
};
};
return
(
return
(
<
IconButton
size=
"sm
"
disabled=
{
state
.
uploadingFlag
}
>
<
Button
className=
"px-2 relative"
size=
"sm"
variant=
"plain
"
disabled=
{
state
.
uploadingFlag
}
>
<
PaperclipIcon
className=
"w-5 h-5 mx-auto"
/>
<
PaperclipIcon
className=
"w-5 h-5 mx-auto"
/>
<
input
<
input
className=
"absolute inset-0 w-full h-full opacity-0 cursor-pointer"
className=
"absolute inset-0 w-full h-full opacity-0 cursor-pointer"
...
@@ -78,7 +78,7 @@ const UploadResourceButton = () => {
...
@@ -78,7 +78,7 @@ const UploadResourceButton = () => {
multiple=
{
true
}
multiple=
{
true
}
accept=
"*"
accept=
"*"
/>
/>
</
Icon
Button
>
</
Button
>
);
);
};
};
...
...
web/src/components/MemoEditor/index.tsx
View file @
963706ae
import
{
Select
,
Option
,
Button
,
Divider
}
from
"@mui/joy"
;
import
{
Select
,
Option
,
Divider
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
SendIcon
}
from
"lucide-react"
;
import
{
LoaderIcon
,
SendIcon
}
from
"lucide-react"
;
import
React
,
{
useEffect
,
useMemo
,
useRef
,
useState
}
from
"react"
;
import
React
,
{
useEffect
,
useMemo
,
useRef
,
useState
}
from
"react"
;
import
DatePicker
from
"react-datepicker"
;
import
DatePicker
from
"react-datepicker"
;
import
"react-datepicker/dist/react-datepicker.css"
;
import
"react-datepicker/dist/react-datepicker.css"
;
...
@@ -442,7 +443,7 @@ const MemoEditor = (props: Props) => {
...
@@ -442,7 +443,7 @@ const MemoEditor = (props: Props) => {
<
ResourceListView
resourceList=
{
state
.
resourceList
}
setResourceList=
{
handleSetResourceList
}
/>
<
ResourceListView
resourceList=
{
state
.
resourceList
}
setResourceList=
{
handleSetResourceList
}
/>
<
RelationListView
relationList=
{
referenceRelations
}
setRelationList=
{
handleSetRelationList
}
/>
<
RelationListView
relationList=
{
referenceRelations
}
setRelationList=
{
handleSetRelationList
}
/>
<
div
className=
"relative w-full flex flex-row justify-between items-center pt-2"
onFocus=
{
(
e
)
=>
e
.
stopPropagation
()
}
>
<
div
className=
"relative w-full flex flex-row justify-between items-center pt-2"
onFocus=
{
(
e
)
=>
e
.
stopPropagation
()
}
>
<
div
className=
"flex flex-row justify-start items-center opacity-80 dark:opacity-60"
>
<
div
className=
"flex flex-row justify-start items-center opacity-80 dark:opacity-60
-space-x-1
"
>
<
TagSelector
editorRef=
{
editorRef
}
/>
<
TagSelector
editorRef=
{
editorRef
}
/>
<
MarkdownMenu
editorRef=
{
editorRef
}
/>
<
MarkdownMenu
editorRef=
{
editorRef
}
/>
<
UploadResourceButton
/>
<
UploadResourceButton
/>
...
@@ -482,18 +483,13 @@ const MemoEditor = (props: Props) => {
...
@@ -482,18 +483,13 @@ const MemoEditor = (props: Props) => {
</
div
>
</
div
>
<
div
className=
"shrink-0 flex flex-row justify-end items-center gap-2"
>
<
div
className=
"shrink-0 flex flex-row justify-end items-center gap-2"
>
{
props
.
onCancel
&&
(
{
props
.
onCancel
&&
(
<
Button
className=
"!font-normal"
color=
"neutral"
variant=
"plain"
loading
=
{
state
.
isRequesting
}
onClick=
{
handleCancelBtnClick
}
>
<
Button
variant=
"plain"
disabled
=
{
state
.
isRequesting
}
onClick=
{
handleCancelBtnClick
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
)
}
)
}
<
Button
<
Button
color=
"primary"
disabled=
{
!
allowSave
||
state
.
isRequesting
}
onClick=
{
handleSaveBtnClick
}
>
className=
"!font-normal"
disabled=
{
!
allowSave
}
loading=
{
state
.
isRequesting
}
endDecorator=
{
<
SendIcon
className=
"w-4 h-auto"
/>
}
onClick=
{
handleSaveBtnClick
}
>
{
t
(
"editor.save"
)
}
{
t
(
"editor.save"
)
}
{
!
state
.
isRequesting
?
<
SendIcon
className=
"w-4 h-auto ml-1"
/>
:
<
LoaderIcon
className=
"w-4 h-auto ml-1 animate-spin"
/>
}
</
Button
>
</
Button
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/components/NavigationDrawer.tsx
View file @
963706ae
import
{
Drawer
,
IconButton
}
from
"@mui/joy"
;
import
{
Drawer
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
MenuIcon
}
from
"lucide-react"
;
import
{
MenuIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useLocation
}
from
"react-router-dom"
;
...
@@ -22,9 +23,9 @@ const NavigationDrawer = () => {
...
@@ -22,9 +23,9 @@ const NavigationDrawer = () => {
return
(
return
(
<>
<>
<
IconButton
onClick=
{
toggleDrawer
(
true
)
}
>
<
Button
variant=
"plain"
className=
"!bg-transparent px-2"
onClick=
{
toggleDrawer
(
true
)
}
>
<
MenuIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
<
MenuIcon
className=
"w-5 h-auto dark:text-gray-400"
/>
</
Icon
Button
>
</
Button
>
<
Drawer
anchor=
"left"
size=
"sm"
open=
{
open
}
onClose=
{
toggleDrawer
(
false
)
}
>
<
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"
>
<
div
className=
"w-full h-full overflow-auto px-4 bg-zinc-100 dark:bg-zinc-900"
>
<
Navigation
/>
<
Navigation
/>
...
...
web/src/components/PagedMemoList/PagedMemoList.tsx
View file @
963706ae
import
{
Button
}
from
"@
mui/joy
"
;
import
{
Button
}
from
"@
usememos/mui
"
;
import
{
ArrowDownIcon
,
LoaderIcon
}
from
"lucide-react"
;
import
{
ArrowDownIcon
,
LoaderIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
DEFAULT_LIST_MEMOS_PAGE_SIZE
}
from
"@/helpers/consts"
;
import
{
DEFAULT_LIST_MEMOS_PAGE_SIZE
}
from
"@/helpers/consts"
;
...
@@ -62,14 +62,9 @@ const PagedMemoList = (props: Props) => {
...
@@ -62,14 +62,9 @@ const PagedMemoList = (props: Props) => {
)
}
)
}
{
!
state
.
isRequesting
&&
state
.
nextPageToken
&&
(
{
!
state
.
isRequesting
&&
state
.
nextPageToken
&&
(
<
div
className=
"w-full flex flex-row justify-center items-center my-4"
>
<
div
className=
"w-full flex flex-row justify-center items-center my-4"
>
<
Button
<
Button
variant=
"plain"
onClick=
{
()
=>
fetchMoreMemos
(
state
.
nextPageToken
)
}
>
variant=
"plain"
color=
"neutral"
loading=
{
state
.
isRequesting
}
endDecorator=
{
<
ArrowDownIcon
className=
"w-4 h-auto"
/>
}
onClick=
{
()
=>
fetchMoreMemos
(
state
.
nextPageToken
)
}
>
{
t
(
"memo.load-more"
)
}
{
t
(
"memo.load-more"
)
}
<
ArrowDownIcon
className=
"ml-2 w-4 h-auto"
/>
</
Button
>
</
Button
>
</
div
>
</
div
>
)
}
)
}
...
...
web/src/components/PasswordSignInForm.tsx
View file @
963706ae
import
{
Button
,
Checkbox
,
Input
}
from
"@mui/joy"
;
import
{
Checkbox
,
Input
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
LoaderIcon
}
from
"lucide-react"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -108,14 +110,15 @@ const PasswordSignInForm = () => {
...
@@ -108,14 +110,15 @@ const PasswordSignInForm = () => {
</
div
>
</
div
>
<
div
className=
"flex flex-row justify-end items-center w-full mt-6"
>
<
div
className=
"flex flex-row justify-end items-center w-full mt-6"
>
<
Button
<
Button
className=
"w-full"
size=
"md"
type=
"submit"
type=
"submit"
color=
"primary"
size=
"lg"
fullWidth
disabled=
{
actionBtnLoadingState
.
isLoading
}
disabled=
{
actionBtnLoadingState
.
isLoading
}
loading=
{
actionBtnLoadingState
.
isLoading
}
onClick=
{
handleSignInButtonClick
}
onClick=
{
handleSignInButtonClick
}
>
>
{
t
(
"common.sign-in"
)
}
{
t
(
"common.sign-in"
)
}
{
actionBtnLoadingState
.
isLoading
&&
<
LoaderIcon
className=
"w-5 h-auto ml-2 animate-spin opacity-60"
/>
}
</
Button
>
</
Button
>
</
div
>
</
div
>
</
form
>
</
form
>
...
...
web/src/components/RenameTagDialog.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Input
,
List
,
ListItem
}
from
"@mui/joy"
;
import
{
Input
,
List
,
ListItem
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
XIcon
}
from
"lucide-react"
;
import
React
,
{
useState
}
from
"react"
;
import
React
,
{
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -54,9 +55,9 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
...
@@ -54,9 +55,9 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
<>
<>
<
div
className=
"dialog-header-container"
>
<
div
className=
"dialog-header-container"
>
<
p
className=
"title-text"
>
{
"Rename tag"
}
</
p
>
<
p
className=
"title-text"
>
{
"Rename tag"
}
</
p
>
<
IconButton
size=
"sm
"
onClick=
{
()
=>
destroy
()
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
()
=>
destroy
()
}
>
<
XIcon
className=
"w-5 h-auto"
/>
<
XIcon
className=
"w-5 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container max-w-xs"
>
<
div
className=
"dialog-content-container max-w-xs"
>
<
div
className=
"w-full flex flex-col justify-start items-start mb-3"
>
<
div
className=
"w-full flex flex-col justify-start items-start mb-3"
>
...
@@ -82,10 +83,10 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
...
@@ -82,10 +83,10 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
</
List
>
</
List
>
</
div
>
</
div
>
<
div
className=
"w-full flex flex-row justify-end items-center space-x-2"
>
<
div
className=
"w-full flex flex-row justify-end items-center space-x-2"
>
<
Button
color=
"neutral"
variant=
"plain"
disabled=
{
requestState
.
isLoading
}
loading
=
{
requestState
.
isLoading
}
onClick=
{
destroy
}
>
<
Button
variant=
"plain"
disabled
=
{
requestState
.
isLoading
}
onClick=
{
destroy
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
<
Button
color=
"primary"
disabled=
{
requestState
.
isLoading
}
loading=
{
requestState
.
isLoading
}
onClick=
{
handleConfirm
}
>
<
Button
color=
"primary"
disabled=
{
requestState
.
isLoading
}
onClick=
{
handleConfirm
}
>
{
t
(
"common.confirm"
)
}
{
t
(
"common.confirm"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/Settings/AccessTokenSection.tsx
View file @
963706ae
import
{
Button
,
IconButton
}
from
"@mui/joy
"
;
import
{
Button
}
from
"@usememos/mui
"
;
import
copy
from
"copy-to-clipboard"
;
import
copy
from
"copy-to-clipboard"
;
import
{
ClipboardIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
ClipboardIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
...
@@ -63,8 +63,7 @@ const AccessTokenSection = () => {
...
@@ -63,8 +63,7 @@ const AccessTokenSection = () => {
</
div
>
</
div
>
<
div
className=
"mt-4 sm:mt-0"
>
<
div
className=
"mt-4 sm:mt-0"
>
<
Button
<
Button
variant=
"outlined"
color=
"primary"
color=
"neutral"
onClick=
{
()
=>
{
onClick=
{
()
=>
{
showCreateAccessTokenDialog
(
handleCreateAccessTokenDialogConfirm
);
showCreateAccessTokenDialog
(
handleCreateAccessTokenDialogConfirm
);
}
}
}
}
...
@@ -101,9 +100,9 @@ const AccessTokenSection = () => {
...
@@ -101,9 +100,9 @@ const AccessTokenSection = () => {
<
tr
key=
{
userAccessToken
.
accessToken
}
>
<
tr
key=
{
userAccessToken
.
accessToken
}
>
<
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"
>
<
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
>
<
span
className=
"font-mono"
>
{
getFormatedAccessToken
(
userAccessToken
.
accessToken
)
}
</
span
>
<
IconButton
color=
"neutral"
variant=
"plain"
size=
"sm"
onClick=
{
()
=>
copyAccessToken
(
userAccessToken
.
accessToken
)
}
>
<
Button
variant=
"plain"
size=
"sm"
onClick=
{
()
=>
copyAccessToken
(
userAccessToken
.
accessToken
)
}
>
<
ClipboardIcon
className=
"w-4 h-auto text-gray-400"
/>
<
ClipboardIcon
className=
"w-4 h-auto text-gray-400"
/>
</
Icon
Button
>
</
Button
>
</
td
>
</
td
>
<
td
className=
"whitespace-nowrap py-2 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-400"
>
<
td
className=
"whitespace-nowrap py-2 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-400"
>
{
userAccessToken
.
description
}
{
userAccessToken
.
description
}
...
@@ -115,16 +114,15 @@ const AccessTokenSection = () => {
...
@@ -115,16 +114,15 @@ const AccessTokenSection = () => {
{
userAccessToken
.
expiresAt
?.
toLocaleString
()
??
"Never"
}
{
userAccessToken
.
expiresAt
?.
toLocaleString
()
??
"Never"
}
</
td
>
</
td
>
<
td
className=
"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm"
>
<
td
className=
"relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm"
>
<
IconButton
<
Button
color=
"danger"
variant=
"plain"
variant=
"plain"
size=
"sm"
size=
"sm"
onClick=
{
()
=>
{
onClick=
{
()
=>
{
handleDeleteAccessToken
(
userAccessToken
.
accessToken
);
handleDeleteAccessToken
(
userAccessToken
.
accessToken
);
}
}
}
}
>
>
<
TrashIcon
className=
"w-4 h-auto"
/>
<
TrashIcon
className=
"
text-red-600
w-4 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
td
>
</
td
>
</
tr
>
</
tr
>
))
}
))
}
...
...
web/src/components/Settings/MemberSection.tsx
View file @
963706ae
import
{
Button
,
Dropdown
,
Input
,
Menu
,
MenuButton
,
MenuItem
,
Radio
,
RadioGroup
}
from
"@mui/joy"
;
import
{
Dropdown
,
Input
,
Menu
,
MenuButton
,
MenuItem
,
Radio
,
RadioGroup
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
sortBy
}
from
"lodash-es"
;
import
{
sortBy
}
from
"lodash-es"
;
import
{
MoreVerticalIcon
}
from
"lucide-react"
;
import
{
MoreVerticalIcon
}
from
"lucide-react"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
import
React
,
{
useEffect
,
useState
}
from
"react"
;
...
@@ -158,7 +159,9 @@ const MemberSection = () => {
...
@@ -158,7 +159,9 @@ const MemberSection = () => {
</
RadioGroup
>
</
RadioGroup
>
</
div
>
</
div
>
<
div
className=
"mt-2"
>
<
div
className=
"mt-2"
>
<
Button
onClick=
{
handleCreateUserBtnClick
}
>
{
t
(
"common.create"
)
}
</
Button
>
<
Button
color=
"primary"
onClick=
{
handleCreateUserBtnClick
}
>
{
t
(
"common.create"
)
}
</
Button
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center mt-6"
>
<
div
className=
"w-full flex flex-row justify-between items-center mt-6"
>
...
...
web/src/components/Settings/MemoRelatedSettings.tsx
View file @
963706ae
import
{
Button
,
Input
,
Switch
,
Select
,
Option
,
Chip
,
ChipDelete
}
from
"@mui/joy"
;
import
{
Input
,
Switch
,
Select
,
Option
,
Chip
,
ChipDelete
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
isEqual
,
uniq
}
from
"lodash-es"
;
import
{
isEqual
,
uniq
}
from
"lodash-es"
;
import
{
CheckIcon
}
from
"lucide-react"
;
import
{
CheckIcon
}
from
"lucide-react"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
...
@@ -179,7 +180,7 @@ const MemoRelatedSettings = () => {
...
@@ -179,7 +180,7 @@ const MemoRelatedSettings = () => {
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"mt-2 w-full flex justify-end"
>
<
div
className=
"mt-2 w-full flex justify-end"
>
<
Button
disabled=
{
isEqual
(
memoRelatedSetting
,
originalSetting
)
}
onClick=
{
updateSetting
}
>
<
Button
color=
"primary"
disabled=
{
isEqual
(
memoRelatedSetting
,
originalSetting
)
}
onClick=
{
updateSetting
}
>
{
t
(
"common.save"
)
}
{
t
(
"common.save"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/Settings/MyAccountSection.tsx
View file @
963706ae
import
{
Button
,
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
MoreVerticalIcon
,
PenLineIcon
}
from
"lucide-react"
;
import
{
MoreVerticalIcon
,
PenLineIcon
}
from
"lucide-react"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
showChange
PasswordDialog
from
"../Change
PasswordDialog"
;
import
showChange
MemberPasswordDialog
from
"../ChangeMember
PasswordDialog"
;
import
showUpdateAccountDialog
from
"../UpdateAccountDialog"
;
import
showUpdateAccountDialog
from
"../UpdateAccountDialog"
;
import
UserAvatar
from
"../UserAvatar"
;
import
UserAvatar
from
"../UserAvatar"
;
import
AccessTokenSection
from
"./AccessTokenSection"
;
import
AccessTokenSection
from
"./AccessTokenSection"
;
...
@@ -25,18 +26,18 @@ const MyAccountSection = () => {
...
@@ -25,18 +26,18 @@ const MyAccountSection = () => {
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"w-full flex flex-row justify-start items-center mt-2 space-x-2"
>
<
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
}
>
<
Button
variant=
"outlined"
size=
"sm"
onClick=
{
showUpdateAccountDialog
}
>
<
PenLineIcon
className=
"w-4 h-4 mx-auto mr-1"
/>
<
PenLineIcon
className=
"w-4 h-4 mx-auto mr-1"
/>
{
t
(
"common.edit"
)
}
{
t
(
"common.edit"
)
}
</
Button
>
</
Button
>
<
Dropdown
>
<
Dropdown
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
Button
variant=
"outlined"
color=
"neutral"
size=
"sm"
>
<
Button
variant=
"outlined"
size=
"sm"
>
<
MoreVerticalIcon
className=
"w-4 h-4 mx-auto"
/>
<
MoreVerticalIcon
className=
"w-4 h-4 mx-auto"
/>
</
Button
>
</
Button
>
</
MenuButton
>
</
MenuButton
>
<
Menu
className=
"text-sm"
size=
"sm"
placement=
"bottom"
>
<
Menu
className=
"text-sm"
size=
"sm"
placement=
"bottom"
>
<
MenuItem
onClick=
{
showChangePasswordDialog
}
>
{
t
(
"setting.account-section.change-password"
)
}
</
MenuItem
>
<
MenuItem
onClick=
{
()
=>
showChangeMemberPasswordDialog
(
user
)
}
>
{
t
(
"setting.account-section.change-password"
)
}
</
MenuItem
>
</
Menu
>
</
Menu
>
</
Dropdown
>
</
Dropdown
>
</
div
>
</
div
>
...
...
web/src/components/Settings/SSOSection.tsx
View file @
963706ae
import
{
Button
,
Divider
,
Dropdown
,
List
,
ListItem
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Divider
,
Dropdown
,
List
,
ListItem
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
MoreVerticalIcon
}
from
"lucide-react"
;
import
{
MoreVerticalIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -42,7 +43,9 @@ const SSOSection = () => {
...
@@ -42,7 +43,9 @@ const SSOSection = () => {
<
span
className=
"font-mono text-gray-400"
>
{
t
(
"setting.sso-section.sso-list"
)
}
</
span
>
<
span
className=
"font-mono text-gray-400"
>
{
t
(
"setting.sso-section.sso-list"
)
}
</
span
>
<
LearnMore
url=
"https://usememos.com/docs/advanced-settings/keycloak"
/>
<
LearnMore
url=
"https://usememos.com/docs/advanced-settings/keycloak"
/>
</
div
>
</
div
>
<
Button
onClick=
{
()
=>
showCreateIdentityProviderDialog
(
undefined
,
fetchIdentityProviderList
)
}
>
{
t
(
"common.create"
)
}
</
Button
>
<
Button
color=
"primary"
onClick=
{
()
=>
showCreateIdentityProviderDialog
(
undefined
,
fetchIdentityProviderList
)
}
>
{
t
(
"common.create"
)
}
</
Button
>
</
div
>
</
div
>
<
Divider
/>
<
Divider
/>
{
identityProviderList
.
map
((
identityProvider
)
=>
(
{
identityProviderList
.
map
((
identityProvider
)
=>
(
...
...
web/src/components/Settings/StorageSection.tsx
View file @
963706ae
import
{
Button
,
Divider
,
Input
,
List
,
ListItem
,
Radio
,
RadioGroup
,
Tooltip
}
from
"@mui/joy"
;
import
{
Divider
,
Input
,
List
,
ListItem
,
Radio
,
RadioGroup
,
Tooltip
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
HelpCircleIcon
}
from
"lucide-react"
;
import
{
HelpCircleIcon
}
from
"lucide-react"
;
import
{
useMemo
,
useState
}
from
"react"
;
import
{
useMemo
,
useState
}
from
"react"
;
...
@@ -183,7 +184,7 @@ const StorageSection = () => {
...
@@ -183,7 +184,7 @@ const StorageSection = () => {
</>
</>
)
}
)
}
<
div
>
<
div
>
<
Button
disabled=
{
!
allowSaveStorageSetting
}
onClick=
{
saveWorkspaceStorageSetting
}
>
<
Button
color=
"primary"
disabled=
{
!
allowSaveStorageSetting
}
onClick=
{
saveWorkspaceStorageSetting
}
>
{
t
(
"common.save"
)
}
{
t
(
"common.save"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/Settings/WebhookSection.tsx
View file @
963706ae
import
{
Button
,
IconButton
}
from
"@mui/joy
"
;
import
{
Button
}
from
"@usememos/mui
"
;
import
{
ExternalLinkIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
ExternalLinkIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
...
@@ -47,8 +47,7 @@ const WebhookSection = () => {
...
@@ -47,8 +47,7 @@ const WebhookSection = () => {
</
div
>
</
div
>
<
div
>
<
div
>
<
Button
<
Button
variant=
"outlined"
color=
"primary"
color=
"neutral"
onClick=
{
()
=>
{
onClick=
{
()
=>
{
showCreateWebhookDialog
(
handleCreateAccessTokenDialogConfirm
);
showCreateWebhookDialog
(
handleCreateAccessTokenDialogConfirm
);
}
}
}
}
...
@@ -80,16 +79,15 @@ const WebhookSection = () => {
...
@@ -80,16 +79,15 @@ const WebhookSection = () => {
<
td
className=
"whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400"
>
{
webhook
.
name
}
</
td
>
<
td
className=
"whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400"
>
{
webhook
.
name
}
</
td
>
<
td
className=
"whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400"
>
{
webhook
.
url
}
</
td
>
<
td
className=
"whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400"
>
{
webhook
.
url
}
</
td
>
<
td
className=
"relative whitespace-nowrap px-3 py-2 text-right text-sm"
>
<
td
className=
"relative whitespace-nowrap px-3 py-2 text-right text-sm"
>
<
IconButton
<
Button
color=
"danger"
variant=
"plain"
variant=
"plain"
size=
"sm"
size=
"sm"
onClick=
{
()
=>
{
onClick=
{
()
=>
{
handleDeleteWebhook
(
webhook
);
handleDeleteWebhook
(
webhook
);
}
}
}
}
>
>
<
TrashIcon
className=
"w-4 h-auto"
/>
<
TrashIcon
className=
"
text-red-600
w-4 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
td
>
</
td
>
</
tr
>
</
tr
>
))
}
))
}
...
...
web/src/components/Settings/WorkspaceSection.tsx
View file @
963706ae
import
{
Button
,
Select
,
Textarea
,
Option
,
Divider
,
Switch
}
from
"@mui/joy"
;
import
{
Select
,
Textarea
,
Option
,
Divider
,
Switch
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
ExternalLinkIcon
}
from
"lucide-react"
;
import
{
ExternalLinkIcon
}
from
"lucide-react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
...
@@ -57,7 +58,7 @@ const WorkspaceSection = () => {
...
@@ -57,7 +58,7 @@ const WorkspaceSection = () => {
{
t
(
"setting.system-section.server-name"
)
}
:
{
" "
}
{
t
(
"setting.system-section.server-name"
)
}
:
{
" "
}
<
span
className=
"font-mono font-bold"
>
{
workspaceGeneralSetting
.
customProfile
?.
title
||
"Memos"
}
</
span
>
<
span
className=
"font-mono font-bold"
>
{
workspaceGeneralSetting
.
customProfile
?.
title
||
"Memos"
}
</
span
>
</
div
>
</
div
>
<
Button
variant=
"outlined"
color=
"neutral"
onClick=
{
handleUpdateCustomizedProfileButtonClick
}
>
<
Button
variant=
"outlined"
onClick=
{
handleUpdateCustomizedProfileButtonClick
}
>
{
t
(
"common.edit"
)
}
{
t
(
"common.edit"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
@@ -147,7 +148,7 @@ const WorkspaceSection = () => {
...
@@ -147,7 +148,7 @@ const WorkspaceSection = () => {
</
Select
>
</
Select
>
</
div
>
</
div
>
<
div
className=
"mt-2 w-full flex justify-end"
>
<
div
className=
"mt-2 w-full flex justify-end"
>
<
Button
disabled=
{
isEqual
(
workspaceGeneralSetting
,
originalSetting
)
}
onClick=
{
handleSaveGeneralSetting
}
>
<
Button
color=
"primary"
disabled=
{
isEqual
(
workspaceGeneralSetting
,
originalSetting
)
}
onClick=
{
handleSaveGeneralSetting
}
>
{
t
(
"common.save"
)
}
{
t
(
"common.save"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
...
...
web/src/components/UpdateAccountDialog.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Input
,
Textarea
}
from
"@mui/joy"
;
import
{
Input
,
Textarea
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
...
@@ -146,9 +147,9 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
...
@@ -146,9 +147,9 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
<>
<>
<
div
className=
"dialog-header-container !w-64"
>
<
div
className=
"dialog-header-container !w-64"
>
<
p
className=
"title-text"
>
{
t
(
"setting.account-section.update-information"
)
}
</
p
>
<
p
className=
"title-text"
>
{
t
(
"setting.account-section.update-information"
)
}
</
p
>
<
IconButton
size=
"sm
"
onClick=
{
handleCloseBtnClick
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
handleCloseBtnClick
}
>
<
XIcon
className=
"w-5 h-auto"
/>
<
XIcon
className=
"w-5 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container space-y-2"
>
<
div
className=
"dialog-content-container space-y-2"
>
<
div
className=
"w-full flex flex-row justify-start items-center"
>
<
div
className=
"w-full flex flex-row justify-start items-center"
>
...
@@ -203,7 +204,7 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
...
@@ -203,7 +204,7 @@ const UpdateAccountDialog: React.FC<Props> = ({ destroy }: Props) => {
onChange=
{
handleDescriptionChanged
}
onChange=
{
handleDescriptionChanged
}
/>
/>
<
div
className=
"w-full flex flex-row justify-end items-center pt-4 space-x-2"
>
<
div
className=
"w-full flex flex-row justify-end items-center pt-4 space-x-2"
>
<
Button
color=
"neutral"
variant=
"plain"
onClick=
{
handleCloseBtnClick
}
>
<
Button
variant=
"plain"
onClick=
{
handleCloseBtnClick
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
<
Button
color=
"primary"
onClick=
{
handleSaveBtnClick
}
>
<
Button
color=
"primary"
onClick=
{
handleSaveBtnClick
}
>
...
...
web/src/components/UpdateCustomizedProfileDialog.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Input
}
from
"@mui/joy"
;
import
{
Input
}
from
"@mui/joy"
;
import
Textarea
from
"@mui/joy/Textarea/Textarea"
;
import
Textarea
from
"@mui/joy/Textarea/Textarea"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
XIcon
}
from
"lucide-react"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -102,9 +103,9 @@ const UpdateCustomizedProfileDialog: React.FC<Props> = ({ destroy }: Props) => {
...
@@ -102,9 +103,9 @@ const UpdateCustomizedProfileDialog: React.FC<Props> = ({ destroy }: Props) => {
<>
<>
<
div
className=
"dialog-header-container"
>
<
div
className=
"dialog-header-container"
>
<
p
className=
"title-text"
>
{
t
(
"setting.system-section.customize-server.title"
)
}
</
p
>
<
p
className=
"title-text"
>
{
t
(
"setting.system-section.customize-server.title"
)
}
</
p
>
<
IconButton
size=
"sm
"
onClick=
{
handleCloseButtonClick
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
handleCloseButtonClick
}
>
<
XIcon
className=
"w-5 h-auto"
/>
<
XIcon
className=
"w-5 h-auto"
/>
</
Icon
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"dialog-content-container min-w-[16rem]"
>
<
div
className=
"dialog-content-container min-w-[16rem]"
>
<
p
className=
"text-sm mb-1"
>
{
t
(
"setting.system-section.server-name"
)
}
</
p
>
<
p
className=
"text-sm mb-1"
>
{
t
(
"setting.system-section.server-name"
)
}
</
p
>
...
@@ -123,11 +124,13 @@ const UpdateCustomizedProfileDialog: React.FC<Props> = ({ destroy }: Props) => {
...
@@ -123,11 +124,13 @@ const UpdateCustomizedProfileDialog: React.FC<Props> = ({ destroy }: Props) => {
{
t
(
"common.restore"
)
}
{
t
(
"common.restore"
)
}
</
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"flex flex-row justify-end items-center"
>
<
div
className=
"flex flex-row justify-end items-center
gap-2
"
>
<
Button
variant=
"plain"
onClick=
{
handleCloseButtonClick
}
>
<
Button
variant=
"plain"
onClick=
{
handleCloseButtonClick
}
>
{
t
(
"common.cancel"
)
}
{
t
(
"common.cancel"
)
}
</
Button
>
</
Button
>
<
Button
onClick=
{
handleSaveButtonClick
}
>
{
t
(
"common.save"
)
}
</
Button
>
<
Button
color=
"primary"
onClick=
{
handleSaveButtonClick
}
>
{
t
(
"common.save"
)
}
</
Button
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/components/UserBanner.tsx
View file @
963706ae
...
@@ -24,7 +24,7 @@ const UserBanner = (props: Props) => {
...
@@ -24,7 +24,7 @@ const UserBanner = (props: Props) => {
const
workspaceGeneralSetting
=
const
workspaceGeneralSetting
=
workspaceSettingStore
.
getWorkspaceSettingByKey
(
WorkspaceSettingKey
.
GENERAL
).
generalSetting
||
WorkspaceGeneralSetting
.
fromPartial
({});
workspaceSettingStore
.
getWorkspaceSettingByKey
(
WorkspaceSettingKey
.
GENERAL
).
generalSetting
||
WorkspaceGeneralSetting
.
fromPartial
({});
const
title
=
(
user
?
user
.
nickname
||
user
.
username
:
workspaceGeneralSetting
.
customProfile
?.
title
)
||
"Memos"
;
const
title
=
(
user
?
user
.
nickname
||
user
.
username
:
workspaceGeneralSetting
.
customProfile
?.
title
)
||
"Memos"
;
const
avatarUrl
=
(
user
?
user
.
avatarUrl
:
workspaceGeneralSetting
.
customProfile
?.
logoUrl
)
||
"/logo.webp"
;
const
avatarUrl
=
(
user
?
user
.
avatarUrl
:
workspaceGeneralSetting
.
customProfile
?.
logoUrl
)
||
"/
full-
logo.webp"
;
const
handleSignOut
=
async
()
=>
{
const
handleSignOut
=
async
()
=>
{
await
authServiceClient
.
signOut
({});
await
authServiceClient
.
signOut
({});
...
@@ -37,11 +37,11 @@ const UserBanner = (props: Props) => {
...
@@ -37,11 +37,11 @@ const UserBanner = (props: Props) => {
<
MenuButton
disabled=
{
!
user
}
slots=
{
{
root
:
"div"
}
}
>
<
MenuButton
disabled=
{
!
user
}
slots=
{
{
root
:
"div"
}
}
>
<
div
<
div
className=
{
clsx
(
className=
{
clsx
(
"py-1 my-1 w-auto flex flex-row justify-start items-center cursor-pointer
rounded-2xl border border-transparent
text-gray-800 dark:text-gray-400"
,
"py-1 my-1 w-auto flex flex-row justify-start items-center cursor-pointer text-gray-800 dark:text-gray-400"
,
collapsed
?
"px-1"
:
"px-3"
,
collapsed
?
"px-1"
:
"px-3"
,
)
}
)
}
>
>
<
UserAvatar
className=
"sh
adow sh
rink-0"
avatarUrl=
{
avatarUrl
}
/>
<
UserAvatar
className=
"shrink-0"
avatarUrl=
{
avatarUrl
}
/>
{
!
collapsed
&&
<
span
className=
"ml-2 text-lg font-medium text-slate-800 dark:text-gray-300 shrink truncate"
>
{
title
}
</
span
>
}
{
!
collapsed
&&
<
span
className=
"ml-2 text-lg font-medium text-slate-800 dark:text-gray-300 shrink truncate"
>
{
title
}
</
span
>
}
</
div
>
</
div
>
</
MenuButton
>
</
MenuButton
>
...
...
web/src/components/UserStatisticsView.tsx
View file @
963706ae
import
{
Divider
,
IconButton
,
Tooltip
}
from
"@mui/joy"
;
import
{
Divider
,
Tooltip
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
clsx
from
"clsx"
;
import
clsx
from
"clsx"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
countBy
}
from
"lodash-es"
;
import
{
countBy
}
from
"lodash-es"
;
...
@@ -81,12 +82,20 @@ const UserStatisticsView = () => {
...
@@ -81,12 +82,20 @@ const UserStatisticsView = () => {
<
MoreVerticalIcon
className=
"w-4 h-auto shrink-0 opacity-60"
/>
<
MoreVerticalIcon
className=
"w-4 h-auto shrink-0 opacity-60"
/>
</
PopoverTrigger
>
</
PopoverTrigger
>
<
PopoverContent
className=
"flex flex-row justify-end items-center"
align=
"end"
alignOffset=
{
-
12
}
>
<
PopoverContent
className=
"flex flex-row justify-end items-center"
align=
"end"
alignOffset=
{
-
12
}
>
<
IconButton
size=
"sm"
onClick=
{
()
=>
setVisibleMonthString
(
dayjs
(
visibleMonthString
).
subtract
(
1
,
"month"
).
format
(
"YYYY-MM"
))
}
>
<
Button
size=
"sm"
variant=
"plain"
onClick=
{
()
=>
setVisibleMonthString
(
dayjs
(
visibleMonthString
).
subtract
(
1
,
"month"
).
format
(
"YYYY-MM"
))
}
>
<
ChevronLeftIcon
className=
"w-5 h-auto shrink-0 opacity-60"
/>
<
ChevronLeftIcon
className=
"w-5 h-auto shrink-0 opacity-60"
/>
</
IconButton
>
</
Button
>
<
IconButton
size=
"sm"
onClick=
{
()
=>
setVisibleMonthString
(
dayjs
(
visibleMonthString
).
add
(
1
,
"month"
).
format
(
"YYYY-MM"
))
}
>
<
Button
size=
"sm"
variant=
"plain"
onClick=
{
()
=>
setVisibleMonthString
(
dayjs
(
visibleMonthString
).
add
(
1
,
"month"
).
format
(
"YYYY-MM"
))
}
>
<
ChevronRightIcon
className=
"w-5 h-auto shrink-0 opacity-60"
/>
<
ChevronRightIcon
className=
"w-5 h-auto shrink-0 opacity-60"
/>
</
Icon
Button
>
</
Button
>
</
PopoverContent
>
</
PopoverContent
>
</
Popover
>
</
Popover
>
</
div
>
</
div
>
...
...
web/src/components/ui/Popover.tsx
View file @
963706ae
...
@@ -17,7 +17,7 @@ const PopoverContent = React.forwardRef<
...
@@ -17,7 +17,7 @@ const PopoverContent = React.forwardRef<
align=
{
align
}
align=
{
align
}
sideOffset=
{
sideOffset
}
sideOffset=
{
sideOffset
}
className=
{
clsx
(
className=
{
clsx
(
"z-[2000] w-auto rounded-md border dark:border-zinc-800 bg-popover p-2 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
,
"z-[2000] w-auto rounded-md b
g-white dark:bg-zinc-900 b
order dark:border-zinc-800 bg-popover p-2 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
,
className
,
className
,
)
}
)
}
{
...
props
}
{
...
props
}
...
...
web/src/css/global.css
deleted
100644 → 0
View file @
8635aed1
body
{
@apply
text-base
w-full
min-h-[100svh]
bg-zinc-100
dark
:
bg-zinc-900
;
}
#root
{
@apply
relative
w-full
min-h-full;
}
html
.dark
{
color-scheme
:
dark
;
scrollbar-color
:
hsla
(
0
,
0%
,
100%
,
0.4
)
hsla
(
0
,
0%
,
100%
,
0.029
);
}
html
.light
{
color-scheme
:
light
;
}
web/src/css/tailwind.css
View file @
963706ae
...
@@ -2,63 +2,6 @@
...
@@ -2,63 +2,6 @@
@tailwind
components
;
@tailwind
components
;
@tailwind
utilities
;
@tailwind
utilities
;
@layer
base
{
:root
{
--background
:
0
0%
100%
;
--foreground
:
240
10%
3.9%
;
--card
:
0
0%
100%
;
--card-foreground
:
240
10%
3.9%
;
--popover
:
0
0%
100%
;
--popover-foreground
:
240
10%
3.9%
;
--primary
:
240
5.9%
10%
;
--primary-foreground
:
0
0%
98%
;
--secondary
:
240
4.8%
95.9%
;
--secondary-foreground
:
240
5.9%
10%
;
--muted
:
240
4.8%
95.9%
;
--muted-foreground
:
240
3.8%
46.1%
;
--accent
:
240
4.8%
95.9%
;
--accent-foreground
:
240
5.9%
10%
;
--destructive
:
0
84.2%
60.2%
;
--destructive-foreground
:
0
0%
98%
;
--border
:
240
5.9%
90%
;
--input
:
240
5.9%
90%
;
--ring
:
240
10%
3.9%
;
--radius
:
0.5rem
;
--chart-1
:
12
76%
61%
;
--chart-2
:
173
58%
39%
;
--chart-3
:
197
37%
24%
;
--chart-4
:
43
74%
66%
;
--chart-5
:
27
87%
67%
;
}
.dark
{
--background
:
240
10%
3.9%
;
--foreground
:
0
0%
98%
;
--card
:
240
10%
3.9%
;
--card-foreground
:
0
0%
98%
;
--popover
:
240
10%
3.9%
;
--popover-foreground
:
0
0%
98%
;
--primary
:
0
0%
98%
;
--primary-foreground
:
240
5.9%
10%
;
--secondary
:
240
3.7%
15.9%
;
--secondary-foreground
:
0
0%
98%
;
--muted
:
240
3.7%
15.9%
;
--muted-foreground
:
240
5%
64.9%
;
--accent
:
240
3.7%
15.9%
;
--accent-foreground
:
0
0%
98%
;
--destructive
:
0
62.8%
30.6%
;
--destructive-foreground
:
0
0%
98%
;
--border
:
240
3.7%
15.9%
;
--input
:
240
3.7%
15.9%
;
--ring
:
240
4.9%
83.9%
;
--chart-1
:
220
70%
50%
;
--chart-2
:
160
60%
45%
;
--chart-3
:
30
80%
55%
;
--chart-4
:
280
65%
60%
;
--chart-5
:
340
75%
55%
;
}
}
@layer
utilities
{
@layer
utilities
{
.hide-scrollbar
{
.hide-scrollbar
{
-ms-overflow-style
:
none
;
/* IE and Edge */
-ms-overflow-style
:
none
;
/* IE and Edge */
...
@@ -75,3 +18,10 @@
...
@@ -75,3 +18,10 @@
word-break
:
normal
;
word-break
:
normal
;
}
}
}
}
html
.dark
{
color-scheme
:
dark
;
}
html
.light
{
color-scheme
:
light
;
}
web/src/layouts/RootLayout.tsx
View file @
963706ae
import
{
Button
,
IconButton
,
Tooltip
}
from
"@mui/joy"
;
import
{
Tooltip
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
clsx
from
"clsx"
;
import
clsx
from
"clsx"
;
import
{
ChevronLeftIcon
,
ChevronRightIcon
}
from
"lucide-react"
;
import
{
ChevronLeftIcon
,
ChevronRightIcon
}
from
"lucide-react"
;
import
{
Suspense
,
useEffect
,
useState
}
from
"react"
;
import
{
Suspense
,
useEffect
,
useState
}
from
"react"
;
...
@@ -55,14 +56,15 @@ const RootLayout = () => {
...
@@ -55,14 +56,15 @@ const RootLayout = () => {
onClick=
{
()
=>
setCollapsed
(
!
collapsed
)
}
onClick=
{
()
=>
setCollapsed
(
!
collapsed
)
}
>
>
{
!
collapsed
?
(
{
!
collapsed
?
(
<
Button
variant=
"plain"
color=
"neutral"
startDecorator=
{
<
ChevronLeftIcon
className=
"w-5 h-auto opacity-70"
/>
}
>
<
Button
className=
"rounded-xl"
variant=
"plain"
>
<
ChevronLeftIcon
className=
"w-5 h-auto opacity-70 mr-1"
/>
{
t
(
"common.collapse"
)
}
{
t
(
"common.collapse"
)
}
</
Button
>
</
Button
>
)
:
(
)
:
(
<
Tooltip
title=
{
t
(
"common.expand"
)
}
placement=
"right"
arrow
>
<
Tooltip
title=
{
t
(
"common.expand"
)
}
placement=
"right"
arrow
>
<
IconButton
>
<
Button
className=
"rounded-xl"
variant=
"plain"
>
<
ChevronRightIcon
className=
"w-5 h-auto opacity-70"
/>
<
ChevronRightIcon
className=
"w-5 h-auto opacity-70"
/>
</
Icon
Button
>
</
Button
>
</
Tooltip
>
</
Tooltip
>
)
}
)
}
</
div
>
</
div
>
...
...
web/src/main.tsx
View file @
963706ae
import
"@github/relative-time-element"
;
import
"@github/relative-time-element"
;
import
{
CssVarsProvider
}
from
"@mui/joy"
;
import
{
CssVarsProvider
}
from
"@mui/joy"
;
import
"@usememos/mui/dist/index.css"
;
import
"leaflet/dist/leaflet.css"
;
import
"leaflet/dist/leaflet.css"
;
import
{
createRoot
}
from
"react-dom/client"
;
import
{
createRoot
}
from
"react-dom/client"
;
import
{
Toaster
}
from
"react-hot-toast"
;
import
{
Toaster
}
from
"react-hot-toast"
;
import
{
Provider
}
from
"react-redux"
;
import
{
Provider
}
from
"react-redux"
;
import
{
RouterProvider
}
from
"react-router-dom"
;
import
{
RouterProvider
}
from
"react-router-dom"
;
import
"./css/global.css"
;
import
"./css/tailwind.css"
;
import
"./css/tailwind.css"
;
import
"./helpers/polyfill"
;
import
"./helpers/polyfill"
;
import
"./i18n"
;
import
"./i18n"
;
...
...
web/src/pages/MemoDetail.tsx
View file @
963706ae
import
{
Button
}
from
"@
mui/joy
"
;
import
{
Button
}
from
"@
usememos/mui
"
;
import
clsx
from
"clsx"
;
import
clsx
from
"clsx"
;
import
{
ArrowUpLeftFromCircleIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
ArrowUpLeftFromCircleIcon
,
MessageCircleIcon
}
from
"lucide-react"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
...
@@ -36,7 +36,7 @@ const MemoDetail = () => {
...
@@ -36,7 +36,7 @@ const MemoDetail = () => {
const
commentRelations
=
const
commentRelations
=
memo
?.
relations
.
filter
((
relation
)
=>
relation
.
relatedMemo
?.
name
===
memo
.
name
&&
relation
.
type
===
MemoRelation_Type
.
COMMENT
)
||
[];
memo
?.
relations
.
filter
((
relation
)
=>
relation
.
relatedMemo
?.
name
===
memo
.
name
&&
relation
.
type
===
MemoRelation_Type
.
COMMENT
)
||
[];
const
comments
=
commentRelations
.
map
((
relation
)
=>
memoStore
.
getMemoByName
(
relation
.
memo
!
.
name
)).
filter
((
memo
)
=>
memo
)
as
any
as
Memo
[];
const
comments
=
commentRelations
.
map
((
relation
)
=>
memoStore
.
getMemoByName
(
relation
.
memo
!
.
name
)).
filter
((
memo
)
=>
memo
)
as
any
as
Memo
[];
const
showCreateCommentButton
=
workspaceMemoRelatedSetting
.
enableComment
&&
currentUser
;
const
showCreateCommentButton
=
workspaceMemoRelatedSetting
.
enableComment
&&
currentUser
&&
!
showCommentEditor
;
// Prepare memo.
// Prepare memo.
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -120,27 +120,23 @@ const MemoDetail = () => {
...
@@ -120,27 +120,23 @@ const MemoDetail = () => {
{
comments
.
length
===
0
?
(
{
comments
.
length
===
0
?
(
showCreateCommentButton
&&
(
showCreateCommentButton
&&
(
<
div
className=
"w-full flex flex-row justify-center items-center py-6"
>
<
div
className=
"w-full flex flex-row justify-center items-center py-6"
>
<
Button
<
Button
variant=
"plain"
color=
"primary"
onClick=
{
handleShowCommentEditor
}
>
variant=
"plain"
<
span
className=
"text-gray-500"
>
{
t
(
"memo.comment.write-a-comment"
)
}
</
span
>
color=
"neutral"
<
MessageCircleIcon
className=
"ml-2 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
>
</
Button
>
</
Button
>
</
div
>
</
div
>
)
)
)
:
(
)
:
(
<>
<>
<
div
className=
"w-full flex flex-row justify-between items-center
px
-3 mb-2"
>
<
div
className=
"w-full flex flex-row justify-between items-center
h-8 pl
-3 mb-2"
>
<
div
className=
"flex flex-row justify-start items-center"
>
<
div
className=
"flex flex-row justify-start items-center"
>
<
MessageCircleIcon
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"
>
{
t
(
"memo.comment.self"
)
}
</
span
>
<
span
className=
"text-gray-400 text-sm ml-1"
>
(
{
comments
.
length
}
)
</
span
>
<
span
className=
"text-gray-400 text-sm ml-1"
>
(
{
comments
.
length
}
)
</
span
>
</
div
>
</
div
>
{
showCreateCommentButton
&&
(
{
showCreateCommentButton
&&
(
<
Button
variant=
"plain"
color=
"
neutral
"
onClick=
{
handleShowCommentEditor
}
>
<
Button
variant=
"plain"
color=
"
primary"
className=
"text-gray-500
"
onClick=
{
handleShowCommentEditor
}
>
<
span
className=
"font-normal text-gray-500"
>
{
t
(
"memo.comment.write-a-comment"
)
}
</
span
>
{
t
(
"memo.comment.write-a-comment"
)
}
</
Button
>
</
Button
>
)
}
)
}
</
div
>
</
div
>
...
...
web/src/pages/Resources.tsx
View file @
963706ae
import
{
Divider
,
IconButton
,
Input
,
Tooltip
}
from
"@mui/joy"
;
import
{
Divider
,
Input
,
Tooltip
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
includes
}
from
"lodash-es"
;
import
{
includes
}
from
"lodash-es"
;
import
{
PaperclipIcon
,
SearchIcon
,
TrashIcon
}
from
"lucide-react"
;
import
{
PaperclipIcon
,
SearchIcon
,
TrashIcon
}
from
"lucide-react"
;
...
@@ -132,9 +133,9 @@ const Resources = () => {
...
@@ -132,9 +133,9 @@ const Resources = () => {
<
span
className=
"text-gray-600 dark:text-gray-400"
>
Unused resources
</
span
>
<
span
className=
"text-gray-600 dark:text-gray-400"
>
Unused resources
</
span
>
<
span
className=
"text-gray-500 dark:text-gray-500 opacity-80"
>
(
{
unusedResources
.
length
}
)
</
span
>
<
span
className=
"text-gray-500 dark:text-gray-500 opacity-80"
>
(
{
unusedResources
.
length
}
)
</
span
>
<
Tooltip
title=
"Delete all"
placement=
"top"
>
<
Tooltip
title=
"Delete all"
placement=
"top"
>
<
IconButton
size=
"sm
"
onClick=
{
handleDeleteUnusedResources
}
>
<
Button
size=
"sm"
variant=
"plain
"
onClick=
{
handleDeleteUnusedResources
}
>
<
TrashIcon
className=
"w-4 h-auto opacity-60"
/>
<
TrashIcon
className=
"w-4 h-auto opacity-60"
/>
</
Icon
Button
>
</
Button
>
</
Tooltip
>
</
Tooltip
>
</
div
>
</
div
>
{
unusedResources
.
map
((
resource
)
=>
{
{
unusedResources
.
map
((
resource
)
=>
{
...
...
web/src/pages/SignIn.tsx
View file @
963706ae
import
{
Button
,
Divider
}
from
"@mui/joy"
;
import
{
Divider
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
Link
}
from
"react-router-dom"
;
...
@@ -96,10 +97,9 @@ const SignIn = () => {
...
@@ -96,10 +97,9 @@ const SignIn = () => {
{
identityProviderList
.
map
((
identityProvider
)
=>
(
{
identityProviderList
.
map
((
identityProvider
)
=>
(
<
Button
<
Button
key=
{
identityProvider
.
name
}
key=
{
identityProvider
.
name
}
color=
"primary"
variant=
"outlined"
variant=
"outlined"
color=
"neutral"
fullWidth
className=
"w-full"
size=
"md"
onClick=
{
()
=>
handleSignInWithIdentityProvider
(
identityProvider
)
}
onClick=
{
()
=>
handleSignInWithIdentityProvider
(
identityProvider
)
}
>
>
{
t
(
"common.sign-in-with"
,
{
provider
:
identityProvider
.
title
})
}
{
t
(
"common.sign-in-with"
,
{
provider
:
identityProvider
.
title
})
}
...
...
web/src/pages/SignUp.tsx
View file @
963706ae
import
{
Button
,
Input
}
from
"@mui/joy"
;
import
{
Input
}
from
"@mui/joy"
;
import
{
Button
}
from
"@usememos/mui"
;
import
{
LoaderIcon
}
from
"lucide-react"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
ClientError
}
from
"nice-grpc-web"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
...
@@ -119,14 +121,15 @@ const SignUp = () => {
...
@@ -119,14 +121,15 @@ const SignUp = () => {
</
div
>
</
div
>
<
div
className=
"flex flex-row justify-end items-center w-full mt-6"
>
<
div
className=
"flex flex-row justify-end items-center w-full mt-6"
>
<
Button
<
Button
className=
"w-full"
size=
"md"
type=
"submit"
type=
"submit"
color=
"primary"
size=
"lg"
fullWidth
disabled=
{
actionBtnLoadingState
.
isLoading
}
disabled=
{
actionBtnLoadingState
.
isLoading
}
loading=
{
actionBtnLoadingState
.
isLoading
}
onClick=
{
handleSignUpButtonClick
}
onClick=
{
handleSignUpButtonClick
}
>
>
{
t
(
"common.sign-up"
)
}
{
t
(
"common.sign-up"
)
}
{
actionBtnLoadingState
.
isLoading
&&
<
LoaderIcon
className=
"w-5 h-auto ml-2 animate-spin opacity-60"
/>
}
</
Button
>
</
Button
>
</
div
>
</
div
>
</
form
>
</
form
>
...
...
web/src/pages/UserProfile.tsx
View file @
963706ae
import
{
Button
}
from
"@
mui/joy
"
;
import
{
Button
}
from
"@
usememos/mui
"
;
import
copy
from
"copy-to-clipboard"
;
import
copy
from
"copy-to-clipboard"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
ExternalLinkIcon
}
from
"lucide-react"
;
import
{
ExternalLinkIcon
}
from
"lucide-react"
;
...
@@ -88,13 +88,9 @@ const UserProfile = () => {
...
@@ -88,13 +88,9 @@ const UserProfile = () => {
(
user
?
(
(
user
?
(
<>
<>
<
div
className=
"my-4 w-full flex justify-end items-center gap-2"
>
<
div
className=
"my-4 w-full flex justify-end items-center gap-2"
>
<
Button
<
Button
variant=
"outlined"
onClick=
{
handleCopyProfileLink
}
>
color=
"neutral"
variant=
"outlined"
endDecorator=
{
<
ExternalLinkIcon
className=
"w-4 h-auto opacity-60"
/>
}
onClick=
{
handleCopyProfileLink
}
>
{
t
(
"common.share"
)
}
{
t
(
"common.share"
)
}
<
ExternalLinkIcon
className=
"ml-1 w-4 h-auto opacity-60"
/>
</
Button
>
</
Button
>
</
div
>
</
div
>
<
div
className=
"w-full flex flex-col justify-start items-start pt-4 pb-8 px-3"
>
<
div
className=
"w-full flex flex-col justify-start items-start pt-4 pb-8 px-3"
>
...
...
web/tailwind.config.js
View file @
963706ae
...
@@ -2,33 +2,12 @@
...
@@ -2,33 +2,12 @@
/** @type {import('tailwindcss').Config} */
/** @type {import('tailwindcss').Config} */
module
.
exports
=
{
module
.
exports
=
{
darkMode
:
[
"class"
],
darkMode
:
[
"class"
],
content
:
[
"./index.html"
,
"./src/**/*.{
ts
,tsx}"
],
content
:
[
"./index.html"
,
"./src/**/*.{
js,ts,jsx
,tsx}"
],
prefix
:
""
,
prefix
:
""
,
theme
:
{
theme
:
{
fontSize
:
{
xs
:
".75rem"
,
sm
:
".875rem"
,
base
:
"1rem"
,
lg
:
"1.125rem"
,
xl
:
"1.25rem"
,
"2xl"
:
"1.5rem"
,
"3xl"
:
"1.875rem"
,
"4xl"
:
"2.25rem"
,
"5xl"
:
"2.5rem"
,
"6xl"
:
"3rem"
,
},
container
:
{
center
:
true
,
padding
:
"2rem"
,
screens
:
{
"2xl"
:
"1400px"
,
},
},
extend
:
{
extend
:
{
spacing
:
{
spacing
:
{
112
:
"28rem"
,
128
:
"32rem"
,
128
:
"32rem"
,
180
:
"45rem"
,
},
},
zIndex
:
{
zIndex
:
{
1
:
"1"
,
1
:
"1"
,
...
@@ -41,46 +20,6 @@ module.exports = {
...
@@ -41,46 +20,6 @@ module.exports = {
gridTemplateRows
:
{
gridTemplateRows
:
{
7
:
"repeat(7, minmax(0, 1fr))"
,
7
:
"repeat(7, minmax(0, 1fr))"
,
},
},
colors
:
{
border
:
"hsl(var(--border))"
,
input
:
"hsl(var(--input))"
,
ring
:
"hsl(var(--ring))"
,
background
:
"hsl(var(--background))"
,
foreground
:
"hsl(var(--foreground))"
,
primary
:
{
DEFAULT
:
"hsl(var(--primary))"
,
foreground
:
"hsl(var(--primary-foreground))"
,
},
secondary
:
{
DEFAULT
:
"hsl(var(--secondary))"
,
foreground
:
"hsl(var(--secondary-foreground))"
,
},
destructive
:
{
DEFAULT
:
"hsl(var(--destructive))"
,
foreground
:
"hsl(var(--destructive-foreground))"
,
},
muted
:
{
DEFAULT
:
"hsl(var(--muted))"
,
foreground
:
"hsl(var(--muted-foreground))"
,
},
accent
:
{
DEFAULT
:
"hsl(var(--accent))"
,
foreground
:
"hsl(var(--accent-foreground))"
,
},
popover
:
{
DEFAULT
:
"hsl(var(--popover))"
,
foreground
:
"hsl(var(--popover-foreground))"
,
},
card
:
{
DEFAULT
:
"hsl(var(--card))"
,
foreground
:
"hsl(var(--card-foreground))"
,
},
},
borderRadius
:
{
lg
:
"var(--radius)"
,
md
:
"calc(var(--radius) - 2px)"
,
sm
:
"calc(var(--radius) - 4px)"
,
},
},
},
},
},
plugins
:
[
require
(
"tailwindcss-animate"
)],
plugins
:
[
require
(
"tailwindcss-animate"
)],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment