mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
fix: update workspace general setting
This commit is contained in:
@ -5,9 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"go.uber.org/zap"
|
|
||||||
|
|
||||||
"github.com/usememos/memos/internal/log"
|
|
||||||
"github.com/usememos/memos/server/profile"
|
"github.com/usememos/memos/server/profile"
|
||||||
"github.com/usememos/memos/store"
|
"github.com/usememos/memos/store"
|
||||||
)
|
)
|
||||||
@ -18,18 +16,12 @@ type SystemStatus struct {
|
|||||||
DBSize int64 `json:"dbSize"`
|
DBSize int64 `json:"dbSize"`
|
||||||
|
|
||||||
// System settings
|
// System settings
|
||||||
// Allow sign up.
|
|
||||||
AllowSignUp bool `json:"allowSignUp"`
|
|
||||||
// Disable password login.
|
// Disable password login.
|
||||||
DisablePasswordLogin bool `json:"disablePasswordLogin"`
|
DisablePasswordLogin bool `json:"disablePasswordLogin"`
|
||||||
// Disable public memos.
|
// Disable public memos.
|
||||||
DisablePublicMemos bool `json:"disablePublicMemos"`
|
DisablePublicMemos bool `json:"disablePublicMemos"`
|
||||||
// Max upload size.
|
// Max upload size.
|
||||||
MaxUploadSizeMiB int `json:"maxUploadSizeMiB"`
|
MaxUploadSizeMiB int `json:"maxUploadSizeMiB"`
|
||||||
// Additional style.
|
|
||||||
AdditionalStyle string `json:"additionalStyle"`
|
|
||||||
// Additional script.
|
|
||||||
AdditionalScript string `json:"additionalScript"`
|
|
||||||
// Customized server profile, including server name and external url.
|
// Customized server profile, including server name and external url.
|
||||||
CustomizedProfile CustomizedProfile `json:"customizedProfile"`
|
CustomizedProfile CustomizedProfile `json:"customizedProfile"`
|
||||||
// Storage service ID.
|
// Storage service ID.
|
||||||
@ -74,8 +66,6 @@ func (s *APIV1Service) GetSystemStatus(c echo.Context) error {
|
|||||||
Mode: s.Profile.Mode,
|
Mode: s.Profile.Mode,
|
||||||
Version: s.Profile.Version,
|
Version: s.Profile.Version,
|
||||||
},
|
},
|
||||||
// Allow sign up by default.
|
|
||||||
AllowSignUp: true,
|
|
||||||
MaxUploadSizeMiB: 32,
|
MaxUploadSizeMiB: 32,
|
||||||
CustomizedProfile: CustomizedProfile{
|
CustomizedProfile: CustomizedProfile{
|
||||||
Name: "Memos",
|
Name: "Memos",
|
||||||
@ -101,10 +91,7 @@ func (s *APIV1Service) GetSystemStatus(c echo.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace general setting").SetInternal(err)
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace general setting").SetInternal(err)
|
||||||
}
|
}
|
||||||
systemStatus.AllowSignUp = !workspaceGeneralSetting.DisallowSignup
|
|
||||||
systemStatus.DisablePasswordLogin = workspaceGeneralSetting.DisallowPasswordLogin
|
systemStatus.DisablePasswordLogin = workspaceGeneralSetting.DisallowPasswordLogin
|
||||||
systemStatus.AdditionalStyle = workspaceGeneralSetting.AdditionalStyle
|
|
||||||
systemStatus.AdditionalScript = workspaceGeneralSetting.AdditionalScript
|
|
||||||
|
|
||||||
systemSettingList, err := s.Store.ListWorkspaceSettings(ctx, &store.FindWorkspaceSetting{})
|
systemSettingList, err := s.Store.ListWorkspaceSettings(ctx, &store.FindWorkspaceSetting{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -140,7 +127,7 @@ func (s *APIV1Service) GetSystemStatus(c echo.Context) error {
|
|||||||
case SystemSettingMemoDisplayWithUpdatedTsName.String():
|
case SystemSettingMemoDisplayWithUpdatedTsName.String():
|
||||||
systemStatus.MemoDisplayWithUpdatedTs = baseValue.(bool)
|
systemStatus.MemoDisplayWithUpdatedTs = baseValue.(bool)
|
||||||
default:
|
default:
|
||||||
log.Warn("Unknown system setting name", zap.String("setting name", systemSetting.Name))
|
// Skip unknown system setting.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,20 +3,20 @@ package v2
|
|||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
var authenticationAllowlistMethods = map[string]bool{
|
var authenticationAllowlistMethods = map[string]bool{
|
||||||
"/memos.api.v2.WorkspaceService/GetWorkspaceProfile": true,
|
"/memos.api.v2.WorkspaceService/GetWorkspaceProfile": true,
|
||||||
"/memos.api.v2.WorkspaceService/GetWorkspaceSetting": true,
|
"/memos.api.v2.WorkspaceSettingService/GetWorkspaceSetting": true,
|
||||||
"/memos.api.v2.AuthService/GetAuthStatus": true,
|
"/memos.api.v2.AuthService/GetAuthStatus": true,
|
||||||
"/memos.api.v2.AuthService/SignIn": true,
|
"/memos.api.v2.AuthService/SignIn": true,
|
||||||
"/memos.api.v2.AuthService/SignInWithSSO": true,
|
"/memos.api.v2.AuthService/SignInWithSSO": true,
|
||||||
"/memos.api.v2.AuthService/SignOut": true,
|
"/memos.api.v2.AuthService/SignOut": true,
|
||||||
"/memos.api.v2.AuthService/SignUp": true,
|
"/memos.api.v2.AuthService/SignUp": true,
|
||||||
"/memos.api.v2.UserService/GetUser": true,
|
"/memos.api.v2.UserService/GetUser": true,
|
||||||
"/memos.api.v2.MemoService/ListMemos": true,
|
"/memos.api.v2.MemoService/ListMemos": true,
|
||||||
"/memos.api.v2.MemoService/GetMemo": true,
|
"/memos.api.v2.MemoService/GetMemo": true,
|
||||||
"/memos.api.v2.MemoService/GetMemoByName": true,
|
"/memos.api.v2.MemoService/GetMemoByName": true,
|
||||||
"/memos.api.v2.MemoService/ListMemoResources": true,
|
"/memos.api.v2.MemoService/ListMemoResources": true,
|
||||||
"/memos.api.v2.MemoService/ListMemoRelations": true,
|
"/memos.api.v2.MemoService/ListMemoRelations": true,
|
||||||
"/memos.api.v2.MemoService/ListMemoComments": true,
|
"/memos.api.v2.MemoService/ListMemoComments": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUnauthorizeAllowedMethod returns whether the method is exempted from authentication.
|
// isUnauthorizeAllowedMethod returns whether the method is exempted from authentication.
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { useColorScheme } from "@mui/joy";
|
import { useColorScheme } from "@mui/joy";
|
||||||
import mermaid from "mermaid";
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Outlet } from "react-router-dom";
|
import { Outlet } from "react-router-dom";
|
||||||
@ -7,19 +6,22 @@ import storage from "./helpers/storage";
|
|||||||
import { getSystemColorScheme } from "./helpers/utils";
|
import { getSystemColorScheme } from "./helpers/utils";
|
||||||
import useNavigateTo from "./hooks/useNavigateTo";
|
import useNavigateTo from "./hooks/useNavigateTo";
|
||||||
import { useGlobalStore } from "./store/module";
|
import { useGlobalStore } from "./store/module";
|
||||||
import { useUserStore } from "./store/v1";
|
import { useUserStore, useWorkspaceSettingStore } from "./store/v1";
|
||||||
|
import { WorkspaceGeneralSetting, WorkspaceSettingKey } from "./types/proto/store/workspace_setting";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
const navigateTo = useNavigateTo();
|
const navigateTo = useNavigateTo();
|
||||||
const { mode, setMode } = useColorScheme();
|
const { mode, setMode } = useColorScheme();
|
||||||
const globalStore = useGlobalStore();
|
const globalStore = useGlobalStore();
|
||||||
|
const workspaceSettingStore = useWorkspaceSettingStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const { appearance, locale, systemStatus } = globalStore.state;
|
const { appearance, locale, systemStatus } = globalStore.state;
|
||||||
const userSetting = userStore.userSetting;
|
const userSetting = userStore.userSetting;
|
||||||
|
const workspaceGeneralSetting =
|
||||||
mermaid.initialize({ startOnLoad: false, theme: mode });
|
workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL).generalSetting ||
|
||||||
|
WorkspaceGeneralSetting.fromPartial({});
|
||||||
|
|
||||||
// Redirect to sign up page if no host.
|
// Redirect to sign up page if no host.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -30,6 +32,7 @@ const App = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initialState = async () => {
|
const initialState = async () => {
|
||||||
|
await workspaceSettingStore.fetchWorkspaceSetting(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL);
|
||||||
try {
|
try {
|
||||||
await userStore.fetchCurrentUser();
|
await userStore.fetchCurrentUser();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -61,21 +64,21 @@ const App = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (systemStatus.additionalStyle) {
|
if (workspaceGeneralSetting.additionalStyle) {
|
||||||
const styleEl = document.createElement("style");
|
const styleEl = document.createElement("style");
|
||||||
styleEl.innerHTML = systemStatus.additionalStyle;
|
styleEl.innerHTML = workspaceGeneralSetting.additionalStyle;
|
||||||
styleEl.setAttribute("type", "text/css");
|
styleEl.setAttribute("type", "text/css");
|
||||||
document.body.insertAdjacentElement("beforeend", styleEl);
|
document.body.insertAdjacentElement("beforeend", styleEl);
|
||||||
}
|
}
|
||||||
}, [systemStatus.additionalStyle]);
|
}, [workspaceGeneralSetting.additionalStyle]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (systemStatus.additionalScript) {
|
if (workspaceGeneralSetting.additionalScript) {
|
||||||
const scriptEl = document.createElement("script");
|
const scriptEl = document.createElement("script");
|
||||||
scriptEl.innerHTML = systemStatus.additionalScript;
|
scriptEl.innerHTML = workspaceGeneralSetting.additionalScript;
|
||||||
document.head.appendChild(scriptEl);
|
document.head.appendChild(scriptEl);
|
||||||
}
|
}
|
||||||
}, [systemStatus.additionalScript]);
|
}, [workspaceGeneralSetting.additionalScript]);
|
||||||
|
|
||||||
// Dynamic update metadata with customized profile.
|
// Dynamic update metadata with customized profile.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useColorScheme } from "@mui/joy";
|
||||||
import mermaid from "mermaid";
|
import mermaid from "mermaid";
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
@ -6,14 +7,16 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MermaidBlock: React.FC<Props> = ({ content }: Props) => {
|
const MermaidBlock: React.FC<Props> = ({ content }: Props) => {
|
||||||
|
const { mode } = useColorScheme();
|
||||||
const mermaidDockBlock = useRef<null>(null);
|
const mermaidDockBlock = useRef<null>(null);
|
||||||
|
mermaid.initialize({ startOnLoad: false, theme: mode });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!mermaidDockBlock.current) {
|
if (!mermaidDockBlock.current) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render mermaid when mounted
|
// Render mermaid when mounted.
|
||||||
mermaid.run({
|
mermaid.run({
|
||||||
nodes: [mermaidDockBlock.current],
|
nodes: [mermaidDockBlock.current],
|
||||||
});
|
});
|
||||||
|
@ -72,13 +72,14 @@ const SystemSection = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDisablePasswordLoginChanged = async (value: boolean) => {
|
const handleDisablePasswordLoginChanged = async (value: boolean) => {
|
||||||
setWorkspaceGeneralSetting({ ...workspaceGeneralSetting, disallowPasswordLogin: value });
|
const setting = { ...workspaceGeneralSetting, disallowPasswordLogin: value };
|
||||||
await workspaceSettingServiceClient.setWorkspaceSetting({
|
await workspaceSettingServiceClient.setWorkspaceSetting({
|
||||||
setting: {
|
setting: {
|
||||||
name: `${WorkspaceSettingPrefix}${WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL}`,
|
name: `${WorkspaceSettingPrefix}${WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL}`,
|
||||||
generalSetting: workspaceGeneralSetting,
|
generalSetting: setting,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
setWorkspaceGeneralSetting(setting);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateCustomizedProfileButtonClick = () => {
|
const handleUpdateCustomizedProfileButtonClick = () => {
|
||||||
@ -223,7 +224,7 @@ const SystemSection = () => {
|
|||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("common.settings")}</p>
|
<p className="font-medium text-gray-700 dark:text-gray-500">{t("common.settings")}</p>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="normal-text">{t("setting.system-section.allow-user-signup")}</span>
|
<span className="normal-text">{t("setting.system-section.allow-user-signup")}</span>
|
||||||
<Switch checked={workspaceGeneralSetting.disallowSignup} onChange={(event) => handleAllowSignUpChanged(event.target.checked)} />
|
<Switch checked={!workspaceGeneralSetting.disallowSignup} onChange={(event) => handleAllowSignUpChanged(event.target.checked)} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="normal-text">{t("setting.system-section.disable-password-login")}</span>
|
<span className="normal-text">{t("setting.system-section.disable-password-login")}</span>
|
||||||
|
@ -11,13 +11,16 @@ import { absolutifyLink } from "@/helpers/utils";
|
|||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||||
import { useGlobalStore } from "@/store/module";
|
import { useGlobalStore } from "@/store/module";
|
||||||
import { useUserStore } from "@/store/v1";
|
import { useUserStore, useWorkspaceSettingStore } from "@/store/v1";
|
||||||
|
import { WorkspaceGeneralSetting } from "@/types/proto/api/v2/workspace_setting_service";
|
||||||
|
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
const SignIn = () => {
|
const SignIn = () => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const navigateTo = useNavigateTo();
|
const navigateTo = useNavigateTo();
|
||||||
const globalStore = useGlobalStore();
|
const globalStore = useGlobalStore();
|
||||||
|
const workspaceSettingStore = useWorkspaceSettingStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const actionBtnLoadingState = useLoading(false);
|
const actionBtnLoadingState = useLoading(false);
|
||||||
const { appearance, locale, systemStatus } = globalStore.state;
|
const { appearance, locale, systemStatus } = globalStore.state;
|
||||||
@ -25,8 +28,12 @@ const SignIn = () => {
|
|||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [remember, setRemember] = useState(true);
|
const [remember, setRemember] = useState(true);
|
||||||
const disablePasswordLogin = systemStatus.disablePasswordLogin;
|
|
||||||
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
||||||
|
const workspaceGeneralSetting =
|
||||||
|
workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL).generalSetting ||
|
||||||
|
WorkspaceGeneralSetting.fromPartial({});
|
||||||
|
|
||||||
|
console.log("workspaceGeneralSetting", workspaceGeneralSetting);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchIdentityProviderList = async () => {
|
const fetchIdentityProviderList = async () => {
|
||||||
@ -112,7 +119,7 @@ const SignIn = () => {
|
|||||||
<img className="h-14 w-auto rounded-full shadow" src={systemStatus.customizedProfile.logoUrl} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={systemStatus.customizedProfile.logoUrl} alt="" />
|
||||||
<p className="ml-2 text-5xl text-black opacity-80 dark:text-gray-200">{systemStatus.customizedProfile.name}</p>
|
<p className="ml-2 text-5xl text-black opacity-80 dark:text-gray-200">{systemStatus.customizedProfile.name}</p>
|
||||||
</div>
|
</div>
|
||||||
{!disablePasswordLogin && (
|
{!workspaceGeneralSetting.disallowPasswordLogin && (
|
||||||
<>
|
<>
|
||||||
<form className="w-full mt-2" onSubmit={handleFormSubmit}>
|
<form className="w-full mt-2" onSubmit={handleFormSubmit}>
|
||||||
<div className="flex flex-col justify-start items-start w-full gap-4">
|
<div className="flex flex-col justify-start items-start w-full gap-4">
|
||||||
@ -164,7 +171,7 @@ const SignIn = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{systemStatus.allowSignUp && (
|
{!workspaceGeneralSetting.disallowSignup && (
|
||||||
<p className="w-full mt-4 text-sm">
|
<p className="w-full mt-4 text-sm">
|
||||||
<span className="dark:text-gray-500">{t("auth.sign-up-tip")}</span>
|
<span className="dark:text-gray-500">{t("auth.sign-up-tip")}</span>
|
||||||
<Link to="/auth/signup" className="cursor-pointer ml-2 text-blue-600 hover:underline" unstable_viewTransition>
|
<Link to="/auth/signup" className="cursor-pointer ml-2 text-blue-600 hover:underline" unstable_viewTransition>
|
||||||
@ -176,7 +183,7 @@ const SignIn = () => {
|
|||||||
)}
|
)}
|
||||||
{identityProviderList.length > 0 && (
|
{identityProviderList.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{!disablePasswordLogin && <Divider className="!my-4">{t("common.or")}</Divider>}
|
{!workspaceGeneralSetting.disallowPasswordLogin && <Divider className="!my-4">{t("common.or")}</Divider>}
|
||||||
<div className="w-full flex flex-col space-y-2">
|
<div className="w-full flex flex-col space-y-2">
|
||||||
{identityProviderList.map((identityProvider) => (
|
{identityProviderList.map((identityProvider) => (
|
||||||
<Button
|
<Button
|
||||||
|
@ -10,12 +10,9 @@ export const initialGlobalState = async () => {
|
|||||||
locale: "en" as Locale,
|
locale: "en" as Locale,
|
||||||
appearance: "system" as Appearance,
|
appearance: "system" as Appearance,
|
||||||
systemStatus: {
|
systemStatus: {
|
||||||
allowSignUp: false,
|
|
||||||
disablePasswordLogin: false,
|
disablePasswordLogin: false,
|
||||||
disablePublicMemos: false,
|
disablePublicMemos: false,
|
||||||
maxUploadSizeMiB: 0,
|
maxUploadSizeMiB: 0,
|
||||||
additionalStyle: "",
|
|
||||||
additionalScript: "",
|
|
||||||
memoDisplayWithUpdatedTs: false,
|
memoDisplayWithUpdatedTs: false,
|
||||||
customizedProfile: {
|
customizedProfile: {
|
||||||
name: "Memos",
|
name: "Memos",
|
||||||
|
@ -17,11 +17,8 @@ const globalSlice = createSlice({
|
|||||||
mode: "demo",
|
mode: "demo",
|
||||||
version: "",
|
version: "",
|
||||||
},
|
},
|
||||||
allowSignUp: false,
|
|
||||||
disablePasswordLogin: false,
|
disablePasswordLogin: false,
|
||||||
disablePublicMemos: false,
|
disablePublicMemos: false,
|
||||||
additionalStyle: "",
|
|
||||||
additionalScript: "",
|
|
||||||
memoDisplayWithUpdatedTs: false,
|
memoDisplayWithUpdatedTs: false,
|
||||||
customizedProfile: {
|
customizedProfile: {
|
||||||
name: "Memos",
|
name: "Memos",
|
||||||
|
@ -3,3 +3,4 @@ export * from "./memo";
|
|||||||
export * from "./inbox";
|
export * from "./inbox";
|
||||||
export * from "./resourceName";
|
export * from "./resourceName";
|
||||||
export * from "./resource";
|
export * from "./resource";
|
||||||
|
export * from "./workspaceSetting";
|
||||||
|
29
web/src/store/v1/workspaceSetting.ts
Normal file
29
web/src/store/v1/workspaceSetting.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { create } from "zustand";
|
||||||
|
import { combine } from "zustand/middleware";
|
||||||
|
import { workspaceSettingServiceClient } from "@/grpcweb";
|
||||||
|
import { WorkspaceSetting } from "@/types/proto/api/v2/workspace_setting_service";
|
||||||
|
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||||
|
import { WorkspaceSettingPrefix } from "./resourceName";
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
workspaceSettingByName: Record<string, WorkspaceSetting>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDefaultState = (): State => ({
|
||||||
|
workspaceSettingByName: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useWorkspaceSettingStore = create(
|
||||||
|
combine(getDefaultState(), (set, get) => ({
|
||||||
|
fetchWorkspaceSetting: async (key: WorkspaceSettingKey) => {
|
||||||
|
const { setting } = await workspaceSettingServiceClient.getWorkspaceSetting({ name: `${WorkspaceSettingPrefix}${key}` });
|
||||||
|
if (!setting) {
|
||||||
|
throw new Error("Workspace setting not found");
|
||||||
|
}
|
||||||
|
set({ workspaceSettingByName: { ...get().workspaceSettingByName, [setting.name]: setting } });
|
||||||
|
},
|
||||||
|
getWorkspaceSettingByKey: (key: WorkspaceSettingKey) => {
|
||||||
|
return get().workspaceSettingByName[`${WorkspaceSettingPrefix}${key}`];
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
);
|
3
web/src/types/modules/system.d.ts
vendored
3
web/src/types/modules/system.d.ts
vendored
@ -15,12 +15,9 @@ interface SystemStatus {
|
|||||||
host?: User;
|
host?: User;
|
||||||
profile: Profile;
|
profile: Profile;
|
||||||
// System settings
|
// System settings
|
||||||
allowSignUp: boolean;
|
|
||||||
disablePasswordLogin: boolean;
|
disablePasswordLogin: boolean;
|
||||||
disablePublicMemos: boolean;
|
disablePublicMemos: boolean;
|
||||||
maxUploadSizeMiB: number;
|
maxUploadSizeMiB: number;
|
||||||
additionalStyle: string;
|
|
||||||
additionalScript: string;
|
|
||||||
customizedProfile: CustomizedProfile;
|
customizedProfile: CustomizedProfile;
|
||||||
storageServiceId: number;
|
storageServiceId: number;
|
||||||
localStoragePath: string;
|
localStoragePath: string;
|
||||||
|
Reference in New Issue
Block a user