feat: edit replicas in the list
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
import { CheckOutlined, FormOutlined, UndoOutlined } from '@ant-design/icons';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { Button, Input, InputNumber, Tooltip } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import RowContext from '../row-context';
|
import RowContext from '../row-context';
|
||||||
@@ -5,9 +8,59 @@ import '../styles/cell.less';
|
|||||||
import { SealColumnProps } from '../types';
|
import { SealColumnProps } from '../types';
|
||||||
|
|
||||||
const SealColumn: React.FC<SealColumnProps> = (props) => {
|
const SealColumn: React.FC<SealColumnProps> = (props) => {
|
||||||
const row: Record<string, any> = useContext(RowContext);
|
const intl = useIntl();
|
||||||
console.log('seal column====', row);
|
const { row, onCell } = useContext(RowContext);
|
||||||
const { dataIndex, render, align } = props;
|
const { dataIndex, render, align, editable, valueType, title } = props;
|
||||||
|
const [isEditing, setIsEditing] = React.useState(false);
|
||||||
|
const [current, setCurrent] = React.useState(row[dataIndex]);
|
||||||
|
const cachedValue = React.useRef(row[dataIndex]);
|
||||||
|
|
||||||
|
const handleEdit = () => {
|
||||||
|
setIsEditing(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
cachedValue.current = current;
|
||||||
|
await onCell?.(
|
||||||
|
{
|
||||||
|
...row,
|
||||||
|
[dataIndex]: current
|
||||||
|
},
|
||||||
|
dataIndex
|
||||||
|
);
|
||||||
|
setIsEditing(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUndo = () => {
|
||||||
|
setCurrent(cachedValue.current);
|
||||||
|
setIsEditing(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderContent = () => {
|
||||||
|
if (isEditing && editable) {
|
||||||
|
return valueType === 'number' ? (
|
||||||
|
<InputNumber
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
min={0}
|
||||||
|
value={current}
|
||||||
|
onChange={(val) => {
|
||||||
|
setCurrent(val as any);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Input
|
||||||
|
value={current}
|
||||||
|
onChange={(e) => {
|
||||||
|
setCurrent(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (render) {
|
||||||
|
return render(current, row);
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames('cell', {
|
className={classNames('cell', {
|
||||||
@@ -16,11 +69,60 @@ const SealColumn: React.FC<SealColumnProps> = (props) => {
|
|||||||
'cell-right': align === 'right'
|
'cell-right': align === 'right'
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<span className="cell-content">
|
<span className="cell-content">{renderContent()}</span>
|
||||||
{render
|
{editable && (
|
||||||
? render(row[dataIndex], { ...row, dataIndex })
|
<>
|
||||||
: row[dataIndex]}
|
{isEditing ? (
|
||||||
</span>
|
<>
|
||||||
|
<Tooltip
|
||||||
|
key="confirm"
|
||||||
|
title={intl.formatMessage({ id: 'common.button.confirm' })}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
className="m-l-10"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
<CheckOutlined />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip
|
||||||
|
title={intl.formatMessage({ id: 'common.button.undo' })}
|
||||||
|
key="undo"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
className="m-l-10"
|
||||||
|
onClick={handleUndo}
|
||||||
|
>
|
||||||
|
<UndoOutlined />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Tooltip
|
||||||
|
key="edit"
|
||||||
|
title={
|
||||||
|
<span>
|
||||||
|
{intl.formatMessage({ id: 'common.button.edit' })}
|
||||||
|
<span className="m-l-5">{title}</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
className="m-l-10"
|
||||||
|
onClick={handleEdit}
|
||||||
|
>
|
||||||
|
<FormOutlined />
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const TableRow: React.FC<
|
|||||||
columns,
|
columns,
|
||||||
pollingChildren,
|
pollingChildren,
|
||||||
watchChildren,
|
watchChildren,
|
||||||
|
onCell,
|
||||||
onExpand,
|
onExpand,
|
||||||
renderChildren,
|
renderChildren,
|
||||||
loadChildren,
|
loadChildren,
|
||||||
@@ -43,14 +44,6 @@ const TableRow: React.FC<
|
|||||||
const childrenDataRef = useRef<any[]>([]);
|
const childrenDataRef = useRef<any[]>([]);
|
||||||
childrenDataRef.current = childrenData;
|
childrenDataRef.current = childrenData;
|
||||||
|
|
||||||
console.log(
|
|
||||||
'table row====',
|
|
||||||
record,
|
|
||||||
childrenData,
|
|
||||||
record.name,
|
|
||||||
firstLoad,
|
|
||||||
expanded
|
|
||||||
);
|
|
||||||
const { updateChunkedList, cacheDataListRef } = useUpdateChunkedList({
|
const { updateChunkedList, cacheDataListRef } = useUpdateChunkedList({
|
||||||
dataList: childrenData,
|
dataList: childrenData,
|
||||||
setDataList: setChildrenData
|
setDataList: setChildrenData
|
||||||
@@ -101,7 +94,6 @@ const TableRow: React.FC<
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleLoadChildren = async () => {
|
const handleLoadChildren = async () => {
|
||||||
console.log('first load=====', firstLoad);
|
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const data = await loadChildren?.(record);
|
const data = await loadChildren?.(record);
|
||||||
@@ -153,7 +145,6 @@ const TableRow: React.FC<
|
|||||||
const handleRowExpand = async () => {
|
const handleRowExpand = async () => {
|
||||||
setExpanded(!expanded);
|
setExpanded(!expanded);
|
||||||
onExpand?.(!expanded, record, record[rowKey]);
|
onExpand?.(!expanded, record, record[rowKey]);
|
||||||
console.log('expanded=====', record);
|
|
||||||
|
|
||||||
if (pollTimer.current) {
|
if (pollTimer.current) {
|
||||||
clearInterval(pollTimer.current);
|
clearInterval(pollTimer.current);
|
||||||
@@ -189,11 +180,6 @@ const TableRow: React.FC<
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!firstLoad && expanded) {
|
if (!firstLoad && expanded) {
|
||||||
console.log(
|
|
||||||
'update children=====',
|
|
||||||
record.name,
|
|
||||||
tableContext.allChildren
|
|
||||||
);
|
|
||||||
cacheDataListRef.current = childrenData;
|
cacheDataListRef.current = childrenData;
|
||||||
filterUpdateChildrenHandler();
|
filterUpdateChildrenHandler();
|
||||||
}
|
}
|
||||||
@@ -249,7 +235,7 @@ const TableRow: React.FC<
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RowContext.Provider value={{ ...record, rowIndex }}>
|
<RowContext.Provider value={{ row: { ...record, rowIndex }, onCell }}>
|
||||||
<div className="row-box">
|
<div className="row-box">
|
||||||
<div
|
<div
|
||||||
className={classNames('row-wrapper', {
|
className={classNames('row-wrapper', {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
|
|||||||
childParentKey,
|
childParentKey,
|
||||||
onExpand,
|
onExpand,
|
||||||
onSort,
|
onSort,
|
||||||
|
onCell,
|
||||||
expandedRowKeys,
|
expandedRowKeys,
|
||||||
loading,
|
loading,
|
||||||
expandable,
|
expandable,
|
||||||
@@ -135,6 +136,7 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
|
|||||||
renderChildren={renderChildren}
|
renderChildren={renderChildren}
|
||||||
loadChildren={loadChildren}
|
loadChildren={loadChildren}
|
||||||
loadChildrenAPI={loadChildrenAPI}
|
loadChildrenAPI={loadChildrenAPI}
|
||||||
|
onCell={onCell}
|
||||||
onExpand={onExpand}
|
onExpand={onExpand}
|
||||||
expandedRowKeys={expandedRowKeys}
|
expandedRowKeys={expandedRowKeys}
|
||||||
></TableRow>
|
></TableRow>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const RowContext = React.createContext({});
|
const RowContext = React.createContext<any>({});
|
||||||
|
|
||||||
export default RowContext;
|
export default RowContext;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ export interface SealColumnProps {
|
|||||||
headerStyle?: React.CSSProperties;
|
headerStyle?: React.CSSProperties;
|
||||||
sorter?: boolean;
|
sorter?: boolean;
|
||||||
defaultSortOrder?: 'ascend' | 'descend';
|
defaultSortOrder?: 'ascend' | 'descend';
|
||||||
|
editable?: boolean;
|
||||||
|
valueType?: 'text' | 'number' | 'date' | 'datetime' | 'time';
|
||||||
sortOrder?: 'ascend' | 'descend' | null;
|
sortOrder?: 'ascend' | 'descend' | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +44,7 @@ export interface SealTableProps {
|
|||||||
pollingChildren?: boolean;
|
pollingChildren?: boolean;
|
||||||
watchChildren?: boolean;
|
watchChildren?: boolean;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
|
onCell?: (record: any, dataIndex: string) => void;
|
||||||
onSort?: (dataIndex: string, order: 'ascend' | 'descend') => void;
|
onSort?: (dataIndex: string, order: 'ascend' | 'descend') => void;
|
||||||
onExpand?: (expanded: boolean, record: any, rowKey: any) => void;
|
onExpand?: (expanded: boolean, record: any, rowKey: any) => void;
|
||||||
renderChildren?: (data: any) => React.ReactNode;
|
renderChildren?: (data: any) => React.ReactNode;
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ export default {
|
|||||||
'common.button.next': 'Next',
|
'common.button.next': 'Next',
|
||||||
'common.button.prev': 'Previous',
|
'common.button.prev': 'Previous',
|
||||||
'common.button.back': 'Back',
|
'common.button.back': 'Back',
|
||||||
|
'common.button.undo': 'Undo',
|
||||||
'common.button.discardChange': 'Discard',
|
'common.button.discardChange': 'Discard',
|
||||||
'common.tips.save':
|
'common.tips.save':
|
||||||
'You have unsaved changes, leaving this page will discard changes.',
|
'You have unsaved changes, leaving this page will discard changes.',
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ export default {
|
|||||||
'common.button.next': '下一步',
|
'common.button.next': '下一步',
|
||||||
'common.button.prev': '上一步',
|
'common.button.prev': '上一步',
|
||||||
'common.button.back': '返回',
|
'common.button.back': '返回',
|
||||||
|
'common.button.undo': '撤销',
|
||||||
'common.button.discardChange': '放弃',
|
'common.button.discardChange': '放弃',
|
||||||
'common.tips.save': '您有未保存的更改,离开此页面将放弃更改。',
|
'common.tips.save': '您有未保存的更改,离开此页面将放弃更改。',
|
||||||
'common.tips.cancel': '您有未保存的更改。确定放弃更改?',
|
'common.tips.cancel': '您有未保存的更改。确定放弃更改?',
|
||||||
|
|||||||
@@ -196,6 +196,21 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
setSortOrder(order);
|
setSortOrder(order);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOnCell = async (record: any, dataIndex: string) => {
|
||||||
|
const params = {
|
||||||
|
id: record.id,
|
||||||
|
data: _.omit(record, [
|
||||||
|
'id',
|
||||||
|
'ready_replicas',
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'rowIndex'
|
||||||
|
])
|
||||||
|
};
|
||||||
|
await updateModel(params);
|
||||||
|
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||||
|
};
|
||||||
|
|
||||||
const handleAddModal = () => {
|
const handleAddModal = () => {
|
||||||
setOpenAddModal(true);
|
setOpenAddModal(true);
|
||||||
setTitle(intl.formatMessage({ id: 'models.button.deploy' }));
|
setTitle(intl.formatMessage({ id: 'models.button.deploy' }));
|
||||||
@@ -420,6 +435,7 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
childParentKey="model_id"
|
childParentKey="model_id"
|
||||||
expandable={true}
|
expandable={true}
|
||||||
onSort={handleOnSort}
|
onSort={handleOnSort}
|
||||||
|
onCell={handleOnCell}
|
||||||
pollingChildren={false}
|
pollingChildren={false}
|
||||||
watchChildren={true}
|
watchChildren={true}
|
||||||
loadChildren={getModelInstances}
|
loadChildren={getModelInstances}
|
||||||
@@ -478,6 +494,8 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
key="replicas"
|
key="replicas"
|
||||||
align="center"
|
align="center"
|
||||||
span={4}
|
span={4}
|
||||||
|
editable
|
||||||
|
valueType="number"
|
||||||
render={(text, record: ListItem) => {
|
render={(text, record: ListItem) => {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
Reference in New Issue
Block a user