/** * Groups dashboard card. * * List view + detail/manage view. The list stays compact (5/page); the * detail card carries per-bot membership / oncall / role management actions. * * Global dashboard scope: `/dashboard` renders the full groups matrix. The * row view summarizes coverage across all bot columns (joined/total) instead * of pretending the matrix has a single caller-bot column. * * Security: * - `invokerOpenId` is the invoking admin's `ou_*` (invoker-lock anchor). * - Admin gate runs at the command entry AND on every callback. * - sender union_id NEVER lands on action.value. * * Response: success returns `{ card }` only (no toast) β€” single-pass render, * no stale-frame flash. Errors / permission denials return `{ toast }`. * * Sort order: keep model output order verbatim; resorting in the card would * silently diverge from the Web Dashboard. */ import type { GroupDetailMemberDto, GroupsBotInput, GroupsChatInput } from '../../dashboard/groups-card-model.js'; import type { DaemonClient } from '../../dashboard/daemon-internal-client.js'; import { type Locale } from '../../i18n/index.js'; import type { CardActionData } from './card-handler.js'; export declare const GROUPS_ACTION_REFRESH: "dash_groups_refresh"; export declare const GROUPS_ACTION_PAGE: "dash_groups_page"; export declare const GROUPS_ACTION_DETAIL: "dash_groups_detail"; export declare const GROUPS_ACTION_BACK_TO_LIST: "dash_groups_back_to_list"; export declare const GROUPS_ACTION_ADD_BOT: "dash_groups_add_bot"; export declare const GROUPS_ACTION_LEAVE_BOT: "dash_groups_leave_bot"; export declare const GROUPS_ACTION_ONCALL_BIND: "dash_groups_oncall_bind"; export declare const GROUPS_ACTION_ONCALL_UNBIND: "dash_groups_oncall_unbind"; export declare const GROUPS_ACTION_ROLE_OPEN: "dash_groups_role_open"; export declare const GROUPS_ACTION_ROLE_SAVE: "dash_groups_role_save"; export declare const GROUPS_ACTION_ROLE_DELETE: "dash_groups_role_delete"; export interface BuildGroupsCardOpts { invokerOpenId: string; locale: Locale; /** 1-based page index. Caller clamps; this just renders what's given. */ page: number; /** Page size override, threaded through every button value. */ pageSize?: number; /** Navigation origin. `'overview'` means this card was opened via * `/dashboard overview` β†’ goto groups; the footer renders an extra * "πŸ”™ θΏ”ε›žζ€»θ§ˆ" button, and every button.value carries `origin=overview` * to keep that affordance across rebuilds. Undefined β†’ standalone card, * no overview link. */ origin?: 'overview'; /** Dashboard scope. `'global'` returns the full groups matrix rather than * the caller-bot scoped matrix. */ scope?: 'global'; } interface GroupsNavOpts { invokerOpenId: string; locale: Locale; page?: number; pageSize?: number; origin?: 'overview'; scope?: 'global'; } type GroupsMatrix = { chats: ReadonlyArray; bots: ReadonlyArray; }; /** Build the groups list card JSON. Pure (composes + paginates + renders). */ export declare function buildGroupsCard(matrix: GroupsMatrix, opts: BuildGroupsCardOpts): string; export declare function buildGroupsDetailCard(matrix: GroupsMatrix, chat: GroupsChatInput, opts: GroupsNavOpts): string; export declare function buildGroupsRoleCard(chat: GroupsChatInput, member: GroupDetailMemberDto, roleContent: string, opts: GroupsNavOpts): string; /** ─── Handler ─────────────────────────────────────────────────────────── */ export interface GroupsCardHandlerDeps { getOwnerOpenId?: (larkAppId: string) => string | undefined; getDashboardAdminOpenIds?: (larkAppId: string) => ReadonlyArray | undefined; createClient: (larkAppId: string) => DaemonClient; locale?: Locale; } export interface GroupsCardHandlerResult { toast?: { type: 'info' | 'success' | 'error'; content: string; }; card?: { type: 'raw'; data: Record; }; } /** Dispatch a `dash_groups_*` action callback. Mirrors sessions-card. */ export declare function handleGroupsCardAction(data: CardActionData, larkAppId: string, deps: GroupsCardHandlerDeps): Promise; export {}; //# sourceMappingURL=groups-card.d.ts.map