fix(style): textarea label background
This commit is contained in:
@@ -45,6 +45,24 @@ export const GPU_SERVICE_INSTANCE_PV_EVENTS_API = (params: {
|
||||
return `/clusters/${params.clusterID}/proxy/apis/worker.gpustack.ai/v1/namespaces/${params.namespace}/instancepersistentvolumes/${params.name}/events`;
|
||||
};
|
||||
|
||||
// TODO: replace placeholder once start/stop endpoints are finalized
|
||||
export const GPU_SERVICE_INSTANCE_START_API = (params: {
|
||||
namespace: string;
|
||||
name: string;
|
||||
clusterID?: number;
|
||||
}) => {
|
||||
return `/clusters/${params.clusterID}/proxy/apis/worker.gpustack.ai/v1/namespaces/${params.namespace}/instances/${params.name}/start`;
|
||||
};
|
||||
|
||||
// TODO: replace placeholder once start/stop endpoints are finalized
|
||||
export const GPU_SERVICE_INSTANCE_STOP_API = (params: {
|
||||
namespace: string;
|
||||
name: string;
|
||||
clusterID?: number;
|
||||
}) => {
|
||||
return `/clusters/${params.clusterID}/proxy/apis/worker.gpustack.ai/v1/namespaces/${params.namespace}/instances/${params.name}/stop`;
|
||||
};
|
||||
|
||||
// =========== Instances ===========
|
||||
|
||||
export async function queryGPUServiceInstances(
|
||||
@@ -212,6 +230,56 @@ export async function queryGPUServiceInstancePVEvents(
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: replace placeholder once start/stop endpoints are finalized
|
||||
export async function startGPUServiceInstance(
|
||||
params: {
|
||||
namespace: string;
|
||||
name: string;
|
||||
clusterID?: number;
|
||||
},
|
||||
option?: any
|
||||
) {
|
||||
if (!params.clusterID) {
|
||||
return;
|
||||
}
|
||||
return request(
|
||||
GPU_SERVICE_INSTANCE_START_API({
|
||||
namespace: params.namespace,
|
||||
clusterID: params.clusterID,
|
||||
name: params.name
|
||||
}),
|
||||
{
|
||||
method: 'POST',
|
||||
cancelToken: option?.token
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: replace placeholder once start/stop endpoints are finalized
|
||||
export async function stopGPUServiceInstance(
|
||||
params: {
|
||||
namespace: string;
|
||||
name: string;
|
||||
clusterID?: number;
|
||||
},
|
||||
option?: any
|
||||
) {
|
||||
if (!params.clusterID) {
|
||||
return;
|
||||
}
|
||||
return request(
|
||||
GPU_SERVICE_INSTANCE_STOP_API({
|
||||
namespace: params.namespace,
|
||||
clusterID: params.clusterID,
|
||||
name: params.name
|
||||
}),
|
||||
{
|
||||
method: 'POST',
|
||||
cancelToken: option?.token
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export async function queryGPUServiceInstanceLog(
|
||||
params: InstanceLogQueryParams & {
|
||||
namespace: string;
|
||||
|
||||
@@ -64,6 +64,18 @@ export const rowActionList = [
|
||||
locale: true,
|
||||
icon: icons.ProfileOutlined
|
||||
},
|
||||
{
|
||||
label: 'common.button.start',
|
||||
key: 'start',
|
||||
locale: true,
|
||||
icon: icons.Play
|
||||
},
|
||||
{
|
||||
label: 'common.button.stop',
|
||||
key: 'stop',
|
||||
locale: true,
|
||||
icon: icons.Stop
|
||||
},
|
||||
// {
|
||||
// label: 'common.button.edit',
|
||||
// key: 'edit',
|
||||
@@ -87,6 +99,27 @@ export const rowActionList = [
|
||||
}
|
||||
];
|
||||
|
||||
export const batchActionList = [
|
||||
{
|
||||
label: 'common.button.start',
|
||||
key: 'start',
|
||||
icon: icons.Play
|
||||
},
|
||||
{
|
||||
label: 'common.button.stop',
|
||||
key: 'stop',
|
||||
icon: icons.Stop
|
||||
},
|
||||
{
|
||||
label: 'common.button.delete',
|
||||
key: 'delete',
|
||||
icon: icons.DeleteOutlined,
|
||||
props: {
|
||||
danger: true
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export const InstanceTypePhaseValueMap = {
|
||||
// Available: 'Available',
|
||||
// Unavailable: 'Unavailable'
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Input as CInput } from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import { FormData } from '../config/types';
|
||||
import formStyles from '../styles/instances.module.less';
|
||||
|
||||
const Basic = ({
|
||||
action,
|
||||
@@ -37,13 +38,15 @@ const Basic = ({
|
||||
required
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item<FormData> name={['spec', 'description']}>
|
||||
<CInput.TextArea
|
||||
disabled={disabled}
|
||||
label={intl.formatMessage({ id: 'common.table.description' })}
|
||||
scaleSize
|
||||
/>
|
||||
</Form.Item>
|
||||
<div className={formStyles.command}>
|
||||
<Form.Item<FormData> name={['spec', 'description']}>
|
||||
<CInput.TextArea
|
||||
disabled={disabled}
|
||||
label={intl.formatMessage({ id: 'common.table.description' })}
|
||||
scaleSize
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,16 +5,28 @@ import { PaginationKey, TABLE_SORT_DIRECTIONS } from '@/config/settings';
|
||||
import useTableFetch from '@/hooks/use-table-fetch';
|
||||
import { ProviderValueMap } from '@/pages/cluster-management/config';
|
||||
import { useQueryClusterList } from '@/pages/cluster-management/services/use-query-cluster-list';
|
||||
import { handleBatchRequest } from '@/utils';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
BaseSelect,
|
||||
DeleteModal,
|
||||
DropdownButtons,
|
||||
FilterBar,
|
||||
IconFont,
|
||||
NoResult
|
||||
} from '@gpustack/core-ui';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { ConfigProvider, Divider, Flex, message, Modal, Table } from 'antd';
|
||||
import {
|
||||
Button,
|
||||
ConfigProvider,
|
||||
Divider,
|
||||
Flex,
|
||||
message,
|
||||
Modal,
|
||||
Space,
|
||||
Table
|
||||
} from 'antd';
|
||||
import { useAtom } from 'jotai';
|
||||
import _ from 'lodash';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
@@ -22,11 +34,14 @@ import { PageContainerInner } from '../../_components/page-box';
|
||||
import {
|
||||
deleteGPUServiceInstance,
|
||||
GPU_SERVICE_INSTANCES_API,
|
||||
queryGPUServiceInstances
|
||||
queryGPUServiceInstances,
|
||||
startGPUServiceInstance,
|
||||
stopGPUServiceInstance
|
||||
} from './apis';
|
||||
import AddModal from './components/add-modal';
|
||||
import ViewEventsModal from './components/view-events-modal';
|
||||
import ViewLogsModal from './components/view-logs-modal';
|
||||
import { batchActionList } from './config';
|
||||
import { FormData, ListItem } from './config/types';
|
||||
import useCreateInstance from './hooks/use-create-instance';
|
||||
import useInstancesColumns from './hooks/use-instances-columns';
|
||||
@@ -49,6 +64,26 @@ const GPUService: React.FC = () => {
|
||||
[namespace, clusterID]
|
||||
);
|
||||
|
||||
const startInstance = useCallback(
|
||||
(row: ListItem) =>
|
||||
startGPUServiceInstance({
|
||||
namespace: row.metadata?.namespace || namespace,
|
||||
clusterID,
|
||||
name: row.metadata?.name as string
|
||||
}),
|
||||
[namespace, clusterID]
|
||||
);
|
||||
|
||||
const stopInstance = useCallback(
|
||||
(row: ListItem) =>
|
||||
stopGPUServiceInstance({
|
||||
namespace: row.metadata?.namespace || namespace,
|
||||
clusterID,
|
||||
name: row.metadata?.name as string
|
||||
}),
|
||||
[namespace, clusterID]
|
||||
);
|
||||
|
||||
const fetchInstances = useMemoizedFn(
|
||||
async (
|
||||
params: any,
|
||||
@@ -225,6 +260,80 @@ const GPUService: React.FC = () => {
|
||||
});
|
||||
});
|
||||
|
||||
const handleStart = useMemoizedFn(async (row: ListItem) => {
|
||||
modalRef.current?.show({
|
||||
title: intl.formatMessage({ id: 'common.title.start.confirm' }),
|
||||
content: 'gpuservice.instance',
|
||||
okText: 'common.button.start',
|
||||
operation: 'common.start.single.confirm',
|
||||
name: row.metadata?.name,
|
||||
async onOk() {
|
||||
try {
|
||||
await startInstance(row);
|
||||
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const handleStop = useMemoizedFn(async (row: ListItem) => {
|
||||
modalRef.current?.show({
|
||||
title: intl.formatMessage({ id: 'common.title.stop.confirm' }),
|
||||
content: 'gpuservice.instance',
|
||||
okText: 'common.button.stop',
|
||||
operation: 'common.stop.single.confirm',
|
||||
name: row.metadata?.name,
|
||||
async onOk() {
|
||||
try {
|
||||
await stopInstance(row);
|
||||
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const handleStartBatch = useMemoizedFn(() => {
|
||||
modalRef.current?.show({
|
||||
title: intl.formatMessage({ id: 'common.title.start.confirm' }),
|
||||
content: 'gpuservice.instance',
|
||||
okText: 'common.button.start',
|
||||
operation: 'common.start.confirm',
|
||||
selection: true,
|
||||
async onOk() {
|
||||
const res = await handleBatchRequest(
|
||||
rowSelection.selectedRows as ListItem[],
|
||||
startInstance
|
||||
);
|
||||
fetchData();
|
||||
return res;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const handleStopBatch = useMemoizedFn(() => {
|
||||
modalRef.current?.show({
|
||||
title: intl.formatMessage({ id: 'common.title.stop.confirm' }),
|
||||
content: 'gpuservice.instance',
|
||||
okText: 'common.button.stop',
|
||||
operation: 'common.stop.confirm',
|
||||
selection: true,
|
||||
async onOk() {
|
||||
const res = await handleBatchRequest(
|
||||
rowSelection.selectedRows as ListItem[],
|
||||
stopInstance
|
||||
);
|
||||
fetchData();
|
||||
return res;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const handleSelect = useMemoizedFn((val: string, row: ListItem) => {
|
||||
if (val === 'view') {
|
||||
openViewInstanceModal(row);
|
||||
@@ -244,6 +353,20 @@ const GPUService: React.FC = () => {
|
||||
openViewLogsModal(row);
|
||||
} else if (val === 'viewevent') {
|
||||
openViewEventsModal(row);
|
||||
} else if (val === 'start') {
|
||||
handleStart(row);
|
||||
} else if (val === 'stop') {
|
||||
handleStop(row);
|
||||
}
|
||||
});
|
||||
|
||||
const handleBatchActionSelect = useMemoizedFn((val: string) => {
|
||||
if (val === 'start') {
|
||||
handleStartBatch();
|
||||
} else if (val === 'stop') {
|
||||
handleStopBatch();
|
||||
} else if (val === 'delete') {
|
||||
handleDeleteBatch();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -317,14 +440,34 @@ const GPUService: React.FC = () => {
|
||||
selectHolder={intl.formatMessage({
|
||||
id: 'gpuservice.instance.filter.cluster'
|
||||
})}
|
||||
buttonText={intl.formatMessage({ id: 'gpuservice.instance.add' })}
|
||||
handleSearch={handleSearch}
|
||||
handleSelectChange={handleClusterChange}
|
||||
handleDeleteByBatch={handleDeleteBatch}
|
||||
handleClickPrimary={openCreateInstanceModal}
|
||||
handleInputChange={handleNameChange}
|
||||
rowSelection={rowSelection}
|
||||
widths={{ input: 300 }}
|
||||
right={
|
||||
<Space size={16}>
|
||||
<Button
|
||||
icon={<PlusOutlined />}
|
||||
type="primary"
|
||||
onClick={openCreateInstanceModal}
|
||||
>
|
||||
{intl.formatMessage({ id: 'gpuservice.instance.add' })}
|
||||
</Button>
|
||||
<DropdownButtons
|
||||
items={batchActionList}
|
||||
extra={
|
||||
rowSelection.selectedRowKeys.length > 0 && (
|
||||
<span>({rowSelection.selectedRowKeys.length})</span>
|
||||
)
|
||||
}
|
||||
size="large"
|
||||
showText={true}
|
||||
disabled={!rowSelection.selectedRowKeys.length}
|
||||
onSelect={handleBatchActionSelect}
|
||||
/>
|
||||
</Space>
|
||||
}
|
||||
/>
|
||||
<ConfigProvider renderEmpty={renderEmpty}>
|
||||
<Table
|
||||
|
||||
@@ -24,3 +24,11 @@
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.command {
|
||||
:global {
|
||||
.seal-textarea-label {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useIntl } from '@umijs/max';
|
||||
import { Flex, Form } from 'antd';
|
||||
import { useMemo } from 'react';
|
||||
import { GPUsConfigs } from '../../../resources/config/gpu-driver';
|
||||
import formStyles from '../../instances/styles/instances.module.less';
|
||||
import {
|
||||
ImagePullPolicyOptions,
|
||||
normalizeCommand,
|
||||
@@ -154,22 +155,24 @@ const Basic: React.FC<BasicProps> = ({
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item<FormData>
|
||||
name={['spec', 'command']}
|
||||
normalize={normalizeCommand}
|
||||
getValueProps={(value) => ({ value: stringifyCommand(value) })}
|
||||
>
|
||||
<Textarea
|
||||
disabled={disabled}
|
||||
label={intl.formatMessage({ id: 'gpuservice.template.command' })}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'gpuservice.template.command.placeholder'
|
||||
})}
|
||||
trim={false}
|
||||
alwaysFocus
|
||||
scaleSize
|
||||
/>
|
||||
</Form.Item>
|
||||
<div className={formStyles.command}>
|
||||
<Form.Item<FormData>
|
||||
name={['spec', 'command']}
|
||||
normalize={normalizeCommand}
|
||||
getValueProps={(value) => ({ value: stringifyCommand(value) })}
|
||||
>
|
||||
<Textarea
|
||||
disabled={disabled}
|
||||
label={intl.formatMessage({ id: 'gpuservice.template.command' })}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'gpuservice.template.command.placeholder'
|
||||
})}
|
||||
trim={false}
|
||||
alwaysFocus
|
||||
scaleSize
|
||||
/>
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
<Flex gap={16}>
|
||||
<div style={{ flex: 1 }}>
|
||||
|
||||
Reference in New Issue
Block a user