Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66e8f83395 | ||
|
|
41ebceca8f | ||
|
|
632685672c | ||
|
|
bd2e4bb633 | ||
|
|
835633d44b | ||
|
|
75773e6b00 | ||
|
|
a21b9b5244 | ||
|
|
38bf76dc14 | ||
|
|
9461341104 | ||
|
|
5b5b2c6364 | ||
|
|
a006263e51 | ||
|
|
febdd38f7c | ||
|
|
1b4d335b09 |
@@ -344,3 +344,16 @@ textarea:hover {
|
||||
.text-success {
|
||||
color: var(--ant-color-success);
|
||||
}
|
||||
|
||||
.desc-fill {
|
||||
font-weight: 600;
|
||||
color: var(--ant-color-text);
|
||||
background-color: var(--ant-color-fill-content);
|
||||
line-height: 1.5;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.line-6 {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
@@ -20,17 +20,30 @@ export const getRequestId = () => {
|
||||
return store.get(requestIdAtom);
|
||||
};
|
||||
|
||||
// store for cluster list: res.items from api
|
||||
export const clusterListAtom = atom<
|
||||
{
|
||||
label: string;
|
||||
value: number;
|
||||
provider: string;
|
||||
state: string;
|
||||
is_default: boolean;
|
||||
workers: number;
|
||||
ready_workers: number;
|
||||
gpus: number;
|
||||
}[]
|
||||
>([]);
|
||||
|
||||
// store for worker list: res.items from api
|
||||
export const workerListAtom = atom<
|
||||
{
|
||||
label: string;
|
||||
value: number;
|
||||
cluster_id: number;
|
||||
state: string;
|
||||
id: number;
|
||||
labels: Record<string, any>;
|
||||
name: string;
|
||||
}[]
|
||||
>([]);
|
||||
|
||||
|
||||
@@ -54,3 +54,4 @@ export const userSettingsHelperAtom = atom(
|
||||
});
|
||||
}
|
||||
);
|
||||
export const hideModalTemporarilyAtom = atom<boolean>(false);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: iconfont; /* Project id 4613488 */
|
||||
src: url('iconfont.woff2?t=1763436184844') format('woff2'),
|
||||
url('iconfont.woff?t=1763436184844') format('woff'),
|
||||
url('iconfont.ttf?t=1763436184844') format('truetype');
|
||||
src: url('iconfont.woff2?t=1766993792323') format('woff2'),
|
||||
url('iconfont.woff?t=1766993792323') format('woff'),
|
||||
url('iconfont.ttf?t=1766993792323') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@@ -13,6 +13,18 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-cloud::before {
|
||||
content: "\e6bc";
|
||||
}
|
||||
|
||||
.icon-server02::before {
|
||||
content: "\e6bd";
|
||||
}
|
||||
|
||||
.icon-drag_handle::before {
|
||||
content: "\e6b9";
|
||||
}
|
||||
|
||||
.icon-basic::before {
|
||||
content: "\e6bb";
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5,6 +5,27 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "46296038",
|
||||
"name": "cloud",
|
||||
"font_class": "cloud",
|
||||
"unicode": "e6bc",
|
||||
"unicode_decimal": 59068
|
||||
},
|
||||
{
|
||||
"icon_id": "46296037",
|
||||
"name": "server",
|
||||
"font_class": "server02",
|
||||
"unicode": "e6bd",
|
||||
"unicode_decimal": 59069
|
||||
},
|
||||
{
|
||||
"icon_id": "46272083",
|
||||
"name": "drag_handle",
|
||||
"font_class": "drag_handle",
|
||||
"unicode": "e6b9",
|
||||
"unicode_decimal": 59065
|
||||
},
|
||||
{
|
||||
"icon_id": "46055620",
|
||||
"name": "basic",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,8 @@
|
||||
import { createFromIconfontCN } from '@ant-design/icons';
|
||||
// import './iconfont/iconfont.js';
|
||||
import './iconfont/iconfont.js';
|
||||
|
||||
const IconFont = createFromIconfontCN({
|
||||
scriptUrl: '//at.alicdn.com/t/c/font_4613488_xvmo08q7urm.js'
|
||||
scriptUrl: ''
|
||||
});
|
||||
|
||||
export default IconFont;
|
||||
|
||||
@@ -168,14 +168,17 @@ export default function useOverlayScroller(data?: {
|
||||
|
||||
// add wheel event
|
||||
const handleWheelEvent = () => {
|
||||
scrollElementRef.current?.addEventListener?.('wheel', handleWheelCallback);
|
||||
scrollElementRef.current?.addEventListener?.('wheel', handleWheelCallback, {
|
||||
passive: true
|
||||
});
|
||||
};
|
||||
|
||||
// remove wheel event
|
||||
const removeWheelEvent = () => {
|
||||
scrollElementRef.current?.removeEventListener?.(
|
||||
'wheel',
|
||||
handleWheelCallback
|
||||
handleWheelCallback,
|
||||
{ passive: true }
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -202,23 +202,16 @@ export const ExtraContent = (props: { isDarkTheme?: boolean }) => {
|
||||
items: helpList.map((item) => ({
|
||||
key: item.key,
|
||||
label: (
|
||||
<span className="flex flex-center">
|
||||
<a
|
||||
className="flex flex-center gap-8"
|
||||
href={item.url}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{item.icon}
|
||||
<a
|
||||
className="m-l-8 "
|
||||
href={item.url}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
onClick() {
|
||||
if (item.key === 'version') {
|
||||
showVersion();
|
||||
}
|
||||
}
|
||||
{item.label}
|
||||
</a>
|
||||
)
|
||||
}))
|
||||
};
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ export default {
|
||||
'backend.mode.yaml': 'YAML Mode',
|
||||
'backend.form.healthCheckPath': 'Health Check Path',
|
||||
'backend.form.defaultExecuteCommand': 'Default Execution Command',
|
||||
'backend.form.defaultExecuteCommand.tips':
|
||||
'{{model_path}}, {{port}}, {{worker_ip}} and {{model_name}} are placeholders that will be substituted with the actual values during deployment.',
|
||||
'backend.form.defaultExecuteCommand.tips': `'{{'model_path'}}', '{{'port'}}', '{{'worker_ip'}}' and '{{'model_name'}}' are placeholders that will be substituted with the actual values during deployment.`,
|
||||
'backend.form.defaultBackendParameters': 'Default Backend Parameters',
|
||||
'backend.form.versionConfig': 'Versions Config',
|
||||
'backend.form.addParameter': 'Add Parameter',
|
||||
|
||||
@@ -51,8 +51,7 @@ export default {
|
||||
'If multiple outbound IPs exist, specify the one you want the worker to use. Please double-check with <span class="bold-text">hostname -I | xargs -n1</span>.',
|
||||
'clusters.addworker.nvidiaNotes-02':
|
||||
'If a model directory already exists on the worker, you can specify the path to mount it.',
|
||||
'clusters.addworker.hygonNotes': `If the <span class="bold-text">/opt/hyhal</span> directory does not exist, create a symbolic link to the Hygon installation path.
|
||||
Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
||||
'clusters.addworker.hygonNotes': `If <span class="bold-text">/opt/hyhal</span> or <span class="bold-text">/opt/dtk</span> does not exist, create symbolic links pointing to the corresponding Hygon installation paths, for example: <span class="desc-fill">ln -s /path/to/hyhal /opt/hyhal</span> <span class="desc-fill">ln -s /path/to/dtk /opt/dtk</span>.`,
|
||||
'clusters.addworker.corexNotes': `If the <span class="bold-text">/lib/modules</span> directory does not exist, create a symbolic link to the Iluvatar installation path:
|
||||
<span class="bold-text">ln -s /path/to/corex /lib/modules</span>. Same applies to the <span class="bold-text">/usr/local/corex</span> directory.`,
|
||||
'clusters.addworker.metaxNotes': `If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, create a symbolic link to the MetaX installation path:
|
||||
|
||||
@@ -19,8 +19,7 @@ export default {
|
||||
'backend.mode.yaml': 'YAML Mode',
|
||||
'backend.form.healthCheckPath': 'Health Check Path',
|
||||
'backend.form.defaultExecuteCommand': 'Default Execution Command',
|
||||
'backend.form.defaultExecuteCommand.tips':
|
||||
'{{model_path}}, {{port}}, {{worker_ip}} and {{model_name}} are placeholders that will be substituted with the actual values during deployment.',
|
||||
'backend.form.defaultExecuteCommand.tips': `'{{'model_path'}}', '{{'port'}}', '{{'worker_ip'}}' and '{{'model_name'}}' are placeholders that will be substituted with the actual values during deployment.`,
|
||||
'backend.form.defaultBackendParameters': 'Default Backend Parameters',
|
||||
'backend.form.versionConfig': 'Versions Config',
|
||||
'backend.form.addParameter': 'Add Parameter',
|
||||
|
||||
@@ -51,8 +51,7 @@ export default {
|
||||
'If multiple outbound IPs exist, specify the one you want the worker to use. Please double-check with <span class="bold-text">hostname -I | xargs -n1</span>.',
|
||||
'clusters.addworker.nvidiaNotes-02':
|
||||
'If a model directory already exists on the worker, you can specify the path to mount it.',
|
||||
'clusters.addworker.hygonNotes': `If the <span class="bold-text">/opt/hyhal</span> directory does not exist, create a symbolic link to the Hygon installation path.
|
||||
Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
||||
'clusters.addworker.hygonNotes': `If <span class="bold-text">/opt/hyhal</span> or <span class="bold-text">/opt/dtk</span> does not exist, create symbolic links pointing to the corresponding Hygon installation paths, for example: <span class="desc-fill">ln -s /path/to/hyhal /opt/hyhal</span> <span class="desc-fill">ln -s /path/to/dtk /opt/dtk</span>.`,
|
||||
'clusters.addworker.corexNotes': `If the <span class="bold-text">/lib/modules</span> directory does not exist, create a symbolic link to the Iluvatar installation path:
|
||||
<span class="bold-text">ln -s /path/to/corex /lib/modules</span>. Same applies to the <span class="bold-text">/usr/local/corex</span> directory.`,
|
||||
'clusters.addworker.metaxNotes': `If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, create a symbolic link to the MetaX installation path:
|
||||
@@ -165,7 +164,7 @@ Same applies to the <span class="bold-text">/opt/dtk</span> directory.`,
|
||||
// 43. 'cluster.provider.comingsoon': 'Coming soon',
|
||||
// 44. 'clusters.addworker.nvidiaNotes-01': 'If multiple outbound IPs exist, specify the one you want the worker to use. Please double-check with <span class="bold-text">hostname -I | xargs -n1</span>.',
|
||||
// 45. 'clusters.addworker.nvidiaNotes-02': 'If a model directory already exists on the worker, you can specify the path to mount it.',
|
||||
// 46. 'clusters.addworker.hygonNotes': 'If the <span class="bold-text">/opt/hyhal</span> directory does not exist, create a symbolic link to the Hygon installation path. Same applies to the <span class="bold-text">/opt/dtk</span> directory.',
|
||||
// 46. 'clusters.addworker.hygonNotes': `If <span class="bold-text">/opt/hyhal</span> or <span class="bold-text">/opt/dtk</span> does not exist, create symbolic links pointing to the corresponding Hygon installation paths, for example: <span class="desc-fill">ln -s /path/to/hyhal /opt/hyhal</span> <span class="desc-fill">ln -s /path/to/dtk /opt/dtk</span>.`,
|
||||
// 47. 'clusters.addworker.corexNotes': 'If the <span class="bold-text">/lib/modules</span> directory does not exist, create a symbolic link to the Iluvatar installation path: <span class="bold-text">ln -s /path/to/corex /lib/modules</span>. Same applies to the <span class="bold-text">/usr/local/corex</span> directory.',
|
||||
// 48. 'clusters.addworker.metaxNotes': 'If the <span class="bold-text">/opt/mxdriver</span> directory does not exist, create a symbolic link to the MetaX installation path: <span class="bold-text">ln -s /path/to/metax /opt/mxdriver</span>. Same applies to the <span class="bold-text">/opt/maca</span> directory.',
|
||||
// 49. 'clusters.addworker.cambriconNotes': 'If the <span class="bold-text">/usr/local/neuware</span> directory does not exist, create a symbolic link to the Cambricon installation path: <span class="bold-text">ln -s /path/to/neuware /usr/local/neuware</span>.'
|
||||
|
||||
@@ -19,8 +19,7 @@ export default {
|
||||
'backend.mode.yaml': 'Режим YAML',
|
||||
'backend.form.healthCheckPath': 'Путь проверки здоровья',
|
||||
'backend.form.defaultExecuteCommand': 'Команда выполнения по умолчанию',
|
||||
'backend.form.defaultExecuteCommand.tips':
|
||||
'{{model_path}}, {{port}}, {{worker_ip}} и {{model_name}} заполняются реальными значениями во время запуска',
|
||||
'backend.form.defaultExecuteCommand.tips': `'{{'model_path'}}', '{{'port'}}', '{{'worker_ip'}}' и '{{'model_name'}}' заполняются реальными значениями во время запуска`,
|
||||
'backend.form.defaultBackendParameters': 'Параметры бэкенда по умолчанию',
|
||||
'backend.form.versionConfig': 'Конфигурация версий',
|
||||
'backend.form.addParameter': 'Добавить параметр',
|
||||
|
||||
@@ -51,8 +51,7 @@ export default {
|
||||
'Если существует несколько исходящих IP-адресов, укажите тот, который должен использовать воркер. Пожалуйста, перепроверьте с помощью <span class="bold-text">hostname -I | xargs -n1</span>.',
|
||||
'clusters.addworker.nvidiaNotes-02':
|
||||
'Если директория с моделями уже существует на воркере, вы можете указать путь для её монтирования.',
|
||||
'clusters.addworker.hygonNotes':
|
||||
'Если директория <span class="bold-text">/opt/hyhal</span> не существует, создайте символическую ссылку на путь установки Hygon: <span class="bold-text">/opt/hyhal</span>. Аналогично для директории <span class="bold-text">/opt/dtk</span>.',
|
||||
'clusters.addworker.hygonNotes': `If <span class="bold-text">/opt/hyhal</span> or <span class="bold-text">/opt/dtk</span> does not exist, create symbolic links pointing to the corresponding Hygon installation paths, for example: <span class="desc-fill">ln -s /path/to/hyhal /opt/hyhal</span> <span class="desc-fill">ln -s /path/to/dtk /opt/dtk</span>.`,
|
||||
'clusters.addworker.corexNotes':
|
||||
'Если директория <span class="bold-text">/lib/modules</span> не существует, создайте символическую ссылку на путь установки Iluvatar: <span class="bold-text">ln -s /path/to/corex /lib/modules</span>. Аналогично для директории <span class="bold-text">/usr/local/corex</span>.',
|
||||
'clusters.addworker.metaxNotes':
|
||||
@@ -97,47 +96,29 @@ export default {
|
||||
'напр. /data/cache (путь должен начинаться с /)',
|
||||
'clusters.addworker.vendorNotes.title': 'Примечания для устройств {vendor}',
|
||||
'clusters.button.genToken':
|
||||
'Need to create a new token? Click <a href="{link}" target="_blank">here</a>.',
|
||||
'clusters.addworker.amdNotes-01': `If the <span class="bold-text">/opt/rocm</span> directory does not exist, please create a symbolic link pointing to the ROCm installed path: <span class="bold-text">ln -s /path/to/rocm /opt/rocm</span>.`,
|
||||
'Нужен новый токен? Нажмите <a href="{link}" target="_blank">здесь</a>.',
|
||||
'clusters.addworker.amdNotes-01': `Если директория <span class="bold-text">/opt/rocm</span> не существует, создайте символическую ссылку на путь установки ROCm: <span class="bold-text">ln -s /путь/к/rocm /opt/rocm</span>.`,
|
||||
'clusters.addworker.message.success_single':
|
||||
'{count} new worker has been added to the cluster.',
|
||||
'{count} новый воркер был добавлен в кластер.',
|
||||
'clusters.addworker.message.success_multiple':
|
||||
'{count} new workers have been added to the cluster.',
|
||||
'clusters.create.serverUrl': 'Server URL',
|
||||
'clusters.create.workerConfig': 'Worker Configuration',
|
||||
'clusters.addworker.containerName': 'Worker Container Name',
|
||||
'{count} новых воркеров были добавлены в кластер.',
|
||||
'clusters.create.serverUrl': 'URL сервера',
|
||||
'clusters.create.workerConfig': 'Конфигурация воркера',
|
||||
'clusters.addworker.containerName': 'Имя контейнера воркера',
|
||||
'clusters.addworker.containerName.tips':
|
||||
'Specify a name for the worker container.',
|
||||
'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||
'Укажите имя для контейнера воркера.',
|
||||
'clusters.addworker.dataVolume': 'Том данных GPUStack',
|
||||
'clusters.addworker.dataVolume.tips':
|
||||
'Specify a data storage path for GPUStack.',
|
||||
'clusters.table.ip.internal': 'Internal',
|
||||
'clusters.table.ip.external': 'External',
|
||||
'Укажите путь для хранения данных GPUStack.',
|
||||
'clusters.table.ip.internal': 'Внутренний',
|
||||
'clusters.table.ip.external': 'Внешний',
|
||||
'clusters.form.serverUrl.tips':
|
||||
'Specify the server URL accessible from your cloud provider.',
|
||||
'clusters.form.setDefault': 'Set as Default',
|
||||
'clusters.form.setDefault.tips': 'Default for deployment.'
|
||||
'Укажите URL сервера, доступный из вашего облачного провайдера.',
|
||||
'clusters.form.setDefault': 'Установить по умолчанию',
|
||||
'clusters.form.setDefault.tips':
|
||||
'Использовать по умолчанию для развертывания.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
// 1. 'clusters.addworker.amdNotes-01': `If the <span class="bold-text">/opt/rocm</span> directory does not exist, please create a symbolic link pointing to the ROCm installed path: <span class="bold-text">ln -s /path/to/rocm /opt/rocm</span>.`,
|
||||
// 2. 'clusters.button.genToken': 'Need to create a new token? Click <a href="{link}" target="_blank">here</a>.',
|
||||
// 3. 'clusters.addworker.cacheVolume': 'Model Cache Volume Mount',
|
||||
// 4. 'clusters.addworker.cacheVolume.tips': 'If you want to customize the model cache directory, you can specify the path to mount it.',
|
||||
// 5. 'clusters.addworker.message.success_single': '{count} new worker has been added to the cluster.',
|
||||
// 6. 'clusters.addworker.message.success_multiple': '{count} new workers have been added to the cluster.',
|
||||
// 7. 'clusters.create.serverUrl': 'Server URL',
|
||||
// 8. 'clusters.create.workerConfig': 'Worker Configuration'
|
||||
// 9. 'clusters.addworker.containerName': 'Worker Container Name',
|
||||
// 10. 'clusters.addworker.containerName.tips':'Specify a name for the worker container.',
|
||||
// 11. 'clusters.addworker.dataVolume': 'GPUStack Data Volume',
|
||||
// 12. 'clusters.addworker.dataVolume.tips': 'Specify a data storage path for GPUStack.',
|
||||
// 10. 'clusters.table.ip.internal': 'Internal',
|
||||
// 11. 'clusters.table.ip.external': 'External',
|
||||
// 12. 'clusters.form.serverUrl.tips': 'Specify the server URL accessible from your cloud provider.'
|
||||
// 13. 'clusters.addworker.specifyWorkerIP': 'Specify Worker IP <span class="text-tertiary">{type}</span>',
|
||||
// 14. 'clusters.form.setDefault': 'Set as Default',
|
||||
// 15. 'clusters.form.setDefault.tips': 'Default for deployment',
|
||||
// 16. 'clusters.addworker.enterWorkerAddress': 'Enter worker external address',
|
||||
// 17. 'clusters.addworker.enterWorkerAddress.error': 'Please enter the worker external address.',
|
||||
// 1. 'clusters.addworker.hygonNotes': `If <span class="bold-text">/opt/hyhal</span> or <span class="bold-text">/opt/dtk</span> does not exist, create symbolic links pointing to the corresponding Hygon installation paths, for example: <span class="desc-fill">ln -s /path/to/hyhal /opt/hyhal</span> <span class="desc-fill">ln -s /path/to/dtk /opt/dtk</span>.`,
|
||||
// ================================================================
|
||||
|
||||
@@ -265,15 +265,12 @@ export default {
|
||||
'common.form.rule.selectInput': 'Выберите или введите {name}',
|
||||
'common.tag.experimental': 'Экспериментальный',
|
||||
'common.title.example': 'Пример',
|
||||
'common.button.dontshowagain': "Don't show again",
|
||||
'common.sorter.tips.ascend': 'Click to sort ascending',
|
||||
'common.sorter.tips.descend': 'Click to sort descending',
|
||||
'common.sorter.tips.cancel': 'Click to cancel sorting'
|
||||
'common.button.dontshowagain': "Больше не показывать",
|
||||
'common.sorter.tips.ascend': 'Нажмите для сортировки по возрастанию',
|
||||
'common.sorter.tips.descend': 'Нажмите для сортировки по убыванию',
|
||||
'common.sorter.tips.cancel': 'Нажмите, чтобы отменить сортировку'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
// 1. 'common.button.dontshowagain': "Don't show again",
|
||||
// 2. 'common.sorter.tips.ascend': 'Click to sort ascending',
|
||||
// 3. 'common.sorter.tips.descend': 'Click to sort descending',
|
||||
// 4. 'common.sorter.tips.cancel': 'Click to cancel sorting'
|
||||
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -268,24 +268,18 @@ export default {
|
||||
'Используйте следующий префикс пути и укажите имя модели либо в заголовке запроса <span class="bold-text">X-GPUStack-Model</span>, либо в поле model в теле запроса. Все запросы с этим префиксом пути будут перенаправлены в бэкенд вывода.',
|
||||
'models.form.backendVersion.deprecated': 'Устаревший',
|
||||
'models.accessSettings.public.desc':
|
||||
'Accessible to anyone without authentication.',
|
||||
'Доступно всем без аутентификации.',
|
||||
'models.accessSettings.authed.tips':
|
||||
'Accessible to all authenticated platform users.',
|
||||
'Доступно всем аутентифицированным пользователям платформы.',
|
||||
'models.accessSettings.allowedUsers.tips':
|
||||
'Only designated users can access the model.',
|
||||
'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
|
||||
'Доступ к модели имеют только назначенные пользователи.',
|
||||
'models.form.backendVersions.tips': `Чтобы использовать больше версий, перейдите на страницу {link} и отредактируйте бэкенд для добавления версий.`,
|
||||
'models.catalog.nogpus.tips':
|
||||
'No compatible GPUs are available in the selected cluster for this model.',
|
||||
'models.form.modelfile.notfound': `The model file path you specified does not exist on the GPUStack server. It's recommended to place the model file at the same path on both the GPUStack server and GPUStack workers. This helps GPUStack make better decisions.`,
|
||||
'models.form.readyWorkers': 'workers ready'
|
||||
'В выбранном кластере нет доступных GPU, совместимых с этой моделью.',
|
||||
'models.form.modelfile.notfound': `Указанный путь к файлу модели не существует на сервере GPUStack. Рекомендуется размещать файл модели по одному и тому же пути как на сервере GPUStack, так и на воркерах GPUStack. Это поможет системе принимать лучшие решения по распределению ресурсов.`,
|
||||
'models.form.readyWorkers': 'воркеров готово'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
// 1. 'models.accessSettings.public.desc': 'Accessible to anyone without authentication.',
|
||||
// 2. 'models.accessSettings.authed.tips': 'Accessible to all authenticated platform users.',
|
||||
// 3. 'models.accessSettings.allowedUsers.tips': 'Only designated users can access the model.',
|
||||
// 4. 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
|
||||
// 5. 'models.catalog.nogpus.tips': 'No compatible GPUs are available in the selected cluster for this model.',
|
||||
// 6. 'models.form.modelfile.notfound': `The model file path you specified does not exist on the GPUStack server. It's recommended to place the model file at the same path on both the GPUStack server and GPUStack workers. This helps GPUStack make better decisions.`,
|
||||
// 7. 'models.form.readyWorkers': 'workers ready'
|
||||
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -40,9 +40,9 @@ export default {
|
||||
'users.status.deactivate': 'Деактивировать аккаунт',
|
||||
'users.status.inactiveAccount': 'Неактивный аккаунт',
|
||||
'users.login.getInitialPassword':
|
||||
'Run the following command on your server to retrieve the initial admin password.'
|
||||
'Выполните следующую команду на вашем сервере, чтобы получить начальный пароль администратора.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
// 1. 'users.login.getInitialPassword': 'Run the following command on your server to retrieve the initial admin password.'
|
||||
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -19,8 +19,7 @@ export default {
|
||||
'backend.mode.yaml': 'YAML 模式',
|
||||
'backend.form.healthCheckPath': '健康检查路径',
|
||||
'backend.form.defaultExecuteCommand': '默认执行命令',
|
||||
'backend.form.defaultExecuteCommand.tips':
|
||||
'{{model_path}}、{{port}}、{{worker_ip}} 和 {{model_name}} 都是占位符,在部署过程中会被替换为实际的值。',
|
||||
'backend.form.defaultExecuteCommand.tips': `'{{'model_path'}}'、'{{'port'}}'、'{{'worker_ip'}}' 和 '{{'model_name'}}' 都是占位符,在部署过程中会被替换为实际的值。`,
|
||||
'backend.form.defaultBackendParameters': '默认后端参数',
|
||||
'backend.form.versionConfig': '版本配置',
|
||||
'backend.form.addParameter': '添加参数',
|
||||
|
||||
@@ -49,8 +49,9 @@ export default {
|
||||
'如果节点有多个出站 IP 地址,请填写 <span class="bold-text">WORKER_IP</span>,以确保使用指定的 IP。可通过命令 <span class="bold-text">hostname -I | xargs -n1</span> 进行确认。',
|
||||
'clusters.addworker.nvidiaNotes-02':
|
||||
'如果节点上已经存在模型目录,你可以指定该路径进行挂载。',
|
||||
'clusters.addworker.hygonNotes':
|
||||
'如果 <span class="bold-text">/opt/hyhal</span> 目录不存在,请创建指向海光安装路径的符号链接:<span class="bold-text">/opt/hyhal</span>。与 <span class="bold-text">/opt/dtk</span> 目录相同。',
|
||||
'clusters.addworker.hygonNotes': `如果 <span class="bold-text">/opt/hyhal</span> 或 <span class="bold-text">/opt/dtk</span> 不存在,请创建指向对应海光安装路径的符号链接,例如:
|
||||
<span class="desc-fill line-6">ln -s /path/to/hyhal /opt/hyhal</span>
|
||||
<span class="desc-fill line-6">ln -s /path/to/dtk /opt/dtk</span>`,
|
||||
'clusters.addworker.corexNotes':
|
||||
'如果 <span class="bold-text">/lib/modules</span> 目录不存在,请创建指向天数智芯安装路径的符号链接:<span class="bold-text">ln -s /path/to/corex /lib/modules</span>。与 <span class="bold-text">/usr/local/corex</span> 目录相同。',
|
||||
'clusters.addworker.metaxNotes':
|
||||
|
||||
@@ -164,6 +164,7 @@ const ClusterCreate = () => {
|
||||
setCurrentStep((prev) => Math.min(prev + 1, steps.length - 1));
|
||||
}
|
||||
} catch (error) {
|
||||
setSubmitLoading(false);
|
||||
console.log('next error:', error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -37,11 +37,7 @@ import {
|
||||
K8sStepsFromCluter
|
||||
} from './components/add-worker/config';
|
||||
import PoolRows from './components/pool-rows';
|
||||
import {
|
||||
ClusterStatusValueMap,
|
||||
ProviderType,
|
||||
ProviderValueMap
|
||||
} from './config';
|
||||
import { ProviderType, ProviderValueMap } from './config';
|
||||
import {
|
||||
ClusterListItem,
|
||||
CredentialListItem,
|
||||
@@ -79,7 +75,8 @@ const Clusters: React.FC = () => {
|
||||
useExpandedRowKeys(expandAtom);
|
||||
const navigate = useNavigate();
|
||||
const intl = useIntl();
|
||||
const { handleAddWorker, AddWorkerModal, setStepList } = useAddWorker({});
|
||||
const { handleAddWorker, checkDefaultCluster, AddWorkerModal, setStepList } =
|
||||
useAddWorker({});
|
||||
|
||||
const [openAddModal, setOpenAddModal] = useState<{
|
||||
open: boolean;
|
||||
@@ -265,12 +262,12 @@ const Clusters: React.FC = () => {
|
||||
dataSource.loadend &&
|
||||
dataSource.dataList?.length > 0
|
||||
) {
|
||||
const targetCluster = dataSource.dataList.find(
|
||||
(cluster) =>
|
||||
cluster.state === ClusterStatusValueMap.Ready &&
|
||||
!cluster.workers &&
|
||||
!cluster.worker_pools?.length
|
||||
);
|
||||
const list = dataSource.dataList?.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
...item
|
||||
}));
|
||||
const targetCluster = checkDefaultCluster(list);
|
||||
|
||||
if (targetCluster) {
|
||||
const actionMap = {
|
||||
@@ -280,7 +277,7 @@ const Clusters: React.FC = () => {
|
||||
};
|
||||
handleSelect(
|
||||
actionMap[targetCluster.provider as string],
|
||||
targetCluster
|
||||
targetCluster as ListItem
|
||||
);
|
||||
// reset session
|
||||
setClusterSession(null);
|
||||
|
||||
@@ -17,7 +17,7 @@ interface AddWorkerContextProps {
|
||||
token: string;
|
||||
image: string;
|
||||
server_url: string;
|
||||
cluster_id: number;
|
||||
cluster_id: number | null;
|
||||
};
|
||||
registerField: (key: SummaryDataKey) => () => void;
|
||||
updateField: (key: SummaryDataKey, value: any) => void;
|
||||
|
||||
@@ -41,7 +41,7 @@ type AddWorkerProps = {
|
||||
token: string;
|
||||
image: string;
|
||||
server_url: string;
|
||||
cluster_id: number;
|
||||
cluster_id: number | null;
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -32,12 +32,12 @@ type AddWorkerProps = {
|
||||
stepList: StepName[];
|
||||
onClusterChange?: (value: number, row?: any) => void;
|
||||
onCancel: () => void;
|
||||
cluster_id: number;
|
||||
cluster_id: number | null;
|
||||
registrationInfo?: {
|
||||
token: string;
|
||||
image: string;
|
||||
server_url: string;
|
||||
cluster_id: number;
|
||||
cluster_id: number | null;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -64,12 +64,12 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
|
||||
token: string;
|
||||
image: string;
|
||||
server_url: string;
|
||||
cluster_id: number;
|
||||
cluster_id: number | null;
|
||||
}>({
|
||||
token: '',
|
||||
image: '',
|
||||
server_url: '',
|
||||
cluster_id: 0
|
||||
cluster_id: null
|
||||
});
|
||||
|
||||
const handleOnClusterChange = async (value: number, row?: any) => {
|
||||
|
||||
@@ -21,12 +21,12 @@ const useAddWorker = (props: {
|
||||
open: boolean;
|
||||
provider: ProviderType;
|
||||
title: string;
|
||||
cluster_id: number;
|
||||
cluster_id: number | null;
|
||||
}>({
|
||||
open: false,
|
||||
provider: null,
|
||||
title: '',
|
||||
cluster_id: 0
|
||||
cluster_id: null
|
||||
});
|
||||
|
||||
const handleAddWorker = async (row: ClusterListItem) => {
|
||||
@@ -43,7 +43,12 @@ const useAddWorker = (props: {
|
||||
open: true,
|
||||
title: title,
|
||||
provider: row.provider as ProviderType,
|
||||
cluster_id: row.id
|
||||
cluster_id: [
|
||||
ProviderValueMap.Docker,
|
||||
ProviderValueMap.Kubernetes
|
||||
].includes(row.provider as string)
|
||||
? row.id
|
||||
: null
|
||||
});
|
||||
} catch (error: any) {
|
||||
message.error(error?.message || 'Failed to fetch cluster token');
|
||||
@@ -67,6 +72,38 @@ const useAddWorker = (props: {
|
||||
.filter((item) => item.state === ClusterStatusValueMap.Ready);
|
||||
}, [clusterList]);
|
||||
|
||||
const checkDefaultCluster = (
|
||||
clusterList: Global.BaseOption<number, ClusterListItem>[]
|
||||
) => {
|
||||
// select default and ready cluster first, digitalocean no READY state
|
||||
let currentData = clusterList.find(
|
||||
(item) => item.is_default && item.state === ClusterStatusValueMap.Ready
|
||||
);
|
||||
|
||||
if (!currentData) {
|
||||
// select docker ready cluster
|
||||
currentData = clusterList.find(
|
||||
(item) =>
|
||||
item.provider === ProviderValueMap.Docker &&
|
||||
item.state === ClusterStatusValueMap.Ready
|
||||
);
|
||||
}
|
||||
|
||||
if (!currentData) {
|
||||
// select any ready cluster
|
||||
currentData = clusterList.find(
|
||||
(item) => item.state === ClusterStatusValueMap.Ready
|
||||
);
|
||||
}
|
||||
|
||||
if (!currentData) {
|
||||
// maybe no ready a digitalocean cluster
|
||||
currentData = clusterList[0];
|
||||
}
|
||||
|
||||
return currentData || null;
|
||||
};
|
||||
|
||||
const AddWorkerModal = (
|
||||
<AddWorker
|
||||
title={openAddWorker.title}
|
||||
@@ -82,7 +119,7 @@ const useAddWorker = (props: {
|
||||
open: false,
|
||||
provider: null,
|
||||
title: '',
|
||||
cluster_id: 0
|
||||
cluster_id: null
|
||||
})
|
||||
}
|
||||
></AddWorker>
|
||||
@@ -90,6 +127,7 @@ const useAddWorker = (props: {
|
||||
|
||||
return {
|
||||
handleAddWorker,
|
||||
checkDefaultCluster,
|
||||
AddWorkerModal,
|
||||
setStepList
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { clusterSessionAtom } from '@/atoms/clusters';
|
||||
import { hideModalTemporarilyAtom } from '@/atoms/settings';
|
||||
import IconFont from '@/components/icon-font';
|
||||
import ScrollerModal from '@/components/scroller-modal/index';
|
||||
import { PageAction } from '@/config';
|
||||
@@ -60,7 +61,9 @@ export default function useAddResource(options?: { onCreated?: () => void }) {
|
||||
const navigate = useNavigate();
|
||||
const { setUserSettings, userSettings } = useUserSettings();
|
||||
const [, setClusterSession] = useAtom(clusterSessionAtom);
|
||||
const [hideModalTemporarily, setHideModalTemporarily] = useState(false);
|
||||
const [hideModalTemporarily, setHideModalTemporarily] = useAtom(
|
||||
hideModalTemporarilyAtom
|
||||
);
|
||||
const { fetchResource, resourceCount, resourceAtom } = useClusterList();
|
||||
|
||||
const [loadingStatus, setLoadingStatus] = useState({
|
||||
|
||||
@@ -153,6 +153,8 @@ export const useGenerateWorkerOptions = () => {
|
||||
{ state: string; labels: Record<string, string>; cluster_id: number }
|
||||
>[]
|
||||
>([]);
|
||||
const [, setClusterListAtom] = useAtom(clusterListAtom);
|
||||
const [, setWorkerListAtom] = useAtom(workerListAtom);
|
||||
|
||||
const generateCascaderWorkerOptions = (
|
||||
workerList: WorkerListItem[],
|
||||
@@ -201,29 +203,31 @@ export const useGenerateWorkerOptions = () => {
|
||||
const data = await getDataList();
|
||||
const [workerList, clusterList] = data;
|
||||
generateCascaderWorkerOptions(workerList, clusterList);
|
||||
setWorkersList(
|
||||
workerList.map((item) => ({
|
||||
cluster_id: item.cluster_id,
|
||||
state: item.state,
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
id: item.id,
|
||||
labels: item.labels || {},
|
||||
name: item.name
|
||||
}))
|
||||
);
|
||||
setClusterList(
|
||||
clusterList.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
provider: item.provider as string,
|
||||
state: item.state,
|
||||
is_default: item.is_default,
|
||||
workers: item.workers,
|
||||
ready_workers: item.ready_workers,
|
||||
gpus: item.gpus
|
||||
}))
|
||||
);
|
||||
|
||||
const workerOptions = workerList.map((item) => ({
|
||||
cluster_id: item.cluster_id,
|
||||
state: item.state,
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
id: item.id,
|
||||
labels: item.labels || {},
|
||||
name: item.name
|
||||
}));
|
||||
const clusterOptions = clusterList.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
provider: item.provider as string,
|
||||
state: item.state,
|
||||
is_default: item.is_default,
|
||||
workers: item.workers,
|
||||
ready_workers: item.ready_workers,
|
||||
gpus: item.gpus
|
||||
}));
|
||||
|
||||
setWorkersList(workerOptions);
|
||||
setClusterList(clusterOptions);
|
||||
setWorkerListAtom(workerOptions);
|
||||
setClusterListAtom(clusterOptions);
|
||||
};
|
||||
return {
|
||||
getWorkerOptionList,
|
||||
@@ -280,7 +284,12 @@ export default function useFormInitialValues() {
|
||||
const list =
|
||||
data.items?.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
value: item.id,
|
||||
cluster_id: item.cluster_id,
|
||||
state: item.state,
|
||||
id: item.id,
|
||||
labels: item.labels || {},
|
||||
name: item.name
|
||||
})) || [];
|
||||
setWorkerList(data.items);
|
||||
setWorkerListAtom(list);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { hideModalTemporarilyAtom } from '@/atoms/settings';
|
||||
import { userAtom } from '@/atoms/user';
|
||||
import { clearAtomStorage, clearStorageUserSettings } from '@/atoms/utils';
|
||||
import { request } from '@umijs/max';
|
||||
@@ -29,6 +30,7 @@ export const logout = async (userInfo?: any) => {
|
||||
});
|
||||
clearStorageUserSettings();
|
||||
clearAtomStorage(userAtom);
|
||||
clearAtomStorage(hideModalTemporarilyAtom);
|
||||
|
||||
if (res?.logout_url) {
|
||||
window.location.href = res.logout_url;
|
||||
|
||||
@@ -14,6 +14,7 @@ interface ActiveModelsProps {
|
||||
|
||||
const ActiveModels: React.FC<ActiveModelsProps> = (props) => {
|
||||
const { spans, modelSelections, setModelRefs } = props;
|
||||
|
||||
return (
|
||||
<Row gutter={[16, 0]} style={{ height: '100%' }}>
|
||||
{modelSelections.map((model, index) => (
|
||||
@@ -21,7 +22,8 @@ const ActiveModels: React.FC<ActiveModelsProps> = (props) => {
|
||||
span={spans.span}
|
||||
key={`${model.value || 'empty'}-${model.uid}`}
|
||||
style={{
|
||||
height: spans.count < 4 ? 'calc(100% - 16px)' : 'calc(50% - 16px)'
|
||||
height: spans.count < 4 ? 'calc(100% - 16px)' : 'calc(50% - 16px)',
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
<ModelItem
|
||||
|
||||
@@ -47,7 +47,8 @@ interface ModelItemProps {
|
||||
}
|
||||
|
||||
const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
|
||||
const { modelList, model, instanceId } = props;
|
||||
const { modelList, ...restProps } = props;
|
||||
const { model, instanceId } = restProps;
|
||||
const {
|
||||
globalParams,
|
||||
setGlobalParams,
|
||||
@@ -66,14 +67,20 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
|
||||
paramsConfig,
|
||||
initialValues,
|
||||
parameters
|
||||
} = useInitLLmMeta(props, {
|
||||
defaultValues: {
|
||||
...llmInitialValues,
|
||||
model: model
|
||||
} = useInitLLmMeta(
|
||||
{
|
||||
...restProps,
|
||||
modelList: modelFullList
|
||||
},
|
||||
defaultParamsConfig: ChatParamsConfig,
|
||||
metaKeys: LLM_METAKEYS
|
||||
});
|
||||
{
|
||||
defaultValues: {
|
||||
...llmInitialValues,
|
||||
model: model
|
||||
},
|
||||
defaultParamsConfig: ChatParamsConfig,
|
||||
metaKeys: LLM_METAKEYS
|
||||
}
|
||||
);
|
||||
const intl = useIntl();
|
||||
const isApplyToAllModels = useRef(false);
|
||||
const [systemMessage, setSystemMessage] = useState<string>('');
|
||||
|
||||
@@ -12,13 +12,7 @@ import { generateRandomNumber } from '@/utils';
|
||||
import { useSearchParams } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import _ from 'lodash';
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { ParamsSchema } from '../config/types';
|
||||
import {
|
||||
IMG_METAKEYS,
|
||||
@@ -133,37 +127,34 @@ export const useInitLLmMeta = (
|
||||
return fields?.join(',');
|
||||
}, [paramsConfig]);
|
||||
|
||||
const handleOnModelChange = useCallback(
|
||||
(val: string) => {
|
||||
if (!val) return;
|
||||
const model = modelList.find((item) => item.value === val);
|
||||
const { form: initialData, meta } = extractLLMMeta(model?.meta);
|
||||
setModelMeta(meta);
|
||||
setInitialValues({
|
||||
...initialData,
|
||||
model: val
|
||||
});
|
||||
setParams({
|
||||
...initialData,
|
||||
model: val
|
||||
});
|
||||
const config = defaultParamsConfig.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
attrs:
|
||||
item.name === 'max_tokens'
|
||||
? { ...item.attrs, max: meta.max_tokens }
|
||||
: {
|
||||
...item.attrs
|
||||
}
|
||||
};
|
||||
});
|
||||
setParamsConfig(config);
|
||||
},
|
||||
[modelList, defaultParamsConfig]
|
||||
);
|
||||
const handleOnModelChange = useMemoizedFn((val: string) => {
|
||||
if (!val) return;
|
||||
const model = modelList.find((item) => item.value === val);
|
||||
const { form: initialData, meta } = extractLLMMeta(model?.meta);
|
||||
setModelMeta(meta);
|
||||
setInitialValues({
|
||||
...initialData,
|
||||
model: val
|
||||
});
|
||||
setParams({
|
||||
...initialData,
|
||||
model: val
|
||||
});
|
||||
const config = defaultParamsConfig.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
attrs:
|
||||
item.name === 'max_tokens'
|
||||
? { ...item.attrs, max: meta.max_tokens }
|
||||
: {
|
||||
...item.attrs
|
||||
}
|
||||
};
|
||||
});
|
||||
setParamsConfig(config);
|
||||
});
|
||||
|
||||
const handleOnValuesChange = useCallback(
|
||||
const handleOnValuesChange = useMemoizedFn(
|
||||
(changeValues: Record<string, any>, allValues: Record<string, any>) => {
|
||||
if (changeValues.model) {
|
||||
handleOnModelChange(changeValues.model);
|
||||
@@ -172,8 +163,7 @@ export const useInitLLmMeta = (
|
||||
setParams(allValues);
|
||||
setInitialValues(allValues);
|
||||
}
|
||||
},
|
||||
[handleOnModelChange]
|
||||
}
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -405,35 +395,32 @@ export const useInitImageMeta = (
|
||||
return fields?.join(',');
|
||||
}, [paramsConfig]);
|
||||
|
||||
const handleOnModelChange = useCallback(
|
||||
(val: string) => {
|
||||
if (!val) return;
|
||||
const model = modelList.find((item) => item.value === val);
|
||||
const { form: initialData, sizeOptions } = extractIMGMeta(model?.meta);
|
||||
const newParamsConfig = generateImageParamsConfig(model, sizeOptions);
|
||||
const handleOnModelChange = useMemoizedFn((val: string) => {
|
||||
if (!val) return;
|
||||
const model = modelList.find((item) => item.value === val);
|
||||
const { form: initialData, sizeOptions } = extractIMGMeta(model?.meta);
|
||||
const newParamsConfig = generateImageParamsConfig(model, sizeOptions);
|
||||
|
||||
if (!isOpenaiCompatible) {
|
||||
setParamsConfig([...newParamsConfig, ...ImageAdvancedParamsConfig]);
|
||||
} else {
|
||||
setParamsConfig(newParamsConfig);
|
||||
}
|
||||
setBasicParamsConfig(newParamsConfig);
|
||||
setImageSizeOptions(sizeOptions);
|
||||
setModelMeta(model?.meta || {});
|
||||
setInitialValues({
|
||||
...initialData,
|
||||
seed: parameters.seed,
|
||||
model: val
|
||||
});
|
||||
setParams({
|
||||
...initialData,
|
||||
seed: parameters.seed,
|
||||
model: val
|
||||
});
|
||||
updateCacheFormData(initialData);
|
||||
},
|
||||
[modelList, isOpenaiCompatible]
|
||||
);
|
||||
if (!isOpenaiCompatible) {
|
||||
setParamsConfig([...newParamsConfig, ...ImageAdvancedParamsConfig]);
|
||||
} else {
|
||||
setParamsConfig(newParamsConfig);
|
||||
}
|
||||
setBasicParamsConfig(newParamsConfig);
|
||||
setImageSizeOptions(sizeOptions);
|
||||
setModelMeta(model?.meta || {});
|
||||
setInitialValues({
|
||||
...initialData,
|
||||
seed: parameters.seed,
|
||||
model: val
|
||||
});
|
||||
setParams({
|
||||
...initialData,
|
||||
seed: parameters.seed,
|
||||
model: val
|
||||
});
|
||||
updateCacheFormData(initialData);
|
||||
});
|
||||
|
||||
const handleOnValuesChange = useMemoizedFn(
|
||||
(changeValues: Record<string, any>, allValues: Record<string, any>) => {
|
||||
|
||||
@@ -5,10 +5,6 @@ import useTableFetch from '@/hooks/use-table-fetch';
|
||||
import PageBox from '@/pages/_components/page-box';
|
||||
import { queryClusterList } from '@/pages/cluster-management/apis';
|
||||
import { DockerStepsFromWorker } from '@/pages/cluster-management/components/add-worker/config';
|
||||
import {
|
||||
ClusterStatusValueMap,
|
||||
ProviderValueMap
|
||||
} from '@/pages/cluster-management/config';
|
||||
import { ClusterListItem } from '@/pages/cluster-management/config/types';
|
||||
import useAddWorker from '@/pages/cluster-management/hooks/use-add-worker';
|
||||
import useNoResourceResult from '@/pages/llmodels/hooks/use-no-resource-result';
|
||||
@@ -82,10 +78,11 @@ const Workers: React.FC = () => {
|
||||
open: false,
|
||||
currentData: null
|
||||
});
|
||||
const { handleAddWorker, AddWorkerModal, setStepList } = useAddWorker({
|
||||
clusterList: clusterData.list,
|
||||
clusterLoading: clusterData.loading
|
||||
});
|
||||
const { handleAddWorker, checkDefaultCluster, AddWorkerModal, setStepList } =
|
||||
useAddWorker({
|
||||
clusterList: clusterData.list,
|
||||
clusterLoading: clusterData.loading
|
||||
});
|
||||
|
||||
const getClusterList = async () => {
|
||||
try {
|
||||
@@ -105,6 +102,7 @@ const Workers: React.FC = () => {
|
||||
value: item.id,
|
||||
id: item.id,
|
||||
state: item.state,
|
||||
is_default: item.is_default,
|
||||
provider: item.provider
|
||||
}));
|
||||
setClusterData({
|
||||
@@ -193,16 +191,9 @@ const Workers: React.FC = () => {
|
||||
});
|
||||
|
||||
const handleOnAddWorker = () => {
|
||||
let currentData = clusterData.list.find(
|
||||
(item) =>
|
||||
item.provider === ProviderValueMap.Docker &&
|
||||
item.state === ClusterStatusValueMap.Ready
|
||||
);
|
||||
if (!currentData) {
|
||||
currentData = clusterData.list[0];
|
||||
}
|
||||
if (currentData) {
|
||||
handleAddWorker(currentData as ClusterListItem);
|
||||
const targetCluster = checkDefaultCluster(clusterData.list);
|
||||
if (targetCluster) {
|
||||
handleAddWorker(targetCluster as ClusterListItem);
|
||||
} else {
|
||||
message.info(intl.formatMessage({ id: 'noresult.resources.cluster' }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user