feat(web): 更换页面框架为pro-layout
This commit is contained in:
96
service-web/client/src/pages/overview/Cloud.tsx
Normal file
96
service-web/client/src/pages/overview/Cloud.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import React from 'react'
|
||||
import {
|
||||
amisRender,
|
||||
commonInfo,
|
||||
crudCommonOptions,
|
||||
serviceLogByAppName,
|
||||
serviceLogByAppNameAndHost,
|
||||
time,
|
||||
} from '../../util/amis.ts'
|
||||
|
||||
const cloudCrud = (title: string, path: string) => {
|
||||
return {
|
||||
type: 'crud',
|
||||
title: title,
|
||||
api: `${commonInfo.baseUrl}${path}`,
|
||||
...crudCommonOptions(),
|
||||
interval: 2000,
|
||||
headerToolbar: ['reload'],
|
||||
loadDataOnce: true,
|
||||
perPage: 100,
|
||||
columns: [
|
||||
{
|
||||
label: '名称',
|
||||
type: 'tpl',
|
||||
tpl: `\${name} \${IF(size === undefined, '', '<span class="font-bold label label-primary">' + size + '</span>')}`,
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: '状态',
|
||||
align: 'center',
|
||||
width: 60,
|
||||
},
|
||||
{
|
||||
name: 'serviceUpTime',
|
||||
label: '启动时间',
|
||||
...time('serviceUpTime'),
|
||||
align: 'center',
|
||||
width: 160,
|
||||
},
|
||||
{name: 'url', label: '地址'},
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
fixed: 'right',
|
||||
className: 'nowrap',
|
||||
buttons: [
|
||||
{
|
||||
label: '日志',
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
tooltip: '打开Grafana日志',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, doAction, event) => {
|
||||
let data = context.props.data
|
||||
let url = ''
|
||||
if (data['metadata']) {
|
||||
url = serviceLogByAppNameAndHost(data.serviceId, data.metadata.hostname)
|
||||
} else if (data['name']) {
|
||||
url = serviceLogByAppName(data.name)
|
||||
}
|
||||
window.open(url, '_blank')
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
const Cloud: React.FC = () => {
|
||||
return (
|
||||
<div className="hudi-cloud bg-white">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
body: [
|
||||
cloudCrud('服务列表', '/cloud/list'),
|
||||
cloudCrud('服务列表 (IP)', '/cloud/list_ip'),
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Cloud
|
||||
96
service-web/client/src/pages/overview/Queue.tsx
Normal file
96
service-web/client/src/pages/overview/Queue.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import {
|
||||
amisRender,
|
||||
commonInfo,
|
||||
copyField,
|
||||
crudCommonOptions,
|
||||
paginationCommonOptions,
|
||||
time,
|
||||
yarnQueueCrud,
|
||||
} from '../../util/amis.ts'
|
||||
|
||||
const queueCrud = (name: string) => {
|
||||
return {
|
||||
type: 'crud',
|
||||
title: name,
|
||||
api: `\${base}/queue/all?name=${name}`,
|
||||
...crudCommonOptions(),
|
||||
interval: 10000,
|
||||
loadDataOnce: true,
|
||||
perPage: 5,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
'filter-toggler',
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '共 <span class=\'text-primary font-bold\'>${total|default:0}</span> 个任务',
|
||||
},
|
||||
paginationCommonOptions(false),
|
||||
],
|
||||
footerToolbar: [],
|
||||
columns: [
|
||||
{
|
||||
name: 'data.flinkJobId',
|
||||
label: '任务 ID',
|
||||
width: 190,
|
||||
...copyField('data.flinkJobId'),
|
||||
},
|
||||
{
|
||||
name: 'data.alias',
|
||||
label: '别名',
|
||||
className: 'nowrap',
|
||||
...copyField('data.alias'),
|
||||
},
|
||||
{
|
||||
name: 'data.batch',
|
||||
label: '批次',
|
||||
width: 100,
|
||||
type: 'tpl',
|
||||
tpl: '<span class="label label-warning">${data.batch}</span>',
|
||||
},
|
||||
{
|
||||
name: 'priority',
|
||||
label: '优先级',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
type: 'tpl',
|
||||
tpl: '<span class="label bg-info">${priority}</span>',
|
||||
},
|
||||
{
|
||||
name: 'data.comment',
|
||||
label: '备注',
|
||||
className: 'nowrap',
|
||||
},
|
||||
{
|
||||
name: 'createTime',
|
||||
label: '任务提交时间',
|
||||
...time('createTime'),
|
||||
width: 160,
|
||||
fixed: 'right',
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
const Queue = () => {
|
||||
let items = []
|
||||
for (let name of Object.keys(commonInfo.clusters.compaction)) {
|
||||
// @ts-ignore
|
||||
items.push(yarnQueueCrud(name, commonInfo.clusters.compaction[name]))
|
||||
items.push(queueCrud(`compaction-queue-${name}`))
|
||||
}
|
||||
return (
|
||||
<div className="hudi-queue bg-white overflow-y-scroll">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
body: [
|
||||
queueCrud('compaction-queue-pre'),
|
||||
...items,
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Queue
|
||||
256
service-web/client/src/pages/overview/Table.tsx
Normal file
256
service-web/client/src/pages/overview/Table.tsx
Normal file
@@ -0,0 +1,256 @@
|
||||
import {
|
||||
aliasTextInput,
|
||||
amisRender,
|
||||
commonInfo,
|
||||
compactionStatusMapping,
|
||||
crudCommonOptions,
|
||||
filterableField,
|
||||
flinkJobDialog,
|
||||
flinkJobIdTextInput,
|
||||
hudiTableTypeMapping,
|
||||
mappingField,
|
||||
paginationCommonOptions,
|
||||
runModeMapping,
|
||||
tableMetaDialog,
|
||||
tableRunningStateMapping,
|
||||
timeAndFrom,
|
||||
} from '../../util/amis.ts'
|
||||
|
||||
function Table() {
|
||||
return (
|
||||
<div className="hudi-table bg-white">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
body: [
|
||||
{
|
||||
id: 'table-service',
|
||||
type: 'service',
|
||||
data: {},
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/table/list`,
|
||||
data: {
|
||||
page: '${page|default:undefined}',
|
||||
count: '${perPage|default:undefined}',
|
||||
order: '${orderBy|default:undefined}',
|
||||
direction: '${orderDir|default:undefined}',
|
||||
search_flink_job_id: '${flinkJobId|default:undefined}',
|
||||
search_alias: '${alias|default:undefined}',
|
||||
filter_hudi_table_type: '${tableMeta\\.hudi\\.targetTableType|default:undefined}',
|
||||
filter_run_mode: '${flinkJob\\.runMode|default:undefined}',
|
||||
filter_compaction_status: '${syncState\\.compactionStatus|default:undefined}',
|
||||
},
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
// interval: 10000,
|
||||
filter: {
|
||||
title: '表筛选',
|
||||
body: [
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
...flinkJobIdTextInput('58d0da94-1b3c-4234-948d-482ae3425e70'),
|
||||
size: 'lg',
|
||||
},
|
||||
{
|
||||
...aliasTextInput('58d0da94-1b3c-4234-948d-482ae3425e70'),
|
||||
size: 'lg',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
level: 'primary',
|
||||
label: '查询',
|
||||
},
|
||||
{
|
||||
type: 'reset',
|
||||
label: '重置',
|
||||
},
|
||||
],
|
||||
},
|
||||
filterTogglable: true,
|
||||
filterDefaultVisible: true,
|
||||
perPage: 20,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
'filter-toggler',
|
||||
paginationCommonOptions(),
|
||||
],
|
||||
footerToolbar: [
|
||||
paginationCommonOptions(),
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
label: 'Flink job id',
|
||||
width: 195,
|
||||
fixed: 'left',
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
body: [
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '${flinkJobId}',
|
||||
size: 'xs',
|
||||
actionType: 'dialog',
|
||||
tooltip: '查看详情',
|
||||
dialog: flinkJobDialog(),
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '',
|
||||
icon: 'fa fa-copy',
|
||||
size: 'xs',
|
||||
actionType: 'copy',
|
||||
content: '${flinkJobId}',
|
||||
tooltip: '复制 ID',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '别名',
|
||||
type: 'wrapper',
|
||||
fixed: 'left',
|
||||
size: 'none',
|
||||
className: 'nowrap',
|
||||
body: [
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '${tableMeta.alias}',
|
||||
size: 'xs',
|
||||
actionType: 'dialog',
|
||||
tooltip: '查看详情',
|
||||
dialog: tableMetaDialog(),
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '',
|
||||
icon: 'fa fa-copy',
|
||||
size: 'xs',
|
||||
actionType: 'copy',
|
||||
content: '${tableMeta.alias}',
|
||||
tooltip: '复制别名',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'tableMeta.hudi.targetTableType',
|
||||
label: '表类型',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
...mappingField('tableMeta.hudi.targetTableType', hudiTableTypeMapping),
|
||||
filterable: filterableField(hudiTableTypeMapping, true),
|
||||
},
|
||||
{
|
||||
name: 'flinkJob.runMode',
|
||||
label: '任务类型',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
...mappingField('flinkJob.runMode', runModeMapping),
|
||||
filterable: filterableField(runModeMapping, true),
|
||||
},
|
||||
{
|
||||
name: 'syncRunning',
|
||||
label: '同步运行状态',
|
||||
align: 'center',
|
||||
...mappingField('syncRunning', tableRunningStateMapping),
|
||||
className: 'bg-green-50',
|
||||
width: 75,
|
||||
},
|
||||
{
|
||||
name: 'source_start_time',
|
||||
label: '同步启动时间',
|
||||
...timeAndFrom('syncState.sourceStartTime', 'syncState.sourceStartTimeFromNow', '未启动'),
|
||||
sortable: true,
|
||||
className: 'bg-green-50',
|
||||
},
|
||||
{
|
||||
name: 'source_receive_time',
|
||||
label: '同步接收时间',
|
||||
...timeAndFrom('syncState.sourceReceiveTime', 'syncState.sourceReceiveTimeFromNow', '无数据'),
|
||||
sortable: true,
|
||||
className: 'bg-green-50',
|
||||
},
|
||||
{
|
||||
name: 'source_checkpoint_time',
|
||||
label: '同步心跳时间',
|
||||
...timeAndFrom('syncState.sourceCheckpointTime', 'syncState.sourceCheckpointTimeFromNow', '未启动'),
|
||||
sortable: true,
|
||||
className: 'bg-green-50',
|
||||
},
|
||||
{
|
||||
name: 'source_publish_time',
|
||||
label: '源端发布时间',
|
||||
...timeAndFrom('syncState.sourcePublishTime', 'syncState.sourcePublishTimeFromNow', '无增量'),
|
||||
sortable: true,
|
||||
className: 'bg-green-50',
|
||||
},
|
||||
{
|
||||
name: 'source_operation_time',
|
||||
label: '源端业务时间',
|
||||
...timeAndFrom('syncState.sourceOperationTime', 'syncState.sourceOperationTimeFromNow', '无增量'),
|
||||
sortable: true,
|
||||
className: 'bg-green-50',
|
||||
},
|
||||
{
|
||||
name: 'compactionRunning',
|
||||
label: '压缩运行状态',
|
||||
align: 'center',
|
||||
...mappingField('compactionRunning', tableRunningStateMapping),
|
||||
className: 'bg-cyan-50',
|
||||
width: 75,
|
||||
},
|
||||
{
|
||||
name: 'syncState.compactionStatus',
|
||||
label: '压缩状态',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
...mappingField('syncState.compactionStatus', compactionStatusMapping),
|
||||
filterable: filterableField(compactionStatusMapping, true),
|
||||
className: 'bg-cyan-50',
|
||||
},
|
||||
{
|
||||
name: 'compaction_start_time',
|
||||
label: '压缩启动时间',
|
||||
...timeAndFrom('syncState.compactionStartTime', 'syncState.compactionStartTimeFromNow'),
|
||||
sortable: true,
|
||||
className: 'bg-cyan-50',
|
||||
},
|
||||
{
|
||||
name: 'compaction_latest_operation_time',
|
||||
label: '压缩业务时间',
|
||||
...timeAndFrom('syncState.compactionLatestOperationTime', 'syncState.compactionLatestOperationTimeFromNow', '无'),
|
||||
sortable: true,
|
||||
className: 'bg-cyan-50',
|
||||
},
|
||||
{
|
||||
name: 'compaction_finish_time',
|
||||
label: '压缩完成时间',
|
||||
...timeAndFrom('syncState.compactionFinishTime', 'syncState.compactionFinishTimeFromNow'),
|
||||
sortable: true,
|
||||
className: 'bg-cyan-50',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Table
|
||||
195
service-web/client/src/pages/overview/Task.tsx
Normal file
195
service-web/client/src/pages/overview/Task.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo, paginationCommonOptions, serviceLogByAppName, yarnCrudColumns} from '../../util/amis.ts'
|
||||
|
||||
const Task: React.FC = () => {
|
||||
return (
|
||||
<div className="hudi-task bg-white">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
title: '检索文件',
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
label: '提交任务',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/task/scan`,
|
||||
data: {
|
||||
key: '${key|default:undefined}',
|
||||
hdfs: '${hdfs|default:undefined}',
|
||||
pulsar: '${pulsar|default:undefined}',
|
||||
topic: '${topic|default:undefined}',
|
||||
mode: '${scan_mode|default:undefined}',
|
||||
fields: '${fields|default:undefined}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
body: [
|
||||
{
|
||||
name: 'scan_mode',
|
||||
type: 'checkboxes',
|
||||
label: '检索范围',
|
||||
checkAll: true,
|
||||
required: true,
|
||||
value: 'log',
|
||||
options: [
|
||||
{label: '消息队列', value: 'queue'},
|
||||
{label: '日志文件', value: 'log'},
|
||||
{label: '数据文件', value: 'base'},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'key',
|
||||
label: '检索字段',
|
||||
required: true,
|
||||
clearable: true,
|
||||
description: '检索带有该字符的记录',
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'hdfs',
|
||||
label: 'HDFS路经',
|
||||
requiredOn: '${CONTAINS(scan_mode, \'log\') || CONTAINS(scan_mode, \'base\')}',
|
||||
visibleOn: '${CONTAINS(scan_mode, \'log\') || CONTAINS(scan_mode, \'base\')}',
|
||||
clearable: true,
|
||||
description: '输入表HDFS路径',
|
||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'fields',
|
||||
label: '指定字段',
|
||||
visibleOn: '${CONTAINS(scan_mode, \'base\')}',
|
||||
clearable: true,
|
||||
description: '逗号分隔,可以大幅提高parquet文件检索速度,但无法获取指定字段外的字段内容',
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'topic',
|
||||
label: 'Pulsar主题',
|
||||
requiredOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||
visibleOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||
clearable: true,
|
||||
description: '输入Pulsar主题',
|
||||
autoComplete: `${commonInfo.baseUrl}/table/all_pulsar_topic?key=$term`,
|
||||
columnRatio: 4,
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'pulsar',
|
||||
label: 'Pulsar地址',
|
||||
requiredOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||
visibleOn: '${CONTAINS(scan_mode, \'queue\')}',
|
||||
clearable: true,
|
||||
description: '输入Pulsar地址',
|
||||
autoComplete: `${commonInfo.baseUrl}/table/all_pulsar?key=$term`,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
title: '综合查询',
|
||||
actions: [
|
||||
{
|
||||
type: 'action',
|
||||
label: '总数&最后操作时间',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/task/table_summary`,
|
||||
data: {
|
||||
hdfs: '${hdfs|default:undefined}',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
label: '最后10条记录',
|
||||
actionType: 'ajax',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/task/table_sampling`,
|
||||
data: {
|
||||
hdfs: '${hdfs|default:undefined}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'hdfs',
|
||||
label: 'HDFS路经',
|
||||
required: true,
|
||||
clearable: true,
|
||||
description: '输入表HDFS路径',
|
||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/yarn/job_list`,
|
||||
data: {
|
||||
clusters: commonInfo.clusters.sync_names(),
|
||||
page: '${page|default:undefined}',
|
||||
count: '${perPage|default:undefined}',
|
||||
order: '${orderBy|default:undefined}',
|
||||
direction: '${orderDir|default:undefined}',
|
||||
filter_state: '${state|default:undefined}',
|
||||
filter_final_status: '${finalStatus|default:undefined}',
|
||||
search_id: '${id|default:undefined}',
|
||||
search_name: 'Service_Task',
|
||||
precise: false,
|
||||
},
|
||||
},
|
||||
affixHeader: false,
|
||||
interval: 10000,
|
||||
syncLocation: false,
|
||||
silentPolling: true,
|
||||
resizable: false,
|
||||
perPage: 10,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
{
|
||||
label: '任务管理器日志',
|
||||
type: 'action',
|
||||
tooltip: '打开Grafana日志',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
script: () => window.open(serviceLogByAppName('service-executor-manager'), '_blank'),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
paginationCommonOptions(),
|
||||
],
|
||||
footerToolbar: [],
|
||||
columns: yarnCrudColumns(),
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Task
|
||||
316
service-web/client/src/pages/overview/Tool.tsx
Normal file
316
service-web/client/src/pages/overview/Tool.tsx
Normal file
@@ -0,0 +1,316 @@
|
||||
import React from 'react'
|
||||
import {
|
||||
aliasTextInput,
|
||||
amisRender,
|
||||
commonInfo,
|
||||
crudCommonOptions,
|
||||
flinkJobIdTextInput,
|
||||
formReloadFlinkJobIdTextInputAndAliasTextInput,
|
||||
hdfsDialog,
|
||||
paginationCommonOptions,
|
||||
readOnlyDialogOptions,
|
||||
timelineColumns,
|
||||
} from '../../util/amis.ts'
|
||||
|
||||
const Tool: React.FC = () => {
|
||||
return (
|
||||
<div className="hudi-tool bg-white">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
body: [
|
||||
{
|
||||
type: 'panel',
|
||||
title: '乱七八糟小工具',
|
||||
body: [
|
||||
{
|
||||
type: 'action',
|
||||
label: 'SQL日志',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '日志',
|
||||
...readOnlyDialogOptions(),
|
||||
size: 'lg',
|
||||
body: {
|
||||
type: 'crud',
|
||||
api: `${commonInfo.baseUrl}/log/query_sql_log`,
|
||||
...crudCommonOptions(),
|
||||
loadDataOnce: true,
|
||||
perPage: 50,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
paginationCommonOptions(undefined, 10),
|
||||
],
|
||||
footerToolbar: [
|
||||
paginationCommonOptions(undefined, 10),
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: 'sql',
|
||||
label: 'SQL',
|
||||
},
|
||||
{
|
||||
name: 'createTime',
|
||||
label: '执行时间',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
label: 'ZK节点',
|
||||
className: 'ml-2',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: '日志',
|
||||
...readOnlyDialogOptions(),
|
||||
size: 'lg',
|
||||
body: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
title: 'HDFS文件管理器',
|
||||
actions: [
|
||||
{
|
||||
label: '直接下载',
|
||||
type: 'action',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'custom',
|
||||
// @ts-ignore
|
||||
script: (context, action, event) => {
|
||||
let downloadUrl = `${event.data.base}/hudi/hdfs_download?root=${encodeURI(event.data.hdfs)}`
|
||||
window.open(downloadUrl, '_blank')
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'submit',
|
||||
label: '查看',
|
||||
actionType: 'dialog',
|
||||
dialog: hdfsDialog('hdfs'),
|
||||
},
|
||||
],
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'hdfs',
|
||||
label: 'HDFS根路经',
|
||||
required: true,
|
||||
clearable: true,
|
||||
description: '输入表HDFS路径',
|
||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
title: '查询时间线',
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
label: '查询时间线',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: 'Hudi 表时间线',
|
||||
actions: [],
|
||||
size: 'lg',
|
||||
body: {
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/hudi/timeline/list_hdfs`,
|
||||
data: {
|
||||
page: '${page|default:undefined}',
|
||||
count: '${perPage|default:undefined}',
|
||||
order: '${orderBy|default:undefined}',
|
||||
direction: '${orderDir|default:undefined}',
|
||||
hdfs: '${hdfs|default:undefined}',
|
||||
filter_type: '${type|default:active}',
|
||||
filter_action: '${action|default:undefined}',
|
||||
filter_state: '${state|default:undefined}',
|
||||
},
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
perPage: 50,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
paginationCommonOptions(undefined, 10),
|
||||
],
|
||||
footerToolbar: [
|
||||
paginationCommonOptions(undefined, 10),
|
||||
],
|
||||
columns: timelineColumns(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'submit',
|
||||
label: '查询表结构',
|
||||
actionType: 'dialog',
|
||||
dialog: {
|
||||
title: 'Hudi 表结构',
|
||||
actions: [],
|
||||
size: 'lg',
|
||||
body: {
|
||||
type: 'service',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/hudi/schema`,
|
||||
data: {
|
||||
hdfs: '${hdfs|default:undefined}',
|
||||
},
|
||||
},
|
||||
body: {
|
||||
type: 'page',
|
||||
body: {
|
||||
type: 'json',
|
||||
source: '${detail}',
|
||||
levelExpand: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'hdfs',
|
||||
label: 'HDFS路经',
|
||||
required: true,
|
||||
clearable: true,
|
||||
description: '输入表HDFS路径',
|
||||
autoComplete: `${commonInfo.baseUrl}/table/all_hdfs?key=$term`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
title: '提交压缩任务',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/schedule/table`,
|
||||
data: {
|
||||
flink_job_id: '${flinkJobId|default:undefined}',
|
||||
alias: '${alias|default:undefined}',
|
||||
recommend: '${recommend === \'undefined\' ? undefined : recommend|default:undefined}',
|
||||
force: '${force === \'undefined\' ? undefined : force|default:undefined}',
|
||||
},
|
||||
},
|
||||
...formReloadFlinkJobIdTextInputAndAliasTextInput('0fe6a96c-6b6e-4346-b18e-c631c2389f48'),
|
||||
body: [
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
flinkJobIdTextInput('0fe6a96c-6b6e-4346-b18e-c631c2389f48', true),
|
||||
aliasTextInput('0fe6a96c-6b6e-4346-b18e-c631c2389f48', true),
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
name: 'recommend',
|
||||
type: 'radios',
|
||||
label: '优先指定集群',
|
||||
selectFirst: true,
|
||||
options: [
|
||||
{label: '无', value: 'undefined'},
|
||||
...Object.keys(commonInfo.clusters.compaction)
|
||||
.map(name => {
|
||||
return {label: name, value: name}
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'force',
|
||||
type: 'radios',
|
||||
label: '强制指定集群',
|
||||
selectFirst: true,
|
||||
options: [
|
||||
{label: '无', value: 'undefined'},
|
||||
...Object.keys(commonInfo.clusters.compaction)
|
||||
.map(name => {
|
||||
return {label: name, value: name}
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
title: '批量提交压缩任务',
|
||||
api: {
|
||||
method: 'post',
|
||||
url: `${commonInfo.baseUrl}/schedule/table_batch`,
|
||||
dataType: 'form',
|
||||
},
|
||||
body: [
|
||||
{
|
||||
name: 'lines',
|
||||
type: 'textarea',
|
||||
label: '表信息 (flink_job_id alias\\n)',
|
||||
clearable: true,
|
||||
minRows: 5,
|
||||
maxRows: 5,
|
||||
className: 'no-resize',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'form',
|
||||
title: '停止所有压缩任务',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/schedule/stop_all`,
|
||||
data: {
|
||||
flink_job_id: '${flinkJobId|default:undefined}',
|
||||
alias: '${alias|default:undefined}',
|
||||
disable_meta: '${disableMeta|default:undefined}',
|
||||
},
|
||||
},
|
||||
...formReloadFlinkJobIdTextInputAndAliasTextInput('163e043e-8cee-41fd-b5a4-0442ac682aec'),
|
||||
body: [
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
...flinkJobIdTextInput('163e043e-8cee-41fd-b5a4-0442ac682aec', true),
|
||||
columnRatio: 5,
|
||||
},
|
||||
{
|
||||
...aliasTextInput('163e043e-8cee-41fd-b5a4-0442ac682aec', true),
|
||||
columnRatio: 5,
|
||||
},
|
||||
{
|
||||
name: 'disableMeta',
|
||||
type: 'checkbox',
|
||||
label: '是否禁用表',
|
||||
option: '表status设为n',
|
||||
columnRatio: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Tool
|
||||
185
service-web/client/src/pages/overview/Version.tsx
Normal file
185
service-web/client/src/pages/overview/Version.tsx
Normal file
@@ -0,0 +1,185 @@
|
||||
import {
|
||||
aliasTextInput,
|
||||
amisRender,
|
||||
commonInfo,
|
||||
crudCommonOptions,
|
||||
filterableField,
|
||||
flinkJobDialog,
|
||||
flinkJobIdTextInput,
|
||||
mappingField,
|
||||
paginationCommonOptions,
|
||||
tableMetaDialog,
|
||||
versionUpdateStateMapping,
|
||||
} from '../../util/amis.ts'
|
||||
|
||||
function Version() {
|
||||
return (
|
||||
<div className="hudi-version">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
body: [
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/version_update/list`,
|
||||
data: {
|
||||
page: '${page|default:undefined}',
|
||||
count: '${perPage|default:undefined}',
|
||||
order: '${orderBy|default:undefined}',
|
||||
direction: '${orderDir|default:undefined}',
|
||||
search_flink_job_id: '${flinkJobId|default:undefined}',
|
||||
search_alias: '${alias|default:undefined}',
|
||||
search_version: '${version|default:undefined}',
|
||||
filter_schedules: '${updated|default:undefined}',
|
||||
},
|
||||
},
|
||||
data: {
|
||||
now: '${DATETOSTR(DATEMODIFY(NOW(), -1, \'days\'), \'YYYYMMDD\')}',
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
interval: 10000,
|
||||
filter: {
|
||||
mode: 'inline',
|
||||
title: '表筛选',
|
||||
body: [
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
...flinkJobIdTextInput('c5cac9d3-844a-4d86-b2c5-0c10f2283667'),
|
||||
size: 'md',
|
||||
},
|
||||
{
|
||||
...aliasTextInput('c5cac9d3-844a-4d86-b2c5-0c10f2283667'),
|
||||
size: 'md',
|
||||
},
|
||||
{
|
||||
type: 'input-date',
|
||||
name: 'version',
|
||||
label: '版本',
|
||||
clearable: true,
|
||||
placeholder: '通过版本搜索',
|
||||
size: 'md',
|
||||
format: 'YYYYMMDD',
|
||||
inputFormat: 'YYYYMMDD',
|
||||
value: '${now}',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
level: 'primary',
|
||||
label: '查询',
|
||||
},
|
||||
{
|
||||
type: 'reset',
|
||||
label: '重置',
|
||||
},
|
||||
],
|
||||
},
|
||||
filterTogglable: true,
|
||||
filterDefaultVisible: true,
|
||||
perPage: 20,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
'filter-toggler',
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '共 <span class=\'text-primary font-bold\'>${total|default:0}</span> 个表,其中 <span class=\'text-success font-bold\'>${scheduled|default:0}</span> 个表已跨天,<span class=\'text-danger font-bold\'>${unScheduled|default:0}</span> 个表未跨天',
|
||||
},
|
||||
paginationCommonOptions(),
|
||||
],
|
||||
footerToolbar: [
|
||||
paginationCommonOptions(),
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
label: 'Flink job id',
|
||||
width: 195,
|
||||
fixed: 'left',
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
body: [
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '${flinkJobId}',
|
||||
size: 'xs',
|
||||
actionType: 'dialog',
|
||||
tooltip: '查看详情',
|
||||
dialog: flinkJobDialog(),
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '',
|
||||
icon: 'fa fa-copy',
|
||||
size: 'xs',
|
||||
actionType: 'copy',
|
||||
content: '${flinkJobId}',
|
||||
tooltip: '复制 ID',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '别名',
|
||||
type: 'wrapper',
|
||||
fixed: 'left',
|
||||
size: 'none',
|
||||
className: 'nowrap',
|
||||
body: [
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '${tableMeta.alias}',
|
||||
size: 'xs',
|
||||
actionType: 'dialog',
|
||||
tooltip: '查看详情',
|
||||
dialog: tableMetaDialog(),
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '',
|
||||
icon: 'fa fa-copy',
|
||||
size: 'xs',
|
||||
actionType: 'copy',
|
||||
content: '${tableMeta.alias}',
|
||||
tooltip: '复制别名',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'priority',
|
||||
label: '表优先级',
|
||||
align: 'center',
|
||||
width: 75,
|
||||
sortable: true,
|
||||
}, {
|
||||
name: 'version',
|
||||
label: '版本',
|
||||
align: 'center',
|
||||
width: 75,
|
||||
},
|
||||
{
|
||||
name: 'updated',
|
||||
label: '状态',
|
||||
align: 'center',
|
||||
...mappingField('updated', versionUpdateStateMapping),
|
||||
filterable: filterableField(versionUpdateStateMapping, true),
|
||||
width: 70,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Version
|
||||
123
service-web/client/src/pages/overview/Yarn.tsx
Normal file
123
service-web/client/src/pages/overview/Yarn.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import React from 'react'
|
||||
import {useLocation, useParams} from 'react-router'
|
||||
import {
|
||||
amisRender,
|
||||
commonInfo,
|
||||
crudCommonOptions,
|
||||
paginationCommonOptions,
|
||||
yarnCrudColumns,
|
||||
yarnQueueCrud,
|
||||
} from '../../util/amis.ts'
|
||||
|
||||
const Yarn: React.FC = () => {
|
||||
const {clusters, queue, search} = useParams()
|
||||
const location = useLocation()
|
||||
return (
|
||||
<div key={location.key} className="hudi-yarn bg-white">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
body: [
|
||||
{
|
||||
id: `${clusters}-yarn-service`,
|
||||
name: `${clusters}-yarn-service`,
|
||||
type: 'service',
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '<span class="font-bold text-xl">集群资源</span>',
|
||||
},
|
||||
yarnQueueCrud(clusters, queue),
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '<span class="font-bold text-xl">集群任务</span>',
|
||||
// className: 'mb-2 block',
|
||||
},
|
||||
{
|
||||
type: 'crud',
|
||||
api: {
|
||||
method: 'get',
|
||||
url: `${commonInfo.baseUrl}/yarn/job_list`,
|
||||
data: {
|
||||
clusters: `${clusters}`,
|
||||
page: '${page|default:undefined}',
|
||||
count: '${perPage|default:undefined}',
|
||||
order: '${orderBy|default:undefined}',
|
||||
direction: '${orderDir|default:undefined}',
|
||||
filter_state: '${state|default:undefined}',
|
||||
filter_final_status: '${finalStatus|default:undefined}',
|
||||
search_id: '${id|default:undefined}',
|
||||
search_name: '${name|default:undefined}',
|
||||
completion: 'true',
|
||||
},
|
||||
},
|
||||
defaultParams: {
|
||||
name: search,
|
||||
},
|
||||
...crudCommonOptions(),
|
||||
interval: 10000,
|
||||
filter: {
|
||||
mode: 'inline',
|
||||
title: '任务筛选',
|
||||
body: [
|
||||
{
|
||||
type: 'group',
|
||||
body: [
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'id',
|
||||
label: 'ID',
|
||||
clearable: true,
|
||||
placeholder: '通过 ID 搜索',
|
||||
size: 'md',
|
||||
},
|
||||
{
|
||||
type: 'input-text',
|
||||
name: 'name',
|
||||
label: '名称',
|
||||
clearable: true,
|
||||
placeholder: '通过名称搜索',
|
||||
size: 'md',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'submit',
|
||||
level: 'primary',
|
||||
label: '查询',
|
||||
},
|
||||
{
|
||||
type: 'reset',
|
||||
label: '重置',
|
||||
},
|
||||
],
|
||||
},
|
||||
filterTogglable: true,
|
||||
filterDefaultVisible: false,
|
||||
perPage: 20,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
'filter-toggler',
|
||||
{
|
||||
type: 'tpl',
|
||||
tpl: '共 <span class=\'text-primary font-bold\'>${total|default:0}</span> 个任务,其中 <span class=\'text-success font-bold\'>${running|default:0}</span> 个任务运行中,<span class=\'text-danger font-bold\'>${unRunning|default:0}</span> 个任务处于非运行状态',
|
||||
},
|
||||
paginationCommonOptions(),
|
||||
],
|
||||
footerToolbar: [
|
||||
paginationCommonOptions(),
|
||||
],
|
||||
columns: yarnCrudColumns(),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Yarn
|
||||
19
service-web/client/src/pages/overview/YarnCluster.tsx
Normal file
19
service-web/client/src/pages/overview/YarnCluster.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react'
|
||||
import {amisRender, commonInfo, yarnQueueCrud} from '../../util/amis.ts'
|
||||
|
||||
const YarnCluster: React.FC = () => {
|
||||
return (
|
||||
<div className="hudi-yarn-cluster bg-white">
|
||||
{amisRender(
|
||||
{
|
||||
type: 'wrapper',
|
||||
body: [
|
||||
...Object.keys(commonInfo.clusters.compaction).map(name => yarnQueueCrud(name)),
|
||||
],
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default YarnCluster
|
||||
Reference in New Issue
Block a user