Prefill IM channel runtime config

This commit is contained in:
taohe
2026-06-11 17:02:02 +08:00
parent 4f56437030
commit dae7c7870e
6 changed files with 198 additions and 9 deletions
@@ -57,6 +57,10 @@ export function ChannelRuntimeConfigDialog({
() => provider?.credential_fields ?? [],
[provider?.credential_fields],
);
const credentialValues = useMemo<ChannelRuntimeConfigValues>(
() => provider?.credential_values ?? {},
[provider?.credential_values],
);
useEffect(() => {
if (!open || !provider) {
@@ -64,11 +68,14 @@ export function ChannelRuntimeConfigDialog({
return;
}
setValues(
Object.fromEntries(fields.map((field) => [field.name, ""])) as
| ChannelRuntimeConfigValues
| {},
Object.fromEntries(
fields.map((field) => [
field.name,
credentialValues[field.name] ?? "",
]),
) as ChannelRuntimeConfigValues,
);
}, [fields, open, provider]);
}, [credentialValues, fields, open, provider]);
if (!provider) {
return null;
+3 -2
View File
@@ -7,6 +7,8 @@ export interface ChannelCredentialField {
required: boolean;
}
export type ChannelRuntimeConfigValues = Record<string, string>;
export interface ChannelProvider {
provider: ChannelProviderId;
display_name: string;
@@ -17,6 +19,7 @@ export interface ChannelProvider {
auth_mode: string;
connection_status: string;
credential_fields: ChannelCredentialField[];
credential_values?: ChannelRuntimeConfigValues;
}
export interface ChannelProvidersResponse {
@@ -48,5 +51,3 @@ export interface ChannelConnectResponse {
instruction: string;
expires_in: number;
}
export type ChannelRuntimeConfigValues = Record<string, string>;
+58
View File
@@ -27,6 +27,7 @@ type MockChannelProvider = {
type: string;
required: boolean;
}>;
credential_values?: Record<string, string>;
};
function defaultProviders(): MockChannelProvider[] {
@@ -166,6 +167,12 @@ test.describe("IM channels", () => {
required: true,
},
],
credential_values: slackConfigured
? {
bot_token: "********",
app_token: "********",
}
: {},
},
{
provider: "discord",
@@ -208,6 +215,7 @@ test.describe("IM channels", () => {
auth_mode: "binding_code",
connection_status: "connected",
credential_fields: [],
credential_values: {},
}),
});
});
@@ -244,9 +252,59 @@ test.describe("IM channels", () => {
await expect(
page.getByRole("dialog", { name: "Modify Slack" }),
).toBeVisible();
await expect(page.getByLabel("Bot token")).toHaveValue("********");
await expect(page.getByLabel("App token")).toHaveValue("********");
expect(submittedValues).toEqual({
bot_token: "xoxb-ui",
app_token: "xapp-ui",
});
});
test("runtime setup dialog prefills editable credential values", async ({
page,
}) => {
mockLangGraphAPI(page);
mockChannelsAPI(page, [
{
provider: "feishu",
display_name: "Feishu",
enabled: true,
configured: true,
connectable: true,
auth_mode: "binding_code",
connection_status: "connected",
credential_fields: [
{
name: "app_id",
label: "App ID",
type: "text",
required: true,
},
{
name: "app_secret",
label: "App secret",
type: "password",
required: true,
},
],
credential_values: {
app_id: "cli_feishu_app",
app_secret: "********",
},
},
]);
await page.goto("/workspace/chats/new");
const sidebar = page.locator("[data-sidebar='sidebar']");
await expect(sidebar.getByText("Feishu")).toBeVisible({ timeout: 15_000 });
await sidebar.getByRole("button", { name: "Connected" }).click();
const setupDialog = page.getByRole("dialog", { name: "Modify Feishu" });
await expect(setupDialog).toBeVisible();
await expect(setupDialog.getByLabel("App ID")).toHaveValue(
"cli_feishu_app",
);
await expect(setupDialog.getByLabel("App secret")).toHaveValue("********");
});
});
+14 -1
View File
@@ -45,6 +45,10 @@ describe("channels api", () => {
configured: true,
auth_mode: "deep_link",
connection_status: "not_connected",
credential_values: {
bot_token: "********",
bot_username: "deerflow_bot",
},
},
],
}),
@@ -52,7 +56,16 @@ describe("channels api", () => {
await expect(listChannelProviders()).resolves.toMatchObject({
enabled: true,
providers: [{ provider: "telegram", display_name: "Telegram" }],
providers: [
{
provider: "telegram",
display_name: "Telegram",
credential_values: {
bot_token: "********",
bot_username: "deerflow_bot",
},
},
],
});
expect(mockedFetch).toHaveBeenCalledWith("/backend/api/channels/providers");
});