Skip to content

Commit

Permalink
[Refactor][web] refactor devops overview list layout (#3126)
Browse files Browse the repository at this point in the history
Co-authored-by: Zzm0809 <[email protected]>
  • Loading branch information
Zzm0809 and Zzm0809 authored Feb 1, 2024
1 parent a254632 commit e587f49
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 54 deletions.
3 changes: 2 additions & 1 deletion dinky-web/src/locales/en-US/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ export default {
'devops.jobinfo.remap.cluster.title.help':
'(Note: This operation will modify the configuration of the cluster instance simultaneously.)',
'devops.jobinfo.remap.job.title': 'Job mapping information',

'devops.joblist.clear.filter': 'Cancel Selected',
'devops.joblist.clear.filtertips': 'Clear selected tasks, but not clear other filter conditions',
'devops.joblist.detail': 'Job Detail',
'devops.joblist.history': 'History',
'devops.joblist.joblist': 'Job List',
Expand Down
2 changes: 2 additions & 0 deletions dinky-web/src/locales/zh-CN/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ export default {
'devops.jobinfo.remap.cluster.title': '集群实例映射信息',
'devops.jobinfo.remap.cluster.title.help': ' (注意:此操作会同步修改集群实例配置)',
'devops.jobinfo.remap.job.title': 'Job映射信息',
'devops.joblist.clear.filter': '取消选择',
'devops.joblist.clear.filtertips': '清除选择的任务,并不是清除其他得筛选条件',

'devops.joblist.detail': '详情',
'devops.joblist.history': '历史',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export const showBadge = (type: string) => {
*/

export const buildProjectTree = (
data: Catalogue[],
data: Catalogue[] = [],
searchValue: string = '',
path: string[] = []
): any =>
Expand Down
264 changes: 213 additions & 51 deletions dinky-web/src/pages/DevOps/JobList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@

import JobLifeCycleTag from '@/components/JobTags/JobLifeCycleTag';
import StatusTag from '@/components/JobTags/StatusTag';
import {
buildProjectTree,
generateList,
getParentKey
} from '@/pages/DataStudio/LeftContainer/Project/function';
import { getTaskData } from '@/pages/DataStudio/LeftContainer/Project/service';
import { DevopContext } from '@/pages/DevOps';
import { JOB_LIFE_CYCLE } from '@/pages/DevOps/constants';
import { getJobDuration } from '@/pages/DevOps/function';
Expand All @@ -28,19 +34,32 @@ import { PROTABLE_OPTIONS_PUBLIC } from '@/services/constants';
import { API_CONSTANTS } from '@/services/endpoints';
import { Jobs } from '@/types/DevOps/data';
import { l } from '@/utils/intl';
import { ClockCircleTwoTone, EyeTwoTone, RedoOutlined } from '@ant-design/icons';
import { SplitPane } from '@andrewray/react-multi-split-pane';
import { Pane } from '@andrewray/react-multi-split-pane/dist/lib/Pane';
import { ClearOutlined, ClockCircleTwoTone, EyeTwoTone, RedoOutlined } from '@ant-design/icons';
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { ProCard, ProTable } from '@ant-design/pro-components';
import { Button, Radio, Table } from 'antd';
import { useContext, useEffect, useRef, useState } from 'react';
import { Button, Empty, Radio, Table, Tree } from 'antd';
import Search from 'antd/es/input/Search';
import { Key, useContext, useEffect, useRef, useState } from 'react';
import { history } from 'umi';

const { DirectoryTree } = Tree;

const JobList = () => {
const refObject = useRef<HTMLDivElement>(null);
const tableRef = useRef<ActionType>();
const { statusFilter, setStatusFilter } = useContext<any>(DevopContext);
const [stepFilter, setStepFilter] = useState<number | undefined>();
const [taskFilter, setTaskFilter] = useState<string | undefined>();
const [taskId, setTaskId] = useState<number>();
const [searchValue, setSearchValueValue] = useState('');
const [data, setData] = useState<any[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState(true);
const [expandedKeys, setExpandedKeys] = useState<Key[]>([]);
const [selectedKey, setSelectedKey] = useState<Key[]>([]);

console.log(statusFilter);
const jobListColumns: ProColumns<Jobs.JobInstance>[] = [
{
title: l('global.table.jobname'),
Expand Down Expand Up @@ -95,60 +114,203 @@ const JobList = () => {
}
];

// 重置选中的 key 和 taskId | reset the selected key and taskId
const resetValue = () => {
setSelectedKey([]);
setTaskId(undefined);
tableRef.current?.reload();
};

// 监听 statusFilter 的变化,如果为 undefined 则重置选中的 key 和 taskId | listen for changes in statusFilter, if it is undefined, reset the selected key and taskId
useEffect(() => {
if (statusFilter === undefined) {
resetValue();
}
}, [statusFilter]);

/**
* 获取任务数据 | query task data
*/
useEffect(() => {
getTaskData().then((res) => {
if (res) {
setData(buildProjectTree(res, searchValue, []));
}
});
}, [searchValue]);

useEffect(() => {
setInterval(() => tableRef.current?.reload(false), 5 * 1000);
}, []);

return (
<ProCard boxShadow={true}>
<ProTable<Jobs.JobInstance>
{...PROTABLE_OPTIONS_PUBLIC}
search={false}
loading={{ delay: 1000 }}
rowKey={(record) => record.jid}
columns={jobListColumns}
params={{ isHistory: false, status: statusFilter, step: stepFilter, name: taskFilter }}
actionRef={tableRef}
toolbar={{
settings: false,
search: { onSearch: (value: string) => setTaskFilter(value) },
filter: (
<>
<Radio.Group defaultValue={undefined} onChange={(e) => setStepFilter(e.target.value)}>
<Radio.Button value={undefined} defaultChecked={true}>
{l('global.table.lifecycle.all')}
</Radio.Button>
<Radio.Button value={JOB_LIFE_CYCLE.PUBLISH}>
{l('global.table.lifecycle.publish')}
</Radio.Button>
<Radio.Button value={JOB_LIFE_CYCLE.DEVELOP}>
{l('global.table.lifecycle.dev')}
</Radio.Button>
</Radio.Group>
</>
),
actions: [<Button icon={<RedoOutlined />} onClick={() => tableRef.current?.reload()} />]
}}
request={async (params, sorter, filter: any) =>
queryList(API_CONSTANTS.JOB_INSTANCE, {
...params,
sorter,
filter
})
const onChangeSearch = (e: any) => {
let { value } = e.target;
if (!value) {
setSearchValueValue(value);
return;
}
value = String(value).trim();
const expandList: any[] = generateList(data, []);
let expandedKeys: any = expandList
.map((item: any) => {
if (item?.name.indexOf(value) > -1) {
return getParentKey(item.key, data);
}
expandable={{
expandedRowRender: (record) => <JobHistoryList taskId={record.taskId} key={record.jid} />,
expandIcon: ({ expanded, onExpand, record }) => (
<Button
className={'options-button'}
key={`${record.id}_history`}
onClick={(e) => onExpand(record, e)}
title={l('devops.joblist.history')}
icon={<ClockCircleTwoTone twoToneColor={expanded ? '#52c41a' : '#4096ff'} />}
return null;
})
.filter((item: any, i: number, self: any) => item && self.indexOf(item) === i);
setExpandedKeys(expandedKeys);
setSearchValueValue(value);
setAutoExpandParent(true);
};

function onNodeClick(info: any) {
const {
node: { isLeaf, name, type, parentId, path, key, taskId, fullInfo }
} = info;
if (isLeaf) {
// 如果是 leaf 节点 则设置选中的 key 和 taskId | if it is a leaf node, set the selected key and taskId
setSelectedKey([key]);
setTaskId(taskId);
} else {
// 如果不是 leaf 节点 则设置选中的 key 和 taskId 为 undefined | if it is not a leaf node, set the selected key and taskId to undefined
setTaskId(undefined);
setSelectedKey([]);
}
}

return (
<ProCard
boxShadow
ghost
size={'small'}
bodyStyle={{
height: parent.innerHeight - 215,
marginTop: -30,
overflow: 'auto',
width: '99vw'
}}
>
<SplitPane
split={'vertical'}
defaultSizes={[100, 500]}
minSize={200}
className={'split-pane'}
>
<Pane
className={'split-pane'}
forwardRef={refObject}
minSize={200}
size={200}
split={'horizontal'}
>
<Search
style={{ margin: '8px 0px' }}
placeholder={l('global.search.text')}
onChange={onChangeSearch}
allowClear={true}
addonAfter={
// 如果选中的 key 长度大于 0 则显示清除按钮 | if the length of the selected key is greater than 0, the clear button is displayed
selectedKey.length > 0 && (
<Button
title={l('devops.joblist.clear.filtertips')}
icon={<ClearOutlined />}
onClick={() => resetValue()}
>
{l('devops.joblist.clear.filter')}
</Button>
)
}
/>

{data.length ? (
<DirectoryTree
className={'treeList'}
onSelect={(_, info) => onNodeClick(info)}
// onRightClick={onRightClick}
expandedKeys={expandedKeys}
// expandAction={'doubleClick'}
selectedKeys={selectedKey}
onExpand={(expandedKeys: Key[]) => setExpandedKeys(expandedKeys)}
treeData={data}
autoExpandParent={autoExpandParent}
/>
)
}}
/>
) : (
<Empty className={'code-content-empty'} />
)}
</Pane>

<Pane
className={'split-pane'}
forwardRef={refObject}
minSize={200}
size={200}
split={'horizontal'}
>
<ProTable<Jobs.JobInstance>
{...PROTABLE_OPTIONS_PUBLIC}
search={false}
tableStyle={{ height: parent.innerHeight - 210 }}
loading={{ delay: 1000 }}
rowKey={(record) => record.jid}
columns={jobListColumns}
params={{
isHistory: false,
status: statusFilter,
step: stepFilter,
name: taskFilter,
taskId: taskId
}}
actionRef={tableRef}
toolbar={{
settings: false,
search: { onSearch: (value: string) => setTaskFilter(value) },
filter: (
<>
<Radio.Group
defaultValue={undefined}
onChange={(e) => setStepFilter(e.target.value)}
>
<Radio.Button value={undefined} defaultChecked={true}>
{l('global.table.lifecycle.all')}
</Radio.Button>
<Radio.Button value={JOB_LIFE_CYCLE.PUBLISH}>
{l('global.table.lifecycle.publish')}
</Radio.Button>
<Radio.Button value={JOB_LIFE_CYCLE.DEVELOP}>
{l('global.table.lifecycle.dev')}
</Radio.Button>
</Radio.Group>
</>
),
actions: [
<Button icon={<RedoOutlined />} onClick={() => tableRef.current?.reload()} />
]
}}
request={async (params, sorter, filter: any) =>
queryList(API_CONSTANTS.JOB_INSTANCE, {
...params,
sorter,
filter
})
}
expandable={{
expandedRowRender: (record) => (
<JobHistoryList taskId={record.taskId} key={record.jid} />
),
expandIcon: ({ expanded, onExpand, record }) => (
<Button
className={'options-button'}
key={`${record.id}_history`}
onClick={(e) => onExpand(record, e)}
title={l('devops.joblist.history')}
icon={<ClockCircleTwoTone twoToneColor={expanded ? '#52c41a' : '#4096ff'} />}
/>
)
}}
/>
</Pane>
</SplitPane>
</ProCard>
);
};
Expand Down
2 changes: 1 addition & 1 deletion dinky-web/src/pages/DevOps/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default () => {
<SlowlyAppear>
<PageContainer title={false} breadcrumb={{ style: { display: 'none' } }}>
<DevopContext.Provider value={{ statusFilter, setStatusFilter }}>
<Space direction='vertical' size={16}>
<Space direction='vertical' size={24}>
<JobOverview />
<JobList />
</Space>
Expand Down

0 comments on commit e587f49

Please sign in to comment.