mirror of
https://github.com/trailbaseio/trailbase.git
synced 2026-05-20 16:30:05 -05:00
Minor: clean up config handling.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { splitProps, Show } from "solid-js";
|
||||
import { splitProps, Match, Switch } from "solid-js";
|
||||
import type { ValidComponent } from "solid-js";
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -23,14 +23,20 @@ export function IconButton<T extends ValidComponent = "button">(
|
||||
const B = () => <Button variant="ghost" size="icon" {...others} />;
|
||||
|
||||
return (
|
||||
<Show when={local.tooltip} fallback={<B />}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as="div">
|
||||
<B />
|
||||
</TooltipTrigger>
|
||||
<Switch>
|
||||
<Match when={local.tooltip}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as="div">
|
||||
<B />
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent>{props.tooltip}</TooltipContent>
|
||||
</Tooltip>
|
||||
</Show>
|
||||
<TooltipContent>{props.tooltip}</TooltipContent>
|
||||
</Tooltip>
|
||||
</Match>
|
||||
|
||||
<Match when={true}>
|
||||
<B />
|
||||
</Match>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -295,7 +295,11 @@ function createAuthSettingsForm(opts: {
|
||||
newConfig.auth = proxyToConfig(value);
|
||||
|
||||
console.debug("Submitting provider config:", value);
|
||||
await setConfig(queryClient, newConfig);
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: newConfig,
|
||||
throw: true,
|
||||
});
|
||||
|
||||
opts.postSubmit();
|
||||
},
|
||||
|
||||
@@ -56,7 +56,11 @@ function DatabaseSettingsForm(props: {
|
||||
const linkDb = async (name: string) => {
|
||||
const newConfig = Config.fromPartial(props.config);
|
||||
newConfig.databases = [...newConfig.databases, { name }];
|
||||
await setConfig(queryClient, newConfig, { throw: false });
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: newConfig,
|
||||
throw: false,
|
||||
});
|
||||
};
|
||||
|
||||
const unlinkSelectedDbs = async () => {
|
||||
@@ -67,7 +71,11 @@ function DatabaseSettingsForm(props: {
|
||||
(d) => !markedForUnlink.has(d.name ?? ""),
|
||||
);
|
||||
|
||||
await setConfig(queryClient, newConfig, { throw: false });
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: newConfig,
|
||||
throw: false,
|
||||
});
|
||||
};
|
||||
|
||||
const dbTable = createMemo(() => {
|
||||
|
||||
@@ -141,7 +141,11 @@ export function EmailSettings(props: {
|
||||
|
||||
const newConfig = Config.fromPartial(c);
|
||||
newConfig.email = value;
|
||||
await setConfig(queryClient, newConfig);
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: newConfig,
|
||||
throw: true,
|
||||
});
|
||||
|
||||
props.postSubmit();
|
||||
},
|
||||
|
||||
@@ -139,7 +139,12 @@ function JobSettingsImpl(props: {
|
||||
jobs,
|
||||
} satisfies Config;
|
||||
|
||||
await setConfig(queryClient, newConfig);
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: newConfig,
|
||||
throw: true,
|
||||
});
|
||||
|
||||
props.refetchJobs();
|
||||
props.postSubmit();
|
||||
},
|
||||
|
||||
@@ -65,7 +65,7 @@ import { Version } from "@/components/Version";
|
||||
import {
|
||||
createConfigQuery,
|
||||
setConfig,
|
||||
invalidateAllAdminQueries,
|
||||
invalidateConfig,
|
||||
} from "@/lib/api/config";
|
||||
import { createSystemInfoQuery } from "@/lib/api/info";
|
||||
import { createIsMobile } from "@/lib/signals";
|
||||
@@ -155,7 +155,11 @@ function ServerSettingsForm(
|
||||
onSubmit: async ({ value }: { value: ServerConfig }) => {
|
||||
const newConfig = Config.fromPartial(props.config);
|
||||
newConfig.server = value;
|
||||
await setConfig(queryClient, newConfig);
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: newConfig,
|
||||
throw: true,
|
||||
});
|
||||
|
||||
props.postSubmit?.();
|
||||
},
|
||||
@@ -512,7 +516,7 @@ export function SettingsPage() {
|
||||
titleSelect={activeSite().label}
|
||||
leading={<SidebarTrigger />}
|
||||
left={
|
||||
<IconButton onClick={() => invalidateAllAdminQueries(queryClient)}>
|
||||
<IconButton onClick={() => invalidateConfig(queryClient)}>
|
||||
<TbRefresh />
|
||||
</IconButton>
|
||||
}
|
||||
|
||||
@@ -726,8 +726,11 @@ function IndividualRecordApiSettingsForm(props: {
|
||||
|
||||
const isCreate = props.mode === Mode.Create;
|
||||
try {
|
||||
const newConfig = updateRecordApiConfig(c, value);
|
||||
await setConfig(queryClient, newConfig);
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: updateRecordApiConfig(c, value),
|
||||
throw: true,
|
||||
});
|
||||
|
||||
showToast({
|
||||
title: "Success",
|
||||
@@ -1294,9 +1297,12 @@ function DeleteUpdateButtons(props: {
|
||||
|
||||
if (apiName !== undefined) {
|
||||
try {
|
||||
const newConfig = removeRecordApiConfig(c, tableName.name, apiName);
|
||||
await setConfig({
|
||||
client: queryClient,
|
||||
config: removeRecordApiConfig(c, tableName.name, apiName),
|
||||
throw: true,
|
||||
});
|
||||
|
||||
await setConfig(queryClient, newConfig);
|
||||
showToast({
|
||||
title: "Success",
|
||||
description: `API "${apiName}" deleted`,
|
||||
|
||||
@@ -5,48 +5,15 @@ import { GetConfigResponse, UpdateConfigRequest } from "@proto/config_api";
|
||||
import { adminFetch } from "@/lib/fetch";
|
||||
import { showToast } from "@/components/ui/toast";
|
||||
|
||||
type UpdateOptions = {
|
||||
throw?: boolean;
|
||||
};
|
||||
|
||||
export async function setConfig(
|
||||
queryClient: QueryClient,
|
||||
config: Config,
|
||||
opts?: UpdateOptions,
|
||||
): Promise<void> {
|
||||
const data = queryClient.getQueryData<GetConfigResponse>(key);
|
||||
const hash = data?.hash;
|
||||
if (!hash) {
|
||||
console.error("Missing hash from:", data);
|
||||
return;
|
||||
export function createConfigQuery() {
|
||||
async function getConfig(): Promise<GetConfigResponse> {
|
||||
const response = await adminFetch("/config");
|
||||
const array = new Uint8Array(await (await response.blob()).arrayBuffer());
|
||||
return GetConfigResponse.decode(array);
|
||||
}
|
||||
|
||||
const request: UpdateConfigRequest = {
|
||||
config,
|
||||
hash,
|
||||
};
|
||||
console.debug("Updating config:", request);
|
||||
await updateConfig(request, opts);
|
||||
|
||||
// Trigger refetch after updating config.
|
||||
invalidateConfig(queryClient);
|
||||
}
|
||||
|
||||
export function invalidateAllAdminQueries(queryClient: QueryClient) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["admin"],
|
||||
});
|
||||
}
|
||||
|
||||
export function invalidateConfig(queryClient: QueryClient) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: key,
|
||||
});
|
||||
}
|
||||
|
||||
export function createConfigQuery() {
|
||||
return useQuery(() => ({
|
||||
queryKey: key,
|
||||
queryKey: _configKey,
|
||||
queryFn: async () => {
|
||||
const config = await getConfig();
|
||||
console.debug("Fetched config:", config);
|
||||
@@ -57,17 +24,12 @@ export function createConfigQuery() {
|
||||
}));
|
||||
}
|
||||
|
||||
async function getConfig(): Promise<GetConfigResponse> {
|
||||
const response = await adminFetch("/config");
|
||||
const array = new Uint8Array(await (await response.blob()).arrayBuffer());
|
||||
return GetConfigResponse.decode(array);
|
||||
}
|
||||
|
||||
async function updateConfig(
|
||||
request: UpdateConfigRequest,
|
||||
opts?: UpdateOptions,
|
||||
): Promise<void> {
|
||||
try {
|
||||
export async function setConfig(opts: {
|
||||
client: QueryClient;
|
||||
config: Config;
|
||||
throw: boolean;
|
||||
}): Promise<void> {
|
||||
async function updateConfig(request: UpdateConfigRequest) {
|
||||
await adminFetch("/config", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -76,17 +38,45 @@ async function updateConfig(
|
||||
body: new Uint8Array(UpdateConfigRequest.encode(request).finish()),
|
||||
throwOnError: true,
|
||||
});
|
||||
} catch (err) {
|
||||
showToast({
|
||||
title: "Config Error",
|
||||
description: `${err}`,
|
||||
variant: "error",
|
||||
});
|
||||
}
|
||||
|
||||
if (!(opts?.throw ?? true)) {
|
||||
throw err;
|
||||
// Get previous fetch.
|
||||
const hash = opts.client.getQueryData<GetConfigResponse>(_configKey)?.hash;
|
||||
if (!hash) {
|
||||
console.error("Missing hash");
|
||||
return;
|
||||
}
|
||||
|
||||
const request: UpdateConfigRequest = {
|
||||
config: opts.config,
|
||||
hash,
|
||||
};
|
||||
|
||||
console.debug("Updating config:", request);
|
||||
|
||||
if (opts.throw) {
|
||||
await updateConfig(request);
|
||||
} else {
|
||||
try {
|
||||
await updateConfig(request);
|
||||
} catch (err) {
|
||||
showToast({
|
||||
title: "Config update failed",
|
||||
description: `${err}`,
|
||||
variant: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger re-fetch after updating config.
|
||||
invalidateConfig(opts.client);
|
||||
}
|
||||
|
||||
const key = ["admin", "proto_config"];
|
||||
export function invalidateConfig(queryClient: QueryClient) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: _configKey,
|
||||
});
|
||||
}
|
||||
|
||||
const _configKey = ["admin", "proto_config"];
|
||||
|
||||
Reference in New Issue
Block a user