Files
gpustack-ui/src/pages/gpu-service/templates/index.tsx
T

207 lines
5.8 KiB
TypeScript

import { PageAction } from '@/config';
import useTableFetch from '@/hooks/use-table-fetch';
import {
DeleteModal,
FilterBar,
IconFont,
InfiniteScrollerProvider,
NoResult
} from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
import _ from 'lodash';
import { useMemo } from 'react';
import PageBox from '../../_components/page-box';
import { GPUsConfigs } from '../../resources/config/gpu-driver';
import {
createGPUServiceTemplate,
deleteGPUServiceTemplate,
GPU_SERVICE_TEMPLATES_API,
queryGPUServiceTemplates,
updateGPUServiceTemplate
} from './apis';
import AddModal from './components/add-modal';
import TemplateCardList from './components/template-list';
import { FormData, ListItem } from './config/types';
import useCreateTemplate from './hooks/use-create-template';
const GPUServiceTemplates: React.FC = () => {
const intl = useIntl();
const {
dataSource,
rowSelection,
queryParams,
modalRef,
fetchData,
handleDelete,
handleSearch,
handleNameChange,
handleQueryChange
} = useTableFetch<ListItem>({
fetchAPI: queryGPUServiceTemplates,
deleteAPI: deleteGPUServiceTemplate,
API: GPU_SERVICE_TEMPLATES_API,
watch: false,
isInfiniteScroll: true,
contentForDelete: intl.formatMessage({ id: 'gpuservice.template' }),
defaultQueryParams: {
perPage: 24,
// Management view: drop Global rows for non-admin callers — the
// page is a CRUD surface, and admin-curated Global templates
// they can't edit only add visual noise. The instance-create
// picker (uses ``useQueryTemplates`` separately) doesn't set
// this and so still sees Global presets.
mine: true
}
});
const { openTemplateModalStatus, openTemplateModal, closeTemplateModal } =
useCreateTemplate();
const manufacturerOptions = useMemo(
() => [
...Object.values(GPUsConfigs).map((item) => ({
label: item.locales.locale
? intl.formatMessage({ id: item.locales.label })
: item.locales.label,
value: item.gpuVendor as string
})),
{ label: 'CPU', value: 'cpu' }
],
[intl]
);
const handleFilterByManufacturer = (value: string) => {
handleQueryChange({
manufacturer: value,
page: 1
});
};
const handleAddTemplate = () => {
openTemplateModal(
PageAction.CREATE,
intl.formatMessage({ id: 'gpuservice.template.add' })
);
};
const handleEditTemplate = (row: ListItem) => {
openTemplateModal(
PageAction.EDIT,
intl.formatMessage({ id: 'gpuservice.template.edit' }),
row
);
};
const handleModalOk = async (data: FormData) => {
try {
if (openTemplateModalStatus.action === PageAction.EDIT) {
await updateGPUServiceTemplate({
id: openTemplateModalStatus.currentData!.id,
data
});
} else {
await createGPUServiceTemplate({ data });
}
closeTemplateModal();
handleSearch();
} catch (error) {
// ignore
}
};
const handleOnSelect = (item: { action: string; data: ListItem }) => {
if (item.action === 'edit') {
handleEditTemplate(item.data);
return;
}
if (item.action === 'delete') {
handleDelete({ ...item.data, name: item.data.name });
}
};
const loadMore = useMemoizedFn((nextPage: number) => {
fetchData({
query: {
...queryParams,
page: nextPage
},
loadmore: true
});
});
const handleRefresh = () => {
fetchData({ query: { ...queryParams, page: 1 } });
};
return (
<PageBox>
<FilterBar
marginBottom={22}
marginTop={30}
widths={{
input: 230
}}
inputHolder={intl.formatMessage({
id: 'gpuservice.template.filter.name'
})}
selectHolder={intl.formatMessage({
id: 'gpuservice.template.filter.vendor'
})}
buttonText={intl.formatMessage({ id: 'gpuservice.template.add' })}
handleClickPrimary={handleAddTemplate}
handleSearch={handleRefresh}
handleSelectChange={handleFilterByManufacturer}
handleInputChange={handleNameChange}
rowSelection={rowSelection}
showSelect={true}
selectOptions={manufacturerOptions}
/>
<InfiniteScrollerProvider
value={{
total: dataSource.totalPage,
current: queryParams.page!,
loading: dataSource.loading,
refresh: loadMore,
throttleDelay: 300
}}
>
<TemplateCardList
dataList={dataSource.dataList}
loading={dataSource.loading}
isFirst={!dataSource.loadend}
onSelect={handleOnSelect}
/>
<NoResult
loading={dataSource.loading}
loadend={dataSource.loadend}
dataSource={dataSource.dataList}
image={<IconFont type="icon-instance-template-filled" />}
filters={_.omit(queryParams, ['sort_by'])}
noFoundText={intl.formatMessage({
id: 'noresult.gpuservice.template.nofound'
})}
title={intl.formatMessage({
id: 'noresult.gpuservice.template.title'
})}
subTitle={intl.formatMessage({
id: 'noresult.gpuservice.template.subTitle'
})}
onClick={handleAddTemplate}
buttonText={intl.formatMessage({ id: 'noresult.button.add' })}
/>
</InfiniteScrollerProvider>
<AddModal
action={openTemplateModalStatus.action}
open={openTemplateModalStatus.open}
title={openTemplateModalStatus.title}
currentData={openTemplateModalStatus.currentData}
onCancel={closeTemplateModal}
onOk={handleModalOk}
/>
<DeleteModal ref={modalRef} />
</PageBox>
);
};
export default GPUServiceTemplates;