mirror of
https://github.com/multica-ai/multica.git
synced 2026-06-17 03:38:32 +02:00
feat(lark): surface installation region in settings UI
Read the per-installation region off the listings response: build the "Manage in Lark" dev-console host from it (open.feishu.cn vs open.larksuite.com instead of a hardcoded mainland host) and render a Feishu / Lark badge on each connected bot. The field is optional and defaults to Feishu when an older server omits it (API-compat). Adds the region_feishu / region_lark labels to all four locales. MUL-3083 Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -13,6 +13,12 @@ export interface LarkInstallation {
|
||||
bot_open_id: string;
|
||||
installer_user_id: string;
|
||||
status: "active" | "revoked" | string;
|
||||
/** Which Lark cloud the bot lives on: "feishu" (mainland) or "lark"
|
||||
* (international). Auto-detected at install time. Optional so an older
|
||||
* desktop build parsing a newer server — or a newer build hitting a
|
||||
* server that predates the field — defaults to Feishu in the UI
|
||||
* (see CLAUDE.md → API Response Compatibility). */
|
||||
region?: "feishu" | "lark" | string;
|
||||
installed_at: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
|
||||
@@ -233,6 +233,8 @@
|
||||
"empty_description_cta": "Bind to Lark",
|
||||
"empty_description_suffix": "to install a Bot for it.",
|
||||
"revoked_badge": "revoked",
|
||||
"region_feishu": "Feishu",
|
||||
"region_lark": "Lark",
|
||||
"installed_at_label": "Installed {{when}}",
|
||||
"disconnect": "Disconnect",
|
||||
"disconnecting": "Disconnecting…",
|
||||
|
||||
@@ -233,6 +233,8 @@
|
||||
"empty_description_cta": "Lark に接続",
|
||||
"empty_description_suffix": "をクリックすると、対応するボットを設置できます。",
|
||||
"revoked_badge": "取り消し済み",
|
||||
"region_feishu": "Feishu",
|
||||
"region_lark": "Lark",
|
||||
"installed_at_label": "{{when}} に設置",
|
||||
"disconnect": "切断",
|
||||
"disconnecting": "切断しています…",
|
||||
|
||||
@@ -310,6 +310,8 @@
|
||||
"empty_description_cta": "Lark에 연결",
|
||||
"empty_description_suffix": "을(를) 클릭해 봇을 설치하세요.",
|
||||
"revoked_badge": "취소됨",
|
||||
"region_feishu": "Feishu",
|
||||
"region_lark": "Lark",
|
||||
"installed_at_label": "{{when}} 설치됨",
|
||||
"disconnect": "연결 해제",
|
||||
"disconnecting": "연결을 해제하는 중…",
|
||||
|
||||
@@ -233,6 +233,8 @@
|
||||
"empty_description_cta": "绑定到飞书",
|
||||
"empty_description_suffix": "即可为它安装 Bot。",
|
||||
"revoked_badge": "已撤销",
|
||||
"region_feishu": "飞书",
|
||||
"region_lark": "Lark",
|
||||
"installed_at_label": "安装于 {{when}}",
|
||||
"disconnect": "断开连接",
|
||||
"disconnecting": "正在断开…",
|
||||
|
||||
@@ -251,6 +251,32 @@ describe("LarkAgentBindButton (CTA gate)", () => {
|
||||
expect(link.rel).toContain("noopener");
|
||||
});
|
||||
|
||||
it("points the Manage link at open.larksuite.com for a Lark-international (region=lark) installation", () => {
|
||||
// Dual-region: a bot installed against the Lark international cloud
|
||||
// must manage at open.larksuite.com, not the Feishu default. The
|
||||
// region rides on the listings response, auto-detected at install.
|
||||
installationsRef.current.installations = [
|
||||
{
|
||||
id: "inst-lark",
|
||||
workspace_id: "ws-1",
|
||||
agent_id: "agent-1",
|
||||
app_id: "cli_lark_app",
|
||||
bot_open_id: "ou_lark_bot",
|
||||
installer_user_id: "user-1",
|
||||
status: "active",
|
||||
region: "lark",
|
||||
installed_at: "2026-06-03T00:00:00Z",
|
||||
created_at: "2026-06-03T00:00:00Z",
|
||||
updated_at: "2026-06-03T00:00:00Z",
|
||||
},
|
||||
];
|
||||
render(<LarkAgentBindButton agentId="agent-1" agentName="Bot" />, {
|
||||
wrapper: I18nWrapper,
|
||||
});
|
||||
const link = screen.getByRole("link", { name: /Manage in Lark/i }) as HTMLAnchorElement;
|
||||
expect(link.href).toBe("https://open.larksuite.com/app/cli_lark_app");
|
||||
});
|
||||
|
||||
it("still shows the bind CTA when an installation exists for a DIFFERENT agent (per-agent scoping)", () => {
|
||||
installationsRef.current.installations = [
|
||||
{
|
||||
|
||||
@@ -232,6 +232,11 @@ function InstallationRow({
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium">
|
||||
{agentName}
|
||||
<span className="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">
|
||||
{installation.region === "lark"
|
||||
? t(($) => $.lark.region_lark)
|
||||
: t(($) => $.lark.region_feishu)}
|
||||
</span>
|
||||
{!isActive && (
|
||||
<span className="ml-2 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">
|
||||
{t(($) => $.lark.revoked_badge)}
|
||||
@@ -359,12 +364,17 @@ export function LarkAgentBindButton({
|
||||
// a new tab so the user can manage scopes / display name / additional
|
||||
// permissions without re-scanning the QR.
|
||||
//
|
||||
// The dev console URL host follows the same default as the backend's
|
||||
// LARK_BASE_URL (open.feishu.cn for mainland Lark). Operators on the
|
||||
// Lark international tenant currently see the wrong host; future-
|
||||
// proofing requires the backend to surface a per-installation
|
||||
// `dev_console_url` on the listings response. Tracked separately.
|
||||
const LARK_DEV_CONSOLE_HOST = "https://open.feishu.cn";
|
||||
// The dev-console host depends on which Lark cloud the bot lives on:
|
||||
// Feishu (mainland) bots are managed at open.feishu.cn, Lark
|
||||
// (international) bots at open.larksuite.com. The region is auto-detected
|
||||
// at install time and surfaced per installation on the listings
|
||||
// response; an older server that omits `region` defaults to Feishu
|
||||
// (API-compat — see CLAUDE.md).
|
||||
function larkDevConsoleHost(region?: string): string {
|
||||
return region === "lark"
|
||||
? "https://open.larksuite.com"
|
||||
: "https://open.feishu.cn";
|
||||
}
|
||||
|
||||
function LarkAgentBotConnectedBadge({
|
||||
installation,
|
||||
@@ -374,7 +384,7 @@ function LarkAgentBotConnectedBadge({
|
||||
className?: string;
|
||||
}) {
|
||||
const { t } = useT("settings");
|
||||
const manageHref = `${LARK_DEV_CONSOLE_HOST}/app/${encodeURIComponent(installation.app_id)}`;
|
||||
const manageHref = `${larkDevConsoleHost(installation.region)}/app/${encodeURIComponent(installation.app_id)}`;
|
||||
return (
|
||||
<div className={className} data-testid="lark-agent-bot-connected">
|
||||
<span className="inline-flex items-center gap-2 text-xs text-muted-foreground">
|
||||
|
||||
Reference in New Issue
Block a user