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
1b3083b2
Unverified
Commit
1b3083b2
authored
Jul 07, 2025
by
Johnny
Committed by
GitHub
Jul 07, 2025
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: themes (#4824)
parent
3426a791
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
375 additions
and
83 deletions
+375
-83
workspace_service.proto
proto/api/v1/workspace_service.proto
+11
-8
workspace_service.pb.go
proto/gen/api/v1/workspace_service.pb.go
+29
-18
apidocs.swagger.yaml
proto/gen/apidocs.swagger.yaml
+5
-0
workspace_setting.pb.go
proto/gen/store/workspace_setting.pb.go
+29
-18
workspace_setting.proto
proto/store/workspace_setting.proto
+11
-9
workspace_service.go
server/router/api/v1/workspace_service.go
+2
-0
components.json
web/components.json
+1
-1
App.tsx
web/src/App.tsx
+6
-0
WorkspaceSection.tsx
web/src/components/Settings/WorkspaceSection.tsx
+9
-0
ThemeSelector.tsx
web/src/components/ThemeSelector.tsx
+31
-0
dropdown-menu.tsx
web/src/components/ui/dropdown-menu.tsx
+2
-1
popover.tsx
web/src/components/ui/popover.tsx
+2
-1
sheet.tsx
web/src/components/ui/sheet.tsx
+2
-1
tooltip.tsx
web/src/components/ui/tooltip.tsx
+4
-2
index.css
web/src/index.css
+1
-1
index.ts
web/src/theme/index.ts
+0
-5
default.css
web/src/themes/default.css
+0
-0
paper.css
web/src/themes/paper.css
+152
-0
workspace_service.ts
web/src/types/proto/api/v1/workspace_service.ts
+36
-18
theme.ts
web/src/utils/theme.ts
+42
-0
No files found.
proto/api/v1/workspace_service.proto
View file @
1b3083b2
...
@@ -72,25 +72,28 @@ message WorkspaceSetting {
...
@@ -72,25 +72,28 @@ message WorkspaceSetting {
}
}
message
WorkspaceGeneralSetting
{
message
WorkspaceGeneralSetting
{
// theme is the name of the selected theme.
// This references a CSS file in the web/public/themes/ directory.
string
theme
=
1
;
// disallow_user_registration disallows user registration.
// disallow_user_registration disallows user registration.
bool
disallow_user_registration
=
1
;
bool
disallow_user_registration
=
2
;
// disallow_password_auth disallows password authentication.
// disallow_password_auth disallows password authentication.
bool
disallow_password_auth
=
2
;
bool
disallow_password_auth
=
3
;
// additional_script is the additional script.
// additional_script is the additional script.
string
additional_script
=
3
;
string
additional_script
=
4
;
// additional_style is the additional style.
// additional_style is the additional style.
string
additional_style
=
4
;
string
additional_style
=
5
;
// custom_profile is the custom profile.
// custom_profile is the custom profile.
WorkspaceCustomProfile
custom_profile
=
5
;
WorkspaceCustomProfile
custom_profile
=
6
;
// week_start_day_offset is the week start day offset from Sunday.
// week_start_day_offset is the week start day offset from Sunday.
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// Default is Sunday.
// Default is Sunday.
int32
week_start_day_offset
=
6
;
int32
week_start_day_offset
=
7
;
// disallow_change_username disallows changing username.
// disallow_change_username disallows changing username.
bool
disallow_change_username
=
7
;
bool
disallow_change_username
=
8
;
// disallow_change_nickname disallows changing nickname.
// disallow_change_nickname disallows changing nickname.
bool
disallow_change_nickname
=
8
;
bool
disallow_change_nickname
=
9
;
}
}
message
WorkspaceCustomProfile
{
message
WorkspaceCustomProfile
{
...
...
proto/gen/api/v1/workspace_service.pb.go
View file @
1b3083b2
...
@@ -300,24 +300,27 @@ func (*WorkspaceSetting_MemoRelatedSetting) isWorkspaceSetting_Value() {}
...
@@ -300,24 +300,27 @@ func (*WorkspaceSetting_MemoRelatedSetting) isWorkspaceSetting_Value() {}
type
WorkspaceGeneralSetting
struct
{
type
WorkspaceGeneralSetting
struct
{
state
protoimpl
.
MessageState
`protogen:"open.v1"`
state
protoimpl
.
MessageState
`protogen:"open.v1"`
// theme is the name of the selected theme.
// This references a CSS file in the web/public/themes/ directory.
Theme
string
`protobuf:"bytes,1,opt,name=theme,proto3" json:"theme,omitempty"`
// disallow_user_registration disallows user registration.
// disallow_user_registration disallows user registration.
DisallowUserRegistration
bool
`protobuf:"varint,
1
,opt,name=disallow_user_registration,json=disallowUserRegistration,proto3" json:"disallow_user_registration,omitempty"`
DisallowUserRegistration
bool
`protobuf:"varint,
2
,opt,name=disallow_user_registration,json=disallowUserRegistration,proto3" json:"disallow_user_registration,omitempty"`
// disallow_password_auth disallows password authentication.
// disallow_password_auth disallows password authentication.
DisallowPasswordAuth
bool
`protobuf:"varint,
2
,opt,name=disallow_password_auth,json=disallowPasswordAuth,proto3" json:"disallow_password_auth,omitempty"`
DisallowPasswordAuth
bool
`protobuf:"varint,
3
,opt,name=disallow_password_auth,json=disallowPasswordAuth,proto3" json:"disallow_password_auth,omitempty"`
// additional_script is the additional script.
// additional_script is the additional script.
AdditionalScript
string
`protobuf:"bytes,
3
,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"`
AdditionalScript
string
`protobuf:"bytes,
4
,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"`
// additional_style is the additional style.
// additional_style is the additional style.
AdditionalStyle
string
`protobuf:"bytes,
4
,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"`
AdditionalStyle
string
`protobuf:"bytes,
5
,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"`
// custom_profile is the custom profile.
// custom_profile is the custom profile.
CustomProfile
*
WorkspaceCustomProfile
`protobuf:"bytes,
5
,opt,name=custom_profile,json=customProfile,proto3" json:"custom_profile,omitempty"`
CustomProfile
*
WorkspaceCustomProfile
`protobuf:"bytes,
6
,opt,name=custom_profile,json=customProfile,proto3" json:"custom_profile,omitempty"`
// week_start_day_offset is the week start day offset from Sunday.
// week_start_day_offset is the week start day offset from Sunday.
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// Default is Sunday.
// Default is Sunday.
WeekStartDayOffset
int32
`protobuf:"varint,
6
,opt,name=week_start_day_offset,json=weekStartDayOffset,proto3" json:"week_start_day_offset,omitempty"`
WeekStartDayOffset
int32
`protobuf:"varint,
7
,opt,name=week_start_day_offset,json=weekStartDayOffset,proto3" json:"week_start_day_offset,omitempty"`
// disallow_change_username disallows changing username.
// disallow_change_username disallows changing username.
DisallowChangeUsername
bool
`protobuf:"varint,
7
,opt,name=disallow_change_username,json=disallowChangeUsername,proto3" json:"disallow_change_username,omitempty"`
DisallowChangeUsername
bool
`protobuf:"varint,
8
,opt,name=disallow_change_username,json=disallowChangeUsername,proto3" json:"disallow_change_username,omitempty"`
// disallow_change_nickname disallows changing nickname.
// disallow_change_nickname disallows changing nickname.
DisallowChangeNickname
bool
`protobuf:"varint,
8
,opt,name=disallow_change_nickname,json=disallowChangeNickname,proto3" json:"disallow_change_nickname,omitempty"`
DisallowChangeNickname
bool
`protobuf:"varint,
9
,opt,name=disallow_change_nickname,json=disallowChangeNickname,proto3" json:"disallow_change_nickname,omitempty"`
unknownFields
protoimpl
.
UnknownFields
unknownFields
protoimpl
.
UnknownFields
sizeCache
protoimpl
.
SizeCache
sizeCache
protoimpl
.
SizeCache
}
}
...
@@ -352,6 +355,13 @@ func (*WorkspaceGeneralSetting) Descriptor() ([]byte, []int) {
...
@@ -352,6 +355,13 @@ func (*WorkspaceGeneralSetting) Descriptor() ([]byte, []int) {
return
file_api_v1_workspace_service_proto_rawDescGZIP
(),
[]
int
{
3
}
return
file_api_v1_workspace_service_proto_rawDescGZIP
(),
[]
int
{
3
}
}
}
func
(
x
*
WorkspaceGeneralSetting
)
GetTheme
()
string
{
if
x
!=
nil
{
return
x
.
Theme
}
return
""
}
func
(
x
*
WorkspaceGeneralSetting
)
GetDisallowUserRegistration
()
bool
{
func
(
x
*
WorkspaceGeneralSetting
)
GetDisallowUserRegistration
()
bool
{
if
x
!=
nil
{
if
x
!=
nil
{
return
x
.
DisallowUserRegistration
return
x
.
DisallowUserRegistration
...
@@ -887,16 +897,17 @@ const file_api_v1_workspace_service_proto_rawDesc = "" +
...
@@ -887,16 +897,17 @@ const file_api_v1_workspace_service_proto_rawDesc = "" +
"
\x0f
storage_setting
\x18\x03
\x01
(
\v
2%.memos.api.v1.WorkspaceStorageSettingH
\x00
R
\x0e
storageSetting
\x12
]
\n
"
+
"
\x0f
storage_setting
\x18\x03
\x01
(
\v
2%.memos.api.v1.WorkspaceStorageSettingH
\x00
R
\x0e
storageSetting
\x12
]
\n
"
+
"
\x14
memo_related_setting
\x18\x04
\x01
(
\v
2).memos.api.v1.WorkspaceMemoRelatedSettingH
\x00
R
\x12
memoRelatedSetting:f
\xea
Ac
\n
"
+
"
\x14
memo_related_setting
\x18\x04
\x01
(
\v
2).memos.api.v1.WorkspaceMemoRelatedSettingH
\x00
R
\x12
memoRelatedSetting:f
\xea
Ac
\n
"
+
"
\x1e
api.memos.dev/WorkspaceSetting
\x12\x1c
workspace/settings/{setting}*
\x11
workspaceSettings2
\x10
workspaceSettingB
\a\n
"
+
"
\x1e
api.memos.dev/WorkspaceSetting
\x12\x1c
workspace/settings/{setting}*
\x11
workspaceSettings2
\x10
workspaceSettingB
\a\n
"
+
"
\x05
value
\"\xd9\x03\n
"
+
"
\x05
value
\"\xef\x03\n
"
+
"
\x17
WorkspaceGeneralSetting
\x12
<
\n
"
+
"
\x17
WorkspaceGeneralSetting
\x12\x14\n
"
+
"
\x1a
disallow_user_registration
\x18\x01
\x01
(
\b
R
\x18
disallowUserRegistration
\x12
4
\n
"
+
"
\x05
theme
\x18\x01
\x01
(
\t
R
\x05
theme
\x12
<
\n
"
+
"
\x16
disallow_password_auth
\x18\x02
\x01
(
\b
R
\x14
disallowPasswordAuth
\x12
+
\n
"
+
"
\x1a
disallow_user_registration
\x18\x02
\x01
(
\b
R
\x18
disallowUserRegistration
\x12
4
\n
"
+
"
\x11
additional_script
\x18\x03
\x01
(
\t
R
\x10
additionalScript
\x12
)
\n
"
+
"
\x16
disallow_password_auth
\x18\x03
\x01
(
\b
R
\x14
disallowPasswordAuth
\x12
+
\n
"
+
"
\x10
additional_style
\x18\x04
\x01
(
\t
R
\x0f
additionalStyle
\x12
K
\n
"
+
"
\x11
additional_script
\x18\x04
\x01
(
\t
R
\x10
additionalScript
\x12
)
\n
"
+
"
\x0e
custom_profile
\x18\x05
\x01
(
\v
2$.memos.api.v1.WorkspaceCustomProfileR
\r
customProfile
\x12
1
\n
"
+
"
\x10
additional_style
\x18\x05
\x01
(
\t
R
\x0f
additionalStyle
\x12
K
\n
"
+
"
\x15
week_start_day_offset
\x18\x06
\x01
(
\x05
R
\x12
weekStartDayOffset
\x12
8
\n
"
+
"
\x0e
custom_profile
\x18\x06
\x01
(
\v
2$.memos.api.v1.WorkspaceCustomProfileR
\r
customProfile
\x12
1
\n
"
+
"
\x18
disallow_change_username
\x18\a
\x01
(
\b
R
\x16
disallowChangeUsername
\x12
8
\n
"
+
"
\x15
week_start_day_offset
\x18\a
\x01
(
\x05
R
\x12
weekStartDayOffset
\x12
8
\n
"
+
"
\x18
disallow_change_nickname
\x18\b
\x01
(
\b
R
\x16
disallowChangeNickname
\"\xa3\x01\n
"
+
"
\x18
disallow_change_username
\x18\b
\x01
(
\b
R
\x16
disallowChangeUsername
\x12
8
\n
"
+
"
\x18
disallow_change_nickname
\x18\t
\x01
(
\b
R
\x16
disallowChangeNickname
\"\xa3\x01\n
"
+
"
\x16
WorkspaceCustomProfile
\x12\x14\n
"
+
"
\x16
WorkspaceCustomProfile
\x12\x14\n
"
+
"
\x05
title
\x18\x01
\x01
(
\t
R
\x05
title
\x12
\n
"
+
"
\x05
title
\x18\x01
\x01
(
\t
R
\x05
title
\x12
\n
"
+
"
\v
description
\x18\x02
\x01
(
\t
R
\v
description
\x12\x19\n
"
+
"
\v
description
\x18\x02
\x01
(
\t
R
\v
description
\x12\x19\n
"
+
...
...
proto/gen/apidocs.swagger.yaml
View file @
1b3083b2
...
@@ -2900,6 +2900,11 @@ definitions:
...
@@ -2900,6 +2900,11 @@ definitions:
apiv1WorkspaceGeneralSetting
:
apiv1WorkspaceGeneralSetting
:
type
:
object
type
:
object
properties
:
properties
:
theme
:
type
:
string
description
:
|-
theme is the name of the selected theme.
This references a CSS file in the web/public/themes/ directory.
disallowUserRegistration
:
disallowUserRegistration
:
type
:
boolean
type
:
boolean
description
:
disallow_user_registration disallows user registration.
description
:
disallow_user_registration disallows user registration.
...
...
proto/gen/store/workspace_setting.pb.go
View file @
1b3083b2
...
@@ -313,24 +313,27 @@ func (x *WorkspaceBasicSetting) GetSchemaVersion() string {
...
@@ -313,24 +313,27 @@ func (x *WorkspaceBasicSetting) GetSchemaVersion() string {
type
WorkspaceGeneralSetting
struct
{
type
WorkspaceGeneralSetting
struct
{
state
protoimpl
.
MessageState
`protogen:"open.v1"`
state
protoimpl
.
MessageState
`protogen:"open.v1"`
// theme is the name of the selected theme.
// This references a CSS file in the web/public/themes/ directory.
Theme
string
`protobuf:"bytes,1,opt,name=theme,proto3" json:"theme,omitempty"`
// disallow_user_registration disallows user registration.
// disallow_user_registration disallows user registration.
DisallowUserRegistration
bool
`protobuf:"varint,
1
,opt,name=disallow_user_registration,json=disallowUserRegistration,proto3" json:"disallow_user_registration,omitempty"`
DisallowUserRegistration
bool
`protobuf:"varint,
2
,opt,name=disallow_user_registration,json=disallowUserRegistration,proto3" json:"disallow_user_registration,omitempty"`
// disallow_password_auth disallows password authentication.
// disallow_password_auth disallows password authentication.
DisallowPasswordAuth
bool
`protobuf:"varint,
2
,opt,name=disallow_password_auth,json=disallowPasswordAuth,proto3" json:"disallow_password_auth,omitempty"`
DisallowPasswordAuth
bool
`protobuf:"varint,
3
,opt,name=disallow_password_auth,json=disallowPasswordAuth,proto3" json:"disallow_password_auth,omitempty"`
// additional_script is the additional script.
// additional_script is the additional script.
AdditionalScript
string
`protobuf:"bytes,
3
,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"`
AdditionalScript
string
`protobuf:"bytes,
4
,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"`
// additional_style is the additional style.
// additional_style is the additional style.
AdditionalStyle
string
`protobuf:"bytes,
4
,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"`
AdditionalStyle
string
`protobuf:"bytes,
5
,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"`
// custom_profile is the custom profile.
// custom_profile is the custom profile.
CustomProfile
*
WorkspaceCustomProfile
`protobuf:"bytes,
5
,opt,name=custom_profile,json=customProfile,proto3" json:"custom_profile,omitempty"`
CustomProfile
*
WorkspaceCustomProfile
`protobuf:"bytes,
6
,opt,name=custom_profile,json=customProfile,proto3" json:"custom_profile,omitempty"`
// week_start_day_offset is the week start day offset from Sunday.
// week_start_day_offset is the week start day offset from Sunday.
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// Default is Sunday.
// Default is Sunday.
WeekStartDayOffset
int32
`protobuf:"varint,
6
,opt,name=week_start_day_offset,json=weekStartDayOffset,proto3" json:"week_start_day_offset,omitempty"`
WeekStartDayOffset
int32
`protobuf:"varint,
7
,opt,name=week_start_day_offset,json=weekStartDayOffset,proto3" json:"week_start_day_offset,omitempty"`
// disallow_change_username disallows changing username.
// disallow_change_username disallows changing username.
DisallowChangeUsername
bool
`protobuf:"varint,
7
,opt,name=disallow_change_username,json=disallowChangeUsername,proto3" json:"disallow_change_username,omitempty"`
DisallowChangeUsername
bool
`protobuf:"varint,
8
,opt,name=disallow_change_username,json=disallowChangeUsername,proto3" json:"disallow_change_username,omitempty"`
// disallow_change_nickname disallows changing nickname.
// disallow_change_nickname disallows changing nickname.
DisallowChangeNickname
bool
`protobuf:"varint,
8
,opt,name=disallow_change_nickname,json=disallowChangeNickname,proto3" json:"disallow_change_nickname,omitempty"`
DisallowChangeNickname
bool
`protobuf:"varint,
9
,opt,name=disallow_change_nickname,json=disallowChangeNickname,proto3" json:"disallow_change_nickname,omitempty"`
unknownFields
protoimpl
.
UnknownFields
unknownFields
protoimpl
.
UnknownFields
sizeCache
protoimpl
.
SizeCache
sizeCache
protoimpl
.
SizeCache
}
}
...
@@ -365,6 +368,13 @@ func (*WorkspaceGeneralSetting) Descriptor() ([]byte, []int) {
...
@@ -365,6 +368,13 @@ func (*WorkspaceGeneralSetting) Descriptor() ([]byte, []int) {
return
file_store_workspace_setting_proto_rawDescGZIP
(),
[]
int
{
2
}
return
file_store_workspace_setting_proto_rawDescGZIP
(),
[]
int
{
2
}
}
}
func
(
x
*
WorkspaceGeneralSetting
)
GetTheme
()
string
{
if
x
!=
nil
{
return
x
.
Theme
}
return
""
}
func
(
x
*
WorkspaceGeneralSetting
)
GetDisallowUserRegistration
()
bool
{
func
(
x
*
WorkspaceGeneralSetting
)
GetDisallowUserRegistration
()
bool
{
if
x
!=
nil
{
if
x
!=
nil
{
return
x
.
DisallowUserRegistration
return
x
.
DisallowUserRegistration
...
@@ -796,16 +806,17 @@ const file_store_workspace_setting_proto_rawDesc = "" +
...
@@ -796,16 +806,17 @@ const file_store_workspace_setting_proto_rawDesc = "" +
"
\x15
WorkspaceBasicSetting
\x12\x1d\n
"
+
"
\x15
WorkspaceBasicSetting
\x12\x1d\n
"
+
"
\n
"
+
"
\n
"
+
"secret_key
\x18\x01
\x01
(
\t
R
\t
secretKey
\x12
%
\n
"
+
"secret_key
\x18\x01
\x01
(
\t
R
\t
secretKey
\x12
%
\n
"
+
"
\x0e
schema_version
\x18\x02
\x01
(
\t
R
\r
schemaVersion
\"\xd8\x03\n
"
+
"
\x0e
schema_version
\x18\x02
\x01
(
\t
R
\r
schemaVersion
\"\xee\x03\n
"
+
"
\x17
WorkspaceGeneralSetting
\x12
<
\n
"
+
"
\x17
WorkspaceGeneralSetting
\x12\x14\n
"
+
"
\x1a
disallow_user_registration
\x18\x01
\x01
(
\b
R
\x18
disallowUserRegistration
\x12
4
\n
"
+
"
\x05
theme
\x18\x01
\x01
(
\t
R
\x05
theme
\x12
<
\n
"
+
"
\x16
disallow_password_auth
\x18\x02
\x01
(
\b
R
\x14
disallowPasswordAuth
\x12
+
\n
"
+
"
\x1a
disallow_user_registration
\x18\x02
\x01
(
\b
R
\x18
disallowUserRegistration
\x12
4
\n
"
+
"
\x11
additional_script
\x18\x03
\x01
(
\t
R
\x10
additionalScript
\x12
)
\n
"
+
"
\x16
disallow_password_auth
\x18\x03
\x01
(
\b
R
\x14
disallowPasswordAuth
\x12
+
\n
"
+
"
\x10
additional_style
\x18\x04
\x01
(
\t
R
\x0f
additionalStyle
\x12
J
\n
"
+
"
\x11
additional_script
\x18\x04
\x01
(
\t
R
\x10
additionalScript
\x12
)
\n
"
+
"
\x0e
custom_profile
\x18\x05
\x01
(
\v
2#.memos.store.WorkspaceCustomProfileR
\r
customProfile
\x12
1
\n
"
+
"
\x10
additional_style
\x18\x05
\x01
(
\t
R
\x0f
additionalStyle
\x12
J
\n
"
+
"
\x15
week_start_day_offset
\x18\x06
\x01
(
\x05
R
\x12
weekStartDayOffset
\x12
8
\n
"
+
"
\x0e
custom_profile
\x18\x06
\x01
(
\v
2#.memos.store.WorkspaceCustomProfileR
\r
customProfile
\x12
1
\n
"
+
"
\x18
disallow_change_username
\x18\a
\x01
(
\b
R
\x16
disallowChangeUsername
\x12
8
\n
"
+
"
\x15
week_start_day_offset
\x18\a
\x01
(
\x05
R
\x12
weekStartDayOffset
\x12
8
\n
"
+
"
\x18
disallow_change_nickname
\x18\b
\x01
(
\b
R
\x16
disallowChangeNickname
\"\xa3\x01\n
"
+
"
\x18
disallow_change_username
\x18\b
\x01
(
\b
R
\x16
disallowChangeUsername
\x12
8
\n
"
+
"
\x18
disallow_change_nickname
\x18\t
\x01
(
\b
R
\x16
disallowChangeNickname
\"\xa3\x01\n
"
+
"
\x16
WorkspaceCustomProfile
\x12\x14\n
"
+
"
\x16
WorkspaceCustomProfile
\x12\x14\n
"
+
"
\x05
title
\x18\x01
\x01
(
\t
R
\x05
title
\x12
\n
"
+
"
\x05
title
\x18\x01
\x01
(
\t
R
\x05
title
\x12
\n
"
+
"
\v
description
\x18\x02
\x01
(
\t
R
\v
description
\x12\x19\n
"
+
"
\v
description
\x18\x02
\x01
(
\t
R
\v
description
\x12\x19\n
"
+
...
...
proto/store/workspace_setting.proto
View file @
1b3083b2
...
@@ -34,25 +34,27 @@ message WorkspaceBasicSetting {
...
@@ -34,25 +34,27 @@ message WorkspaceBasicSetting {
}
}
message
WorkspaceGeneralSetting
{
message
WorkspaceGeneralSetting
{
// theme is the name of the selected theme.
// This references a CSS file in the web/public/themes/ directory.
string
theme
=
1
;
// disallow_user_registration disallows user registration.
// disallow_user_registration disallows user registration.
bool
disallow_user_registration
=
1
;
bool
disallow_user_registration
=
2
;
// disallow_password_auth disallows password authentication.
// disallow_password_auth disallows password authentication.
bool
disallow_password_auth
=
2
;
bool
disallow_password_auth
=
3
;
// additional_script is the additional script.
// additional_script is the additional script.
string
additional_script
=
3
;
string
additional_script
=
4
;
// additional_style is the additional style.
// additional_style is the additional style.
string
additional_style
=
4
;
string
additional_style
=
5
;
// custom_profile is the custom profile.
// custom_profile is the custom profile.
WorkspaceCustomProfile
custom_profile
=
5
;
WorkspaceCustomProfile
custom_profile
=
6
;
// week_start_day_offset is the week start day offset from Sunday.
// week_start_day_offset is the week start day offset from Sunday.
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday
// Default is Sunday.
// Default is Sunday.
int32
week_start_day_offset
=
6
;
int32
week_start_day_offset
=
7
;
// disallow_change_username disallows changing username.
// disallow_change_username disallows changing username.
bool
disallow_change_username
=
7
;
bool
disallow_change_username
=
8
;
// disallow_change_nickname disallows changing nickname.
// disallow_change_nickname disallows changing nickname.
bool
disallow_change_nickname
=
8
;
bool
disallow_change_nickname
=
9
;
}
}
message
WorkspaceCustomProfile
{
message
WorkspaceCustomProfile
{
...
...
server/router/api/v1/workspace_service.go
View file @
1b3083b2
...
@@ -150,6 +150,7 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
...
@@ -150,6 +150,7 @@ func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSe
return
nil
return
nil
}
}
generalSetting
:=
&
v1pb
.
WorkspaceGeneralSetting
{
generalSetting
:=
&
v1pb
.
WorkspaceGeneralSetting
{
Theme
:
setting
.
Theme
,
DisallowUserRegistration
:
setting
.
DisallowUserRegistration
,
DisallowUserRegistration
:
setting
.
DisallowUserRegistration
,
DisallowPasswordAuth
:
setting
.
DisallowPasswordAuth
,
DisallowPasswordAuth
:
setting
.
DisallowPasswordAuth
,
AdditionalScript
:
setting
.
AdditionalScript
,
AdditionalScript
:
setting
.
AdditionalScript
,
...
@@ -175,6 +176,7 @@ func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceGeneralSetting
...
@@ -175,6 +176,7 @@ func convertWorkspaceGeneralSettingToStore(setting *v1pb.WorkspaceGeneralSetting
return
nil
return
nil
}
}
generalSetting
:=
&
storepb
.
WorkspaceGeneralSetting
{
generalSetting
:=
&
storepb
.
WorkspaceGeneralSetting
{
Theme
:
setting
.
Theme
,
DisallowUserRegistration
:
setting
.
DisallowUserRegistration
,
DisallowUserRegistration
:
setting
.
DisallowUserRegistration
,
DisallowPasswordAuth
:
setting
.
DisallowPasswordAuth
,
DisallowPasswordAuth
:
setting
.
DisallowPasswordAuth
,
AdditionalScript
:
setting
.
AdditionalScript
,
AdditionalScript
:
setting
.
AdditionalScript
,
...
...
web/components.json
View file @
1b3083b2
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
"tsx"
:
true
,
"tsx"
:
true
,
"tailwind"
:
{
"tailwind"
:
{
"config"
:
""
,
"config"
:
""
,
"css"
:
"src/
style
.css"
,
"css"
:
"src/
index
.css"
,
"baseColor"
:
"zinc"
,
"baseColor"
:
"zinc"
,
"cssVariables"
:
true
,
"cssVariables"
:
true
,
"prefix"
:
""
"prefix"
:
""
...
...
web/src/App.tsx
View file @
1b3083b2
...
@@ -5,6 +5,7 @@ import { Outlet } from "react-router-dom";
...
@@ -5,6 +5,7 @@ import { Outlet } from "react-router-dom";
import
{
getSystemColorScheme
}
from
"./helpers/utils"
;
import
{
getSystemColorScheme
}
from
"./helpers/utils"
;
import
useNavigateTo
from
"./hooks/useNavigateTo"
;
import
useNavigateTo
from
"./hooks/useNavigateTo"
;
import
{
userStore
,
workspaceStore
}
from
"./store/v2"
;
import
{
userStore
,
workspaceStore
}
from
"./store/v2"
;
import
{
loadTheme
}
from
"./utils/theme"
;
const
App
=
observer
(()
=>
{
const
App
=
observer
(()
=>
{
const
{
i18n
}
=
useTranslation
();
const
{
i18n
}
=
useTranslation
();
...
@@ -103,6 +104,11 @@ const App = observer(() => {
...
@@ -103,6 +104,11 @@ const App = observer(() => {
});
});
},
[
userSetting
?.
locale
,
userSetting
?.
appearance
]);
},
[
userSetting
?.
locale
,
userSetting
?.
appearance
]);
// Load theme when workspace setting changes, validate API response
useEffect
(()
=>
{
loadTheme
(
workspaceGeneralSetting
.
theme
);
},
[
workspaceGeneralSetting
.
theme
]);
return
<
Outlet
/>;
return
<
Outlet
/>;
});
});
...
...
web/src/components/Settings/WorkspaceSection.tsx
View file @
1b3083b2
...
@@ -17,6 +17,7 @@ import { WorkspaceSettingKey } from "@/store/v2/workspace";
...
@@ -17,6 +17,7 @@ import { WorkspaceSettingKey } from "@/store/v2/workspace";
import
{
IdentityProvider
}
from
"@/types/proto/api/v1/idp_service"
;
import
{
IdentityProvider
}
from
"@/types/proto/api/v1/idp_service"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_service"
;
import
{
WorkspaceGeneralSetting
}
from
"@/types/proto/api/v1/workspace_service"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
ThemeSelector
from
"../ThemeSelector"
;
import
UpdateCustomizedProfileDialog
from
"../UpdateCustomizedProfileDialog"
;
import
UpdateCustomizedProfileDialog
from
"../UpdateCustomizedProfileDialog"
;
const
WorkspaceSection
=
observer
(()
=>
{
const
WorkspaceSection
=
observer
(()
=>
{
...
@@ -82,6 +83,14 @@ const WorkspaceSection = observer(() => {
...
@@ -82,6 +83,14 @@ const WorkspaceSection = observer(() => {
</
div
>
</
div
>
<
Separator
/>
<
Separator
/>
<
p
className=
"font-medium text-foreground"
>
{
t
(
"setting.system-section.title"
)
}
</
p
>
<
p
className=
"font-medium text-foreground"
>
{
t
(
"setting.system-section.title"
)
}
</
p
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
Theme
</
span
>
<
ThemeSelector
value=
{
workspaceGeneralSetting
.
theme
||
"default"
}
onValueChange=
{
(
value
)
=>
updatePartialSetting
({
theme
:
value
})
}
className=
"min-w-fit"
/>
</
div
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
div
className=
"w-full flex flex-row justify-between items-center"
>
<
span
>
{
t
(
"setting.system-section.additional-style"
)
}
</
span
>
<
span
>
{
t
(
"setting.system-section.additional-style"
)
}
</
span
>
</
div
>
</
div
>
...
...
web/src/components/ThemeSelector.tsx
0 → 100644
View file @
1b3083b2
import
{
Select
,
SelectContent
,
SelectItem
,
SelectTrigger
,
SelectValue
}
from
"@/components/ui/select"
;
interface
ThemeSelectorProps
{
value
?:
string
;
onValueChange
:
(
value
:
string
)
=>
void
;
className
?:
string
;
}
const
THEMES
=
[
{
value
:
"default"
,
label
:
"Default"
},
{
value
:
"paper"
,
label
:
"Paper"
},
]
as
const
;
export
const
ThemeSelector
=
({
value
=
"default"
,
onValueChange
,
className
}:
ThemeSelectorProps
)
=>
{
return
(
<
Select
value=
{
value
}
onValueChange=
{
onValueChange
}
>
<
SelectTrigger
className=
{
className
}
>
<
SelectValue
/>
</
SelectTrigger
>
<
SelectContent
>
{
THEMES
.
map
((
theme
)
=>
(
<
SelectItem
key=
{
theme
.
value
}
value=
{
theme
.
value
}
>
{
theme
.
label
}
</
SelectItem
>
))
}
</
SelectContent
>
</
Select
>
);
};
export
default
ThemeSelector
;
web/src/components/ui/dropdown-menu.tsx
View file @
1b3083b2
...
@@ -6,7 +6,8 @@ import { cn } from "@/lib/utils";
...
@@ -6,7 +6,8 @@ import { cn } from "@/lib/utils";
const
DropdownMenu
=
React
.
forwardRef
<
const
DropdownMenu
=
React
.
forwardRef
<
React
.
ElementRef
<
typeof
DropdownMenuPrimitive
.
Root
>
,
React
.
ElementRef
<
typeof
DropdownMenuPrimitive
.
Root
>
,
React
.
ComponentPropsWithoutRef
<
typeof
DropdownMenuPrimitive
.
Root
>
React
.
ComponentPropsWithoutRef
<
typeof
DropdownMenuPrimitive
.
Root
>
>
(({
...
props
})
=>
{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
>
(({
...
props
},
_ref
)
=>
{
return
<
DropdownMenuPrimitive
.
Root
data
-
slot=
"dropdown-menu"
{
...
props
}
/>;
return
<
DropdownMenuPrimitive
.
Root
data
-
slot=
"dropdown-menu"
{
...
props
}
/>;
});
});
DropdownMenu
.
displayName
=
"DropdownMenu"
;
DropdownMenu
.
displayName
=
"DropdownMenu"
;
...
...
web/src/components/ui/popover.tsx
View file @
1b3083b2
...
@@ -5,7 +5,8 @@ import { cn } from "@/lib/utils";
...
@@ -5,7 +5,8 @@ import { cn } from "@/lib/utils";
const
Popover
=
React
.
forwardRef
<
const
Popover
=
React
.
forwardRef
<
React
.
ElementRef
<
typeof
PopoverPrimitive
.
Root
>
,
React
.
ElementRef
<
typeof
PopoverPrimitive
.
Root
>
,
React
.
ComponentPropsWithoutRef
<
typeof
PopoverPrimitive
.
Root
>
React
.
ComponentPropsWithoutRef
<
typeof
PopoverPrimitive
.
Root
>
>
(({
...
props
})
=>
{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
>
(({
...
props
},
_ref
)
=>
{
return
<
PopoverPrimitive
.
Root
data
-
slot=
"popover"
{
...
props
}
/>;
return
<
PopoverPrimitive
.
Root
data
-
slot=
"popover"
{
...
props
}
/>;
});
});
Popover
.
displayName
=
"Popover"
;
Popover
.
displayName
=
"Popover"
;
...
...
web/src/components/ui/sheet.tsx
View file @
1b3083b2
...
@@ -4,7 +4,8 @@ import * as React from "react";
...
@@ -4,7 +4,8 @@ import * as React from "react";
import
{
cn
}
from
"@/lib/utils"
;
import
{
cn
}
from
"@/lib/utils"
;
const
Sheet
=
React
.
forwardRef
<
React
.
ElementRef
<
typeof
SheetPrimitive
.
Root
>
,
React
.
ComponentPropsWithoutRef
<
typeof
SheetPrimitive
.
Root
>>
(
const
Sheet
=
React
.
forwardRef
<
React
.
ElementRef
<
typeof
SheetPrimitive
.
Root
>
,
React
.
ComponentPropsWithoutRef
<
typeof
SheetPrimitive
.
Root
>>
(
({
...
props
})
=>
{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
({
...
props
},
_ref
)
=>
{
return
<
SheetPrimitive
.
Root
data
-
slot=
"sheet"
{
...
props
}
/>;
return
<
SheetPrimitive
.
Root
data
-
slot=
"sheet"
{
...
props
}
/>;
},
},
);
);
...
...
web/src/components/ui/tooltip.tsx
View file @
1b3083b2
...
@@ -5,7 +5,8 @@ import { cn } from "@/lib/utils";
...
@@ -5,7 +5,8 @@ import { cn } from "@/lib/utils";
const
TooltipProvider
=
React
.
forwardRef
<
const
TooltipProvider
=
React
.
forwardRef
<
React
.
ElementRef
<
typeof
TooltipPrimitive
.
Provider
>
,
React
.
ElementRef
<
typeof
TooltipPrimitive
.
Provider
>
,
React
.
ComponentPropsWithoutRef
<
typeof
TooltipPrimitive
.
Provider
>
React
.
ComponentPropsWithoutRef
<
typeof
TooltipPrimitive
.
Provider
>
>
(({
delayDuration
=
0
,
...
props
})
=>
{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
>
(({
delayDuration
=
0
,
...
props
},
_ref
)
=>
{
return
<
TooltipPrimitive
.
Provider
data
-
slot=
"tooltip-provider"
delayDuration=
{
delayDuration
}
{
...
props
}
/>;
return
<
TooltipPrimitive
.
Provider
data
-
slot=
"tooltip-provider"
delayDuration=
{
delayDuration
}
{
...
props
}
/>;
});
});
TooltipProvider
.
displayName
=
"TooltipProvider"
;
TooltipProvider
.
displayName
=
"TooltipProvider"
;
...
@@ -13,7 +14,8 @@ TooltipProvider.displayName = "TooltipProvider";
...
@@ -13,7 +14,8 @@ TooltipProvider.displayName = "TooltipProvider";
const
Tooltip
=
React
.
forwardRef
<
const
Tooltip
=
React
.
forwardRef
<
React
.
ElementRef
<
typeof
TooltipPrimitive
.
Root
>
,
React
.
ElementRef
<
typeof
TooltipPrimitive
.
Root
>
,
React
.
ComponentPropsWithoutRef
<
typeof
TooltipPrimitive
.
Root
>
React
.
ComponentPropsWithoutRef
<
typeof
TooltipPrimitive
.
Root
>
>
(({
...
props
})
=>
{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
>
(({
...
props
},
_ref
)
=>
{
return
(
return
(
<
TooltipProvider
>
<
TooltipProvider
>
<
TooltipPrimitive
.
Root
data
-
slot=
"tooltip"
{
...
props
}
/>
<
TooltipPrimitive
.
Root
data
-
slot=
"tooltip"
{
...
props
}
/>
...
...
web/src/index.css
View file @
1b3083b2
@import
"tailwindcss"
;
@import
"tailwindcss"
;
@import
"tw-animate-css"
;
@import
"tw-animate-css"
;
@import
"./
style
.css"
;
@import
"./
themes/default
.css"
;
@custom-variant
dark
(
&
:
is
(.
dark
*
));
@custom-variant
dark
(
&
:
is
(.
dark
*
));
...
...
web/src/theme/index.ts
deleted
100644 → 0
View file @
3426a791
// Theme configuration for Tailwind CSS v4
// This file is kept for compatibility but no longer used for MUI theme configuration
// All styling is now handled by Tailwind CSS
export
default
{};
web/src/
style
.css
→
web/src/
themes/default
.css
View file @
1b3083b2
File moved
web/src/themes/paper.css
0 → 100644
View file @
1b3083b2
:root
{
--background
:
oklch
(
0.9765
0.0086
85.8732
);
--foreground
:
oklch
(
0.2147
0.0157
68.4253
);
--card
:
oklch
(
0.9765
0.0086
85.8732
);
--card-foreground
:
oklch
(
0.1725
0.0098
72.3456
);
--popover
:
oklch
(
0.9882
0.0049
81.2547
);
--popover-foreground
:
oklch
(
0.2058
0.0127
70.1823
);
--primary
:
oklch
(
0.4627
0.0471
52.3674
);
--primary-foreground
:
oklch
(
0.9765
0.0086
85.8732
);
--secondary
:
oklch
(
0.9412
0.0196
78.9456
);
--secondary-foreground
:
oklch
(
0.3725
0.0235
65.7412
);
--muted
:
oklch
(
0.9294
0.0216
82.1567
);
--muted-foreground
:
oklch
(
0.5294
0.0157
69.8745
);
--accent
:
oklch
(
0.9412
0.0196
78.9456
);
--accent-foreground
:
oklch
(
0.2058
0.0127
70.1823
);
--destructive
:
oklch
(
0.4118
0.0392
25.6734
);
--destructive-foreground
:
oklch
(
0.9647
0.0078
88.2341
);
--border
:
oklch
(
0.8824
0.0157
79.3627
);
--input
:
oklch
(
0.8235
0.0196
82.1456
);
--ring
:
oklch
(
0.4627
0.0471
52.3674
);
--chart-1
:
oklch
(
0.5686
0.0549
42.7834
);
--chart-2
:
oklch
(
0.6275
0.0392
85.6723
);
--chart-3
:
oklch
(
0.7843
0.0235
78.9456
);
--chart-4
:
oklch
(
0.7451
0.0314
68.2341
);
--chart-5
:
oklch
(
0.5412
0.0431
55.8934
);
--sidebar
:
oklch
(
0.9647
0.0118
83.7892
);
--sidebar-foreground
:
oklch
(
0.2941
0.0196
67.6524
);
--sidebar-primary
:
oklch
(
0.4627
0.0471
52.3674
);
--sidebar-primary-foreground
:
oklch
(
0.9765
0.0086
85.8732
);
--sidebar-accent
:
oklch
(
0.9412
0.0196
78.9456
);
--sidebar-accent-foreground
:
oklch
(
0.2647
0.0157
71.2341
);
--sidebar-border
:
oklch
(
0.9294
0.0137
80.5674
);
--sidebar-ring
:
oklch
(
0.7647
0.0235
75.8934
);
--font-sans
:
ui-sans-serif
,
system-ui
,
-apple-system
,
BlinkMacSystemFont
,
"Segoe UI"
,
Roboto
,
"Helvetica Neue"
,
Arial
,
"Noto Sans"
,
sans-serif
,
"Apple Color Emoji"
,
"Segoe UI Emoji"
,
"Segoe UI Symbol"
,
"Noto Color Emoji"
;
--font-serif
:
ui-serif
,
Georgia
,
Cambria
,
"Times New Roman"
,
Times
,
serif
;
--font-mono
:
ui-monospace
,
SFMono-Regular
,
Menlo
,
Monaco
,
Consolas
,
"Liberation Mono"
,
"Courier New"
,
monospace
;
--radius
:
0.5rem
;
--shadow-2xs
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.04
);
--shadow-xs
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.04
);
--shadow-sm
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.08
),
0
1px
2px
-1px
hsl
(
34
12%
15%
/
0.08
);
--shadow
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.08
),
0
1px
2px
-1px
hsl
(
34
12%
15%
/
0.08
);
--shadow-md
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.08
),
0
2px
4px
-1px
hsl
(
34
12%
15%
/
0.08
);
--shadow-lg
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.08
),
0
4px
6px
-1px
hsl
(
34
12%
15%
/
0.08
);
--shadow-xl
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.08
),
0
8px
10px
-1px
hsl
(
34
12%
15%
/
0.08
);
--shadow-2xl
:
0
1px
3px
0px
hsl
(
34
12%
15%
/
0.18
);
--tracking-normal
:
0em
;
--spacing
:
0.25rem
;
}
.dark
{
--background
:
oklch
(
0.1608
0.0118
68.4253
);
--foreground
:
oklch
(
0.8627
0.0196
82.1456
);
--card
:
oklch
(
0.1608
0.0118
68.4253
);
--card-foreground
:
oklch
(
0.8824
0.0157
84.5674
);
--popover
:
oklch
(
0.2118
0.0137
71.2341
);
--popover-foreground
:
oklch
(
0.8706
0.0176
83.8934
);
--primary
:
oklch
(
0.6863
0.0392
52.3674
);
--primary-foreground
:
oklch
(
0.1608
0.0118
68.4253
);
--secondary
:
oklch
(
0.2745
0.0157
72.8934
);
--secondary-foreground
:
oklch
(
0.8627
0.0196
82.1456
);
--muted
:
oklch
(
0.1961
0.0098
69.7823
);
--muted-foreground
:
oklch
(
0.6471
0.0196
78.9456
);
--accent
:
oklch
(
0.2549
0.0118
70.5674
);
--accent-foreground
:
oklch
(
0.8627
0.0196
82.1456
);
--destructive
:
oklch
(
0.5294
0.0314
25.6734
);
--destructive-foreground
:
oklch
(
0.9647
0.0078
88.2341
);
--border
:
oklch
(
0.3137
0.0157
71.8928
);
--input
:
oklch
(
0.3725
0.0176
73.2195
);
--ring
:
oklch
(
0.6863
0.0392
52.3674
);
--chart-1
:
oklch
(
0.5686
0.0549
42.7834
);
--chart-2
:
oklch
(
0.6275
0.0392
85.6723
);
--chart-3
:
oklch
(
0.4706
0.0196
75.2341
);
--chart-4
:
oklch
(
0.3529
0.0235
71.8934
);
--chart-5
:
oklch
(
0.5412
0.0431
55.8934
);
--sidebar
:
oklch
(
0.1412
0.0098
66.7077
);
--sidebar-foreground
:
oklch
(
0.8627
0.0196
82.1456
);
--sidebar-primary
:
oklch
(
0.6863
0.0392
52.3674
);
--sidebar-primary-foreground
:
oklch
(
0.1608
0.0118
68.4253
);
--sidebar-accent
:
oklch
(
0.2353
0.0118
69.8934
);
--sidebar-accent-foreground
:
oklch
(
0.8627
0.0196
82.1456
);
--sidebar-border
:
oklch
(
0.3137
0.0157
71.8928
);
--sidebar-ring
:
oklch
(
0.6863
0.0392
52.3674
);
--font-sans
:
ui-sans-serif
,
system-ui
,
-apple-system
,
BlinkMacSystemFont
,
"Segoe UI"
,
Roboto
,
"Helvetica Neue"
,
Arial
,
"Noto Sans"
,
sans-serif
,
"Apple Color Emoji"
,
"Segoe UI Emoji"
,
"Segoe UI Symbol"
,
"Noto Color Emoji"
;
--font-serif
:
ui-serif
,
Georgia
,
Cambria
,
"Times New Roman"
,
Times
,
serif
;
--font-mono
:
ui-monospace
,
SFMono-Regular
,
Menlo
,
Monaco
,
Consolas
,
"Liberation Mono"
,
"Courier New"
,
monospace
;
--radius
:
0.5rem
;
--shadow-2xs
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.05
);
--shadow-xs
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.05
);
--shadow-sm
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.1
),
0
1px
2px
-1px
hsl
(
0
0%
0%
/
0.1
);
--shadow
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.1
),
0
1px
2px
-1px
hsl
(
0
0%
0%
/
0.1
);
--shadow-md
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.1
),
0
2px
4px
-1px
hsl
(
0
0%
0%
/
0.1
);
--shadow-lg
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.1
),
0
4px
6px
-1px
hsl
(
0
0%
0%
/
0.1
);
--shadow-xl
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.1
),
0
8px
10px
-1px
hsl
(
0
0%
0%
/
0.1
);
--shadow-2xl
:
0
1px
3px
0px
hsl
(
0
0%
0%
/
0.25
);
}
@theme
inline
{
--color-background
:
var
(
--background
);
--color-foreground
:
var
(
--foreground
);
--color-card
:
var
(
--card
);
--color-card-foreground
:
var
(
--card-foreground
);
--color-popover
:
var
(
--popover
);
--color-popover-foreground
:
var
(
--popover-foreground
);
--color-primary
:
var
(
--primary
);
--color-primary-foreground
:
var
(
--primary-foreground
);
--color-secondary
:
var
(
--secondary
);
--color-secondary-foreground
:
var
(
--secondary-foreground
);
--color-muted
:
var
(
--muted
);
--color-muted-foreground
:
var
(
--muted-foreground
);
--color-accent
:
var
(
--accent
);
--color-accent-foreground
:
var
(
--accent-foreground
);
--color-destructive
:
var
(
--destructive
);
--color-destructive-foreground
:
var
(
--destructive-foreground
);
--color-border
:
var
(
--border
);
--color-input
:
var
(
--input
);
--color-ring
:
var
(
--ring
);
--color-chart-1
:
var
(
--chart-1
);
--color-chart-2
:
var
(
--chart-2
);
--color-chart-3
:
var
(
--chart-3
);
--color-chart-4
:
var
(
--chart-4
);
--color-chart-5
:
var
(
--chart-5
);
--color-sidebar
:
var
(
--sidebar
);
--color-sidebar-foreground
:
var
(
--sidebar-foreground
);
--color-sidebar-primary
:
var
(
--sidebar-primary
);
--color-sidebar-primary-foreground
:
var
(
--sidebar-primary-foreground
);
--color-sidebar-accent
:
var
(
--sidebar-accent
);
--color-sidebar-accent-foreground
:
var
(
--sidebar-accent-foreground
);
--color-sidebar-border
:
var
(
--sidebar-border
);
--color-sidebar-ring
:
var
(
--sidebar-ring
);
--font-sans
:
var
(
--font-sans
);
--font-mono
:
var
(
--font-mono
);
--font-serif
:
var
(
--font-serif
);
--radius-sm
:
calc
(
var
(
--radius
)
-
4px
);
--radius-md
:
calc
(
var
(
--radius
)
-
2px
);
--radius-lg
:
var
(
--radius
);
--radius-xl
:
calc
(
var
(
--radius
)
+
4px
);
--shadow-2xs
:
var
(
--shadow-2xs
);
--shadow-xs
:
var
(
--shadow-xs
);
--shadow-sm
:
var
(
--shadow-sm
);
--shadow
:
var
(
--shadow
);
--shadow-md
:
var
(
--shadow-md
);
--shadow-lg
:
var
(
--shadow-lg
);
--shadow-xl
:
var
(
--shadow-xl
);
--shadow-2xl
:
var
(
--shadow-2xl
);
}
\ No newline at end of file
web/src/types/proto/api/v1/workspace_service.ts
View file @
1b3083b2
...
@@ -42,6 +42,11 @@ export interface WorkspaceSetting {
...
@@ -42,6 +42,11 @@ export interface WorkspaceSetting {
}
}
export
interface
WorkspaceGeneralSetting
{
export
interface
WorkspaceGeneralSetting
{
/**
* theme is the name of the selected theme.
* This references a CSS file in the web/public/themes/ directory.
*/
theme
:
string
;
/** disallow_user_registration disallows user registration. */
/** disallow_user_registration disallows user registration. */
disallowUserRegistration
:
boolean
;
disallowUserRegistration
:
boolean
;
/** disallow_password_auth disallows password authentication. */
/** disallow_password_auth disallows password authentication. */
...
@@ -394,6 +399,7 @@ export const WorkspaceSetting: MessageFns<WorkspaceSetting> = {
...
@@ -394,6 +399,7 @@ export const WorkspaceSetting: MessageFns<WorkspaceSetting> = {
function
createBaseWorkspaceGeneralSetting
():
WorkspaceGeneralSetting
{
function
createBaseWorkspaceGeneralSetting
():
WorkspaceGeneralSetting
{
return
{
return
{
theme
:
""
,
disallowUserRegistration
:
false
,
disallowUserRegistration
:
false
,
disallowPasswordAuth
:
false
,
disallowPasswordAuth
:
false
,
additionalScript
:
""
,
additionalScript
:
""
,
...
@@ -407,29 +413,32 @@ function createBaseWorkspaceGeneralSetting(): WorkspaceGeneralSetting {
...
@@ -407,29 +413,32 @@ function createBaseWorkspaceGeneralSetting(): WorkspaceGeneralSetting {
export
const
WorkspaceGeneralSetting
:
MessageFns
<
WorkspaceGeneralSetting
>
=
{
export
const
WorkspaceGeneralSetting
:
MessageFns
<
WorkspaceGeneralSetting
>
=
{
encode
(
message
:
WorkspaceGeneralSetting
,
writer
:
BinaryWriter
=
new
BinaryWriter
()):
BinaryWriter
{
encode
(
message
:
WorkspaceGeneralSetting
,
writer
:
BinaryWriter
=
new
BinaryWriter
()):
BinaryWriter
{
if
(
message
.
theme
!==
""
)
{
writer
.
uint32
(
10
).
string
(
message
.
theme
);
}
if
(
message
.
disallowUserRegistration
!==
false
)
{
if
(
message
.
disallowUserRegistration
!==
false
)
{
writer
.
uint32
(
8
).
bool
(
message
.
disallowUserRegistration
);
writer
.
uint32
(
16
).
bool
(
message
.
disallowUserRegistration
);
}
}
if
(
message
.
disallowPasswordAuth
!==
false
)
{
if
(
message
.
disallowPasswordAuth
!==
false
)
{
writer
.
uint32
(
16
).
bool
(
message
.
disallowPasswordAuth
);
writer
.
uint32
(
24
).
bool
(
message
.
disallowPasswordAuth
);
}
}
if
(
message
.
additionalScript
!==
""
)
{
if
(
message
.
additionalScript
!==
""
)
{
writer
.
uint32
(
26
).
string
(
message
.
additionalScript
);
writer
.
uint32
(
34
).
string
(
message
.
additionalScript
);
}
}
if
(
message
.
additionalStyle
!==
""
)
{
if
(
message
.
additionalStyle
!==
""
)
{
writer
.
uint32
(
34
).
string
(
message
.
additionalStyle
);
writer
.
uint32
(
42
).
string
(
message
.
additionalStyle
);
}
}
if
(
message
.
customProfile
!==
undefined
)
{
if
(
message
.
customProfile
!==
undefined
)
{
WorkspaceCustomProfile
.
encode
(
message
.
customProfile
,
writer
.
uint32
(
42
).
fork
()).
join
();
WorkspaceCustomProfile
.
encode
(
message
.
customProfile
,
writer
.
uint32
(
50
).
fork
()).
join
();
}
}
if
(
message
.
weekStartDayOffset
!==
0
)
{
if
(
message
.
weekStartDayOffset
!==
0
)
{
writer
.
uint32
(
48
).
int32
(
message
.
weekStartDayOffset
);
writer
.
uint32
(
56
).
int32
(
message
.
weekStartDayOffset
);
}
}
if
(
message
.
disallowChangeUsername
!==
false
)
{
if
(
message
.
disallowChangeUsername
!==
false
)
{
writer
.
uint32
(
56
).
bool
(
message
.
disallowChangeUsername
);
writer
.
uint32
(
64
).
bool
(
message
.
disallowChangeUsername
);
}
}
if
(
message
.
disallowChangeNickname
!==
false
)
{
if
(
message
.
disallowChangeNickname
!==
false
)
{
writer
.
uint32
(
64
).
bool
(
message
.
disallowChangeNickname
);
writer
.
uint32
(
72
).
bool
(
message
.
disallowChangeNickname
);
}
}
return
writer
;
return
writer
;
},
},
...
@@ -442,11 +451,11 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
...
@@ -442,11 +451,11 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
const
tag
=
reader
.
uint32
();
const
tag
=
reader
.
uint32
();
switch
(
tag
>>>
3
)
{
switch
(
tag
>>>
3
)
{
case
1
:
{
case
1
:
{
if
(
tag
!==
8
)
{
if
(
tag
!==
10
)
{
break
;
break
;
}
}
message
.
disallowUserRegistration
=
reader
.
bool
();
message
.
theme
=
reader
.
string
();
continue
;
continue
;
}
}
case
2
:
{
case
2
:
{
...
@@ -454,15 +463,15 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
...
@@ -454,15 +463,15 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
break
;
break
;
}
}
message
.
disallow
PasswordAuth
=
reader
.
bool
();
message
.
disallow
UserRegistration
=
reader
.
bool
();
continue
;
continue
;
}
}
case
3
:
{
case
3
:
{
if
(
tag
!==
2
6
)
{
if
(
tag
!==
2
4
)
{
break
;
break
;
}
}
message
.
additionalScript
=
reader
.
string
();
message
.
disallowPasswordAuth
=
reader
.
bool
();
continue
;
continue
;
}
}
case
4
:
{
case
4
:
{
...
@@ -470,7 +479,7 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
...
@@ -470,7 +479,7 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
break
;
break
;
}
}
message
.
additionalS
tyle
=
reader
.
string
();
message
.
additionalS
cript
=
reader
.
string
();
continue
;
continue
;
}
}
case
5
:
{
case
5
:
{
...
@@ -478,15 +487,15 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
...
@@ -478,15 +487,15 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
break
;
break
;
}
}
message
.
customProfile
=
WorkspaceCustomProfile
.
decode
(
reader
,
reader
.
uint32
()
);
message
.
additionalStyle
=
reader
.
string
(
);
continue
;
continue
;
}
}
case
6
:
{
case
6
:
{
if
(
tag
!==
48
)
{
if
(
tag
!==
50
)
{
break
;
break
;
}
}
message
.
weekStartDayOffset
=
reader
.
int32
(
);
message
.
customProfile
=
WorkspaceCustomProfile
.
decode
(
reader
,
reader
.
uint32
()
);
continue
;
continue
;
}
}
case
7
:
{
case
7
:
{
...
@@ -494,7 +503,7 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
...
@@ -494,7 +503,7 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
break
;
break
;
}
}
message
.
disallowChangeUsername
=
reader
.
bool
();
message
.
weekStartDayOffset
=
reader
.
int32
();
continue
;
continue
;
}
}
case
8
:
{
case
8
:
{
...
@@ -502,6 +511,14 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
...
@@ -502,6 +511,14 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
break
;
break
;
}
}
message
.
disallowChangeUsername
=
reader
.
bool
();
continue
;
}
case
9
:
{
if
(
tag
!==
72
)
{
break
;
}
message
.
disallowChangeNickname
=
reader
.
bool
();
message
.
disallowChangeNickname
=
reader
.
bool
();
continue
;
continue
;
}
}
...
@@ -519,6 +536,7 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
...
@@ -519,6 +536,7 @@ export const WorkspaceGeneralSetting: MessageFns<WorkspaceGeneralSetting> = {
},
},
fromPartial
(
object
:
DeepPartial
<
WorkspaceGeneralSetting
>
):
WorkspaceGeneralSetting
{
fromPartial
(
object
:
DeepPartial
<
WorkspaceGeneralSetting
>
):
WorkspaceGeneralSetting
{
const
message
=
createBaseWorkspaceGeneralSetting
();
const
message
=
createBaseWorkspaceGeneralSetting
();
message
.
theme
=
object
.
theme
??
""
;
message
.
disallowUserRegistration
=
object
.
disallowUserRegistration
??
false
;
message
.
disallowUserRegistration
=
object
.
disallowUserRegistration
??
false
;
message
.
disallowPasswordAuth
=
object
.
disallowPasswordAuth
??
false
;
message
.
disallowPasswordAuth
=
object
.
disallowPasswordAuth
??
false
;
message
.
additionalScript
=
object
.
additionalScript
??
""
;
message
.
additionalScript
=
object
.
additionalScript
??
""
;
...
...
web/src/utils/theme.ts
0 → 100644
View file @
1b3083b2
import
paperThemeContent
from
"../themes/paper.css?raw"
;
const
VALID_THEMES
=
[
"default"
,
"paper"
]
as
const
;
type
ValidTheme
=
(
typeof
VALID_THEMES
)[
number
];
const
THEME_CONTENT
:
Record
<
ValidTheme
,
string
|
null
>
=
{
default
:
null
,
paper
:
paperThemeContent
,
};
const
validateTheme
=
(
theme
:
string
):
ValidTheme
=>
{
return
VALID_THEMES
.
includes
(
theme
as
ValidTheme
)
?
(
theme
as
ValidTheme
)
:
"default"
;
};
export
const
getStoredTheme
=
():
ValidTheme
=>
{
const
stored
=
localStorage
.
getItem
(
"workspace-theme"
);
return
stored
?
validateTheme
(
stored
)
:
"default"
;
};
export
const
loadTheme
=
(
themeName
:
string
):
void
=>
{
const
validTheme
=
validateTheme
(
themeName
);
// Store theme
localStorage
.
setItem
(
"workspace-theme"
,
validTheme
);
// Remove existing theme
document
.
getElementById
(
"workspace-theme"
)?.
remove
();
// Apply theme (skip for default)
if
(
validTheme
!==
"default"
)
{
const
css
=
THEME_CONTENT
[
validTheme
];
if
(
css
)
{
const
style
=
document
.
createElement
(
"style"
);
style
.
id
=
"workspace-theme"
;
style
.
textContent
=
css
;
document
.
head
.
appendChild
(
style
);
}
}
// Set data attribute
document
.
documentElement
.
setAttribute
(
"data-theme"
,
validTheme
);
};
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