Files
gpustack-ui/src/pages/llmodels/forms/envs-override-popover.tsx
T

180 lines
4.2 KiB
TypeScript

import { WarningOutlined } from '@ant-design/icons';
import {
OverlayScroller,
SimpleTable,
type ColumnProps
} from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Alert, Button, Popover, Radio } from 'antd';
import React, { useMemo } from 'react';
import styled from 'styled-components';
const Container = styled.div`
padding: 8px 12px;
padding-right: 4px;
.title {
font-weight: 500;
margin-bottom: 12px;
}
.btn-wrapper {
display: flex;
justify-content: flex-end;
gap: 16px;
align-items: center;
padding-top: 12px;
}
.buttons {
display: flex;
gap: 8px;
justify-content: flex-end;
}
`;
interface EnvsOverridePopoverProps {
diffEnvs: {
old: Record<string, any>;
new: Record<string, any>;
} | null;
onSave: (data: Record<string, any>) => void;
}
const EnvsOverridePopover: React.FC<EnvsOverridePopoverProps> = (props) => {
const { diffEnvs, onSave } = props;
const [open, setOpen] = React.useState<boolean>(false);
const containerRef = React.useRef<HTMLDivElement>(null);
const [checkedEnvs, setCheckedEnvs] = React.useState<Record<string, any>>({});
const intl = useIntl();
const handleSelectValue = (
e: any,
{ env_name, value }: { env_name: string; value: any }
) => {
setCheckedEnvs((prev) => ({
...prev,
[env_name]: value
}));
};
const columns: ColumnProps[] = [
{
title: 'Environment Variable',
key: 'env_name'
},
{
title: 'Old Value',
key: 'old',
render: ({ row }) => {
return (
<Radio
onChange={(e) =>
handleSelectValue(e, { env_name: row.env_name, value: row.old })
}
checked={row.checkedValue === row.old}
>
{row.old}
</Radio>
);
}
},
{
title: 'New Value',
key: 'new',
render: ({ row }) => {
return (
<Radio
onChange={(e) =>
handleSelectValue(e, { env_name: row.env_name, value: row.new })
}
checked={row.checkedValue === row.new}
>
{row.new}
</Radio>
);
}
}
];
const dataList = useMemo(() => {
if (!diffEnvs) return [];
const list: { env_name: string; old: any; new: any; checkedValue?: any }[] =
[];
Object.keys(diffEnvs.old).forEach((key) => {
list.push({
env_name: key,
old: diffEnvs.old[key],
new: diffEnvs.new[key],
checkedValue: checkedEnvs[key]
});
});
return list;
}, [diffEnvs, checkedEnvs]);
const onOpenChange = (isOpen: boolean) => {
setOpen(isOpen);
};
const handleOnSave = () => {
onSave(checkedEnvs);
setOpen(false);
};
return (
<Popover
arrow={false}
content={
<Container>
<OverlayScroller
maxHeight={300}
styles={{
wrapper: {
paddingInlineStart: 0
}
}}
>
<SimpleTable
columns={columns}
dataSource={dataList}
rowKey="env_name"
theme="light"
/>
</OverlayScroller>
<div className="btn-wrapper">
<Button size="middle" onClick={() => setOpen(false)}>
{intl.formatMessage({ id: 'common.button.close' })}
</Button>
<Button size="middle" type="primary" onClick={handleOnSave}>
{intl.formatMessage({ id: 'common.button.confirm' })}
</Button>
</div>
</Container>
}
open={open}
getPopupContainer={(triggerNode) => containerRef.current || triggerNode}
onOpenChange={onOpenChange}
trigger={'click'}
styles={{
root: {
left: 0,
right: 0,
width: '100%'
},
container: {
width: '100%'
}
}}
>
<div ref={containerRef}>
<Alert
style={{ marginBlock: 16, cursor: 'pointer' }}
icon={<WarningOutlined />}
type="warning"
showIcon
title={'检测到环境变量值不一致,请确认使用的值'}
></Alert>
</div>
</Popover>
);
};
export default EnvsOverridePopover;