feat(providers): expose inline enable/disable toggle in resource table

- Wire useProviderWorkbench.toggleDisabled through ProviderResourcePanel
  to ProviderResourceTable as an inline ToggleSwitch in the actions cell
- Hide the toggle for the Ampcode singleton brand
- Add toast on success/failure and i18n keys (en/zh-CN/zh-TW/ru) for the
  enable/disable labels and a toggleFailed error message
This commit is contained in:
LTbinglingfeng
2026-05-25 00:43:13 +08:00
Unverified
parent 1ceb7e15f5
commit 47ba6ab91c
8 changed files with 70 additions and 4 deletions
@@ -183,6 +183,27 @@ export function ProvidersWorkbenchPage() {
[showConfirmation, showNotification, t, workbench]
);
const handleToggleDisabled = useCallback(
async (resource: ProviderResource, disabled: boolean) => {
try {
await workbench.toggleDisabled(resource, disabled);
showNotification(
disabled
? t('providersPage.toast.disabled')
: t('providersPage.toast.enabled'),
'success'
);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
showNotification(
`${t('providersPage.toast.toggleFailed')}: ${msg}`,
'error'
);
}
},
[showNotification, t, workbench]
);
const handleCreated = useCallback(() => {
showNotification(t('providersPage.toast.created'), 'success');
closeSheet();
@@ -267,6 +288,7 @@ export function ProvidersWorkbenchPage() {
onView={openView}
onEdit={openEdit}
onDelete={handleDelete}
onToggleDisabled={handleToggleDisabled}
onCreate={openCreate}
/>
</div>
@@ -29,6 +29,7 @@ interface ProviderResourcePanelProps {
onView: (resource: ProviderResource) => void;
onEdit: (resource: ProviderResource) => void;
onDelete: (resource: ProviderResource) => void;
onToggleDisabled?: (resource: ProviderResource, disabled: boolean) => void;
onCreate: () => void;
}
@@ -42,6 +43,7 @@ export function ProviderResourcePanel({
onView,
onEdit,
onDelete,
onToggleDisabled,
onCreate,
}: ProviderResourcePanelProps) {
const { t } = useTranslation();
@@ -128,6 +130,7 @@ export function ProviderResourcePanel({
onView={onView}
onEdit={onEdit}
onDelete={onDelete}
onToggleDisabled={onToggleDisabled}
/>
)}
</section>
@@ -119,9 +119,16 @@
.actions {
display: flex;
gap: 4px;
align-items: center;
justify-content: flex-end;
}
.toggleWrap {
display: inline-flex;
align-items: center;
margin-right: 4px;
}
.iconBtn {
display: inline-flex;
align-items: center;
@@ -15,6 +15,7 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/Table';
import { ToggleSwitch } from '@/components/ui/ToggleSwitch';
import type { ProviderResource } from '../types';
import styles from './ProviderResourceTable.module.scss';
@@ -25,6 +26,7 @@ interface ProviderResourceTableProps {
onView: (resource: ProviderResource) => void;
onEdit: (resource: ProviderResource) => void;
onDelete: (resource: ProviderResource) => void;
onToggleDisabled?: (resource: ProviderResource, disabled: boolean) => void;
}
const columnWidths = ['20%', '22%', '8%', '22%', '8%', '20%'];
@@ -36,6 +38,7 @@ export function ProviderResourceTable({
onView,
onEdit,
onDelete,
onToggleDisabled,
}: ProviderResourceTableProps) {
const { t } = useTranslation();
@@ -191,6 +194,25 @@ export function ProviderResourceTable({
<TableCell>{renderStatus(resource)}</TableCell>
<TableCell alignRight>
<div className={styles.actions}>
{!isAmpcode && onToggleDisabled ? (
<span
className={styles.toggleWrap}
onClick={(e) => e.stopPropagation()}
>
<ToggleSwitch
checked={!resource.disabled}
disabled={disableMutations}
onChange={(value) =>
onToggleDisabled(resource, !value)
}
ariaLabel={
resource.disabled
? t('providersPage.actions.enable')
: t('providersPage.actions.disable')
}
/>
</span>
) : null}
<button
type="button"
className={styles.iconBtn}
+4 -1
View File
@@ -1469,6 +1469,8 @@
"save": "Save",
"create": "Create",
"back": "Back",
"enable": "Enable",
"disable": "Disable",
"openModelCatalog": "Open model catalog"
},
"categories": {
@@ -1594,7 +1596,8 @@
"updated": "Updated",
"deleted": "Deleted",
"enabled": "Enabled",
"disabled": "Disabled"
"disabled": "Disabled",
"toggleFailed": "Failed to update status"
},
"modelCatalog": {
"summaryTitle": "Model catalog",
+4 -1
View File
@@ -1466,6 +1466,8 @@
"save": "Сохранить",
"create": "Создать",
"back": "Назад",
"enable": "Включить",
"disable": "Отключить",
"openModelCatalog": "Каталог моделей"
},
"categories": {
@@ -1591,7 +1593,8 @@
"updated": "Обновлено",
"deleted": "Удалено",
"enabled": "Включено",
"disabled": "Отключено"
"disabled": "Отключено",
"toggleFailed": "Не удалось обновить статус"
},
"modelCatalog": {
"summaryTitle": "Каталог моделей",
+4 -1
View File
@@ -1469,6 +1469,8 @@
"save": "保存",
"create": "创建",
"back": "返回",
"enable": "启用",
"disable": "停用",
"openModelCatalog": "查看模型目录"
},
"categories": {
@@ -1594,7 +1596,8 @@
"updated": "更新成功",
"deleted": "删除成功",
"enabled": "已启用",
"disabled": "已停用"
"disabled": "已停用",
"toggleFailed": "更新状态失败"
},
"modelCatalog": {
"summaryTitle": "模型目录",
+4 -1
View File
@@ -1495,6 +1495,8 @@
"save": "儲存",
"create": "建立",
"back": "返回",
"enable": "啟用",
"disable": "停用",
"openModelCatalog": "檢視模型目錄"
},
"categories": {
@@ -1620,7 +1622,8 @@
"updated": "更新成功",
"deleted": "刪除成功",
"enabled": "已啟用",
"disabled": "已停用"
"disabled": "已停用",
"toggleFailed": "更新狀態失敗"
},
"modelCatalog": {
"summaryTitle": "模型目錄",