Commit 8a7e0088 authored by Steven's avatar Steven

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: 's avatarClaude Sonnet 4.5 <noreply@anthropic.com>
parent edd3ced9
......@@ -10,7 +10,7 @@ import { Textarea } from "@/components/ui/textarea";
import { identityProviderServiceClient } from "@/grpcweb";
import useDialog from "@/hooks/useDialog";
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 {
InstanceSetting_GeneralSetting,
......@@ -63,7 +63,7 @@ const InstanceSection = observer(() => {
try {
await instanceStore.upsertInstanceSetting(
create(InstanceSettingSchema, {
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
name: buildInstanceSettingName(InstanceSetting_Key.GENERAL),
value: {
case: "generalSetting",
value: instanceGeneralSetting,
......
......@@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { instanceStore } from "@/store";
import { instanceSettingNamePrefix } from "@/store/common";
import { buildInstanceSettingName } from "@/store/common";
import {
InstanceSetting_Key,
InstanceSetting_MemoRelatedSetting,
......@@ -63,7 +63,7 @@ const MemoRelatedSettings = observer(() => {
try {
await instanceStore.upsertInstanceSetting(
create(InstanceSettingSchema, {
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.MEMO_RELATED}`,
name: buildInstanceSettingName(InstanceSetting_Key.MEMO_RELATED),
value: {
case: "memoRelatedSetting",
value: memoRelatedSetting,
......
......@@ -9,7 +9,7 @@ import { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Switch } from "@/components/ui/switch";
import { instanceStore } from "@/store";
import { instanceSettingNamePrefix } from "@/store/common";
import { buildInstanceSettingName } from "@/store/common";
import {
InstanceSetting_Key,
InstanceSetting_StorageSetting,
......@@ -154,7 +154,7 @@ const StorageSection = observer(() => {
const saveInstanceStorageSetting = async () => {
await instanceStore.upsertInstanceSetting(
create(InstanceSettingSchema, {
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.STORAGE}`,
name: buildInstanceSettingName(InstanceSetting_Key.STORAGE),
value: {
case: "storageSetting",
value: instanceStorageSetting,
......
......@@ -7,7 +7,7 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { instanceStore } from "@/store";
import { instanceSettingNamePrefix } from "@/store/common";
import { buildInstanceSettingName } from "@/store/common";
import {
InstanceSetting_GeneralSetting_CustomProfile,
InstanceSetting_GeneralSetting_CustomProfileSchema,
......@@ -78,7 +78,7 @@ function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props)
try {
await instanceStore.upsertInstanceSetting(
create(InstanceSettingSchema, {
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
name: buildInstanceSettingName(InstanceSetting_Key.GENERAL),
value: {
case: "generalSetting",
value: {
......
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 userNamePrefix = "users/";
export const memoNamePrefix = "memos/";
......@@ -15,3 +18,25 @@ export const extractMemoIdFromName = (name: string) => {
export const extractIdentityProviderIdFromName = (name: string) => {
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,
} from "@/types/proto/api/v1/instance_service_pb";
import { createServerStore, StandardState } from "./base-store";
import { instanceSettingNamePrefix } from "./common";
import { buildInstanceSettingName, getInstanceSettingKeyName, instanceSettingNamePrefix } from "./common";
import { createRequestKey } from "./store-utils";
class InstanceState extends StandardState {
......@@ -25,7 +25,7 @@ class InstanceState extends StandardState {
// Computed property for general settings (memoized)
get generalSetting(): InstanceSetting_GeneralSetting {
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") {
return setting.value.value;
}
......@@ -36,7 +36,7 @@ class InstanceState extends StandardState {
// Computed property for memo-related settings (memoized)
get memoRelatedSetting(): InstanceSetting_MemoRelatedSetting {
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") {
return setting.value.value;
}
......@@ -60,7 +60,7 @@ const instanceStore = (() => {
requestKey,
async () => {
const setting = await instanceServiceClient.getInstanceSetting({
name: `${instanceSettingNamePrefix}${settingKey}`,
name: buildInstanceSettingName(settingKey),
});
// Merge into settings array, avoiding duplicates
......@@ -88,7 +88,7 @@ const instanceStore = (() => {
};
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, {});
};
......
......@@ -16,6 +16,7 @@ import {
UserSettingSchema,
UserStats,
} from "@/types/proto/api/v1/user_service_pb";
import { buildUserSettingName } from "./common";
import { createRequestKey, RequestDeduplicator, StoreError } from "./store-utils";
// Helper to extract setting value from UserSetting oneof
......@@ -164,7 +165,7 @@ const userStore = (() => {
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, {
name: settingName,
value: {
......@@ -188,7 +189,7 @@ const userStore = (() => {
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 generalSetting = getSettingValue<UserSetting_GeneralSetting>(userSetting, "generalSetting");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment