fix: refresh enable backend state
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
import { atom } from 'jotai';
|
||||
|
||||
export const enabledBackendsAtom = atom<any>(null);
|
||||
@@ -430,6 +430,7 @@ export default function useTableFetch<T>(
|
||||
extraStatus,
|
||||
TABLE_SORT_DIRECTIONS,
|
||||
debounceFetchData,
|
||||
setDataSource,
|
||||
setQueryParams,
|
||||
handleDelete,
|
||||
handleDeleteBatch,
|
||||
|
||||
@@ -44,5 +44,5 @@ export default {
|
||||
'backend.filter.source': 'Filter by source',
|
||||
'backend.add.custom': 'Custom',
|
||||
'backend.add.community': 'Community Backends',
|
||||
'backend.community.title': 'Community Backends Marketplace'
|
||||
'backend.community.title': 'Community Backend Marketplace'
|
||||
};
|
||||
|
||||
@@ -113,7 +113,7 @@ export default {
|
||||
'clusters.table.ip.internal': 'Internal',
|
||||
'clusters.table.ip.external': 'External',
|
||||
'clusters.form.serverUrl.tips':
|
||||
'Specify an externally accessible GPUStack service URL if the worker cannot access GPUStack directly.',
|
||||
'Specify an externally accessible GPUStack service URL if the worker cannot access GPUStack Server directly.',
|
||||
'clusters.form.setDefault': 'Set as Default',
|
||||
'clusters.form.setDefault.tips': 'Default for deployment.',
|
||||
'clusters.addworker.noClusters': 'No available Docker clusters found',
|
||||
|
||||
@@ -39,5 +39,5 @@ export default {
|
||||
'users.status.deactivate': 'Deactivate Account',
|
||||
'users.status.inactiveAccount': 'Inactive Account',
|
||||
'users.login.getInitialPassword':
|
||||
'Run the following command on your server to retrieve the initial admin password.'
|
||||
'Run the following command on your GPUStack Server to retrieve the initial admin password.'
|
||||
};
|
||||
|
||||
@@ -44,5 +44,5 @@ export default {
|
||||
'backend.filter.source': 'Filter by source',
|
||||
'backend.add.custom': 'Custom',
|
||||
'backend.add.community': 'Community Backends',
|
||||
'backend.community.title': 'Community Backends Marketplace'
|
||||
'backend.community.title': 'Community Backend Marketplace'
|
||||
};
|
||||
|
||||
@@ -113,7 +113,7 @@ export default {
|
||||
'clusters.table.ip.internal': 'Internal',
|
||||
'clusters.table.ip.external': 'External',
|
||||
'clusters.form.serverUrl.tips':
|
||||
'Specify an externally accessible GPUStack service URL if the worker cannot access GPUStack directly.',
|
||||
'Specify an externally accessible GPUStack service URL if the worker cannot access GPUStack Server directly.',
|
||||
'clusters.form.setDefault': 'Set as Default',
|
||||
'clusters.form.setDefault.tips': 'Default for deployment.',
|
||||
'clusters.addworker.noClusters': 'No available Docker clusters found',
|
||||
@@ -217,7 +217,7 @@ export default {
|
||||
// 78. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.',
|
||||
// 79. 'clusters.table.ip.internal': 'Internal',
|
||||
// 80. 'clusters.table.ip.external': 'External',
|
||||
// 81. 'clusters.form.serverUrl.tips': 'Specify an externally accessible GPUStack service URL if the worker cannot access GPUStack directly.',
|
||||
// 81. 'clusters.form.serverUrl.tips': 'Specify an externally accessible GPUStack service URL if the worker cannot access GPUStack Server directly.',
|
||||
// 82. 'clusters.addworker.externalIP.tips': 'Specify an external IP if the worker is in a VPC or private network.',
|
||||
// 83. 'clusters.form.setDefault': 'Set as Default',
|
||||
// 84. 'clusters.form.setDefault.tips': 'Default for deployment',
|
||||
|
||||
@@ -40,7 +40,7 @@ export default {
|
||||
'users.status.deactivate': 'Deactivate Account',
|
||||
'users.status.inactiveAccount': 'Inactive Account',
|
||||
'users.login.getInitialPassword':
|
||||
'Run the following command on your server to retrieve the initial admin password.'
|
||||
'Run the following command on your GPUStack Server to retrieve the initial admin password.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
@@ -48,5 +48,5 @@ export default {
|
||||
// 2. 'users.status.activate': 'Activate Account',
|
||||
// 3. 'users.status.deactivate': 'Deactivate Account',
|
||||
// 4. 'users.status.inactiveAccount': 'Inactive Account',
|
||||
// 5. 'users.login.getInitialPassword': 'Run the following command on your server to retrieve the initial admin password.'
|
||||
// 5. 'users.login.getInitialPassword': 'Run the following command on your GPUStack Server to retrieve the initial admin password.'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -44,7 +44,7 @@ export default {
|
||||
'backend.filter.source': 'Filter by source',
|
||||
'backend.add.custom': 'Custom',
|
||||
'backend.add.community': 'Community Backends',
|
||||
'backend.community.title': 'Community Backends Marketplace'
|
||||
'backend.community.title': 'Community Backend Marketplace'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
@@ -53,5 +53,5 @@ export default {
|
||||
// 3. 'backend.filter.source': 'Filter by source',
|
||||
// 4. 'backend.add.custom': 'Custom',
|
||||
// 5. 'backend.add.community': 'Community Backends',
|
||||
// 6. 'backend.community.title': 'Community Backends Marketplace'
|
||||
// 6. 'backend.community.title': 'Community Backend Marketplace'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -113,7 +113,7 @@ export default {
|
||||
'clusters.table.ip.internal': 'Внутренний',
|
||||
'clusters.table.ip.external': 'Внешний',
|
||||
'clusters.form.serverUrl.tips':
|
||||
'Если рабочий узел не может напрямую получить доступ к GPUStack, укажите внешний URL службы GPUStack.',
|
||||
'Если рабочий узел не может напрямую получить доступ к GPUStack Server, укажите внешний URL службы GPUStack Server.',
|
||||
'clusters.form.setDefault': 'Установить по умолчанию',
|
||||
'clusters.form.setDefault.tips':
|
||||
'Использовать по умолчанию для развертывания.',
|
||||
|
||||
@@ -102,7 +102,7 @@ export default {
|
||||
'已将 {count} 个新节点添加到集群中。',
|
||||
'clusters.addworker.message.success_multiple':
|
||||
'已将 {count} 个新节点添加到集群中。',
|
||||
'clusters.create.serverUrl': 'GPUStack 服务地址',
|
||||
'clusters.create.serverUrl': 'GPUStack Server 节点地址',
|
||||
'clusters.create.workerConfig': '节点配置',
|
||||
'clusters.addworker.containerName': '节点容器名称',
|
||||
'clusters.addworker.containerName.tips': '为节点容器指定一个名称。',
|
||||
@@ -111,7 +111,7 @@ export default {
|
||||
'clusters.table.ip.internal': '内',
|
||||
'clusters.table.ip.external': '外',
|
||||
'clusters.form.serverUrl.tips':
|
||||
'如果节点无法直接访问 GPUStack,则指定一个可访问的外部 GPUStack 服务地址。',
|
||||
'如果节点无法直接访问 GPUStack Server,则指定一个可访问的外部 GPUStack Server 地址。',
|
||||
'clusters.form.setDefault': '设为默认',
|
||||
'clusters.form.setDefault.tips': '部署时的默认集群。',
|
||||
'clusters.addworker.noClusters': '无可用的 Docker 集群',
|
||||
|
||||
@@ -258,7 +258,7 @@ export default {
|
||||
'models.form.backendVersions.tips': `如需使用更多版本,请前往{link}页面并编辑对应的后端以添加版本。`,
|
||||
'models.catalog.nogpus.tips': '所选集群中没有兼容该模型的 GPU。',
|
||||
'models.form.modelfile.notfound':
|
||||
'你指定的模型文件路径在 GPUStack 服务器上不存在。建议在 GPUStack 服务器和 GPUStack 节点上使用相同的模型文件路径,这有助于 GPUStack 做出更优的调度与决策。',
|
||||
'你指定的模型文件路径在 GPUStack Server 节点上不存在。建议在 GPUStack Server 节点和 GPUStack 节点上使用相同的模型文件路径,这有助于 GPUStack 做出更优的调度与决策。',
|
||||
'models.form.readyWorkers': '节点就绪',
|
||||
'models.form.maxContextLength': '最大上下文长度',
|
||||
'models.form.backend.helperText': '该社区后端暂未启用,部署后将自动启用',
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { enabledBackendsAtom } from '@/atoms/backend';
|
||||
import GSDrawer from '@/components/scroller-modal/gs-drawer';
|
||||
import ColumnWrapper from '@/pages/_components/column-wrapper';
|
||||
import Separator from '@/pages/llmodels/components/separator';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import React from 'react';
|
||||
import { useAtom } from 'jotai';
|
||||
import React, { useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { ListItem } from '../config/types';
|
||||
import useEnableBackend from '../services/use-enable-backend';
|
||||
@@ -23,6 +25,7 @@ const AddCommunityModal: React.FC<{
|
||||
const intl = useIntl();
|
||||
const { handleEnableBackend } = useEnableBackend();
|
||||
const [currentData, setCurrentData] = React.useState<any>(null);
|
||||
const [, setEnabledBackendAtom] = useAtom(enabledBackendsAtom);
|
||||
|
||||
const handleOnEnable = async (checked: boolean, data: ListItem) => {
|
||||
await handleEnableBackend({
|
||||
@@ -32,12 +35,23 @@ const AddCommunityModal: React.FC<{
|
||||
enabled: checked
|
||||
}
|
||||
});
|
||||
setEnabledBackendAtom({
|
||||
...data,
|
||||
enabled: checked
|
||||
});
|
||||
onRefresh?.();
|
||||
};
|
||||
|
||||
const handleOnClick = (data: ListItem) => {
|
||||
setCurrentData(data);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setEnabledBackendAtom(null);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<GSDrawer
|
||||
open={open}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { enabledBackendsAtom } from '@/atoms/backend';
|
||||
import IconFont from '@/components/icon-font';
|
||||
import ThemeTag from '@/components/tags-wrapper/theme-tag';
|
||||
import useTableFetch from '@/hooks/use-table-fetch';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Input, Tooltip } from 'antd';
|
||||
import { useAtom } from 'jotai';
|
||||
import _ from 'lodash';
|
||||
import React, { useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
@@ -28,19 +30,46 @@ const CommunityBackends: React.FC<{
|
||||
onClick: (data: ListItem) => void;
|
||||
}> = ({ onEnable, onClick }) => {
|
||||
const intl = useIntl();
|
||||
const [enabledBackendAtom] = useAtom(enabledBackendsAtom);
|
||||
const [currentData, setCurrentData] = React.useState<ListItem | null>(null);
|
||||
const { dataSource, loadMore, queryParams, handleSearch, handleNameChange } =
|
||||
useTableFetch<ListItem>({
|
||||
fetchAPI: queryBackendsList,
|
||||
API: INFERENCE_BACKEND_API,
|
||||
watch: false,
|
||||
isInfiniteScroll: true,
|
||||
contentForDelete: 'backends.title',
|
||||
defaultQueryParams: {
|
||||
perPage: 24,
|
||||
community: 1
|
||||
}
|
||||
});
|
||||
const {
|
||||
dataSource,
|
||||
loadMore,
|
||||
queryParams,
|
||||
handleSearch,
|
||||
setDataSource,
|
||||
handleNameChange
|
||||
} = useTableFetch<ListItem>({
|
||||
fetchAPI: queryBackendsList,
|
||||
API: INFERENCE_BACKEND_API,
|
||||
watch: false,
|
||||
isInfiniteScroll: true,
|
||||
contentForDelete: 'backends.title',
|
||||
defaultQueryParams: {
|
||||
perPage: 24,
|
||||
community: 1
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (enabledBackendAtom) {
|
||||
setDataSource((prev) => {
|
||||
const newDataList = prev.dataList.map((item) => {
|
||||
if (item.id === enabledBackendAtom.id) {
|
||||
return {
|
||||
...item,
|
||||
enabled: enabledBackendAtom.enabled
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
return {
|
||||
...prev,
|
||||
dataList: newDataList
|
||||
};
|
||||
});
|
||||
}
|
||||
}, [enabledBackendAtom]);
|
||||
|
||||
const handleOnClickItem = (data: ListItem) => {
|
||||
onClick(data);
|
||||
|
||||
Reference in New Issue
Block a user