You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampark.apache.org by kr...@apache.org on 2023/03/07 00:45:17 UTC
[incubator-streampark] branch dev updated: [Feature][ISSUE-2401] show more info of the sql history (#2405)
This is an automated email from the ASF dual-hosted git repository.
kriszu pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampark.git
The following commit(s) were added to refs/heads/dev by this push:
new f3aefcecb [Feature][ISSUE-2401] show more info of the sql history (#2405)
f3aefcecb is described below
commit f3aefcecb3012e32003e215dde7f7cb25bbbac2c
Author: totoro <zh...@foxmail.com>
AuthorDate: Tue Mar 7 08:45:09 2023 +0800
[Feature][ISSUE-2401] show more info of the sql history (#2405)
---
.../src/api/flink/app/flinkSql.ts | 16 ++
.../src/locales/lang/en/flink/app.ts | 3 +
.../src/locales/lang/zh-CN/flink/app.ts | 3 +
.../flink/app/components/AppDetail/DetailTab.vue | 101 ++++++++++++-
.../components/AppDetail/FlinkSqlCompareModal.vue | 166 +++++++++++++++++++++
.../app/components/AppDetail/FlinkSqlDifferent.vue | 142 ++++++++++++++++++
.../app/components/AppDetail/FlinkSqlReview.vue | 55 +++++++
.../src/views/flink/app/data/detail.data.ts | 7 +
8 files changed, 492 insertions(+), 1 deletion(-)
diff --git a/streampark-console/streampark-console-webapp/src/api/flink/app/flinkSql.ts b/streampark-console/streampark-console-webapp/src/api/flink/app/flinkSql.ts
index 4f123390d..1ec71f79e 100644
--- a/streampark-console/streampark-console-webapp/src/api/flink/app/flinkSql.ts
+++ b/streampark-console/streampark-console-webapp/src/api/flink/app/flinkSql.ts
@@ -20,6 +20,8 @@ import { defHttp } from '/@/utils/http/axios';
enum FLINK_SQL_API {
VERIFY = '/flink/sql/verify',
GET = '/flink/sql/get',
+ LIST = '/flink/sql/list',
+ DELETE = '/flink/sql/delete',
HISTORY = '/flink/sql/history',
}
@@ -34,6 +36,20 @@ export function fetchFlinkSql(data) {
});
}
+export function fetchFlinkSqlList(data) {
+ return defHttp.post({
+ url: FLINK_SQL_API.LIST,
+ data,
+ });
+}
+
+export function fetchRemoveFlinkSql(data: { id: string }): Promise<boolean> {
+ return defHttp.post({
+ url: FLINK_SQL_API.DELETE,
+ data,
+ });
+}
+
export function fetchFlinkHistory(data) {
return defHttp.post({
url: FLINK_SQL_API.HISTORY,
diff --git a/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts b/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts
index 2fe53af06..2fd8a4b79 100644
--- a/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts
+++ b/streampark-console/streampark-console-webapp/src/locales/lang/en/flink/app.ts
@@ -75,6 +75,7 @@ export default {
detailTitle: 'Application Info',
flinkWebUi: 'Flink Web UI',
compareConfig: 'Compare Config',
+ compareFlinkSql: 'Compare Flink SQL',
candidate: 'Candidate',
compare: 'Compare',
compareSelectTips: 'Please select the target version',
@@ -88,7 +89,9 @@ export default {
invalidAccessToken: 'access token is invalid,please contact the administrator.',
detailTab: {
configDetail: 'View Config Detail',
+ sqlDetail: 'View SQL Detail',
confDeleteTitle: 'Are you sure delete this record',
+ sqlDeleteTitle: 'Are you sure delete this sql',
copyPath: 'Copy Path',
pointDeleteTitle: 'Are you sure delete?',
copySuccess: 'copied to clipboard successfully',
diff --git a/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts b/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts
index b84e05e44..439a2978b 100644
--- a/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts
+++ b/streampark-console/streampark-console-webapp/src/locales/lang/zh-CN/flink/app.ts
@@ -74,6 +74,7 @@ export default {
detailTitle: '作业详情',
flinkWebUi: 'Flink原生引擎界面',
compareConfig: '比较配置',
+ compareFlinkSql: '比较 Flink SQL',
candidate: '侯选',
compare: '比较',
compareSelectTips: '请选择目标板本',
@@ -86,7 +87,9 @@ export default {
invalidAccessToken: '访问令牌无效,请联系管理员。',
detailTab: {
configDetail: '查看日志详情',
+ sqlDetail: '查看 SQL 详情',
confDeleteTitle: '您确定要删除此记录吗',
+ sqlDeleteTitle: '您确定要删除此 SQL 吗',
copyPath: '复制路径',
pointDeleteTitle: '您确定要删除?',
copySuccess: '已成功复制到剪贴板',
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/DetailTab.vue b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/DetailTab.vue
index 87476b3cf..f85c60f77 100644
--- a/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/DetailTab.vue
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/DetailTab.vue
@@ -32,6 +32,7 @@
import {
getBackupColumns,
getConfColumns,
+ getFlinkSqlColumns,
getOptionLogColumns,
getSavePointColumns,
} from '../../data/detail.data';
@@ -49,6 +50,9 @@
import { useMessage } from '/@/hooks/web/useMessage';
import { useClipboard } from '@vueuse/core';
import { AppTypeEnum, JobTypeEnum, SavePointEnum } from '/@/enums/flinkEnum';
+ import { fetchFlinkSql, fetchFlinkSqlList, fetchRemoveFlinkSql } from '/@/api/flink/app/flinkSql';
+ import FlinkSqlReview from './FlinkSqlReview.vue';
+ import FlinkSqlCompareModal from './FlinkSqlCompareModal.vue';
const DescriptionItem = Descriptions.Item;
const TabPane = Tabs.TabPane;
@@ -101,8 +105,10 @@
};
const [registerCompare, { openModal: openCompareModal }] = useModal();
+ const [registerFlinkSqlCompare, { openModal: openFlinkSqlCompareModal }] = useModal();
const [registerExecOption, { openModal: openExecOptionModal }] = useModal();
const [registerDetailDrawer, { openDrawer: openDetailDrawer }] = useDrawer();
+ const [registerFlinkSqlDrawer, { openDrawer: openFlinkDrawer }] = useDrawer();
const [registerConfigTable, { getDataSource, reload: reloadConf }] = useTable({
api: fetchListVer,
@@ -110,6 +116,14 @@
...tableCommonConf,
});
+ const [registerFlinkSqlTable, { getDataSource: getFlinkSqls, reload: reloadFlinkSql }] = useTable(
+ {
+ api: fetchFlinkSqlList,
+ columns: getFlinkSqlColumns(),
+ ...tableCommonConf,
+ },
+ );
+
const [registerSavePointTable, { reload: reloadSavePoint }] = useTable({
api: fetchSavePonitHistory,
columns: getSavePointColumns(),
@@ -156,6 +170,36 @@
},
];
}
+
+ function getFlinkSqlAction(record: Recordable): ActionItem[] {
+ return [
+ {
+ tooltip: { title: t('flink.app.detail.detailTab.sqlDetail') },
+ type: 'link',
+ icon: 'ant-design:eye-outlined',
+ onClick: handleSqlDetail.bind(null, record),
+ },
+ {
+ tooltip: { title: t('flink.app.detail.compareFlinkSql') },
+ type: 'link',
+ icon: 'ant-design:swap-outlined',
+ onClick: handleCompareFlinkSql.bind(null, record),
+ ifShow: getFlinkSqls().length > 1,
+ },
+ {
+ popConfirm: {
+ title: t('flink.app.detail.detailTab.sqlDeleteTitle'),
+ confirm: handleDeleteFlinkSql.bind(null, record),
+ },
+ auth: 'conf:delete',
+ type: 'link',
+ icon: 'ant-design:delete-outlined',
+ color: 'error',
+ ifShow: !record.effective,
+ },
+ ];
+ }
+
async function handleConfDetail(record: Recordable) {
const hide = createMessage.loading('loading');
try {
@@ -172,12 +216,34 @@
}
}
+ async function handleSqlDetail(record: Recordable) {
+ const hide = createMessage.loading('loading');
+ try {
+ const res = await fetchFlinkSql({
+ id: record.id,
+ });
+ openFlinkDrawer(true, {
+ sql: decodeByBase64(res.sql),
+ });
+ } catch (error: unknown) {
+ console.error(error);
+ } finally {
+ hide();
+ }
+ }
+
/* delete configuration */
async function handleDeleteConf(record: Recordable) {
await fetchRemoveConf({ id: record.id });
reloadConf();
}
+ /* delete flink sql */
+ async function handleDeleteFlinkSql(record: Recordable) {
+ await fetchRemoveFlinkSql({ id: record.id });
+ reloadFlinkSql();
+ }
+
function handleCompare(record: Recordable) {
openCompareModal(true, {
id: record.id,
@@ -186,6 +252,14 @@
});
}
+ function handleCompareFlinkSql(record: Recordable) {
+ openFlinkSqlCompareModal(true, {
+ id: record.id,
+ version: record.version,
+ createTime: record.createTime,
+ });
+ }
+
function getSavePointAction(record: Recordable): ActionItem[] {
return [
{
@@ -269,7 +343,30 @@
</BasicTable>
</TabPane>
<TabPane key="3" tab="Flink SQL" v-if="app.jobType === JobTypeEnum.SQL">
- <div class="sql-box syntax-true" ref="flinkSql" style="height: 600px"></div>
+ <BasicTable @register="registerFlinkSqlTable">
+ <template #bodyCell="{ column, record }">
+ <template v-if="column.dataIndex == 'candidate'">
+ <Tag color="#52c41a" v-if="record.candidate == 0"> None </Tag>
+ <Tag color="#2db7f5" v-if="record.candidate == 1"> New </Tag>
+ <Tag color="#108ee9" v-if="record.candidate == 2"> History </Tag>
+ </template>
+ <template v-if="column.dataIndex == 'version'">
+ <a-button type="primary" shape="circle" size="small" class="mr-10px">
+ {{ record.version }}
+ </a-button>
+ </template>
+ <template v-if="column.dataIndex == 'effective'">
+ <Tag color="green" v-if="record.effective"> Effective </Tag>
+ </template>
+ <template v-if="column.dataIndex == 'createTime'">
+ <Icon icon="ant-design:clock-circle-outlined" />
+ {{ record.createTime }}
+ </template>
+ <template v-if="column.dataIndex == 'operation'">
+ <TableAction :actions="getFlinkSqlAction(record)" />
+ </template>
+ </template>
+ </BasicTable>
</TabPane>
<TabPane key="4" tab="Savepoints" v-if="tabConf.showSaveOption">
<BasicTable @register="registerSavePointTable">
@@ -350,7 +447,9 @@
</Tabs>
<CompareModal @register="registerCompare" />
+ <FlinkSqlCompareModal @register="registerFlinkSqlCompare" />
<ExecOptionModal @register="registerExecOption" />
<Mergely :read-only="true" @register="registerDetailDrawer" />
+ <FlinkSqlReview @register="registerFlinkSqlDrawer" />
</div>
</template>
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlCompareModal.vue b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlCompareModal.vue
new file mode 100644
index 000000000..04f185e6e
--- /dev/null
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlCompareModal.vue
@@ -0,0 +1,166 @@
+<!--
+ 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
+
+ https://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.
+-->
+<script lang="ts">
+ import { computed, defineComponent, reactive, ref, toRaw } from 'vue';
+ import { useI18n } from '/@/hooks/web/useI18n';
+ export default defineComponent({
+ name: 'FlinkSqlCompareModal',
+ });
+</script>
+<script setup lang="ts" name="FlinkSqlCompareModal">
+ import { Select, Tag } from 'ant-design-vue';
+ import { Icon, SvgIcon } from '/@/components/Icon';
+ import { useDetailProviderContext } from '../../hooks/useDetailContext';
+ import { fetchFlinkSql, fetchFlinkSqlList } from '/@/api/flink/app/flinkSql';
+ import { useDrawer } from '/@/components/Drawer';
+ import { BasicForm, useForm } from '/@/components/Form';
+ import { BasicModal, useModalInner } from '/@/components/Modal';
+ import { decodeByBase64 } from '/@/utils/cipher';
+ import { CandidateTypeEnum } from '/@/enums/flinkEnum';
+ import FlinkSqlDifferent from '/@/views/flink/app/components/AppDetail/FlinkSqlDifferent.vue';
+
+ const SelectOption = Select.Option;
+ const { t } = useI18n();
+ defineEmits(['register']);
+ const allFlinkSqlVersions = ref<any[]>([]);
+ const submitLoading = ref<boolean>(false);
+ const compareRecord = reactive<Recordable>({});
+ const values = useDetailProviderContext();
+
+ const [registerFlinkSqlDifferentDrawer, { openDrawer: openFlinkSqlDiffDrawer }] = useDrawer();
+ const [registerModal, { closeModal }] = useModalInner((data) => {
+ data && onReceiveModalData(data);
+ });
+
+ async function onReceiveModalData(data) {
+ const res = await fetchFlinkSqlList({
+ appId: toRaw(values).app.id,
+ pageNo: 1,
+ pageSize: 999999,
+ });
+ Object.assign(compareRecord, data);
+ allFlinkSqlVersions.value = res.records;
+ }
+
+ const [registerForm, { resetFields, submit }] = useForm({
+ labelWidth: 180,
+ colon: true,
+ name: 'compareForm',
+ labelCol: { lg: { span: 7, offset: 0 }, sm: { span: 7, offset: 0 } },
+ wrapperCol: { lg: { span: 16, offset: 0 }, sm: { span: 4, offset: 0 } },
+ baseColProps: { span: 24 },
+ showActionButtonGroup: false,
+ schemas: [
+ { label: 'source version', field: 'source', component: 'Input', slot: 'source' },
+ {
+ label: 'target version',
+ field: 'target',
+ defaultValue: undefined,
+ component: 'Select',
+ slot: 'target',
+ required: true,
+ },
+ ],
+ });
+
+ // submit form
+ async function handleCompareOk(values: Recordable) {
+ submitLoading.value = true;
+ try {
+ const source = await fetchFlinkSql({
+ id: compareRecord.id,
+ });
+ const sourceSql = decodeByBase64(source.sql);
+ const sourceVersion = source.version;
+ const target = await fetchFlinkSql({
+ id: values.target,
+ });
+ const targetSql = decodeByBase64(target.sql);
+ const targetVersion = target.version;
+ closeModal();
+ openFlinkSqlDiffDrawer(true, {
+ immediate: true,
+ param: [
+ {
+ name: 'Flink SQL',
+ format: 'sql',
+ original: sourceSql,
+ modified: targetSql,
+ },
+ ],
+ original: sourceVersion,
+ modified: targetVersion,
+ });
+ } catch (error) {
+ console.error(error);
+ } finally {
+ submitLoading.value = false;
+ }
+ }
+
+ const filterNotCurrSql = computed(() => {
+ return allFlinkSqlVersions.value.filter((x) => x.version !== compareRecord.version);
+ });
+</script>
+<template>
+ <BasicModal @register="registerModal" :afterClose="resetFields">
+ <template #title>
+ <SvgIcon name="swap" />
+ {{ t('flink.app.detail.compareFlinkSql') }}
+ </template>
+ <BasicForm @register="registerForm" @submit="handleCompareOk">
+ <template #source>
+ <a-button type="primary" shape="circle" size="small" style="margin-right: 10px">
+ {{ compareRecord.version }}
+ </a-button>
+ <Icon icon="ant-design:clock-circle-outlined" style="color: darkgrey" />
+ <span style="color: darkgrey">{{ compareRecord.createTime }}</span>
+ </template>
+ <template #target="{ model }">
+ <Select v-model:value="model.target" :placeholder="t('flink.app.detail.compareSelectTips')">
+ <SelectOption v-for="(ver, index) in filterNotCurrSql" :value="ver.id" :key="index">
+ <div style="padding-left: 5px">
+ <a-button type="primary" shape="circle" size="small" style="margin-right: 10px">
+ {{ ver.version }}
+ </a-button>
+ <Tag color="green" style="margin-left: 10px" size="small" v-if="ver.effective">
+ Effective
+ </Tag>
+ <Tag
+ color="cyan"
+ class="ml-5px"
+ size="small"
+ v-if="[CandidateTypeEnum.NEW, CandidateTypeEnum.HISTORY].includes(ver.candidate)"
+ >
+ {{ t('flink.app.detail.candidate') }}
+ </Tag>
+ </div>
+ </SelectOption>
+ </Select>
+ </template>
+ </BasicForm>
+ <template #footer>
+ <a-button key="back" @click="closeModal">
+ {{ t('common.closeText') }}
+ </a-button>
+ <a-button key="submit" type="primary" @click="submit" :loading="submitLoading">
+ {{ t('flink.app.detail.compare') }}
+ </a-button>
+ </template>
+ </BasicModal>
+ <FlinkSqlDifferent @register="registerFlinkSqlDifferentDrawer" />
+</template>
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlDifferent.vue b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlDifferent.vue
new file mode 100644
index 000000000..ea5bf06e1
--- /dev/null
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlDifferent.vue
@@ -0,0 +1,142 @@
+<!--
+ 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
+
+ https://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.
+-->
+<script lang="ts">
+ import { defineComponent } from 'vue';
+ export default defineComponent({
+ name: 'FlinkSqlDifferent',
+ });
+</script>
+<script setup lang="ts" name="FlinkSqlDifferent">
+ import { nextTick, reactive, ref } from 'vue';
+ import { getMonacoOptions } from '../../data';
+ import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+ import { useDiffMonaco } from '../../hooks/useDiffMonaco';
+ import { Tabs } from 'ant-design-vue';
+ import { SvgIcon } from '/@/components/Icon';
+ import { useI18n } from '/@/hooks/web/useI18n';
+
+ const TabPane = Tabs.TabPane;
+
+ const { t } = useI18n();
+
+ const items = ref<any[]>([]);
+ const renderEleMap = new Map<string, boolean>();
+ const version = reactive({
+ original: null,
+ modified: null,
+ });
+ const original = ref<Nullable<string>>(null);
+ const modified = ref<Nullable<string>>(null);
+ const [registerMergelyDrawer, { closeDrawer }] = useDrawerInner((data) => {
+ if (data && data.immediate) {
+ different(data);
+ }
+ });
+ const { setupEditor, disposeEditor } = useDiffMonaco(
+ null,
+ 'sql',
+ () => original.value,
+ () => modified.value,
+ getMonacoOptions(true) as any,
+ false,
+ );
+
+ function different(data: { param: Array<any>; original: string; modified: string }) {
+ Object.assign(version, { original: data.original, modified: data.modified });
+ items.value = data.param;
+ handleRenderTab(0);
+ }
+
+ function handleRenderTab(index: number) {
+ const x = items.value[index];
+ original.value = x.original;
+ modified.value = x.modified;
+ const ele = '#mergely' + index;
+ nextTick(() => {
+ const elem = document.querySelector(ele);
+ handleHeight(elem, 140);
+ // no render
+ if (!renderEleMap.get(ele)) {
+ setupEditor(elem);
+ renderEleMap.set(ele, true);
+ }
+ });
+ }
+ /* Change editor height */
+ function handleHeight(ele: any, h: number) {
+ const height = document.documentElement.offsetHeight || document.body.offsetHeight;
+ ele.style.height = height - h + 'px';
+ }
+
+ async function handleCancel() {
+ await disposeEditor();
+ renderEleMap.clear();
+ closeDrawer();
+ }
+
+ defineExpose({ different });
+</script>
+<template>
+ <BasicDrawer
+ @register="registerMergelyDrawer"
+ width="80%"
+ class="drawer-conf"
+ keyboard
+ :destroyOnClose="true"
+ @close="handleCancel"
+ >
+ <template #title>
+ <SvgIcon name="swap" />
+ <span class="px-10px">{{ t('flink.app.detail.compareFlinkSql') }}</span>
+ <span> ( </span>
+ <span class="pr-5px">{{ t('flink.app.detail.different.original') }}</span>
+ <a-button type="primary" shape="circle" size="small">
+ {{ version.original }}
+ </a-button>
+ <span class="px-10px">VS</span>
+ <span class="pr-5px"> {{ t('flink.app.detail.different.target') }} </span>
+ <a-button type="primary" shape="circle" size="small">
+ {{ version.modified }}
+ </a-button>
+ <span> ) </span>
+ </template>
+ <Tabs type="card" @change="handleRenderTab">
+ <TabPane v-for="(item, index) in items" :key="index" :tab="item.name">
+ <div :id="'mergely'.concat(index.toString())"></div>
+ </TabPane>
+ </Tabs>
+ </BasicDrawer>
+</template>
+<style scoped>
+ .drawer-conf :deep(.ant-drawer-body) {
+ padding: 5px !important;
+ padding-bottom: 0px !important;
+ }
+
+ .drawer-bottom-button {
+ position: absolute;
+ padding-top: 10px;
+ padding-right: 50px;
+ width: 100%;
+ bottom: 10px;
+ z-index: 9;
+ }
+
+ .drwaer-button-item {
+ margin-right: 20px;
+ }
+</style>
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlReview.vue b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlReview.vue
new file mode 100644
index 000000000..7b1c184d5
--- /dev/null
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppDetail/FlinkSqlReview.vue
@@ -0,0 +1,55 @@
+<!--
+ 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
+
+ https://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.
+-->
+<template>
+ <BasicDrawer
+ @register="registerDrawer"
+ :width="800"
+ placement="right"
+ :showOkBtn="false"
+ showFooter
+ >
+ <template #title>
+ <EyeOutlined style="color: green" />
+ Flink SQL preview
+ </template>
+ <div ref="flinkReviewRef" class="h-[calc(100vh-150px)] flink-preview"></div>
+ </BasicDrawer>
+</template>
+
+<script lang="ts" setup>
+ import { EyeOutlined } from '@ant-design/icons-vue';
+ import { ref } from 'vue';
+ import { getMonacoOptions } from '../../data';
+ import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+ import { useMonaco } from '/@/hooks/web/useMonaco';
+ const flinkReviewRef = ref();
+ const { setContent } = useMonaco(flinkReviewRef, {
+ language: 'sql',
+ code: '',
+ options: getMonacoOptions(true) as any,
+ });
+ const [registerDrawer] = useDrawerInner((data) => {
+ if (data) {
+ setContent(data.sql || '');
+ }
+ });
+</script>
+<style lang="less">
+ .flink-preview {
+ border: 1px solid @border-color-base;
+ }
+</style>
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/data/detail.data.ts b/streampark-console/streampark-console-webapp/src/views/flink/app/data/detail.data.ts
index 510e2e5b3..66fcda6c1 100644
--- a/streampark-console/streampark-console-webapp/src/views/flink/app/data/detail.data.ts
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/data/detail.data.ts
@@ -111,6 +111,13 @@ export const getConfColumns = (): BasicColumn[] => [
{ title: 'Modify Time', dataIndex: 'createTime' },
];
+export const getFlinkSqlColumns = (): BasicColumn[] => [
+ { title: 'Version', dataIndex: 'version' },
+ { title: 'Effective', dataIndex: 'effective' },
+ { title: 'Candidate', dataIndex: 'candidate' },
+ { title: 'Modify Time', dataIndex: 'createTime' },
+];
+
export const getSavePointColumns = (): BasicColumn[] => [
{ title: 'Path', dataIndex: 'path' },
{ title: 'Trigger Time', dataIndex: 'triggerTime', width: 250 },