diff --git a/dinky-admin/src/main/java/org/dinky/controller/HistoryController.java b/dinky-admin/src/main/java/org/dinky/controller/HistoryController.java index a75359e3a7..3871670415 100644 --- a/dinky-admin/src/main/java/org/dinky/controller/HistoryController.java +++ b/dinky-admin/src/main/java/org/dinky/controller/HistoryController.java @@ -59,7 +59,7 @@ public class HistoryController { * @param para * @return */ - @PostMapping + @PostMapping("/list") @ApiOperation("Query History List") @ApiImplicitParam(name = "para", value = "Query Parameters", dataType = "JsonNode", paramType = "body") public ProTableResult listHistory(@RequestBody JsonNode para) { diff --git a/dinky-admin/src/main/java/org/dinky/data/model/ext/JobAlertData.java b/dinky-admin/src/main/java/org/dinky/data/model/ext/JobAlertData.java index 706a92c2c1..bc3ba5a980 100644 --- a/dinky-admin/src/main/java/org/dinky/data/model/ext/JobAlertData.java +++ b/dinky-admin/src/main/java/org/dinky/data/model/ext/JobAlertData.java @@ -29,7 +29,6 @@ import org.dinky.data.model.job.JobInstance; import org.dinky.data.options.JobAlertRuleOptions; import org.dinky.job.JobConfig; -import org.dinky.utils.JsonUtils; import org.dinky.utils.TimeUtil; import com.fasterxml.jackson.annotation.JsonProperty; @@ -150,7 +149,7 @@ public static JobAlertData buildData(JobInfoDetail jobInfoDetail) { builder.alertTime(TimeUtil.nowStr()); JobDataDto jobDataDto = jobInfoDetail.getJobDataDto(); - JobConfig job = JsonUtils.parseObject(jobInfoDetail.getHistory().getConfigJson(), JobConfig.class); + JobConfig job = jobInfoDetail.getHistory().getConfigJson(); ClusterInstance clusterInstance = jobInfoDetail.getClusterInstance(); CheckPointOverView checkpoints = jobDataDto.getCheckpoints(); FlinkJobExceptionsDetail exceptions = jobDataDto.getExceptions(); diff --git a/dinky-admin/src/main/java/org/dinky/data/model/job/History.java b/dinky-admin/src/main/java/org/dinky/data/model/job/History.java index 81758efe86..c593ce489e 100644 --- a/dinky-admin/src/main/java/org/dinky/data/model/job/History.java +++ b/dinky-admin/src/main/java/org/dinky/data/model/job/History.java @@ -19,13 +19,20 @@ package org.dinky.data.model.job; +import org.dinky.data.typehandler.JSONObjectHandler; +import org.dinky.job.JobConfig; + import java.io.Serializable; import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.FieldStrategy; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; -import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -84,17 +91,20 @@ public class History implements Serializable { @ApiModelProperty(value = "Result", dataType = "String") private String result; - @TableField(exist = false) - @ApiModelProperty(hidden = true) - private ObjectNode config; - @ApiModelProperty(value = "JSON Configuration", dataType = "String") - private String configJson; + @TableField(typeHandler = JSONObjectHandler.class) + private JobConfig configJson; @ApiModelProperty(value = "Start Time", dataType = "LocalDateTime") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime startTime; @ApiModelProperty(value = "End Time", dataType = "LocalDateTime") + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime endTime; @ApiModelProperty(value = "Task ID", dataType = "Integer") diff --git a/dinky-admin/src/main/java/org/dinky/data/typehandler/JSONObjectHandler.java b/dinky-admin/src/main/java/org/dinky/data/typehandler/JSONObjectHandler.java index 2d0f48a912..097a705db2 100644 --- a/dinky-admin/src/main/java/org/dinky/data/typehandler/JSONObjectHandler.java +++ b/dinky-admin/src/main/java/org/dinky/data/typehandler/JSONObjectHandler.java @@ -28,6 +28,7 @@ import org.dinky.data.model.mapping.ClusterConfigurationMapping; import org.dinky.data.model.mapping.ClusterInstanceMapping; import org.dinky.gateway.model.FlinkClusterConfig; +import org.dinky.job.JobConfig; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; @@ -49,7 +50,8 @@ ClusterInstanceMapping.class, ClusterConfigurationMapping.class, FlinkClusterConfig.class, - TaskExtConfig.class + TaskExtConfig.class, + JobConfig.class }) public class JSONObjectHandler extends AbstractJsonTypeHandler { diff --git a/dinky-admin/src/main/java/org/dinky/job/handler/Job2MysqlHandler.java b/dinky-admin/src/main/java/org/dinky/job/handler/Job2MysqlHandler.java index f29c704df1..789f9144f2 100644 --- a/dinky-admin/src/main/java/org/dinky/job/handler/Job2MysqlHandler.java +++ b/dinky-admin/src/main/java/org/dinky/job/handler/Job2MysqlHandler.java @@ -44,7 +44,6 @@ import org.dinky.service.JobHistoryService; import org.dinky.service.JobInstanceService; import org.dinky.service.TaskService; -import org.dinky.utils.JsonUtils; import java.time.LocalDateTime; @@ -87,12 +86,11 @@ public boolean init() { } history.setJobManagerAddress(job.getJobManagerAddress()); history.setJobName(job.getJobConfig().getJobName()); - history.setSession(job.getJobConfig().getSession()); history.setStatus(job.getStatus().ordinal()); history.setStatement(job.getStatement()); history.setStartTime(job.getStartTime()); history.setTaskId(job.getJobConfig().getTaskId()); - history.setConfigJson(JsonUtils.toJsonString(job.getJobConfig())); + history.setConfigJson(job.getJobConfig()); historyService.save(history); job.setId(history.getId()); diff --git a/dinky-admin/src/main/java/org/dinky/service/HistoryService.java b/dinky-admin/src/main/java/org/dinky/service/HistoryService.java index e7d23a8298..a6ae97ff6f 100644 --- a/dinky-admin/src/main/java/org/dinky/service/HistoryService.java +++ b/dinky-admin/src/main/java/org/dinky/service/HistoryService.java @@ -29,15 +29,6 @@ */ public interface HistoryService extends ISuperService { - /** - * Remove the history of a Git project based on its ID. - * - * @param id The ID of the Git project to remove the history for. - * @return A boolean value indicating whether the removal was successful. - */ - @Deprecated - boolean removeHistoryById(Integer id); - /** * Get latest history info by task id. * diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/HistoryServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/HistoryServiceImpl.java index c87ad1b42b..d4eec4b061 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/HistoryServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/HistoryServiceImpl.java @@ -20,14 +20,15 @@ package org.dinky.service.impl; import org.dinky.data.model.job.History; -import org.dinky.data.result.ResultPool; import org.dinky.mapper.HistoryMapper; import org.dinky.mybatis.service.impl.SuperServiceImpl; import org.dinky.service.HistoryService; import org.springframework.stereotype.Service; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; + +import lombok.RequiredArgsConstructor; /** * HistoryServiceImpl @@ -35,22 +36,13 @@ * @since 2021/6/26 23:08 */ @Service +@RequiredArgsConstructor public class HistoryServiceImpl extends SuperServiceImpl implements HistoryService { - - @Override - public boolean removeHistoryById(Integer id) { - History history = getById(id); - if (history != null) { - ResultPool.remove(history.getJobId()); - } - return removeById(id); - } - @Override public History getLatestHistoryById(Integer id) { - return baseMapper.selectOne(new QueryWrapper() - .eq("task_id", id) - .orderByDesc("start_time") + return baseMapper.selectOne(new LambdaQueryWrapper<>(History.class) + .eq(History::getTaskId, id) + .orderByDesc(History::getStartTime) .last("limit 1")); } } diff --git a/dinky-admin/src/main/java/org/dinky/service/impl/JobInstanceServiceImpl.java b/dinky-admin/src/main/java/org/dinky/service/impl/JobInstanceServiceImpl.java index 8ae38f837d..d4ac0998df 100644 --- a/dinky-admin/src/main/java/org/dinky/service/impl/JobInstanceServiceImpl.java +++ b/dinky-admin/src/main/java/org/dinky/service/impl/JobInstanceServiceImpl.java @@ -50,7 +50,6 @@ import org.dinky.service.JobHistoryService; import org.dinky.service.JobInstanceService; import org.dinky.service.MonitorService; -import org.dinky.utils.JsonUtils; import java.util.List; import java.util.Map; @@ -164,7 +163,7 @@ public JobInfoDetail getJobInfoDetailInfo(JobInstance jobInstance) { jobInfoDetail.setClusterInstance(clusterInstance); History history = historyService.getById(jobInstance.getHistoryId()); - history.setConfig(JsonUtils.parseObject(history.getConfigJson())); + history.setConfigJson(history.getConfigJson()); jobInfoDetail.setHistory(history); if (Asserts.isNotNull(history.getClusterConfigurationId())) { ClusterConfiguration clusterConfig = diff --git a/dinky-admin/src/main/resources/mapper/HistoryMapper.xml b/dinky-admin/src/main/resources/mapper/HistoryMapper.xml index 01839b38f6..758f469231 100644 --- a/dinky-admin/src/main/resources/mapper/HistoryMapper.xml +++ b/dinky-admin/src/main/resources/mapper/HistoryMapper.xml @@ -10,7 +10,7 @@ from dinky_history a - 1=1 + 1=1 and a.task_id = #{param.taskId} and a.job_id = #{param.jobId} @@ -20,9 +20,6 @@ and a.cluster_id = #{param.clusterId} - - and a.session = #{param.session} - and a.status = #{param.status} diff --git a/dinky-core/src/main/java/org/dinky/job/JobConfig.java b/dinky-core/src/main/java/org/dinky/job/JobConfig.java index 565b12420a..7e4ed4b726 100644 --- a/dinky-core/src/main/java/org/dinky/job/JobConfig.java +++ b/dinky-core/src/main/java/org/dinky/job/JobConfig.java @@ -111,13 +111,6 @@ public class JobConfig { notes = "Flag indicating whether to use auto-cancel") private boolean useAutoCancel; - @ApiModelProperty( - value = "Session information", - dataType = "String", - example = "session-123", - notes = "Session information") - private String session; - @ApiModelProperty( value = "Flag indicating whether to use remote execution", dataType = "boolean", diff --git a/dinky-core/src/test/java/org/dinky/core/JobManagerTest.java b/dinky-core/src/test/java/org/dinky/core/JobManagerTest.java index 45e961ca1a..484756b00a 100644 --- a/dinky-core/src/test/java/org/dinky/core/JobManagerTest.java +++ b/dinky-core/src/test/java/org/dinky/core/JobManagerTest.java @@ -49,7 +49,6 @@ public void cancelJobSelect() throws Exception { .useResult(true) .useChangeLog(true) .useAutoCancel(true) - .session("s1") .clusterId(2) .jobName("Test") .fragment(false) diff --git a/dinky-web/src/components/CustomEditor/CodeShow/index.tsx b/dinky-web/src/components/CustomEditor/CodeShow/index.tsx index 8a7a916972..3cc767f018 100644 --- a/dinky-web/src/components/CustomEditor/CodeShow/index.tsx +++ b/dinky-web/src/components/CustomEditor/CodeShow/index.tsx @@ -29,7 +29,7 @@ import { EditorLanguage } from 'monaco-editor/esm/metadata'; import FullscreenBtn from '@/components/CustomEditor/FullscreenBtn'; import { Editor, Monaco } from '@monaco-editor/react'; -import { CSSProperties, memo, useRef, useState } from 'react'; +import { CSSProperties, useRef, useState } from 'react'; export type CodeShowFormProps = { height?: string | number; @@ -266,4 +266,4 @@ const CodeShow = (props: CodeShowFormProps) => { ); }; -export default memo(CodeShow); +export default CodeShow; diff --git a/dinky-web/src/components/CustomEditor/languages/constants.ts b/dinky-web/src/components/CustomEditor/languages/constants.ts index 0aa16cd47a..f84e17d6ae 100644 --- a/dinky-web/src/components/CustomEditor/languages/constants.ts +++ b/dinky-web/src/components/CustomEditor/languages/constants.ts @@ -51,3 +51,5 @@ export enum CustomEditorLanguage { JavaLog = 'javalog', FlinkSQL = 'flinksql' } + +// EditorLanguage diff --git a/dinky-web/src/components/CustomEditor/languages/flinksql/index.tsx b/dinky-web/src/components/CustomEditor/languages/flinksql/index.tsx index 4fe58de166..c4dd2aed07 100644 --- a/dinky-web/src/components/CustomEditor/languages/flinksql/index.tsx +++ b/dinky-web/src/components/CustomEditor/languages/flinksql/index.tsx @@ -30,6 +30,7 @@ export function FlinkSQLLanguage(monaco?: Monaco | undefined, registerCompletion monaco?.languages.register({ id: CustomEditorLanguage.FlinkSQL, extensions: ['.sql'], + mimetypes: ['text/x-flinksql', 'text/x-flinksql', 'text/x-flinksql', 'text/flinksql'], aliases: ['flinksql', 'fsql', 'flinkSQL', 'FlinkSQL'] }); buildMonarchTokensProvider(monaco); @@ -39,4 +40,15 @@ export function FlinkSQLLanguage(monaco?: Monaco | undefined, registerCompletion registerFlinkSQLCompilation(monaco); } buildFlinkSQLConfiguration(monaco); + + monaco?.languages.onLanguageEncountered(CustomEditorLanguage.FlinkSQL, () => { + monaco?.editor?.getModels().forEach((model) => { + model.onDidChangeLanguage(() => { + if (model.getLanguageId() === CustomEditorLanguage.FlinkSQL) { + buildFlinkSQLConfiguration(monaco); + } + }); + }); + buildMonarchTokensProvider(monaco); + }); } diff --git a/dinky-web/src/components/CustomEditor/languages/index.tsx b/dinky-web/src/components/CustomEditor/languages/index.tsx index 86fc4fea24..c449ea5c85 100644 --- a/dinky-web/src/components/CustomEditor/languages/index.tsx +++ b/dinky-web/src/components/CustomEditor/languages/index.tsx @@ -44,7 +44,6 @@ export function LoadCustomEditorLanguage( if (canLoadLanguage(monaco, CustomEditorLanguage.FlinkSQL)) { FlinkSQLLanguage(monaco, registerCompletion); } - console.log(canLoadLanguage(monaco, CustomEditorLanguage.JavaLog)); if (canLoadLanguage(monaco, CustomEditorLanguage.JavaLog)) { LogLanguage(monaco); } diff --git a/dinky-web/src/components/CustomEditor/languages/javalog/index.tsx b/dinky-web/src/components/CustomEditor/languages/javalog/index.tsx index 791c505fde..f37e30e04e 100644 --- a/dinky-web/src/components/CustomEditor/languages/javalog/index.tsx +++ b/dinky-web/src/components/CustomEditor/languages/javalog/index.tsx @@ -25,7 +25,14 @@ export function LogLanguage(monaco: Monaco | undefined) { // Register a new language monaco?.languages.register({ id: CustomEditorLanguage.JavaLog, - extensions: ['.log'], + extensions: [], + mimetypes: [ + 'text/x-java-log', + 'text/x-javalog', + 'text/x-java-source', + 'text/x-java', + 'text/java' + ], aliases: ['javalog', 'Javalog', 'jl', 'log'] }); diff --git a/dinky-web/src/locales/en-US/global.ts b/dinky-web/src/locales/en-US/global.ts index c9e913ae35..87de687ae8 100644 --- a/dinky-web/src/locales/en-US/global.ts +++ b/dinky-web/src/locales/en-US/global.ts @@ -210,5 +210,22 @@ export default { 'global.month.september': 'September', 'global.month.october': 'October', 'global.month.november': 'November', - 'global.month.december': 'December' + 'global.month.december': 'December', + + // job status + 'global.job.status.initiating': 'Initializing', + 'global.job.status.success': 'Success', + 'global.job.status.created': 'Created', + 'global.job.status.running': 'Running', + 'global.job.status.failing': 'Failing', + 'global.job.status.failed': 'Failed', + 'global.job.status.cancelling': 'Cancelling', + 'global.job.status.canceled': 'Canceled', + 'global.job.status.finished': 'Finished', + 'global.job.status.restarting': 'Restarting', + 'global.job.status.suspended': 'Suspended', + 'global.job.status.reconciling': 'Reconciling', + 'global.job.status.reconnecting': 'Reconnecting', + 'global.job.status.unknown': 'Unknown', + 'global.job.status.failed-tip': 'Failed to submit to the cluster, unable to get the task name' }; diff --git a/dinky-web/src/locales/en-US/menu.ts b/dinky-web/src/locales/en-US/menu.ts index 18243136a0..fff68769fe 100644 --- a/dinky-web/src/locales/en-US/menu.ts +++ b/dinky-web/src/locales/en-US/menu.ts @@ -94,7 +94,7 @@ export default { 'menu.datastudio.bi': 'BI', 'menu.datastudio.lineage': 'Lineage', 'menu.datastudio.process': 'Process', - 'menu.datastudio.history': 'History', + 'menu.datastudio.history': 'Execution History', 'menu.datastudio.table-data': 'Table Data', 'menu.datastudio.tool.text-comparison': 'Text Comparison', diff --git a/dinky-web/src/locales/en-US/pages.ts b/dinky-web/src/locales/en-US/pages.ts index 42dab6edae..5d075f63e4 100644 --- a/dinky-web/src/locales/en-US/pages.ts +++ b/dinky-web/src/locales/en-US/pages.ts @@ -432,6 +432,34 @@ export default { 'pages.datastudio.catalog.fieldInformation': 'Field Information', 'pages.datastudio.catalog.selectDatasource': 'Select Datasource', 'pages.datastudio.catalog.openMission': 'Open Mission', + + 'pages.datastudio.label.history.title': 'Job:【{name}】Execution History', + 'pages.datastudio.label.history.noData': 'Please click the job to view the job execution history', + 'pages.datastudio.label.history.execConfig': 'Execution Configuration', + 'pages.datastudio.label.history.statement': 'Execution Statement', + 'pages.datastudio.label.history.result': 'PreView Data', + 'pages.datastudio.label.history.error': 'View Error Log', + 'pages.datastudio.label.history.notSuccess': + 'The Job has not been successfully executed. It cannot be Preview data.', + 'pages.datastudio.label.history.clusterConfigId': 'Cluster Config ID', + 'pages.datastudio.label.history.clusterId': 'Cluster Instance ID', + 'pages.datastudio.label.history.taskType': 'Job Execution Mode', + 'pages.datastudio.label.history.clusterName': 'Cluster Name', + 'pages.datastudio.label.history.changelog': 'ChangeLog', + 'pages.datastudio.label.history.maxRows': 'Max Rows', + 'pages.datastudio.label.history.autoStop': 'Auto Stop', + 'pages.datastudio.label.history.jobId': 'Job ID', + 'pages.datastudio.label.history.jobName': 'Job Name', + 'pages.datastudio.label.history.fragment': 'Global Variables', + 'pages.datastudio.label.history.statementSet': 'StatementSet', + 'pages.datastudio.label.history.parallelism': 'Parallelism', + 'pages.datastudio.label.history.checkpoint': 'Checkpoint Interval', + 'pages.datastudio.label.history.savePointStrategy': 'SavePoint Strategy', + 'pages.datastudio.label.history.savePointPath': 'SavePoint Path', + 'pages.datastudio.label.history.clusterType': 'Cluster Type', + 'pages.datastudio.label.history.clusterInstance': 'Cluster Instance', + 'pages.datastudio.label.history.clusterConfig': 'Cluster Config', + 'pages.datastudio.label.history.local': 'Local (Built-in MiniCluster)', /** * * rc diff --git a/dinky-web/src/locales/zh-CN/global.ts b/dinky-web/src/locales/zh-CN/global.ts index 8aded36ae3..cb6b9eca91 100644 --- a/dinky-web/src/locales/zh-CN/global.ts +++ b/dinky-web/src/locales/zh-CN/global.ts @@ -206,5 +206,22 @@ export default { 'global.month.september': '九月', 'global.month.october': '十月', 'global.month.november': '十一月', - 'global.month.december': '十二月' + 'global.month.december': '十二月', + + // job status + 'global.job.status.initiating': '初始化', + 'global.job.status.success': '成功', + 'global.job.status.created': '已创建', + 'global.job.status.running': '运行中', + 'global.job.status.failing': '失败中', + 'global.job.status.failed': '已失败', + 'global.job.status.cancelling': '取消中', + 'global.job.status.canceled': '已取消', + 'global.job.status.finished': '已完成', + 'global.job.status.restarting': '重启中', + 'global.job.status.suspended': '已挂起', + 'global.job.status.reconciling': '调节中', + 'global.job.status.reconnecting': '重连中', + 'global.job.status.unknown': '未知', + 'global.job.status.failed-tip': '未成功提交到集群,无法获取任务名称/作业ID' }; diff --git a/dinky-web/src/locales/zh-CN/menu.ts b/dinky-web/src/locales/zh-CN/menu.ts index 0d994ac8ae..5885f64f18 100644 --- a/dinky-web/src/locales/zh-CN/menu.ts +++ b/dinky-web/src/locales/zh-CN/menu.ts @@ -93,7 +93,7 @@ export default { 'menu.datastudio.bi': 'BI', 'menu.datastudio.lineage': '血缘', 'menu.datastudio.process': '进程', - 'menu.datastudio.history': '历史', + 'menu.datastudio.history': '执行历史', 'menu.datastudio.table-data': '表数据', 'menu.datastudio.tool.text-comparison': '文本比对', diff --git a/dinky-web/src/locales/zh-CN/pages.ts b/dinky-web/src/locales/zh-CN/pages.ts index 2d94949100..e2fa62d4db 100644 --- a/dinky-web/src/locales/zh-CN/pages.ts +++ b/dinky-web/src/locales/zh-CN/pages.ts @@ -416,6 +416,34 @@ export default { 'pages.metadata.DataSearch': '数据查询', 'pages.metadata.selectDatabase': '选择数据源', 'pages.task.savePointPath': '保存点路径', + + 'pages.datastudio.label.history.title': '任务:【{name}】执行历史记录', + 'pages.datastudio.label.history.noData': '请点击作业,查看作业的执行历史记录', + 'pages.datastudio.label.history.execConfig': '执行配置', + 'pages.datastudio.label.history.statement': '执行语句', + 'pages.datastudio.label.history.result': '预览数据', + 'pages.datastudio.label.history.error': '查看错误日志', + 'pages.datastudio.label.history.notSuccess': '该任务未成功执行,无法预览数据', + 'pages.datastudio.label.history.clusterConfigId': '集群配置ID', + 'pages.datastudio.label.history.clusterId': '集群实例ID', + 'pages.datastudio.label.history.taskType': '任务执行模式', + 'pages.datastudio.label.history.clusterName': '集群名称', + 'pages.datastudio.label.history.changelog': '打印流', + 'pages.datastudio.label.history.maxRows': '最大行数', + 'pages.datastudio.label.history.autoStop': '自动停止', + 'pages.datastudio.label.history.jobId': '任务ID', + 'pages.datastudio.label.history.jobName': '任务名称', + 'pages.datastudio.label.history.fragment': '全局变量', + 'pages.datastudio.label.history.statementSet': '语句集', + 'pages.datastudio.label.history.parallelism': '并行度', + 'pages.datastudio.label.history.checkpoint': 'Checkpoint间隔', + 'pages.datastudio.label.history.savePointStrategy': 'SavePoint策略', + 'pages.datastudio.label.history.savePointPath': 'SavePoint路径', + 'pages.datastudio.label.history.clusterType': '集群类型', + 'pages.datastudio.label.history.clusterInstance': '集群实例', + 'pages.datastudio.label.history.clusterConfig': '集群配置', + 'pages.datastudio.label.history.local': '本地(内置 MiniCluster)', + /** * * rc diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/ErrorMsgInfo.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/ErrorMsgInfo.tsx new file mode 100644 index 0000000000..298cea114d --- /dev/null +++ b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/ErrorMsgInfo.tsx @@ -0,0 +1,59 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import CodeShow from '@/components/CustomEditor/CodeShow'; +import { CustomEditorLanguage } from '@/components/CustomEditor/languages/constants'; +import { JobExecutionHistory } from '@/types/Studio/data'; +import { l } from '@/utils/intl'; +import { FireOutlined } from '@ant-design/icons'; +import ProDescriptions from '@ant-design/pro-descriptions'; +import { Tag } from 'antd'; +import React from 'react'; + +type ErrorMsgInfoProps = { + row: JobExecutionHistory | undefined; +}; + +export const ErrorMsgInfo: React.FC = (props) => { + const { row } = props; + + return ( + <> + + + + {row?.jobName ?? l('global.job.status.failed-tip')} + + + + + {row?.jobId ?? l('global.job.status.failed-tip')} + + + + + + ); +}; diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/JobConfigInfo.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/JobConfigInfo.tsx new file mode 100644 index 0000000000..4a4e447d3f --- /dev/null +++ b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/JobConfigInfo.tsx @@ -0,0 +1,119 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { JobExecutionHistory } from '@/types/Studio/data'; +import { l } from '@/utils/intl'; +import { FireOutlined } from '@ant-design/icons'; +import ProDescriptions from '@ant-design/pro-descriptions'; + +import { Tag } from 'antd'; +import React from 'react'; + +type JobDetailInfoModelProps = { + row: JobExecutionHistory | undefined; +}; + +export const JobConfigInfo: React.FC = (props) => { + const { row } = props; + + return ( + <> + + + + {row?.jobId} + + + + {row?.configJson?.jobName} + + + {row?.configJson?.useRemote + ? l('global.table.runmode.remote') + : l('global.table.runmode.local')} + + + {row?.configJson?.type} + + + + {row?.clusterId + ? l('pages.datastudio.label.history.clusterInstance') + : row?.clusterConfigurationId + ? l('pages.datastudio.label.history.clusterConfig') + : l('pages.datastudio.label.history.local')} + + + + {row?.clusterId ? row?.clusterId : row?.clusterConfigurationId ?? 'None'} + + + + {row?.clusterName} + + + + {row?.configJson?.useChangeLog ? l('button.enable') : l('button.disable')} + + + {row?.configJson?.maxRowNum} + + + {row?.configJson?.useAutoCancel ? l('button.enable') : l('button.disable')} + + + {row?.jobManagerAddress} + + + {row?.configJson?.taskId} + + + + {row?.configJson?.fragment ? l('button.enable') : l('button.disable')} + + + {row?.configJson?.statementSet ? l('button.enable') : l('button.disable')} + + + {row?.configJson?.parallelism} + + + {row?.configJson?.checkpoint} + + + {row?.configJson?.savepointStrategy} + + + {row?.configJson?.savePointPath} + + + + ); +}; diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/PreViewData.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/PreViewData.tsx new file mode 100644 index 0000000000..9d8ac53408 --- /dev/null +++ b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/PreViewData.tsx @@ -0,0 +1,49 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { JobExecutionHistory } from '@/types/Studio/data'; +import { l } from '@/utils/intl'; +import { FireOutlined } from '@ant-design/icons'; +import ProDescriptions from '@ant-design/pro-descriptions'; +import { Tag } from 'antd'; +import React from 'react'; + +type PreViewDataProps = { + row: JobExecutionHistory | undefined; +}; + +export const PreViewData: React.FC = (props) => { + const { row } = props; + + return ( + <> + + + + {row?.jobId ?? l('global.job.status.failed-tip')} + + + + {/*todo: 预览数据组件*/} + {/**/} + + + + ); +}; diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/StatementInfo.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/StatementInfo.tsx new file mode 100644 index 0000000000..ac4beabc55 --- /dev/null +++ b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/StatementInfo.tsx @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import CodeShow from '@/components/CustomEditor/CodeShow'; +import { CustomEditorLanguage } from '@/components/CustomEditor/languages/constants'; +import { JobExecutionHistory } from '@/types/Studio/data'; +import { l } from '@/utils/intl'; +import { FireOutlined } from '@ant-design/icons'; +import ProDescriptions from '@ant-design/pro-descriptions'; +import { Tag } from 'antd'; +import React from 'react'; + +type StatementInfoProps = { + row: JobExecutionHistory | undefined; +}; + +export const StatementInfo: React.FC = (props) => { + const { row } = props; + + console.log(row?.statement); + + return ( + <> + + + + {row?.jobName ?? l('global.job.status.failed-tip')} + + + + + {row?.jobId ?? l('global.job.status.failed-tip')} + + + + + + ); +}; diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/index.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/index.tsx new file mode 100644 index 0000000000..d0e2c83692 --- /dev/null +++ b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/index.tsx @@ -0,0 +1,61 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { ErrorMsgInfo } from '@/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/ErrorMsgInfo'; +import { JobConfigInfo } from '@/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/JobConfigInfo'; +import { PreViewData } from '@/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/PreViewData'; +import { StatementInfo } from '@/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel/StatementInfo'; +import { JobExecutionHistory } from '@/types/Studio/data'; +import { l } from '@/utils/intl'; +import { Modal } from 'antd'; +import React from 'react'; + +type JobDetailInfoModelProps = { + modalVisit: boolean; + handleCancel: () => void; + row: JobExecutionHistory | undefined; + type: number; +}; + +export const JobDetailInfoModel: React.FC = (props) => { + const { modalVisit, handleCancel, row, type } = props; + + return ( + <> + + {type == 1 && } + {type == 2 && } + {type == 3 && } + {type == 4 && } + + + ); +}; diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/index.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/index.tsx new file mode 100644 index 0000000000..fd6ff98c69 --- /dev/null +++ b/dinky-web/src/pages/DataStudio/BottomContainer/JobExecHistory/index.tsx @@ -0,0 +1,305 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { JobDetailInfoModel } from '@/pages/DataStudio/BottomContainer/JobExecHistory/components/JobDetailInfoModel'; +import { getCurrentTab } from '@/pages/DataStudio/function'; +import { DataStudioTabsItemType, StateType } from '@/pages/DataStudio/model'; +import { queryList } from '@/services/api'; +import { API_CONSTANTS } from '@/services/endpoints'; +import { JobExecutionHistory } from '@/types/Studio/data'; +import { formatDateToYYYYMMDDHHMMSS } from '@/utils/function'; +import { l } from '@/utils/intl'; +import { ErrorMessage } from '@/utils/messages'; +import { ClusterOutlined, FireOutlined, RocketOutlined } from '@ant-design/icons'; +import { ActionType, ProList } from '@ant-design/pro-components'; +import { ProListMetas } from '@ant-design/pro-list'; +import { useUpdateEffect } from 'ahooks'; +import { Badge, Divider, Empty, Space, Tag, Typography } from 'antd'; +import React, { useRef, useState } from 'react'; +import { connect } from 'umi'; + +const { Link, Paragraph, Text } = Typography; + +const JobExecHistory: React.FC = (props) => { + const { tabs } = props; + + const currentTab = getCurrentTab(tabs.panes, tabs.activeKey) as DataStudioTabsItemType; + + const refAction = useRef(); + + useUpdateEffect(() => { + refAction.current?.reload(); + }, [tabs.activeKey]); + + const [modalVisit, setModalVisit] = useState(false); + const [historyData, setHistoryData] = useState(); + const [type, setType] = useState(1); + const showDetail = (row: JobExecutionHistory, type: number) => { + setHistoryData(row); + setModalVisit(true); + setType(type); + if (type === 3) { + // todo: 实现预览数据逻辑并展示 + // showJobData(historyData.jobId,dispatch) + // const res = getJobData(historyData.jobId); + // res.then((resd) => { + // setResult(resd.datas); + // }); + } + }; + + const handleCancel = () => { + setModalVisit(false); + }; + + const renderMetaDescription = (item: JobExecutionHistory) => { + return ( + <> + + <> + + [{item.jobManagerAddress}] + + + {l('global.table.startTime')}:{formatDateToYYYYMMDDHHMMSS(item.startTime)} + + {l('global.table.finishTime')}:{formatDateToYYYYMMDDHHMMSS(item.endTime)} + + + + ); + }; + + const renderSubTitle = (item: JobExecutionHistory) => { + return ( + + {item.jobName ? ( + + {item.jobName} + + ) : ( + l('global.job.status.failed-tip') + )} + + {item.clusterName ? ( + + {item.clusterName} + + ) : ( + + {l('pages.devops.jobinfo.localenv')} + + )} + {item.type && ( + + {item.type} + + )} + {item.status == 2 ? ( + + + {l('global.job.status.success')} + + ) : item.status == 1 ? ( + + + {l('global.job.status.running')} + + ) : item.status == 3 ? ( + + + {l('global.job.status.failed')} + + ) : item.status == 4 ? ( + + + {l('global.job.status.canceled')} + + ) : item.status == 0 ? ( + + + {l('global.job.status.initiating')} + + ) : ( + + + {l('global.job.status.unknown')} + + )} + + ); + }; + + const renderActions = (item: JobExecutionHistory) => { + return [ + showDetail(item, 1)}> + {l('pages.datastudio.label.history.execConfig')} + , + showDetail(item, 2)}> + {l('pages.datastudio.label.history.statement')} + , + { + if (item.status != 2) { + await ErrorMessage(l('pages.datastudio.label.history.notSuccess')); + return; + } + showDetail(item, 3); + }} + > + {l('pages.datastudio.label.history.result')} + , + showDetail(item, 4)}> + {l('pages.datastudio.label.history.error')} + + ]; + }; + + const buildMetaInfo = (): ProListMetas => { + return { + title: { + dataIndex: 'jobId', + title: 'JobId', + render: (_, row) => { + return ( + + + {row.jobId ?? l('global.job.status.failed-tip')} + + + ); + } + }, + description: { + search: false, + render: (_, row) => renderMetaDescription(row) + }, + subTitle: { + render: (_, row) => renderSubTitle(row), + search: false + }, + actions: { + render: (text, row) => renderActions(row), + search: false + }, + jobName: { + dataIndex: 'jobName', + // title: l('pages.datastudio.label.history.jobName'), + title: 'JobName' + }, + clusterId: { + dataIndex: 'clusterId', + // title: l('pages.datastudio.label.history.runningCluster'), + title: 'ClusterId' + }, + status: { + // 自己扩展的字段,主要用于筛选,不在列表中显示 + title: l('global.table.status'), + valueType: 'select', + valueEnum: { + '': { text: '全部', status: 'ALL' }, + 0: { + text: '初始化中', + status: 'INITIALIZE' + }, + 1: { + text: '运行中', + status: 'RUNNING' + }, + 2: { + text: '成功', + status: 'SUCCESS' + }, + 3: { + text: '失败', + status: 'FAILED' + }, + 4: { + text: '取消', + status: 'CANCEL' + } + } + }, + startTime: { + dataIndex: 'startTime', + title: l('global.table.startTime'), + valueType: 'dateTimeRange' + }, + endTime: { + dataIndex: 'endTime', + title: l('global.table.finishTime'), + valueType: 'dateTimeRange' + } + }; + }; + + console.log(currentTab); + + return ( + <> + {tabs.panes.length === 0 ? ( + + ) : ( + + actionRef={refAction} + search={{ + filterType: 'light' + }} + size={'small'} + rowKey='id' + params={{ taskId: currentTab?.task?.id }} + dateFormatter={'string'} + headerTitle={l('pages.datastudio.label.history.title', '', { name: currentTab?.label })} + request={(params, sorter, filter: any) => + queryList(API_CONSTANTS.HISTORY_LIST, { + ...{ ...params, taskId: currentTab?.params?.taskId }, + sorter: { id: 'descend' }, + filter + }) + } + pagination={{ + defaultPageSize: 5, + showSizeChanger: true + }} + metas={buildMetaInfo()} + options={{ + search: false, + setting: false, + density: false + }} + /> + )} + + + + ); +}; + +export default connect(({ Studio }: { Studio: StateType }) => ({ + tabs: Studio.tabs +}))(JobExecHistory); diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/Tools/TextComparison/index.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/Tools/TextComparison/index.tsx new file mode 100644 index 0000000000..b8d9a32fc4 --- /dev/null +++ b/dinky-web/src/pages/DataStudio/BottomContainer/Tools/TextComparison/index.tsx @@ -0,0 +1,48 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { convertCodeEditTheme } from '@/utils/function'; +import { DiffEditor } from '@monaco-editor/react'; + +const TextComparison = () => { + return ( + + ); +}; + +export default TextComparison; diff --git a/dinky-web/src/pages/DataStudio/route.tsx b/dinky-web/src/pages/DataStudio/route.tsx index 631beadad5..2805b2488a 100644 --- a/dinky-web/src/pages/DataStudio/route.tsx +++ b/dinky-web/src/pages/DataStudio/route.tsx @@ -19,10 +19,12 @@ import { CircleDataStudioButtonProps } from '@/components/CallBackButton/CircleBtn'; import Console from '@/pages/DataStudio/BottomContainer/Console'; +import JobExecHistory from '@/pages/DataStudio/BottomContainer/JobExecHistory'; import Lineage from '@/pages/DataStudio/BottomContainer/Lineage'; import Result from '@/pages/DataStudio/BottomContainer/Result'; import TableData from '@/pages/DataStudio/BottomContainer/TableData'; import JsonToSql from '@/pages/DataStudio/BottomContainer/Tools/JsonToSql'; +import TextComparison from '@/pages/DataStudio/BottomContainer/Tools/TextComparison'; import { isSql } from '@/pages/DataStudio/HeaderContainer/service'; import Catalog from '@/pages/DataStudio/LeftContainer/Catalog'; import DataSource from '@/pages/DataStudio/LeftContainer/DataSource'; @@ -34,7 +36,6 @@ import JobConfig from '@/pages/DataStudio/RightContainer/JobConfig'; import JobInfo from '@/pages/DataStudio/RightContainer/JobInfo'; import PreViewConfig from '@/pages/DataStudio/RightContainer/PreViewConfig'; import SavePoints from '@/pages/DataStudio/RightContainer/SavePoints'; -import { convertCodeEditTheme } from '@/utils/function'; import { l } from '@/utils/intl'; import { ApartmentOutlined, @@ -58,7 +59,6 @@ import { TableOutlined, ToolOutlined } from '@ant-design/icons'; -import { DiffEditor } from '@monaco-editor/react'; import { ReactNode } from 'react'; export const LeftSide = [ @@ -165,8 +165,8 @@ export const LeftBottomSide = [ auth: '/datastudio/bottom/history', key: 'menu.datastudio.history', icon: , - label: l('menu.datastudio.history') - // children: + label: l('menu.datastudio.history'), + children: }, { auth: '/datastudio/bottom/table-data', @@ -189,28 +189,7 @@ export const LeftBottomMoreTabs: { [c: string]: TabProp[] } = { key: 'menu.datastudio.tool.text-comparison', icon: , label: l('menu.datastudio.tool.text-comparison'), - children: ( - - ) + children: }, { key: 'menu.datastudio.tool.jsonToSql', diff --git a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx index 49a88833ba..75e152a402 100644 --- a/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx +++ b/dinky-web/src/pages/DevOps/JobDetail/JobOverview/components/JobDesc.tsx @@ -117,11 +117,13 @@ const JobDesc = (props: JobProps) => { ) : undefined} - {jobDetail?.history?.config?.useSqlFragment ? l('button.enable') : l('button.disable')} + {jobDetail?.history?.configJson?.useSqlFragment + ? l('button.enable') + : l('button.disable')} - {jobDetail?.history?.config?.useBatchModel + {jobDetail?.history?.configJson?.useBatchModel ? l('global.table.execmode.batch') : l('global.table.execmode.streaming')} @@ -139,11 +141,11 @@ const JobDesc = (props: JobProps) => { - {getSavePointStrategy(jobDetail?.history?.config?.savePointStrategy)} + {getSavePointStrategy(jobDetail?.history?.configJson?.savePointStrategy)} - {jobDetail?.history?.config.savePointPath} + {jobDetail?.history?.configJson.savePointPath} diff --git a/dinky-web/src/pages/DevOps/JobDetail/JobVersion/JobVersionTab.tsx b/dinky-web/src/pages/DevOps/JobDetail/JobVersion/JobVersionTab.tsx index 5201959c46..484c45c721 100644 --- a/dinky-web/src/pages/DevOps/JobDetail/JobVersion/JobVersionTab.tsx +++ b/dinky-web/src/pages/DevOps/JobDetail/JobVersion/JobVersionTab.tsx @@ -19,9 +19,9 @@ import CodeShow from '@/components/CustomEditor/CodeShow'; import VersionList from '@/components/VersionList'; +import { matchLanguage } from '@/pages/DataStudio/MiddleContainer/function'; import { JobProps } from '@/pages/DevOps/JobDetail/data'; import { handleRemoveById } from '@/services/BusinessCrud'; -import { DIALECT } from '@/services/constants'; import { API_CONSTANTS } from '@/services/endpoints'; import { TaskVersionListItem } from '@/types/Studio/data'; import { l } from '@/utils/intl'; @@ -117,9 +117,7 @@ const JobVersionTab = (props: JobProps) => { showFloatButton code={currentVersion?.statement ?? ''} height={parent.innerHeight - 250} - language={ - currentVersion?.dialect?.toLowerCase() === DIALECT.FLINK_SQL ? 'flinksql' : 'sql' - } + language={matchLanguage(currentVersion?.dialect)} /> diff --git a/dinky-web/src/services/endpoints.tsx b/dinky-web/src/services/endpoints.tsx index 3742885c16..57d3dd704e 100644 --- a/dinky-web/src/services/endpoints.tsx +++ b/dinky-web/src/services/endpoints.tsx @@ -293,5 +293,8 @@ export enum API_CONSTANTS { MOVE_CATALOGUE_URL = '/api/catalogue/moveCatalogue', //task - TASK = '/api/task' + TASK = '/api/task', + + // history + HISTORY_LIST = '/api/history/list' } diff --git a/dinky-web/src/types/DevOps/data.d.ts b/dinky-web/src/types/DevOps/data.d.ts index 0434f8ed79..13d615472b 100644 --- a/dinky-web/src/types/DevOps/data.d.ts +++ b/dinky-web/src/types/DevOps/data.d.ts @@ -53,7 +53,6 @@ declare namespace Jobs { tenantId: number; clusterId: number; clusterConfigurationId: number; - session: string; jobId: string; jobName: string; jobManagerAddress: string; @@ -62,8 +61,7 @@ declare namespace Jobs { type: string; error: string; result: string; - config: JobConfig; - configJson: string; + configJson: JobConfig; startTime: string; endTime: string; taskId: number; diff --git a/dinky-web/src/types/Studio/data.d.ts b/dinky-web/src/types/Studio/data.d.ts index e064809fb2..21f1acc7e4 100644 --- a/dinky-web/src/types/Studio/data.d.ts +++ b/dinky-web/src/types/Studio/data.d.ts @@ -107,3 +107,123 @@ export type TaskVersionListItem = { createTime?: string; isLatest?: boolean; }; + +export type ClusterConfig = { + flinkConfigPath: string; + flinkLibPath: string; + hadoopConfigPath: string; + appId: string; +}; + +export type AppConfig = { + userJarPath: string; + userJarParas: string[]; + userJarMainAppClass: string; +}; + +export type K8sConfig = { + configuration: Map; + dockerConfig: Map; + podTemplate: string; + jmPodTemplate: string; + tmPodTemplate: string; +}; + +export type FlinkConfig = { + jobName: string; + jobId: string; + flinkVersion: string; + action: ActionType; + savePointType: SavePointType; + savePoint: string; + configuration: AppConfig; + flinkConfigList: Map[]; +}; + +export type GatewayConfig = { + taskId: number; + jarPaths: string[]; + type: string; + clusterConfig: ClusterConfig; + flinkConfig: FlinkConfig; + appConfig: AppConfig; + kubernetesConfig: K8sConfig; +}; + +export enum ActionType { + SAVEPOINT = 'savepoint', + CANCEL = 'cancel' +} +export enum SavePointType { + TRIGGER = 'trigger', + DISPOSE = 'dispose', + STOP = 'stop', + CANCEL = 'cancel' +} +export enum SavePointStrategy { + NONE = 0, + LATEST = 1, + EARLIEST = 2, + CUSTOM = 3 +} + +export type JobConfig = { + type: string; + checkpoint: number; + savepointStrategy: SavePointStrategy; + savePointPath: string; + parallelism: number; + clusterId: number; + clusterConfigurationId: number; + step: number; + configJson: Map; + useChangeLog: boolean; + useAutoCancel: boolean; + useRemote: boolean; + address: string; + taskId: number; + jarFiles: string[]; + pyFiles: string[]; + jobName: string; + fragment: boolean; + statementSet: boolean; + batchModel: boolean; + maxRowNum: number; + gatewayConfig: GatewayConfig; + variables: Map; +}; + +export type JobExecutionHistory = { + id: number; + clusterId: number; + clusterConfigurationId: number; + clusterName: string; // extend + jobId: string; + jobName: string; + jobManagerAddress: string; + status: number; + type: string; + statement: string; + error: string; + result: any; + configJson: JobConfig; + startTime: Date; + endTime: Date; + taskId: number; +}; + +export enum JobStatus { + INITIALIZING = 'INITIALIZING', + CREATED = 'CREATED', + RUNNING = 'RUNNING', + FAILING = 'FAILING', + FAILED = 'FAILED', + CANCELLING = 'CANCELLING', + CANCELED = 'CANCELED', + FINISHED = 'FINISHED', + RESTARTING = 'RESTARTING', + SUSPENDED = 'SUSPENDED', + RECONCILING = 'RECONCILING', + RECONNECTING = 'RECONNECTING', + UNKNOWN = 'UNKNOWN' +} diff --git a/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_dml.sql b/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_dml.sql index 64162b9f19..3c8d73c762 100644 --- a/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_dml.sql +++ b/script/sql/upgrade/1.0.0-SNAPSHOT_schema/mysql/dinky_dml.sql @@ -284,6 +284,8 @@ alter table dinky_job_history drop column jar_json; alter table dinky_task drop column jar_id; UPDATE dinky_task_version SET task_configure=JSON_REMOVE(task_configure, '$.jarId'); UPDATE dinky_history SET config_json=JSON_REMOVE(config_json, '$.jarId'); +UPDATE dinky_history SET config_json=JSON_REMOVE(config_json, '$.jarTask'); +UPDATE dinky_history SET config_json=JSON_REMOVE(config_json, '$.session'); insert into `dinky_flink_document` (id, category, type, subtype, name, description, fill_value, version, like_num, enabled, create_time, update_time)