diff --git a/mobile/src/components/ui/text.tsx b/mobile/src/components/ui/text.tsx index 2302405f4a..b094e40520 100644 --- a/mobile/src/components/ui/text.tsx +++ b/mobile/src/components/ui/text.tsx @@ -43,6 +43,7 @@ const COLOR_CONFIG: Record = { "text-light-05": "text-text-light-05", "text-dark-03": "text-text-dark-03", "text-dark-05": "text-text-dark-05", + "action-selection-05": "text-action-selection-05", "status-error-01": "text-status-error-01", "status-error-02": "text-status-error-02", "status-error-05": "text-status-error-05", diff --git a/web/lib/opal/src/components/text/components.tsx b/web/lib/opal/src/components/text/components.tsx index 651b969fe3..fcb67c7382 100644 --- a/web/lib/opal/src/components/text/components.tsx +++ b/web/lib/opal/src/components/text/components.tsx @@ -133,6 +133,7 @@ const COLOR_CONFIG: Record = { "text-light-05": "text-text-light-05", "text-dark-03": "text-text-dark-03", "text-dark-05": "text-text-dark-05", + "action-selection-05": "text-action-selection-05", "status-error-01": "text-status-error-01", "status-error-02": "text-status-error-02", "status-error-05": "text-status-error-05", diff --git a/web/lib/shared/src/contracts/typography.ts b/web/lib/shared/src/contracts/typography.ts index c7ca41ff45..1a14fd9d70 100644 --- a/web/lib/shared/src/contracts/typography.ts +++ b/web/lib/shared/src/contracts/typography.ts @@ -47,6 +47,7 @@ export type TextColor = | "text-light-05" | "text-dark-03" | "text-dark-05" + | "action-selection-05" | "status-error-01" | "status-error-02" | "status-error-05" diff --git a/web/src/i18n/messages/ar.json b/web/src/i18n/messages/ar.json index e8c439063c..644c715c7f 100644 --- a/web/src/i18n/messages/ar.json +++ b/web/src/i18n/messages/ar.json @@ -10730,6 +10730,9 @@ "ariaLabel": "حفظ" } }, + "enabledCount": { + "label": "{enabled} من {total}" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/de.json b/web/src/i18n/messages/de.json index fc700ea909..5442750c76 100644 --- a/web/src/i18n/messages/de.json +++ b/web/src/i18n/messages/de.json @@ -10730,6 +10730,9 @@ "ariaLabel": "Speichern" } }, + "enabledCount": { + "label": "{enabled} von {total}" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/en.json b/web/src/i18n/messages/en.json index 7177f7bde9..221c725c0d 100644 --- a/web/src/i18n/messages/en.json +++ b/web/src/i18n/messages/en.json @@ -10730,6 +10730,9 @@ "ariaLabel": "Save" } }, + "enabledCount": { + "label": "{enabled} of {total}" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/es.json b/web/src/i18n/messages/es.json index 55be5945dd..188fed968c 100644 --- a/web/src/i18n/messages/es.json +++ b/web/src/i18n/messages/es.json @@ -10730,6 +10730,9 @@ "ariaLabel": "Guardar" } }, + "enabledCount": { + "label": "{enabled} de {total}" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/fr.json b/web/src/i18n/messages/fr.json index 155e6ef726..052c8a2413 100644 --- a/web/src/i18n/messages/fr.json +++ b/web/src/i18n/messages/fr.json @@ -10730,6 +10730,9 @@ "ariaLabel": "Enregistrer" } }, + "enabledCount": { + "label": "{enabled} sur {total}" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/ja.json b/web/src/i18n/messages/ja.json index d5e42eafb4..55a8ecbdaf 100644 --- a/web/src/i18n/messages/ja.json +++ b/web/src/i18n/messages/ja.json @@ -10730,6 +10730,9 @@ "ariaLabel": "保存" } }, + "enabledCount": { + "label": "{total} 中 {enabled}" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/ko.json b/web/src/i18n/messages/ko.json index 88f0945cfe..ef7b473457 100644 --- a/web/src/i18n/messages/ko.json +++ b/web/src/i18n/messages/ko.json @@ -10730,6 +10730,9 @@ "ariaLabel": "저장" } }, + "enabledCount": { + "label": "{total}개 중 {enabled}개" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/pt.json b/web/src/i18n/messages/pt.json index 698ea7c3d9..49d35086a0 100644 --- a/web/src/i18n/messages/pt.json +++ b/web/src/i18n/messages/pt.json @@ -10730,6 +10730,9 @@ "ariaLabel": "Salvar" } }, + "enabledCount": { + "label": "{enabled} de {total}" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/i18n/messages/zh.json b/web/src/i18n/messages/zh.json index a9da913d87..4ed7a5ef96 100644 --- a/web/src/i18n/messages/zh.json +++ b/web/src/i18n/messages/zh.json @@ -10730,6 +10730,9 @@ "ariaLabel": "保存" } }, + "enabledCount": { + "label": "{total} 个中的 {enabled} 个" + }, "errorPages": { "accessRestricted": { "billingAdminHint": { diff --git a/web/src/refresh-components/EnabledCount.stories.tsx b/web/src/lib/tools/components/EnabledCount.stories.tsx similarity index 70% rename from web/src/refresh-components/EnabledCount.stories.tsx rename to web/src/lib/tools/components/EnabledCount.stories.tsx index 5ca4423d01..d0e03c0bd7 100644 --- a/web/src/refresh-components/EnabledCount.stories.tsx +++ b/web/src/lib/tools/components/EnabledCount.stories.tsx @@ -1,8 +1,8 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; -import EnabledCount from "./EnabledCount"; +import EnabledCount from "@/lib/tools/components/EnabledCount"; const meta: Meta = { - title: "refresh-components/EnabledCount", + title: "tools/EnabledCount", component: EnabledCount, tags: ["autodocs"], parameters: { @@ -20,17 +20,8 @@ export const Default: Story = { }, }; -export const WithName: Story = { - args: { - name: "connector", - enabledCount: 3, - totalCount: 10, - }, -}; - export const AllEnabled: Story = { args: { - name: "source", enabledCount: 8, totalCount: 8, }, @@ -38,7 +29,6 @@ export const AllEnabled: Story = { export const NoneEnabled: Story = { args: { - name: "item", enabledCount: 0, totalCount: 15, }, @@ -46,7 +36,6 @@ export const NoneEnabled: Story = { export const SingleItem: Story = { args: { - name: "document", enabledCount: 1, totalCount: 1, }, diff --git a/web/src/lib/tools/components/EnabledCount.tsx b/web/src/lib/tools/components/EnabledCount.tsx new file mode 100644 index 0000000000..84037d73b2 --- /dev/null +++ b/web/src/lib/tools/components/EnabledCount.tsx @@ -0,0 +1,43 @@ +"use client"; + +import { type ReactNode } from "react"; +import { useTranslations } from "next-intl"; +import { Text } from "@opal/components"; +import { richNodes } from "@opal/utils"; + +interface EnabledCountProps { + enabledCount: number; + totalCount: number; +} + +/** + * How many of a set of tools are switched on, e.g. "3 of 12". + * + * The noun is left to the surrounding row, which already names what is being + * counted — every call site is a tool context. + */ +export default function EnabledCount({ + enabledCount, + totalCount, +}: EnabledCountProps) { + const t = useTranslations("common"); + + // The enabled figure is picked out from the rest of the phrase. It has to + // be a tag rather than a separate element, because where the number falls + // in the sentence is the translation's business, not this component's. + function value(chunks: ReactNode) { + return {richNodes(chunks)}; + } + + return ( + + {richNodes( + t.rich("enabledCount.label", { + enabled: enabledCount, + total: totalCount, + value, + }) + )} + + ); +} diff --git a/web/src/lib/tools/components/MCPLineItem.tsx b/web/src/lib/tools/components/MCPLineItem.tsx index c246e1417a..5b8913af0c 100644 --- a/web/src/lib/tools/components/MCPLineItem.tsx +++ b/web/src/lib/tools/components/MCPLineItem.tsx @@ -19,7 +19,7 @@ import { MCPAuthenticationPerformer, ToolSnapshot, } from "@/lib/tools/types"; -import EnabledCount from "@/refresh-components/EnabledCount"; +import EnabledCount from "@/lib/tools/components/EnabledCount"; export interface MCPServer { id: number; diff --git a/web/src/lib/tools/components/ToolLineItem.tsx b/web/src/lib/tools/components/ToolLineItem.tsx index 8d4722a3d6..183293baae 100644 --- a/web/src/lib/tools/components/ToolLineItem.tsx +++ b/web/src/lib/tools/components/ToolLineItem.tsx @@ -29,7 +29,7 @@ import { useToolsPopover } from "@/lib/tools/providers"; import { ToolSnapshot } from "@/lib/tools/types"; import { getAdminConfigureInfo, getToolTooltip } from "@/lib/tools/utils"; import { Permission } from "@/lib/types"; -import EnabledCount from "@/refresh-components/EnabledCount"; +import EnabledCount from "@/lib/tools/components/EnabledCount"; import { useUser } from "@/providers/UserProvider"; // Names the hover group that swaps the source count for the disable button. diff --git a/web/src/refresh-components/EnabledCount.tsx b/web/src/refresh-components/EnabledCount.tsx deleted file mode 100644 index 9a02659fbf..0000000000 --- a/web/src/refresh-components/EnabledCount.tsx +++ /dev/null @@ -1,28 +0,0 @@ -"use client"; - -import { memo } from "react"; -import Text from "@/refresh-components/texts/Text"; - -interface EnabledCountProps { - name?: string; - enabledCount: number; - totalCount: number; -} - -const EnabledCount = memo( - ({ name, enabledCount, totalCount }: EnabledCountProps) => { - return ( - - - {enabledCount} - - {` of ${totalCount} ${name ?? ""}${ - name && totalCount !== 1 ? "s" : "" - }`} - - ); - } -); -EnabledCount.displayName = "EnabledCount"; - -export default EnabledCount; diff --git a/web/src/sections/actions/ToolsList.tsx b/web/src/sections/actions/ToolsList.tsx index 0b44c0b0b9..941ec5e103 100644 --- a/web/src/sections/actions/ToolsList.tsx +++ b/web/src/sections/actions/ToolsList.tsx @@ -7,7 +7,7 @@ import Text from "@/refresh-components/texts/Text"; import { Button } from "@opal/components"; import FadingEdgeContainer from "@/refresh-components/FadingEdgeContainer"; import ToolItemSkeleton from "@/sections/actions/skeleton/ToolItemSkeleton"; -import EnabledCount from "@/refresh-components/EnabledCount"; +import EnabledCount from "@/lib/tools/components/EnabledCount"; import { SvgEye, SvgXCircle } from "@opal/icons"; export interface ToolsListProps { @@ -96,7 +96,6 @@ const ToolsList: React.FC = ({ )} {onToggleShowOnlyEnabled && enabledCount > 0 && ( diff --git a/web/src/views/AgentEditorPage.tsx b/web/src/views/AgentEditorPage.tsx index a7ac22555c..52df6bb403 100644 --- a/web/src/views/AgentEditorPage.tsx +++ b/web/src/views/AgentEditorPage.tsx @@ -87,7 +87,7 @@ import { useAvailableTools } from "@/lib/tools/hooks"; import { getActionIcon } from "@/lib/tools/utils"; import { AgentEditorMCPServer, MCPTool, ToolSnapshot } from "@/lib/tools/types"; import useFilter from "@/hooks/useFilter"; -import EnabledCount from "@/refresh-components/EnabledCount"; +import EnabledCount from "@/lib/tools/components/EnabledCount"; import { useAppPosition } from "@/lib/position/hooks"; import { isDateInFuture } from "@/lib/dateUtils"; import {