mirror of https://github.com/usememos/memos.git
fix(web): convert enum values to string names in API resource paths
Frontend was incorrectly using numeric enum values (e.g., 1, 2, 3) instead of string names (e.g., "GENERAL", "STORAGE") when constructing API resource paths. This caused the backend to fail with "unsupported instance setting key: INSTANCE_SETTING_KEY_UNSPECIFIED" errors during initialization. Changes: - Add helper functions in store/common.ts to convert enum values to names - getInstanceSettingKeyName() and buildInstanceSettingName() - getUserSettingKeyName() and buildUserSettingName() - Update instance store to use string enum names in API calls - Update user store to use string enum names in API calls - Update all components to use new helper functions for setting names Fixes enum string conversion for: - InstanceSetting_Key (6 locations) - UserSetting_Key (2 locations) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
edd3ced9bf
commit
8a7e00886d
|
|
@ -10,7 +10,7 @@ import { Textarea } from "@/components/ui/textarea";
|
||||||
import { identityProviderServiceClient } from "@/grpcweb";
|
import { identityProviderServiceClient } from "@/grpcweb";
|
||||||
import useDialog from "@/hooks/useDialog";
|
import useDialog from "@/hooks/useDialog";
|
||||||
import { instanceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { instanceSettingNamePrefix } from "@/store/common";
|
import { buildInstanceSettingName } from "@/store/common";
|
||||||
import { IdentityProvider } from "@/types/proto/api/v1/idp_service_pb";
|
import { IdentityProvider } from "@/types/proto/api/v1/idp_service_pb";
|
||||||
import {
|
import {
|
||||||
InstanceSetting_GeneralSetting,
|
InstanceSetting_GeneralSetting,
|
||||||
|
|
@ -63,7 +63,7 @@ const InstanceSection = observer(() => {
|
||||||
try {
|
try {
|
||||||
await instanceStore.upsertInstanceSetting(
|
await instanceStore.upsertInstanceSetting(
|
||||||
create(InstanceSettingSchema, {
|
create(InstanceSettingSchema, {
|
||||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
name: buildInstanceSettingName(InstanceSetting_Key.GENERAL),
|
||||||
value: {
|
value: {
|
||||||
case: "generalSetting",
|
case: "generalSetting",
|
||||||
value: instanceGeneralSetting,
|
value: instanceGeneralSetting,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { instanceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { instanceSettingNamePrefix } from "@/store/common";
|
import { buildInstanceSettingName } from "@/store/common";
|
||||||
import {
|
import {
|
||||||
InstanceSetting_Key,
|
InstanceSetting_Key,
|
||||||
InstanceSetting_MemoRelatedSetting,
|
InstanceSetting_MemoRelatedSetting,
|
||||||
|
|
@ -63,7 +63,7 @@ const MemoRelatedSettings = observer(() => {
|
||||||
try {
|
try {
|
||||||
await instanceStore.upsertInstanceSetting(
|
await instanceStore.upsertInstanceSetting(
|
||||||
create(InstanceSettingSchema, {
|
create(InstanceSettingSchema, {
|
||||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.MEMO_RELATED}`,
|
name: buildInstanceSettingName(InstanceSetting_Key.MEMO_RELATED),
|
||||||
value: {
|
value: {
|
||||||
case: "memoRelatedSetting",
|
case: "memoRelatedSetting",
|
||||||
value: memoRelatedSetting,
|
value: memoRelatedSetting,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { Label } from "@/components/ui/label";
|
||||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { instanceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { instanceSettingNamePrefix } from "@/store/common";
|
import { buildInstanceSettingName } from "@/store/common";
|
||||||
import {
|
import {
|
||||||
InstanceSetting_Key,
|
InstanceSetting_Key,
|
||||||
InstanceSetting_StorageSetting,
|
InstanceSetting_StorageSetting,
|
||||||
|
|
@ -154,7 +154,7 @@ const StorageSection = observer(() => {
|
||||||
const saveInstanceStorageSetting = async () => {
|
const saveInstanceStorageSetting = async () => {
|
||||||
await instanceStore.upsertInstanceSetting(
|
await instanceStore.upsertInstanceSetting(
|
||||||
create(InstanceSettingSchema, {
|
create(InstanceSettingSchema, {
|
||||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.STORAGE}`,
|
name: buildInstanceSettingName(InstanceSetting_Key.STORAGE),
|
||||||
value: {
|
value: {
|
||||||
case: "storageSetting",
|
case: "storageSetting",
|
||||||
value: instanceStorageSetting,
|
value: instanceStorageSetting,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { instanceStore } from "@/store";
|
import { instanceStore } from "@/store";
|
||||||
import { instanceSettingNamePrefix } from "@/store/common";
|
import { buildInstanceSettingName } from "@/store/common";
|
||||||
import {
|
import {
|
||||||
InstanceSetting_GeneralSetting_CustomProfile,
|
InstanceSetting_GeneralSetting_CustomProfile,
|
||||||
InstanceSetting_GeneralSetting_CustomProfileSchema,
|
InstanceSetting_GeneralSetting_CustomProfileSchema,
|
||||||
|
|
@ -78,7 +78,7 @@ function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props)
|
||||||
try {
|
try {
|
||||||
await instanceStore.upsertInstanceSetting(
|
await instanceStore.upsertInstanceSetting(
|
||||||
create(InstanceSettingSchema, {
|
create(InstanceSettingSchema, {
|
||||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
name: buildInstanceSettingName(InstanceSetting_Key.GENERAL),
|
||||||
value: {
|
value: {
|
||||||
case: "generalSetting",
|
case: "generalSetting",
|
||||||
value: {
|
value: {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import { InstanceSetting_Key } from "@/types/proto/api/v1/instance_service_pb";
|
||||||
|
import { UserSetting_Key } from "@/types/proto/api/v1/user_service_pb";
|
||||||
|
|
||||||
export const instanceSettingNamePrefix = "instance/settings/";
|
export const instanceSettingNamePrefix = "instance/settings/";
|
||||||
export const userNamePrefix = "users/";
|
export const userNamePrefix = "users/";
|
||||||
export const memoNamePrefix = "memos/";
|
export const memoNamePrefix = "memos/";
|
||||||
|
|
@ -15,3 +18,25 @@ export const extractMemoIdFromName = (name: string) => {
|
||||||
export const extractIdentityProviderIdFromName = (name: string) => {
|
export const extractIdentityProviderIdFromName = (name: string) => {
|
||||||
return parseInt(name.split(identityProviderNamePrefix).pop() || "", 10);
|
return parseInt(name.split(identityProviderNamePrefix).pop() || "", 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper function to convert InstanceSetting_Key enum value to string name
|
||||||
|
export const getInstanceSettingKeyName = (key: InstanceSetting_Key): string => {
|
||||||
|
// TypeScript enum reverse mapping: converts numeric value to string name
|
||||||
|
return InstanceSetting_Key[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to build instance setting name from key
|
||||||
|
export const buildInstanceSettingName = (key: InstanceSetting_Key): string => {
|
||||||
|
return `${instanceSettingNamePrefix}${getInstanceSettingKeyName(key)}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to convert UserSetting_Key enum value to string name
|
||||||
|
export const getUserSettingKeyName = (key: UserSetting_Key): string => {
|
||||||
|
// TypeScript enum reverse mapping: converts numeric value to string name
|
||||||
|
return UserSetting_Key[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper function to build user setting name from username and key
|
||||||
|
export const buildUserSettingName = (username: string, key: UserSetting_Key): string => {
|
||||||
|
return `${username}/settings/${getUserSettingKeyName(key)}`;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import {
|
||||||
InstanceSettingSchema,
|
InstanceSettingSchema,
|
||||||
} from "@/types/proto/api/v1/instance_service_pb";
|
} from "@/types/proto/api/v1/instance_service_pb";
|
||||||
import { createServerStore, StandardState } from "./base-store";
|
import { createServerStore, StandardState } from "./base-store";
|
||||||
import { instanceSettingNamePrefix } from "./common";
|
import { buildInstanceSettingName, getInstanceSettingKeyName, instanceSettingNamePrefix } from "./common";
|
||||||
import { createRequestKey } from "./store-utils";
|
import { createRequestKey } from "./store-utils";
|
||||||
|
|
||||||
class InstanceState extends StandardState {
|
class InstanceState extends StandardState {
|
||||||
|
|
@ -25,7 +25,7 @@ class InstanceState extends StandardState {
|
||||||
// Computed property for general settings (memoized)
|
// Computed property for general settings (memoized)
|
||||||
get generalSetting(): InstanceSetting_GeneralSetting {
|
get generalSetting(): InstanceSetting_GeneralSetting {
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
const setting = this.settings.find((s) => s.name === `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`);
|
const setting = this.settings.find((s) => s.name === `${instanceSettingNamePrefix}GENERAL`);
|
||||||
if (setting?.value.case === "generalSetting") {
|
if (setting?.value.case === "generalSetting") {
|
||||||
return setting.value.value;
|
return setting.value.value;
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ class InstanceState extends StandardState {
|
||||||
// Computed property for memo-related settings (memoized)
|
// Computed property for memo-related settings (memoized)
|
||||||
get memoRelatedSetting(): InstanceSetting_MemoRelatedSetting {
|
get memoRelatedSetting(): InstanceSetting_MemoRelatedSetting {
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
const setting = this.settings.find((s) => s.name === `${instanceSettingNamePrefix}${InstanceSetting_Key.MEMO_RELATED}`);
|
const setting = this.settings.find((s) => s.name === `${instanceSettingNamePrefix}MEMO_RELATED`);
|
||||||
if (setting?.value.case === "memoRelatedSetting") {
|
if (setting?.value.case === "memoRelatedSetting") {
|
||||||
return setting.value.value;
|
return setting.value.value;
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +60,7 @@ const instanceStore = (() => {
|
||||||
requestKey,
|
requestKey,
|
||||||
async () => {
|
async () => {
|
||||||
const setting = await instanceServiceClient.getInstanceSetting({
|
const setting = await instanceServiceClient.getInstanceSetting({
|
||||||
name: `${instanceSettingNamePrefix}${settingKey}`,
|
name: buildInstanceSettingName(settingKey),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Merge into settings array, avoiding duplicates
|
// Merge into settings array, avoiding duplicates
|
||||||
|
|
@ -88,7 +88,7 @@ const instanceStore = (() => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getInstanceSettingByKey = (settingKey: InstanceSetting_Key): InstanceSetting => {
|
const getInstanceSettingByKey = (settingKey: InstanceSetting_Key): InstanceSetting => {
|
||||||
const setting = state.settings.find((s) => s.name === `${instanceSettingNamePrefix}${settingKey}`);
|
const setting = state.settings.find((s) => s.name === buildInstanceSettingName(settingKey));
|
||||||
return setting || create(InstanceSettingSchema, {});
|
return setting || create(InstanceSettingSchema, {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import {
|
||||||
UserSettingSchema,
|
UserSettingSchema,
|
||||||
UserStats,
|
UserStats,
|
||||||
} from "@/types/proto/api/v1/user_service_pb";
|
} from "@/types/proto/api/v1/user_service_pb";
|
||||||
|
import { buildUserSettingName } from "./common";
|
||||||
import { createRequestKey, RequestDeduplicator, StoreError } from "./store-utils";
|
import { createRequestKey, RequestDeduplicator, StoreError } from "./store-utils";
|
||||||
|
|
||||||
// Helper to extract setting value from UserSetting oneof
|
// Helper to extract setting value from UserSetting oneof
|
||||||
|
|
@ -164,7 +165,7 @@ const userStore = (() => {
|
||||||
throw new Error("No current user");
|
throw new Error("No current user");
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingName = `${state.currentUser}/settings/${UserSetting_Key.GENERAL}`;
|
const settingName = buildUserSettingName(state.currentUser, UserSetting_Key.GENERAL);
|
||||||
const userSetting = create(UserSettingSchema, {
|
const userSetting = create(UserSettingSchema, {
|
||||||
name: settingName,
|
name: settingName,
|
||||||
value: {
|
value: {
|
||||||
|
|
@ -188,7 +189,7 @@ const userStore = (() => {
|
||||||
throw new Error("No current user");
|
throw new Error("No current user");
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingName = `${state.currentUser}/settings/${UserSetting_Key.GENERAL}`;
|
const settingName = buildUserSettingName(state.currentUser, UserSetting_Key.GENERAL);
|
||||||
const userSetting = await userServiceClient.getUserSetting({ name: settingName });
|
const userSetting = await userServiceClient.getUserSetting({ name: settingName });
|
||||||
const generalSetting = getSettingValue<UserSetting_GeneralSetting>(userSetting, "generalSetting");
|
const generalSetting = getSettingValue<UserSetting_GeneralSetting>(userSetting, "generalSetting");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue