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
4e54ec38
Commit
4e54ec38
authored
Jun 01, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update memo related settings
parent
0657a1ef
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
102 additions
and
99 deletions
+102
-99
workspace_setting_service.go
server/router/api/v1/workspace_setting_service.go
+11
-0
MemoRelatedSettings.tsx
web/src/components/Settings/MemoRelatedSettings.tsx
+81
-0
WorkspaceSection.tsx
web/src/components/Settings/WorkspaceSection.tsx
+2
-96
en.json
web/src/locales/en.json
+2
-1
Setting.tsx
web/src/pages/Setting.tsx
+6
-2
No files found.
server/router/api/v1/workspace_setting_service.go
View file @
4e54ec38
...
@@ -46,6 +46,17 @@ func (s *APIV1Service) GetWorkspaceSetting(ctx context.Context, request *v1pb.Ge
...
@@ -46,6 +46,17 @@ func (s *APIV1Service) GetWorkspaceSetting(ctx context.Context, request *v1pb.Ge
return
nil
,
status
.
Errorf
(
codes
.
NotFound
,
"workspace setting not found"
)
return
nil
,
status
.
Errorf
(
codes
.
NotFound
,
"workspace setting not found"
)
}
}
// For storage setting, only host can get it.
if
workspaceSetting
.
Key
==
storepb
.
WorkspaceSettingKey_STORAGE
{
user
,
err
:=
s
.
GetCurrentUser
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get current user: %v"
,
err
)
}
if
user
==
nil
||
user
.
Role
!=
store
.
RoleHost
{
return
nil
,
status
.
Errorf
(
codes
.
PermissionDenied
,
"permission denied"
)
}
}
return
convertWorkspaceSettingFromStore
(
workspaceSetting
),
nil
return
convertWorkspaceSettingFromStore
(
workspaceSetting
),
nil
}
}
...
...
web/src/components/Settings/MemoRelatedSettings.tsx
0 → 100644
View file @
4e54ec38
import
{
Button
,
Input
,
Switch
}
from
"@mui/joy"
;
import
{
isEqual
}
from
"lodash-es"
;
import
{
useState
}
from
"react"
;
import
{
WorkspaceSettingPrefix
,
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
WorkspaceMemoRelatedSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
const
MemoRelatedSettings
=
()
=>
{
const
t
=
useTranslate
();
const
workspaceSettingStore
=
useWorkspaceSettingStore
();
const
originalSetting
=
WorkspaceMemoRelatedSetting
.
fromPartial
(
workspaceSettingStore
.
getWorkspaceSettingByKey
(
WorkspaceSettingKey
.
MEMO_RELATED
)?.
memoRelatedSetting
||
{},
);
const
[
memoRelatedSetting
,
setMemoRelatedSetting
]
=
useState
<
WorkspaceMemoRelatedSetting
>
(
originalSetting
);
const
updatePartialSetting
=
(
partial
:
Partial
<
WorkspaceMemoRelatedSetting
>
)
=>
{
const
newWorkspaceMemoRelatedSetting
=
WorkspaceMemoRelatedSetting
.
fromPartial
({
...
memoRelatedSetting
,
...
partial
,
});
setMemoRelatedSetting
(
newWorkspaceMemoRelatedSetting
);
};
const
updateSetting
=
async
()
=>
{
await
workspaceSettingStore
.
setWorkspaceSetting
({
name
:
`
${
WorkspaceSettingPrefix
}${
WorkspaceSettingKey
.
MEMO_RELATED
}
`
,
memoRelatedSetting
,
});
};
return
(
<
div
className=
"w-full flex flex-col gap-2 pt-2 pb-4"
>
<
p
className=
"font-medium text-gray-700 dark:text-gray-500"
>
Memo related settings
</
p
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.disable-public-memos"
)
}
</
span
>
<
Switch
checked=
{
memoRelatedSetting
.
disallowPublicVisible
}
onChange=
{
(
event
)
=>
updatePartialSetting
({
disallowPublicVisible
:
event
.
target
.
checked
})
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.display-with-updated-time"
)
}
</
span
>
<
Switch
checked=
{
memoRelatedSetting
.
displayWithUpdateTime
}
onChange=
{
(
event
)
=>
updatePartialSetting
({
displayWithUpdateTime
:
event
.
target
.
checked
})
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.enable-auto-compact"
)
}
</
span
>
<
Switch
checked=
{
memoRelatedSetting
.
enableAutoCompact
}
onChange=
{
(
event
)
=>
updatePartialSetting
({
enableAutoCompact
:
event
.
target
.
checked
})
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.enable-double-click-to-edit"
)
}
</
span
>
<
Switch
checked=
{
memoRelatedSetting
.
enableDoubleClickEdit
}
onChange=
{
(
event
)
=>
updatePartialSetting
({
enableDoubleClickEdit
:
event
.
target
.
checked
})
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
Content length limit(Byte)
</
span
>
<
Input
className=
"w-24"
type=
"number"
defaultValue=
{
memoRelatedSetting
.
contentLengthLimit
}
onBlur=
{
(
event
)
=>
updatePartialSetting
({
contentLengthLimit
:
Number
(
event
.
target
.
value
)
})
}
/>
</
div
>
<
div
className=
"mt-2 w-full flex justify-end"
>
<
Button
disabled=
{
isEqual
(
memoRelatedSetting
,
originalSetting
)
}
onClick=
{
updateSetting
}
>
{
t
(
"common.save"
)
}
</
Button
>
</
div
>
</
div
>
);
};
export
default
MemoRelatedSettings
;
web/src/components/Settings/WorkspaceSection.tsx
View file @
4e54ec38
import
{
Button
,
Divider
,
Input
,
Switch
,
Textarea
}
from
"@mui/joy"
;
import
{
Button
,
Switch
,
Textarea
}
from
"@mui/joy"
;
import
{
useState
}
from
"react"
;
import
{
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"
;
import
{
workspaceSettingServiceClient
}
from
"@/grpcweb"
;
import
{
workspaceSettingServiceClient
}
from
"@/grpcweb"
;
import
{
WorkspaceSettingPrefix
,
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
WorkspaceSettingPrefix
,
useWorkspaceSettingStore
}
from
"@/store/v1"
;
import
{
WorkspaceGeneralSetting
,
WorkspaceMemoRelatedSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_setting_service"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
showCommonDialog
}
from
"../Dialog/CommonDialog"
;
import
{
showCommonDialog
}
from
"../Dialog/CommonDialog"
;
...
@@ -17,11 +17,6 @@ const WorkspaceSection = () => {
...
@@ -17,11 +17,6 @@ const WorkspaceSection = () => {
const
[
workspaceGeneralSetting
,
setWorkspaceGeneralSetting
]
=
useState
<
WorkspaceGeneralSetting
>
(
const
[
workspaceGeneralSetting
,
setWorkspaceGeneralSetting
]
=
useState
<
WorkspaceGeneralSetting
>
(
WorkspaceGeneralSetting
.
fromPartial
(
workspaceSettingStore
.
getWorkspaceSettingByKey
(
WorkspaceSettingKey
.
GENERAL
)?.
generalSetting
||
{}),
WorkspaceGeneralSetting
.
fromPartial
(
workspaceSettingStore
.
getWorkspaceSettingByKey
(
WorkspaceSettingKey
.
GENERAL
)?.
generalSetting
||
{}),
);
);
const
[
workspaceMemoRelatedSetting
,
setWorkspaceMemoRelatedSetting
]
=
useState
<
WorkspaceMemoRelatedSetting
>
(
WorkspaceMemoRelatedSetting
.
fromPartial
(
workspaceSettingStore
.
getWorkspaceSettingByKey
(
WorkspaceSettingKey
.
MEMO_RELATED
)?.
memoRelatedSetting
||
{},
),
);
const
handleAllowSignUpChanged
=
async
(
value
:
boolean
)
=>
{
const
handleAllowSignUpChanged
=
async
(
value
:
boolean
)
=>
{
const
setting
=
{
...
workspaceGeneralSetting
,
disallowSignup
:
!
value
};
const
setting
=
{
...
workspaceGeneralSetting
,
disallowSignup
:
!
value
};
...
@@ -104,56 +99,6 @@ const WorkspaceSection = () => {
...
@@ -104,56 +99,6 @@ const WorkspaceSection = () => {
toast
.
success
(
t
(
"message.update-succeed"
));
toast
.
success
(
t
(
"message.update-succeed"
));
};
};
const
handleDisablePublicMemosChanged
=
async
(
value
:
boolean
)
=>
{
const
update
:
WorkspaceMemoRelatedSetting
=
{
...
workspaceMemoRelatedSetting
,
disallowPublicVisible
:
value
};
setWorkspaceMemoRelatedSetting
(
update
);
await
workspaceSettingStore
.
setWorkspaceSetting
({
name
:
`
${
WorkspaceSettingPrefix
}${
WorkspaceSettingKey
.
MEMO_RELATED
}
`
,
memoRelatedSetting
:
update
,
});
};
const
handleMemoDisplayWithUpdatedTs
=
async
(
value
:
boolean
)
=>
{
const
update
:
WorkspaceMemoRelatedSetting
=
{
...
workspaceMemoRelatedSetting
,
displayWithUpdateTime
:
value
};
setWorkspaceMemoRelatedSetting
(
update
);
await
workspaceSettingStore
.
setWorkspaceSetting
({
name
:
`
${
WorkspaceSettingPrefix
}${
WorkspaceSettingKey
.
MEMO_RELATED
}
`
,
memoRelatedSetting
:
update
,
});
};
const
handleMemoEnableAutoCompact
=
async
(
value
:
boolean
)
=>
{
const
update
:
WorkspaceMemoRelatedSetting
=
{
...
workspaceMemoRelatedSetting
,
enableAutoCompact
:
value
};
setWorkspaceMemoRelatedSetting
(
update
);
await
workspaceSettingStore
.
setWorkspaceSetting
({
name
:
`
${
WorkspaceSettingPrefix
}${
WorkspaceSettingKey
.
MEMO_RELATED
}
`
,
memoRelatedSetting
:
update
,
});
};
const
handleMemoEnableDoubleClickToEdit
=
async
(
value
:
boolean
)
=>
{
const
update
:
WorkspaceMemoRelatedSetting
=
{
...
workspaceMemoRelatedSetting
,
enableDoubleClickEdit
:
value
};
setWorkspaceMemoRelatedSetting
(
update
);
await
workspaceSettingStore
.
setWorkspaceSetting
({
name
:
`
${
WorkspaceSettingPrefix
}${
WorkspaceSettingKey
.
MEMO_RELATED
}
`
,
memoRelatedSetting
:
update
,
});
};
const
handleMemoContentLengthLimitChanges
=
async
(
value
:
number
)
=>
{
if
(
value
<
8
*
1024
)
{
toast
.
error
(
"Content length limit should be greater than 8KB"
);
return
;
}
const
update
:
WorkspaceMemoRelatedSetting
=
{
...
workspaceMemoRelatedSetting
,
contentLengthLimit
:
value
};
setWorkspaceMemoRelatedSetting
(
update
);
await
workspaceSettingStore
.
setWorkspaceSetting
({
name
:
`
${
WorkspaceSettingPrefix
}${
WorkspaceSettingKey
.
MEMO_RELATED
}
`
,
memoRelatedSetting
:
update
,
});
};
return
(
return
(
<
div
className=
"w-full flex flex-col gap-2 pt-2 pb-4"
>
<
div
className=
"w-full flex flex-col gap-2 pt-2 pb-4"
>
<
p
className=
"font-medium text-gray-700 dark:text-gray-500"
>
{
t
(
"common.basic"
)
}
</
p
>
<
p
className=
"font-medium text-gray-700 dark:text-gray-500"
>
{
t
(
"common.basic"
)
}
</
p
>
...
@@ -225,45 +170,6 @@ const WorkspaceSection = () => {
...
@@ -225,45 +170,6 @@ const WorkspaceSection = () => {
</
Link
>
</
Link
>
</
div
>
</
div
>
</
div
>
</
div
>
<
Divider
className=
"!my-3"
/>
<
p
className=
"font-medium text-gray-700 dark:text-gray-500"
>
Memo related settings
</
p
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.disable-public-memos"
)
}
</
span
>
<
Switch
checked=
{
workspaceMemoRelatedSetting
.
disallowPublicVisible
}
onChange=
{
(
event
)
=>
handleDisablePublicMemosChanged
(
event
.
target
.
checked
)
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.display-with-updated-time"
)
}
</
span
>
<
Switch
checked=
{
workspaceMemoRelatedSetting
.
displayWithUpdateTime
}
onChange=
{
(
event
)
=>
handleMemoDisplayWithUpdatedTs
(
event
.
target
.
checked
)
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.enable-auto-compact"
)
}
</
span
>
<
Switch
checked=
{
workspaceMemoRelatedSetting
.
enableAutoCompact
}
onChange=
{
(
event
)
=>
handleMemoEnableAutoCompact
(
event
.
target
.
checked
)
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.enable-double-click-to-edit"
)
}
</
span
>
<
Switch
checked=
{
workspaceMemoRelatedSetting
.
enableDoubleClickEdit
}
onChange=
{
(
event
)
=>
handleMemoEnableDoubleClickToEdit
(
event
.
target
.
checked
)
}
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
Content length limit(Byte)
</
span
>
<
Input
className=
"w-32"
type=
"number"
defaultValue=
{
workspaceMemoRelatedSetting
.
contentLengthLimit
}
onBlur=
{
(
event
)
=>
handleMemoContentLengthLimitChanges
(
Number
(
event
.
target
.
value
))
}
/>
</
div
>
</
div
>
</
div
>
);
);
};
};
...
...
web/src/locales/en.json
View file @
4e54ec38
...
@@ -297,7 +297,8 @@
...
@@ -297,7 +297,8 @@
"max-upload-size"
:
"Maximum upload size (MiB)"
,
"max-upload-size"
:
"Maximum upload size (MiB)"
,
"max-upload-size-hint"
:
"Recommended value is 32 MiB."
,
"max-upload-size-hint"
:
"Recommended value is 32 MiB."
,
"server-name"
:
"Server Name"
"server-name"
:
"Server Name"
}
},
"memo-related"
:
"Memo"
},
},
"tag"
:
{
"tag"
:
{
"all-tags"
:
"All Tags"
,
"all-tags"
:
"All Tags"
,
...
...
web/src/pages/Setting.tsx
View file @
4e54ec38
...
@@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useState } from "react";
...
@@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useState } from "react";
import
Icon
from
"@/components/Icon"
;
import
Icon
from
"@/components/Icon"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
MemberSection
from
"@/components/Settings/MemberSection"
;
import
MemberSection
from
"@/components/Settings/MemberSection"
;
import
MemoRelatedSettings
from
"@/components/Settings/MemoRelatedSettings"
;
import
MyAccountSection
from
"@/components/Settings/MyAccountSection"
;
import
MyAccountSection
from
"@/components/Settings/MyAccountSection"
;
import
PreferencesSection
from
"@/components/Settings/PreferencesSection"
;
import
PreferencesSection
from
"@/components/Settings/PreferencesSection"
;
import
SSOSection
from
"@/components/Settings/SSOSection"
;
import
SSOSection
from
"@/components/Settings/SSOSection"
;
...
@@ -17,19 +18,20 @@ import { User_Role } from "@/types/proto/api/v1/user_service";
...
@@ -17,19 +18,20 @@ import { User_Role } from "@/types/proto/api/v1/user_service";
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
WorkspaceSettingKey
}
from
"@/types/proto/store/workspace_setting"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
type
SettingSection
=
"my-account"
|
"preference"
|
"member"
|
"system"
|
"storage"
|
"sso"
;
type
SettingSection
=
"my-account"
|
"preference"
|
"member"
|
"system"
|
"
memo-related"
|
"
storage"
|
"sso"
;
interface
State
{
interface
State
{
selectedSection
:
SettingSection
;
selectedSection
:
SettingSection
;
}
}
const
BASIC_SECTIONS
:
SettingSection
[]
=
[
"my-account"
,
"preference"
];
const
BASIC_SECTIONS
:
SettingSection
[]
=
[
"my-account"
,
"preference"
];
const
ADMIN_SECTIONS
:
SettingSection
[]
=
[
"member"
,
"system"
,
"storage"
,
"sso"
];
const
ADMIN_SECTIONS
:
SettingSection
[]
=
[
"member"
,
"system"
,
"
memo-related"
,
"
storage"
,
"sso"
];
const
SECTION_ICON_MAP
:
Record
<
SettingSection
,
LucideIcon
>
=
{
const
SECTION_ICON_MAP
:
Record
<
SettingSection
,
LucideIcon
>
=
{
"my-account"
:
Icon
.
User
,
"my-account"
:
Icon
.
User
,
preference
:
Icon
.
Cog
,
preference
:
Icon
.
Cog
,
member
:
Icon
.
Users
,
member
:
Icon
.
Users
,
system
:
Icon
.
Settings2
,
system
:
Icon
.
Settings2
,
"memo-related"
:
Icon
.
Library
,
storage
:
Icon
.
Database
,
storage
:
Icon
.
Database
,
sso
:
Icon
.
Key
,
sso
:
Icon
.
Key
,
};
};
...
@@ -125,6 +127,8 @@ const Setting = () => {
...
@@ -125,6 +127,8 @@ const Setting = () => {
<
MemberSection
/>
<
MemberSection
/>
)
:
state
.
selectedSection
===
"system"
?
(
)
:
state
.
selectedSection
===
"system"
?
(
<
WorkspaceSection
/>
<
WorkspaceSection
/>
)
:
state
.
selectedSection
===
"memo-related"
?
(
<
MemoRelatedSettings
/>
)
:
state
.
selectedSection
===
"storage"
?
(
)
:
state
.
selectedSection
===
"storage"
?
(
<
StorageSection
/>
<
StorageSection
/>
)
:
state
.
selectedSection
===
"sso"
?
(
)
:
state
.
selectedSection
===
"sso"
?
(
...
...
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