Files
gpustack-ui/src/pages/cluster-management/components/cloud-options.tsx
T

120 lines
3.5 KiB
TypeScript

import { DropdownActions } from '@gpustack/core-ui';
import ListMap from '@gpustack/core-ui/lib/components/dynamic-form/components/list-map';
import { FieldSchema } from '@gpustack/core-ui/lib/components/dynamic-form/config/types';
import { PlusOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
import { Button, Form } from 'antd';
import _ from 'lodash';
import React, { forwardRef, useImperativeHandle, useMemo } from 'react';
import styled from 'styled-components';
import { CloudOptionItems } from '../config';
import { fieldConfig } from '../config/cloud-options-config';
const Title = styled.div`
display: flex;
height: 40px;
align-items: center;
gap: 16px;
border-radius: var(--ant-border-radius);
margin-bottom: 22px;
font-weight: 600;
`;
const CloudOptions: React.FC<{
ref?: any;
}> = forwardRef((props, ref) => {
const intl = useIntl();
const form = Form.useFormInstance();
const [selectedOptions, setSelectedOptions] = React.useState<Set<string>>(
new Set()
);
const [fieldList, setFieldList] = React.useState<FieldSchema[]>([]);
const items = useMemo(() => {
return CloudOptionItems.map((item) => ({
...item,
disabled: selectedOptions.has(item.key)
}));
}, [selectedOptions]);
const handleAddOption = useMemoizedFn((item: { key: string }) => {
const field = fieldConfig[item.key];
setFieldList((prev) => [...prev, { ...field, name: item.key }]);
setSelectedOptions((prev) => new Set(prev).add(item.key));
});
const menu = useMemo(() => {
return {
items: items,
onClick: handleAddOption
};
}, [items, handleAddOption]);
const handleOnChange = (name: string, value: any) => {
form.setFieldValue(['cloud_options', name], value);
if (_.isEmpty(value)) {
setFieldList((prev) => prev.filter((field) => field.name !== name));
setSelectedOptions((prev) => {
const newSelected = new Set(prev);
newSelected.delete(name);
return newSelected;
});
}
};
// init field list by form data
const initFieldList = () => {
const cloudOptions = form.getFieldValue('cloud_options');
if (cloudOptions) {
const fields = Object.entries(cloudOptions)
.filter(([, value]) => {
return !_.isEmpty(value);
})
.map(([key, value]) => {
const field = fieldConfig[key];
return { ...field, name: key };
});
setFieldList(fields);
setSelectedOptions(new Set(Object.keys(cloudOptions)));
}
};
useImperativeHandle(ref, () => ({
initFieldList
}));
return (
<>
<Title>
<DropdownActions menu={menu}>
<Button variant="filled" color="default">
<PlusOutlined />
<span>
{intl.formatMessage({ id: 'clusters.workerpool.cloudOptions' })}
</span>
</Button>
</DropdownActions>
</Title>
{fieldList.length > 0 &&
fieldList.map((field) => (
<Form.Item
key={field.name}
name={['cloud_options', field.name as string]}
>
<ListMap
btnText={intl.formatMessage({ id: 'common.button.addItem' })}
label={field.title}
dataList={form.getFieldValue(['cloud_options', field.name]) || []}
properties={field.properties || {}}
onChange={(value) => handleOnChange(field.name, value)}
/>
</Form.Item>
))}
</>
);
});
export default CloudOptions;