-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
fix(web): 修复新前端订阅额度转换、额度设置保存失败及供应商无法编辑的问题 #4598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b88d878
b76eea7
06e9ff1
1b1f9f3
0fa6e66
0335274
13d5ec4
dca2811
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| import { useState } from 'react' | ||
| import { useQuery, useQueryClient } from '@tanstack/react-query' | ||
| import { Pencil, Plus, Trash2 } from 'lucide-react' | ||
| import { useTranslation } from 'react-i18next' | ||
| import { Button } from '@/components/ui/button' | ||
| import { | ||
| Dialog, | ||
| DialogContent, | ||
| DialogDescription, | ||
| DialogHeader, | ||
| DialogTitle, | ||
| } from '@/components/ui/dialog' | ||
| import { ConfirmDialog } from '@/components/confirm-dialog' | ||
| import { getLobeIcon } from '@/lib/lobe-icon' | ||
| import { getVendors } from '../../api' | ||
| import { vendorsQueryKeys } from '../../lib' | ||
| import { handleDeleteVendor } from '../../lib/vendor-actions' | ||
| import type { Vendor } from '../../types' | ||
| import { useModels } from '../models-provider' | ||
|
|
||
| type VendorManageDialogProps = { | ||
| open: boolean | ||
| onOpenChange: (open: boolean) => void | ||
| } | ||
|
|
||
| export function VendorManageDialog({ | ||
| open, | ||
| onOpenChange, | ||
| }: VendorManageDialogProps) { | ||
| const { t } = useTranslation() | ||
| const { setOpen, setCurrentVendor } = useModels() | ||
| const queryClient = useQueryClient() | ||
| const [deleteTarget, setDeleteTarget] = useState<Vendor | null>(null) | ||
|
|
||
| const { data, isLoading } = useQuery({ | ||
| queryKey: vendorsQueryKeys.list(), | ||
| queryFn: () => getVendors({ page_size: 1000 }), | ||
| enabled: open, | ||
| }) | ||
|
|
||
| const vendors = data?.data?.items ?? [] | ||
|
|
||
| const handleEdit = (vendor: Vendor) => { | ||
| setCurrentVendor(vendor) | ||
| setOpen('update-vendor') | ||
| } | ||
|
|
||
| const handleCreate = () => { | ||
| setCurrentVendor(null) | ||
| setOpen('create-vendor') | ||
| } | ||
|
|
||
| return ( | ||
| <> | ||
| <Dialog open={open} onOpenChange={onOpenChange}> | ||
| <DialogContent className='max-w-lg'> | ||
| <DialogHeader> | ||
| <DialogTitle>{t('Manage Vendors')}</DialogTitle> | ||
| <DialogDescription> | ||
| {t('Create, edit, or delete vendors')} | ||
| </DialogDescription> | ||
| </DialogHeader> | ||
|
|
||
| <div className='max-h-80 space-y-2 overflow-y-auto'> | ||
| {!isLoading && vendors.length === 0 && ( | ||
| <p className='text-muted-foreground py-4 text-center text-sm'> | ||
| {t('No vendors yet')} | ||
| </p> | ||
| )} | ||
| {vendors.map((vendor) => { | ||
| const icon = vendor.icon | ||
| ? getLobeIcon(vendor.icon, 20) | ||
| : null | ||
| return ( | ||
| <div | ||
| key={vendor.id} | ||
| className='flex items-center justify-between rounded-lg border px-3 py-2' | ||
| > | ||
| <div className='flex items-center gap-2'> | ||
| {icon} | ||
| <div> | ||
| <div className='text-sm font-medium'> | ||
| {vendor.name} | ||
| </div> | ||
| {vendor.description && ( | ||
| <div className='text-muted-foreground text-xs'> | ||
| {vendor.description} | ||
| </div> | ||
| )} | ||
| </div> | ||
| </div> | ||
| <div className='flex items-center gap-1'> | ||
| <Button | ||
| variant='ghost' | ||
| size='icon' | ||
| className='h-8 w-8' | ||
| aria-label={t('Edit Vendor')} | ||
| onClick={() => handleEdit(vendor)} | ||
| > | ||
| <Pencil className='h-4 w-4' /> | ||
| </Button> | ||
| <Button | ||
| variant='ghost' | ||
| size='icon' | ||
| className='text-destructive hover:text-destructive h-8 w-8' | ||
| aria-label={t('Delete Vendor')} | ||
| onClick={() => setDeleteTarget(vendor)} | ||
| > | ||
| <Trash2 className='h-4 w-4' /> | ||
| </Button> | ||
| </div> | ||
| </div> | ||
| ) | ||
| })} | ||
| </div> | ||
|
|
||
| <Button onClick={handleCreate} className='w-full'> | ||
| <Plus className='mr-2 h-4 w-4' /> | ||
| {t('Create Vendor')} | ||
| </Button> | ||
| </DialogContent> | ||
| </Dialog> | ||
|
|
||
| <ConfirmDialog | ||
| open={!!deleteTarget} | ||
| onOpenChange={(v) => !v && setDeleteTarget(null)} | ||
| title={t('Delete Vendor')} | ||
| desc={t('Are you sure you want to delete "{{name}}"?', { | ||
| name: deleteTarget?.name, | ||
| })} | ||
| confirmText={t('Delete')} | ||
| destructive | ||
| handleConfirm={() => { | ||
| if (deleteTarget) { | ||
| handleDeleteVendor(deleteTarget.id, queryClient) | ||
| setDeleteTarget(null) | ||
| } | ||
| }} | ||
| /> | ||
| </> | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "Are you sure you want to delete \"{{name}}\"?": "Êtes-vous sûr de vouloir supprimer \"{{name}}\" ?", | ||
| "Create, edit, or delete vendors": "Créer, modifier ou supprimer des fournisseurs", | ||
| "Delete Vendor": "Supprimer le fournisseur", | ||
| "No vendors yet": "Aucun fournisseur", | ||
| "Vendor created successfully": "Fournisseur créé avec succès", | ||
| "Vendor updated successfully": "Fournisseur mis à jour avec succès" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "Are you sure you want to delete \"{{name}}\"?": "\"{{name}}\" を削除してもよろしいですか?", | ||
| "Create, edit, or delete vendors": "ベンダーの作成、編集、削除", | ||
| "Delete Vendor": "ベンダーを削除", | ||
| "No vendors yet": "ベンダーはまだありません", | ||
| "Vendor created successfully": "ベンダーを作成しました", | ||
| "Vendor updated successfully": "ベンダーを更新しました" | ||
|
Comment on lines
+2
to
+7
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fill in the remaining vendor-dialog translations. This file only adds a small subset of the keys used by 🤖 Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "Are you sure you want to delete \"{{name}}\"?": "Вы уверены, что хотите удалить \"{{name}}\"?", | ||
| "Create, edit, or delete vendors": "Создание, редактирование или удаление поставщиков", | ||
| "Delete Vendor": "Удалить поставщика", | ||
| "No vendors yet": "Поставщиков пока нет", | ||
| "Vendor created successfully": "Поставщик успешно создан", | ||
| "Vendor updated successfully": "Поставщик успешно обновлён" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "Are you sure you want to delete \"{{name}}\"?": "Bạn có chắc muốn xóa \"{{name}}\" không?", | ||
| "Create, edit, or delete vendors": "Tạo, chỉnh sửa hoặc xóa nhà cung cấp", | ||
| "Delete Vendor": "Xóa nhà cung cấp", | ||
| "No vendors yet": "Chưa có nhà cung cấp", | ||
| "Vendor created successfully": "Tạo nhà cung cấp thành công", | ||
| "Vendor updated successfully": "Cập nhật nhà cung cấp thành công" | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.