You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampark.apache.org by be...@apache.org on 2024/03/13 09:41:37 UTC
(incubator-streampark) 01/02: [Improve] job state style improvements
This is an automated email from the ASF dual-hosted git repository.
benjobs pushed a commit to branch sync_2.1.3
in repository https://gitbox.apache.org/repos/asf/incubator-streampark.git
commit 1d6049973cdd0c6d3be823888d3d18c3d76ab86b
Author: benjobs <be...@gmail.com>
AuthorDate: Wed Mar 13 17:39:59 2024 +0800
[Improve] job state style improvements
---
.../src/locales/lang/en/flink/app.ts | 52 ++++++++++++--
.../src/locales/lang/zh-CN/flink/app.ts | 39 +++++++++--
.../src/views/flink/app/View.vue | 2 +-
.../components/AppView/StartApplicationModal.vue | 80 +++++++++++-----------
.../src/views/flink/app/components/State.less | 4 --
.../src/views/flink/app/components/State.tsx | 63 +++++++++--------
6 files changed, 156 insertions(+), 84 deletions(-)
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 e9b778af3..ff03d2723 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
@@ -78,6 +78,38 @@ export default {
releaseFail: 'release application failed,',
releasing: 'Current Application is releasing',
},
+ runState: {
+ added: 'ADDED',
+ initializing: 'INITIALIZING',
+ created: 'CREATED',
+ starting: 'STARTING',
+ restarting: 'RESTARTING',
+ running: 'RUNNING',
+ failing: 'FAILING',
+ failed: 'FAILED',
+ lost: 'LOST',
+ cancelling: 'CANCELLING',
+ canceled: 'CANCELED',
+ finished: 'FINISHED',
+ suspended: 'SUSPENDED',
+ reconciling: 'RECONCILING',
+ mapping: 'MAPPING',
+ silent: 'SILENT',
+ terminated: 'TERMINATED',
+ },
+ releaseState: {
+ failed: 'FAILED',
+ success: 'SUCCESS',
+ waiting: 'WAITING',
+ releasing: 'RELEASING',
+ pending: 'PENDING',
+ },
+ clusterState: {
+ created: 'CREATED',
+ started: 'STARTED',
+ canceled: 'SHUTDOWN',
+ lost: 'LOST',
+ },
detail: {
detailTitle: 'Application Info',
flinkWebUi: 'Flink Web UI',
@@ -126,19 +158,27 @@ export default {
},
},
view: {
- buildTitle: 'Application releasing Progress',
+ buildTitle: 'Job releasing Progress',
stepTitle: 'Steps Detail',
errorLog: 'Error Log',
errorSummary: 'Error Summary',
errorStack: 'Error Stack',
- logTitle: 'Start Log : Application Name [ {0} ]',
+ logTitle: 'Start Log : Job Name [ {0} ]',
refreshTime: 'last refresh time',
refresh: 'refresh',
- start: 'Start Application',
- stop: 'Stop application',
+ start: 'Start Job',
+ stop: 'Stop Job',
savepoint: 'Trigger Savepoint',
- recheck: 'the associated project has changed and this job need to be rechecked',
- changed: 'the application has changed.',
+ fromSavepoint: 'From savepoint',
+ savepointTip: 'Restore the job from savepoint or latest checkpoint',
+ savepointInput: 'Specify the savepoint/checkpoint path',
+ savepointSwitch:
+ 'Specify the savepoint/checkpoint path (Double-click to switch between "input" and "select")',
+ ignoreRestored: 'Ignore failed',
+ ignoreRestoredTip:
+ 'ignore savepoint then cannot be restored, Same as:-allowNonRestoredState(-n)',
+ recheck: 'the associated project has changed and this job need to be release',
+ changed: 'the job has been updated',
},
pod: {
choice: 'Choice',
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 17652ec3e..6ffa0806e 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
@@ -76,6 +76,31 @@ export default {
releaseFail: '发布作业失败',
releasing: '当前作业正在发布中',
},
+ runState: {
+ added: '新增作业',
+ initializing: '初始化',
+ created: '创建中',
+ starting: '启动中',
+ restarting: '重启中',
+ running: '运行中',
+ failing: '失败中',
+ failed: '作业失败',
+ lost: '作业失联',
+ cancelling: '取消中',
+ canceled: '已取消',
+ finished: '已完成',
+ suspended: '已暂停',
+ reconciling: '调整中',
+ mapping: '映射中',
+ silent: '沉默',
+ terminated: '终止',
+ },
+ clusterState: {
+ created: '新增',
+ started: '运行中',
+ canceled: '停止',
+ lost: '失联',
+ },
detail: {
detailTitle: '作业详情',
flinkWebUi: 'Flink Web UI',
@@ -123,7 +148,7 @@ export default {
},
},
view: {
- buildTitle: '应用程序启动进度',
+ buildTitle: '作业启动进度',
stepTitle: '步骤详情',
errorLog: '错误日志',
errorSummary: '错误摘要',
@@ -131,11 +156,17 @@ export default {
logTitle: '启动日志 : 应用名称 [ {0} ]',
refreshTime: '上次刷新时间',
refresh: '刷新',
- start: '开启应用',
+ start: '启动作业',
stop: '停止应用',
savepoint: '触发 Savepoint',
- recheck: '关联的项目已更改,需要重新检查此作业',
- changed: '应用程序已更改。',
+ recheck: '关联的项目已更新,需要重新发布此作业',
+ changed: '作业已更新',
+ fromSavepoint: 'Savepoint 恢复',
+ savepointTip: '作业从 savepoint 或 checkpoint 恢复状态',
+ savepointInput: '指定 savepoint/checkpoint 路径',
+ savepointSwitch: '指定 savepoint/checkpoint 路径 (双击切换"下拉框选择"或"手动输入")',
+ ignoreRestored: '忽略失败',
+ ignoreRestoredTip: '当状态恢复失败时跳过错误,作业继续运行, 同参数:-allowNonRestoredState(-n)',
},
pod: {
choice: '选择',
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue b/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue
index 9b4a4e8e8..f0795c8a9 100644
--- a/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/View.vue
@@ -207,7 +207,7 @@
app['optionState'] === OptionStateEnum.SAVEPOINTING
) {
// yarn-per-job|yarn-session|yarn-application
- handleView(app, unref(yarn));
+ await handleView(app, unref(yarn));
}
}
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppView/StartApplicationModal.vue b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppView/StartApplicationModal.vue
index 98a0f0188..a78699829 100644
--- a/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppView/StartApplicationModal.vue
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/components/AppView/StartApplicationModal.vue
@@ -24,7 +24,7 @@
});
</script>
<script setup lang="ts" name="StartApplicationModal">
- import { h } from 'vue';
+ import { h, ref } from 'vue';
import { Select, Input, Tag } from 'ant-design-vue';
import { BasicForm, useForm } from '/@/components/Form';
import { SvgIcon, Icon } from '/@/components/Icon';
@@ -32,16 +32,15 @@
import { useMessage } from '/@/hooks/web/useMessage';
import { useRouter } from 'vue-router';
import { fetchCheckStart, fetchForcedStop, fetchStart } from '/@/api/flink/app';
-
- import { AppExistsEnum, RestoreModeEnum } from '/@/enums/flinkEnum';
- import { fetchFlinkEnv } from '/@/api/flink/flinkEnv';
- import { renderFlinkAppRestoreMode } from '/@/views/flink/app/hooks/useFlinkRender';
+ import { AppExistsEnum } from '/@/enums/flinkEnum';
const SelectOption = Select.Option;
const { t } = useI18n();
const { Swal } = useMessage();
const router = useRouter();
+ const selectInput = ref<boolean>(false);
+ const selectValue = ref<string>(null);
const emits = defineEmits(['register', 'updateOption']);
const receiveData = reactive<Recordable>({});
@@ -56,61 +55,50 @@
}
});
+ function handleSavePointTip(list) {
+ if (list != null && list.length > 0) {
+ return t('flink.app.view.savepointSwitch');
+ }
+ return t('flink.app.view.savepointInput');
+ }
+
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
name: 'startApplicationModal',
labelWidth: 120,
schemas: [
{
field: 'startSavePointed',
- label: 'from savepoint',
+ label: t('flink.app.view.fromSavepoint'),
component: 'Switch',
componentProps: {
checkedChildren: 'ON',
unCheckedChildren: 'OFF',
},
defaultValue: true,
- afterItem: () =>
- h(
- 'span',
- { class: 'tip-info' },
- 'restore the application from savepoint or latest checkpoint',
- ),
+ afterItem: () => h('span', { class: 'conf-switch' }, t('flink.app.view.savepointTip')),
},
{
field: 'startSavePoint',
- label: 'savepoint',
+ label: 'Savepoint',
component:
receiveData.historySavePoint && receiveData.historySavePoint.length > 0
? 'Select'
: 'Input',
afterItem: () =>
- h(
- 'span',
- { class: 'tip-info' },
- 'restore the application from savepoint or latest checkpoint',
- ),
+ h('span', { class: 'conf-switch' }, handleSavePointTip(receiveData.historySavePoint)),
slot: 'savepoint',
ifShow: ({ values }) => values.startSavePointed,
required: true,
},
- {
- field: 'restoreMode',
- label: 'restore mode',
- component: 'Select',
- defaultValue: RestoreModeEnum.NO_CLAIM,
- render: (renderCallbackParams) => renderFlinkAppRestoreMode(renderCallbackParams),
- ifShow: ({ values }) => values.startSavePointed && checkFlinkVersion(),
- },
{
field: 'allowNonRestoredState',
- label: 'ignore restored',
+ label: t('flink.app.view.ignoreRestored'),
component: 'Switch',
componentProps: {
checkedChildren: 'ON',
unCheckedChildren: 'OFF',
},
- afterItem: () =>
- h('span', { class: 'tip-info' }, 'ignore savepoint then cannot be restored'),
+ afterItem: () => h('span', { class: 'conf-switch' }, t('flink.app.view.ignoreRestoredTip')),
defaultValue: false,
ifShow: ({ values }) => values.startSavePointed,
},
@@ -135,16 +123,20 @@
await handleDoSubmit();
}
+ async function handleReset() {
+ selectInput.value = false;
+ selectValue.value = null;
+ }
+
/* submit */
async function handleDoSubmit() {
try {
const formValue = (await validate()) as Recordable;
const savePointed = formValue.startSavePointed;
const savePointPath = savePointed ? formValue['startSavePoint'] : null;
- const restoreMode = savePointed ? formValue['restoreMode'] : null;
+ handleReset();
const { data } = await fetchStart({
id: receiveData.application.id,
- restoreMode,
savePointed,
savePoint: savePointPath,
allowNonRestored: formValue.allowNonRestoredState || false,
@@ -152,7 +144,7 @@
if (data.data) {
Swal.fire({
icon: 'success',
- title: 'The current job is starting',
+ title: t('flink.app.operation.starting'),
showConfirmButton: false,
timer: 2000,
});
@@ -190,10 +182,14 @@
}
}
- async function checkFlinkVersion() {
- const versionId = receiveData.application.versionId;
- const flinkVersion = await fetchFlinkEnv(versionId);
- return parseInt(flinkVersion.versionOfMiddle) >= 15;
+ function handleSavepoint(model, field, input) {
+ selectInput.value = input;
+ if (input) {
+ selectValue.value = model[field];
+ model[field] = null;
+ } else {
+ model[field] = selectValue.value;
+ }
}
</script>
<template>
@@ -201,6 +197,7 @@
@register="registerModal"
:minHeight="100"
@ok="handleSubmit"
+ @cancel="handleReset"
:okText="t('common.apply')"
:cancelText="t('common.cancelText')"
>
@@ -211,8 +208,12 @@
<BasicForm @register="registerForm" class="!pt-40px">
<template #savepoint="{ model, field }">
- <template v-if="receiveData.historySavePoint && receiveData.historySavePoint.length > 0">
- <Select allow-clear v-model:value="model[field]">
+ <template
+ v-if="
+ !selectInput && receiveData.historySavePoint && receiveData.historySavePoint.length > 0
+ "
+ >
+ <Select v-model:value="model[field]" @dblclick="handleSavepoint(model, field, true)">
<SelectOption v-for="(k, i) in receiveData.historySavePoint" :key="i" :value="k.path">
<span style="color: darkgrey">
<Icon icon="ant-design:clock-circle-outlined" />
@@ -232,8 +233,9 @@
</template>
<Input
v-else
+ @dblclick="handleSavepoint(model, field, false)"
type="text"
- placeholder="Please enter savepoint manually"
+ :placeholder="$t('flink.app.view.savepointInput')"
v-model:value="model[field]"
/>
</template>
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.less b/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.less
index 74c6995d3..895a612a0 100644
--- a/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.less
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.less
@@ -47,10 +47,6 @@
animation: reconciling-color 800ms ease-out infinite alternate;
}
-.status-processing-probing {
- animation: probing-color 800ms ease-out infinite alternate;
-}
-
@keyframes deploying-color {
0% {
border-color: #1abbdc;
diff --git a/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.tsx b/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.tsx
index d9b1e26fd..564b32d01 100644
--- a/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.tsx
+++ b/streampark-console/streampark-console-webapp/src/views/flink/app/components/State.tsx
@@ -19,63 +19,60 @@ import { computed, defineComponent, toRefs, unref } from 'vue';
import { Tag, Tooltip } from 'ant-design-vue';
import './State.less';
import { AppStateEnum, ReleaseStateEnum, OptionStateEnum } from '/@/enums/flinkEnum';
+import { useI18n } from '/@/hooks/web/useI18n';
+const { t } = useI18n();
/* state map*/
export const stateMap = {
- [AppStateEnum.ADDED]: { color: '#2f54eb', title: 'ADDED' },
+ [AppStateEnum.ADDED]: { color: '#2f54eb', title: t('flink.app.runState.added') },
[AppStateEnum.INITIALIZING]: {
color: '#738df8',
- title: 'INITIALIZING',
+ title: t('flink.app.runState.initializing'),
class: 'status-processing-initializing',
},
- [AppStateEnum.CREATED]: { color: '#2f54eb', title: 'CREATED' },
+ [AppStateEnum.CREATED]: { color: '#2f54eb', title: t('flink.app.runState.created') },
[AppStateEnum.STARTING]: {
color: '#1AB58E',
- title: 'STARTING',
+ title: t('flink.app.runState.starting'),
class: 'status-processing-starting',
},
[AppStateEnum.RESTARTING]: {
color: '#13c2c2',
- title: 'RESTARTING',
+ title: t('flink.app.runState.restarting'),
class: 'status-processing-restarting',
},
[AppStateEnum.RUNNING]: {
color: '#52c41a',
- title: 'RUNNING',
+ title: t('flink.app.runState.running'),
class: 'status-processing-running',
},
[AppStateEnum.FAILING]: {
color: '#fa541c',
- title: 'FAILING',
+ title: t('flink.app.runState.failing'),
class: 'status-processing-failing',
},
- [AppStateEnum.FAILED]: { color: '#f5222d', title: 'FAILED' },
- [AppStateEnum.CANCELLING]: { color: '#faad14', title: 'CANCELLING' },
- [AppStateEnum.CANCELED]: { color: '#fa8c16', title: 'CANCELED' },
- [AppStateEnum.FINISHED]: { color: '#1677ff', title: 'FINISHED' },
- [AppStateEnum.SUSPENDED]: { color: '#722ed1', title: 'SUSPENDED' },
+ [AppStateEnum.FAILED]: { color: '#f5222d', title: t('flink.app.runState.failed') },
+ [AppStateEnum.CANCELLING]: { color: '#faad14', title: t('flink.app.runState.cancelling') },
+ [AppStateEnum.CANCELED]: { color: '#fa8c16', title: t('flink.app.runState.canceled') },
+ [AppStateEnum.FINISHED]: { color: '#1890ff', title: t('flink.app.runState.finished') },
+ [AppStateEnum.SUSPENDED]: { color: '#722ed1', title: t('flink.app.runState.suspended') },
[AppStateEnum.RECONCILING]: {
color: '#eb2f96',
- title: 'RECONCILING',
+ title: t('flink.app.runState.reconciling'),
class: 'status-processing-reconciling',
},
- [AppStateEnum.LOST]: { color: '#000000', title: 'LOST' },
+ [AppStateEnum.LOST]: { color: '#333333', title: t('flink.app.runState.lost') },
[AppStateEnum.MAPPING]: {
color: '#13c2c2',
- title: 'MAPPING',
+ title: t('flink.app.runState.mapping'),
class: 'status-processing-restarting',
},
[AppStateEnum.SILENT]: {
color: '#738df8',
- title: 'SILENT',
+ title: t('flink.app.runState.silent'),
class: 'status-processing-initializing',
},
- [AppStateEnum.TERMINATED]: { color: '#8E50FF', title: 'TERMINATED' },
- [AppStateEnum.PROBING]: {
- color: '#2febc9',
- title: 'PROBING',
- class: 'status-processing-probing',
- },
+ [AppStateEnum.TERMINATED]: { color: '#8E50FF', title: t('flink.app.runState.terminated') },
};
/* option state map*/
export const optionStateMap = {
@@ -103,16 +100,19 @@ export const optionStateMap = {
/* release state map*/
export const releaseStateMap = {
- [ReleaseStateEnum.FAILED]: { color: '#f5222d', title: 'FAILED' },
- [ReleaseStateEnum.DONE]: { color: '#52c41a', title: 'DONE' },
- [ReleaseStateEnum.NEED_RELEASE]: { color: '#fa8c16', title: 'WAITING' },
+ [ReleaseStateEnum.FAILED]: { color: '#f5222d', title: t('flink.app.releaseState.failed') },
+ [ReleaseStateEnum.DONE]: { color: '#52c41a', title: t('flink.app.releaseState.success') },
+ [ReleaseStateEnum.NEED_RELEASE]: { color: '#fa8c16', title: t('flink.app.releaseState.waiting') },
[ReleaseStateEnum.RELEASING]: {
color: '#52c41a',
- title: 'RELEASING',
+ title: t('flink.app.releaseState.releasing'),
class: 'status-processing-deploying',
},
- [ReleaseStateEnum.NEED_RESTART]: { color: '#fa8c16', title: 'PENDING' },
- [ReleaseStateEnum.NEED_ROLLBACK]: { color: '#fa8c16', title: 'WAITING' },
+ [ReleaseStateEnum.NEED_RESTART]: { color: '#fa8c16', title: t('flink.app.releaseState.pending') },
+ [ReleaseStateEnum.NEED_ROLLBACK]: {
+ color: '#fa8c16',
+ title: t('flink.app.releaseState.waiting'),
+ },
};
/* build state map*/
@@ -127,6 +127,7 @@ export const buildStatusMap = {
3: { color: '#2ECC71', title: 'SUCCESS' },
4: { color: '#E74C3C', title: 'FAILURE' },
};
+
const overviewMap = {
running: { color: '#52c41a', title: 'RUNNING' },
canceled: { color: '#fa8c16', title: 'CANCELED' },
@@ -152,14 +153,15 @@ export default defineComponent({
},
setup(props) {
const { data, option } = toRefs(props);
+
const tagWidth = computed(() => {
if (props.maxTitle === undefined) return 0;
// create a dom to calculate the width of the tag
const dom = document.createElement('span');
dom.style.display = 'inline-block';
dom.style.fontSize = '10px';
- dom.style.padding = '0 3px';
- dom.style.borderRadius = '1px';
+ dom.style.padding = '0 2px';
+ dom.style.borderRadius = '2px';
dom.textContent = props.maxTitle;
document.body.appendChild(dom);
const width = dom.clientWidth + 2;
@@ -177,6 +179,7 @@ export default defineComponent({
</Tag>
);
};
+
const getStyle = computed(() => {
if (tagWidth.value > 0) {
return { width: `${tagWidth.value}px`, textAlign: 'center' };