mirror of
https://github.com/usememos/memos.git
synced 2025-02-19 04:40:40 +01:00
feat: hide ask ai button when key is empty (#1515)
* Add option to hide Ask AI and update dev version * Fix formatting according to eslint * Replace option to hide Ask AI with auto hiding based on config * Fix golangci-lint errors * Remove showAskAI logic from OpenAPI
This commit is contained in:
parent
648634d376
commit
2c328a4540
@ -24,4 +24,6 @@ type SystemStatus struct {
|
||||
StorageServiceID int `json:"storageServiceId"`
|
||||
// Local storage path
|
||||
LocalStoragePath string `json:"localStoragePath"`
|
||||
// Local storage path
|
||||
OpenAIConfig OpenAIConfig `json:"openAIConfig"`
|
||||
}
|
||||
|
@ -56,6 +56,10 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
|
||||
},
|
||||
StorageServiceID: api.DatabaseStorage,
|
||||
LocalStoragePath: "",
|
||||
OpenAIConfig: api.OpenAIConfig{
|
||||
Key: "",
|
||||
Host: "",
|
||||
},
|
||||
}
|
||||
|
||||
systemSettingList, err := s.Store.FindSystemSettingList(ctx, &api.SystemSettingFind{})
|
||||
@ -95,6 +99,13 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
|
||||
systemStatus.StorageServiceID = int(baseValue.(float64))
|
||||
} else if systemSetting.Name == api.SystemSettingLocalStoragePathName {
|
||||
systemStatus.LocalStoragePath = baseValue.(string)
|
||||
} else if systemSetting.Name == api.SystemSettingOpenAIConfigName {
|
||||
openAIConfig := api.OpenAIConfig{}
|
||||
err := json.Unmarshal([]byte(systemSetting.Value), &openAIConfig)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting open ai config value").SetInternal(err)
|
||||
}
|
||||
systemStatus.OpenAIConfig = openAIConfig
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect } from "react";
|
||||
import { NavLink, useLocation } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useLayoutStore, useUserStore } from "@/store/module";
|
||||
import { useGlobalStore, useLayoutStore, useUserStore } from "@/store/module";
|
||||
import { resolution } from "@/utils/layout";
|
||||
import Icon from "./Icon";
|
||||
import showSettingDialog from "./SettingDialog";
|
||||
@ -14,8 +14,10 @@ const Header = () => {
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const userStore = useUserStore();
|
||||
const globalStore = useGlobalStore();
|
||||
const layoutStore = useLayoutStore();
|
||||
const showHeader = layoutStore.state.showHeader;
|
||||
const showAskAI = globalStore.showAskAI();
|
||||
const isVisitorMode = userStore.isVisitorMode() && !userStore.state.user;
|
||||
|
||||
useEffect(() => {
|
||||
@ -107,13 +109,15 @@ const Header = () => {
|
||||
</NavLink>
|
||||
{!isVisitorMode && (
|
||||
<>
|
||||
<button
|
||||
id="header-ask-ai"
|
||||
className="px-4 pr-5 py-2 rounded-lg flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:shadow dark:hover:bg-zinc-700"
|
||||
onClick={() => showAskAIDialog()}
|
||||
>
|
||||
<Icon.Bot className="mr-3 w-6 h-auto opacity-70" /> {t("ask-ai.title")}
|
||||
</button>
|
||||
{showAskAI && (
|
||||
<button
|
||||
id="header-ask-ai"
|
||||
className="px-4 pr-5 py-2 rounded-lg flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:shadow dark:hover:bg-zinc-700"
|
||||
onClick={() => showAskAIDialog()}
|
||||
>
|
||||
<Icon.Bot className="mr-3 w-6 h-auto opacity-70" /> {t("ask-ai.title")}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
id="header-archived-memo"
|
||||
className="px-4 pr-5 py-2 rounded-lg flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:shadow dark:hover:bg-zinc-700"
|
||||
|
@ -16,6 +16,7 @@ interface State {
|
||||
disablePublicMemos: boolean;
|
||||
additionalStyle: string;
|
||||
additionalScript: string;
|
||||
openAIConfig: OpenAIConfig;
|
||||
}
|
||||
|
||||
const SystemSection = () => {
|
||||
@ -29,10 +30,7 @@ const SystemSection = () => {
|
||||
additionalStyle: systemStatus.additionalStyle,
|
||||
additionalScript: systemStatus.additionalScript,
|
||||
disablePublicMemos: systemStatus.disablePublicMemos,
|
||||
});
|
||||
const [openAIConfig, setOpenAIConfig] = useState<OpenAIConfig>({
|
||||
key: "",
|
||||
host: "",
|
||||
openAIConfig: systemStatus.openAIConfig,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@ -47,18 +45,10 @@ const SystemSection = () => {
|
||||
additionalStyle: systemStatus.additionalStyle,
|
||||
additionalScript: systemStatus.additionalScript,
|
||||
disablePublicMemos: systemStatus.disablePublicMemos,
|
||||
openAIConfig: systemStatus.openAIConfig,
|
||||
});
|
||||
}, [systemStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
api.getSystemSetting().then(({ data: { data: systemSettings } }) => {
|
||||
const openAIConfigSetting = systemSettings.find((setting) => setting.name === "openai-config");
|
||||
if (openAIConfigSetting) {
|
||||
setOpenAIConfig(JSON.parse(openAIConfigSetting.value));
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleAllowSignUpChanged = async (value: boolean) => {
|
||||
setState({
|
||||
...state,
|
||||
@ -97,9 +87,12 @@ const SystemSection = () => {
|
||||
};
|
||||
|
||||
const handleOpenAIConfigKeyChanged = (value: string) => {
|
||||
setOpenAIConfig({
|
||||
...openAIConfig,
|
||||
key: value,
|
||||
setState({
|
||||
...state,
|
||||
openAIConfig: {
|
||||
...state.openAIConfig,
|
||||
key: value,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@ -107,8 +100,9 @@ const SystemSection = () => {
|
||||
try {
|
||||
await api.upsertSystemSetting({
|
||||
name: "openai-config",
|
||||
value: JSON.stringify(openAIConfig),
|
||||
value: JSON.stringify(state.openAIConfig),
|
||||
});
|
||||
globalStore.setSystemStatus({ openAIConfig: state.openAIConfig });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return;
|
||||
@ -117,9 +111,12 @@ const SystemSection = () => {
|
||||
};
|
||||
|
||||
const handleOpenAIConfigHostChanged = (value: string) => {
|
||||
setOpenAIConfig({
|
||||
...openAIConfig,
|
||||
host: value,
|
||||
setState({
|
||||
...state,
|
||||
openAIConfig: {
|
||||
...state.openAIConfig,
|
||||
host: value,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@ -225,7 +222,7 @@ const SystemSection = () => {
|
||||
fontSize: "14px",
|
||||
}}
|
||||
placeholder={t("setting.system-section.openai-api-key-placeholder")}
|
||||
value={openAIConfig.key}
|
||||
value={state.openAIConfig.key}
|
||||
onChange={(event) => handleOpenAIConfigKeyChanged(event.target.value)}
|
||||
/>
|
||||
<div className="form-label mt-2">
|
||||
@ -238,7 +235,7 @@ const SystemSection = () => {
|
||||
fontSize: "14px",
|
||||
}}
|
||||
placeholder={t("setting.system-section.openai-api-host-placeholder")}
|
||||
value={openAIConfig.host}
|
||||
value={state.openAIConfig.host}
|
||||
onChange={(event) => handleOpenAIConfigHostChanged(event.target.value)}
|
||||
/>
|
||||
<Divider className="!mt-3 !my-4" />
|
||||
|
@ -23,6 +23,10 @@ export const initialGlobalState = async () => {
|
||||
appearance: "system",
|
||||
externalUrl: "",
|
||||
},
|
||||
openAIConfig: {
|
||||
key: "",
|
||||
host: "",
|
||||
},
|
||||
} as SystemStatus,
|
||||
};
|
||||
|
||||
@ -65,6 +69,10 @@ export const useGlobalStore = () => {
|
||||
isDev: () => {
|
||||
return state.systemStatus.profile.mode !== "prod";
|
||||
},
|
||||
showAskAI: () => {
|
||||
const openAIConfig = state.systemStatus.openAIConfig;
|
||||
return Boolean(openAIConfig.key && openAIConfig.host);
|
||||
},
|
||||
fetchSystemStatus: async () => {
|
||||
const { data: systemStatus } = (await api.getSystemStatus()).data;
|
||||
store.dispatch(setGlobalState({ systemStatus: systemStatus }));
|
||||
|
@ -31,6 +31,10 @@ const globalSlice = createSlice({
|
||||
appearance: "system",
|
||||
externalUrl: "",
|
||||
},
|
||||
openAIConfig: {
|
||||
key: "",
|
||||
host: "",
|
||||
},
|
||||
},
|
||||
} as State,
|
||||
reducers: {
|
||||
|
1
web/src/types/modules/system.d.ts
vendored
1
web/src/types/modules/system.d.ts
vendored
@ -30,6 +30,7 @@ interface SystemStatus {
|
||||
customizedProfile: CustomizedProfile;
|
||||
storageServiceId: number;
|
||||
localStoragePath: string;
|
||||
openAIConfig: OpenAIConfig;
|
||||
}
|
||||
|
||||
interface SystemSetting {
|
||||
|
Loading…
x
Reference in New Issue
Block a user