feat(channels): 添加渠道状态筛选功能以优化用户体验
在渠道管理页面中引入了渠道状态筛选功能,允许用户根据渠道的启用状态(全部、已启用、已停用)进行过滤。这一改动旨在提升用户在管理渠道时的灵活性和效率,使其能够更方便地找到所需的渠道。更新了相关的国际化文件,以支持多语言环境下的状态筛选描述,确保所有用户都能理解这一新功能。
This commit is contained in:
1 parent
b03b660de7
commit
d3d64bbb77
4 files changed
+34
-16
No files matched your search
@@ -116,7 +116,10 @@
|
||||
"title": "Channels",
|
||||
"description": "Configure AI provider endpoints, manage models and load balancing",
|
||||
"searchPlaceholder": "Search channels...",
|
||||
"enabledOnly": "Enabled only",
|
||||
"statusFilter": "Channel status filter",
|
||||
"filterAll": "All",
|
||||
"filterEnabled": "Enabled",
|
||||
"filterDisabled": "Disabled",
|
||||
"addChannel": "Add Channel",
|
||||
"editChannel": "Edit Channel",
|
||||
"emptyTitle": "Add your first channel",
|
||||
|
||||
@@ -116,7 +116,10 @@
|
||||
"title": "渠道管理",
|
||||
"description": "配置 AI 服务商接口,管理模型和负载均衡策略",
|
||||
"searchPlaceholder": "搜索渠道...",
|
||||
"enabledOnly": "仅已启用",
|
||||
"statusFilter": "渠道状态筛选",
|
||||
"filterAll": "全部",
|
||||
"filterEnabled": "已启用",
|
||||
"filterDisabled": "已停用",
|
||||
"addChannel": "添加渠道",
|
||||
"editChannel": "编辑渠道",
|
||||
"emptyTitle": "添加您的第一个渠道",
|
||||
|
||||
@@ -116,7 +116,10 @@
|
||||
"title": "渠道管理",
|
||||
"description": "設定 AI 服務商介面,管理模型和負載均衡策略",
|
||||
"searchPlaceholder": "搜尋渠道...",
|
||||
"enabledOnly": "僅已啟用",
|
||||
"statusFilter": "渠道狀態篩選",
|
||||
"filterAll": "全部",
|
||||
"filterEnabled": "已啟用",
|
||||
"filterDisabled": "已停用",
|
||||
"addChannel": "新增渠道",
|
||||
"editChannel": "編輯渠道",
|
||||
"emptyTitle": "新增您的第一個渠道",
|
||||
|
||||
@@ -38,6 +38,7 @@ import i18n from "@/i18n";
|
||||
|
||||
type EditMode = "form" | "json";
|
||||
type ModelEditorMode = "visual" | "json";
|
||||
type ChannelStatusFilter = "all" | "enabled" | "disabled";
|
||||
type JsonObject = Record<string, unknown>;
|
||||
type ModelRow = { id: string; name: string; enabled: boolean; default_params?: JsonObject };
|
||||
type FetchedModelCandidate = { id: string; label: string };
|
||||
@@ -577,7 +578,7 @@ export function Channels({ createMode = false, editRoute = false }: { createMode
|
||||
const [modelRows, setModelRows] = useState<ModelRow[]>([createEmptyModelRow()]);
|
||||
const [modelJsonValue, setModelJsonValue] = useState("[]");
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [showEnabledOnly, setShowEnabledOnly] = useState(true);
|
||||
const [statusFilter, setStatusFilter] = useState<ChannelStatusFilter>("enabled");
|
||||
const [openMenu, setOpenMenu] = useState<string | null>(null);
|
||||
const [isFetchedModelsDialogOpen, setIsFetchedModelsDialogOpen] = useState(false);
|
||||
const [fetchedModelCandidates, setFetchedModelCandidates] = useState<FetchedModelCandidate[]>([]);
|
||||
@@ -595,6 +596,11 @@ export function Channels({ createMode = false, editRoute = false }: { createMode
|
||||
{ value: "visual" as const, label: t("common.visual") },
|
||||
{ value: "json" as const, label: t("common.json") },
|
||||
];
|
||||
const statusFilterOptions = [
|
||||
{ value: "all" as const, label: t("channels.filterAll") },
|
||||
{ value: "enabled" as const, label: t("channels.filterEnabled") },
|
||||
{ value: "disabled" as const, label: t("channels.filterDisabled") },
|
||||
];
|
||||
|
||||
const applyModels = (models: ChannelModelMapping[]) => {
|
||||
const normalizedModels = normalizeModels(models);
|
||||
@@ -1092,7 +1098,11 @@ export function Channels({ createMode = false, editRoute = false }: { createMode
|
||||
const rawConfig = parseChannelValue(channel);
|
||||
const config = normalizeChannelFormConfig(rawConfig);
|
||||
|
||||
if (showEnabledOnly && config.enabled === false) {
|
||||
const isEnabled = config.enabled !== false;
|
||||
if (statusFilter === "enabled" && !isEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (statusFilter === "disabled" && isEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1157,17 +1167,16 @@ export function Channels({ createMode = false, editRoute = false }: { createMode
|
||||
className="pl-9"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant={showEnabledOnly ? "secondary" : "outline"}
|
||||
size="sm"
|
||||
aria-pressed={showEnabledOnly}
|
||||
onClick={() => setShowEnabledOnly((current) => !current)}
|
||||
className="w-full sm:w-auto"
|
||||
>
|
||||
<Check className={cn("h-4 w-4", !showEnabledOnly && "opacity-0")} />
|
||||
{t("channels.enabledOnly")}
|
||||
</Button>
|
||||
<ButtonGroup
|
||||
aria-label={t("channels.statusFilter")}
|
||||
value={statusFilter}
|
||||
options={statusFilterOptions}
|
||||
onValueChange={setStatusFilter}
|
||||
activeVariant="secondary"
|
||||
inactiveVariant="outline"
|
||||
className="grid w-full grid-cols-3 sm:inline-flex sm:w-auto"
|
||||
buttonClassName="h-9 rounded-sm px-3"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in new issue
Block a user