From 3ec1e1fd12b93b101316f76d32198c39abd46582 Mon Sep 17 00:00:00 2001 From: zhu-mingye <934230207@qq.com> Date: Fri, 17 Nov 2023 22:48:41 +0800 Subject: [PATCH] improve some feature (#2543) * improve some feature * Spotless Apply --------- Co-authored-by: zhu-mingye --- .../CustomEditor/CodeEdit/index.tsx | 2 +- dinky-web/src/components/Icons/DBIcons.tsx | 56 +- .../BottomContainer/Lineage/index.tsx | 28 +- .../DataStudio/HeaderContainer/function.tsx | 8 +- .../DataStudio/HeaderContainer/index.tsx | 29 +- .../LeftContainer/Project/constants.tsx | 31 +- .../MiddleContainer/Editor/index.tsx | 15 +- .../DataStudio/MiddleContainer/function.tsx | 33 ++ .../RightContainer/JobConfig/function.tsx | 5 +- .../RightContainer/JobConfig/index.tsx | 44 +- dinky-web/src/pages/DataStudio/constants.tsx | 40 +- dinky-web/src/pages/DataStudio/route.tsx | 2 +- dinky-web/src/pages/Metrics/Job/index.tsx | 512 +++++++++--------- .../RegCenter/Alert/AlertInstance/constans.ts | 28 +- .../ConfigurationForm/YarnConfig/index.tsx | 6 +- dinky-web/src/services/constants.tsx | 7 +- 16 files changed, 459 insertions(+), 387 deletions(-) diff --git a/dinky-web/src/components/CustomEditor/CodeEdit/index.tsx b/dinky-web/src/components/CustomEditor/CodeEdit/index.tsx index bc625617d0..9c7fa6cb96 100644 --- a/dinky-web/src/components/CustomEditor/CodeEdit/index.tsx +++ b/dinky-web/src/components/CustomEditor/CodeEdit/index.tsx @@ -292,7 +292,7 @@ const CodeEdit = (props: CodeEditFormProps & connect) => { wordWrap: autoWrap, autoDetectHighContrast: true, lineNumbers, - ...options, + ...options }; return ( <> diff --git a/dinky-web/src/components/Icons/DBIcons.tsx b/dinky-web/src/components/Icons/DBIcons.tsx index 1945751d35..3f3884e796 100644 --- a/dinky-web/src/components/Icons/DBIcons.tsx +++ b/dinky-web/src/components/Icons/DBIcons.tsx @@ -1,18 +1,20 @@ /* - * 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 + * 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. * - * 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 Icon from '@ant-design/icons'; @@ -56,6 +58,36 @@ export const MysqlIcons = (props: any) => { ); }; +export const SQLIcons = (props: any) => { + const size = props.size || defaultSvgSize; + return ( + <> + ( + + + + + )} + /> + + ); +}; + export const OracleIcons = (props: any) => { const size = props.size || defaultSvgSize; return ( diff --git a/dinky-web/src/pages/DataStudio/BottomContainer/Lineage/index.tsx b/dinky-web/src/pages/DataStudio/BottomContainer/Lineage/index.tsx index fb43419240..1dc3d9b2b6 100644 --- a/dinky-web/src/pages/DataStudio/BottomContainer/Lineage/index.tsx +++ b/dinky-web/src/pages/DataStudio/BottomContainer/Lineage/index.tsx @@ -1,19 +1,19 @@ /* * - * 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 + * 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 + * 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. + * 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. * */ @@ -56,11 +56,11 @@ const Lineage: React.FC = (props) => { const params: StudioLineageParams = { type: 1, // todo: 暂时写死 ,后续优化 dialect: dialect, - envId: envId, + envId: envId ?? -1, fragment: fragment, statement: statement, statementSet: statementSet, - databaseId: databaseId, + databaseId: databaseId ?? 0, variables: {} }; getDataByParams(API_CONSTANTS.STUDIO_GET_LINEAGE, params).then((res) => diff --git a/dinky-web/src/pages/DataStudio/HeaderContainer/function.tsx b/dinky-web/src/pages/DataStudio/HeaderContainer/function.tsx index 43f9814049..645fc93b6c 100644 --- a/dinky-web/src/pages/DataStudio/HeaderContainer/function.tsx +++ b/dinky-web/src/pages/DataStudio/HeaderContainer/function.tsx @@ -19,7 +19,7 @@ import { TabsPageType, TaskDataType } from '@/pages/DataStudio/model'; import { JOB_LIFE_CYCLE, JOB_STATUS } from '@/pages/DevOps/constants'; -import { HomeOutlined } from '@ant-design/icons'; +import { EnvironmentOutlined } from '@ant-design/icons'; /** * @description: 生成面包屑 @@ -27,10 +27,12 @@ import { HomeOutlined } from '@ant-design/icons'; export const buildBreadcrumbItems = (breadcrumb: string) => { // 如果有 activeBreadcrumbTitle, 则切割 activeBreadcrumbTitle, 生成面包屑数组, 并映射 const activeBreadcrumbTitleList = Array.from(breadcrumb.split('/')).map((title) => ({ - title: <>{title} + title: title, + // path: `/${title}`, + breadcrumbName: title })); - return [{ title: }, ...activeBreadcrumbTitleList]; + return [{ title: }, ...activeBreadcrumbTitleList]; }; export const projectCommonShow = (type?: TabsPageType) => { diff --git a/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx b/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx index 0756abb6d9..b20f9abe0f 100644 --- a/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx +++ b/dinky-web/src/pages/DataStudio/HeaderContainer/index.tsx @@ -35,11 +35,18 @@ import { executeSql, getJobPlan } from '@/pages/DataStudio/HeaderContainer/service'; -import { StateType, TabsPageSubType, TabsPageType, VIEW } from '@/pages/DataStudio/model'; +import { + DataStudioTabsItemType, + StateType, + TabsPageSubType, + TabsPageType, + VIEW +} from '@/pages/DataStudio/model'; import { JOB_LIFE_CYCLE, JOB_STATUS } from '@/pages/DevOps/constants'; import { ConfigStateType } from '@/pages/SettingCenter/GlobalSetting/model'; import { SettingConfigKeyEnum } from '@/pages/SettingCenter/GlobalSetting/SettingOverView/constants'; import { handlePutDataJson } from '@/services/BusinessCrud'; +import { DIALECT } from '@/services/constants'; import { BaseConfigProperties } from '@/types/SettingCenter/data'; import { l } from '@/utils/intl'; import { SuccessMessageAsync } from '@/utils/messages'; @@ -104,7 +111,7 @@ const HeaderContainer = (props: any) => { ); const currentData = getCurrentData(panes, activeKey); - const currentTab = getCurrentTab(panes, activeKey); + const currentTab = getCurrentTab(panes, activeKey) as DataStudioTabsItemType; useEffect(() => { queryDsConfig(SettingConfigKeyEnum.DOLPHIN_SCHEDULER.toLowerCase()); @@ -215,6 +222,8 @@ const HeaderContainer = (props: any) => { } }; + console.log('currentData', props, currentData); + const showExplain = async () => { modal.confirm({ title: l('pages.datastudio.explain.validate.msg'), @@ -242,7 +251,10 @@ const HeaderContainer = (props: any) => { // 执行图按钮 icon: , title: l('button.graph'), - isShow: projectCommonShow(currentTab?.type), + isShow: + (projectCommonShow(currentTab?.type) && + currentData?.dialect?.toLowerCase() === DIALECT.FLINK_SQL) || + currentData?.dialect?.toLowerCase() === DIALECT.FLINKJAR, click: async () => showDagGraph() }, { @@ -266,7 +278,9 @@ const HeaderContainer = (props: any) => { // 发布按钮 icon: isOnline(currentData) ? : , title: isOnline(currentData) ? l('button.offline') : l('button.publish'), - isShow: currentTab?.type == TabsPageType.project, + isShow: + currentTab?.type == TabsPageType.project && + currentData?.dialect?.toLowerCase() === DIALECT.FLINK_SQL, click: () => handleChangeJobLife() }, { @@ -302,7 +316,10 @@ const HeaderContainer = (props: any) => { click: handlerDebug, hotKey: (e: KeyboardEvent) => e.shiftKey && e.key === 'F9', hotKeyDesc: 'Shift+F9', - isShow: currentTab?.type == TabsPageType.project && !isRunning(currentData), + isShow: + currentTab?.type == TabsPageType.project && + !isRunning(currentData) && + currentData?.dialect?.toLowerCase() === DIALECT.FLINK_SQL, props: { style: { background: '#52c41a' }, type: 'primary' @@ -345,7 +362,7 @@ const HeaderContainer = (props: any) => { return ( - '} items={buildBreadcrumbItems(activeBreadcrumbTitle)} /> + ); }; diff --git a/dinky-web/src/pages/DataStudio/LeftContainer/Project/constants.tsx b/dinky-web/src/pages/DataStudio/LeftContainer/Project/constants.tsx index d86e0602eb..79152ee4f0 100644 --- a/dinky-web/src/pages/DataStudio/LeftContainer/Project/constants.tsx +++ b/dinky-web/src/pages/DataStudio/LeftContainer/Project/constants.tsx @@ -1,19 +1,19 @@ /* * - * 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 + * 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 + * 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. + * 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. * */ @@ -89,7 +89,8 @@ export const JOB_RIGHT_MENU = (disabled = false): MenuItemType[] => [ { key: 'exportJson', icon: , - label: l('right.menu.exportJson') + label: l('right.menu.exportJson'), + disabled: true // todo: 此功能暂时不实现 先禁用掉 }, { key: 'copy', @@ -128,10 +129,6 @@ export const JOB_TYPE: DefaultOptionType[] = [ { value: 'FlinkSqlEnv', label: 'FlinkSqlEnv' - }, - { - value: 'KubernetesApplication', - label: 'KubernetesApplication' } ] }, diff --git a/dinky-web/src/pages/DataStudio/MiddleContainer/Editor/index.tsx b/dinky-web/src/pages/DataStudio/MiddleContainer/Editor/index.tsx index ea5525d6ad..0c9c0dca40 100644 --- a/dinky-web/src/pages/DataStudio/MiddleContainer/Editor/index.tsx +++ b/dinky-web/src/pages/DataStudio/MiddleContainer/Editor/index.tsx @@ -21,6 +21,7 @@ import CodeEdit from '@/components/CustomEditor/CodeEdit'; import { useEditor } from '@/hooks/useEditor'; import { TASK_VAR_FILTER } from '@/pages/DataStudio/MiddleContainer/Editor/constants'; import DiffModal from '@/pages/DataStudio/MiddleContainer/Editor/DiffModal'; +import { matchLanguage } from '@/pages/DataStudio/MiddleContainer/function'; import { DataStudioTabsItemType, StateType, @@ -29,7 +30,6 @@ import { TaskDataType } from '@/pages/DataStudio/model'; import { JOB_LIFE_CYCLE } from '@/pages/DevOps/constants'; -import { DIALECT } from '@/services/constants'; import { API_CONSTANTS } from '@/services/endpoints'; import { l } from '@/utils/intl'; import { connect, useRequest } from '@@/exports'; @@ -141,11 +141,7 @@ const CodeEditor: React.FC = (props) => { @@ -153,12 +149,7 @@ const CodeEditor: React.FC = (props) => { monacoRef={monacoInstance} editorRef={editorInstance} code={tabsItem?.params?.taskData?.statement} - language={ - tabsItem?.params?.taskData?.dialect?.toLowerCase() === DIALECT.FLINK_SQL - ? 'flinksql' - : 'sql' - } - // language={'sql'} + language={matchLanguage(tabsItem?.params?.taskData?.dialect)} editorDidMount={editorDidMount} onChange={handleEditChange} enableSuggestions={true} diff --git a/dinky-web/src/pages/DataStudio/MiddleContainer/function.tsx b/dinky-web/src/pages/DataStudio/MiddleContainer/function.tsx index 3e22f5906d..17ef5f9bf6 100644 --- a/dinky-web/src/pages/DataStudio/MiddleContainer/function.tsx +++ b/dinky-web/src/pages/DataStudio/MiddleContainer/function.tsx @@ -40,11 +40,42 @@ import { PhoenixIcons, PostgresqlIcons, PrestoIcons, + SQLIcons, SqlServerIcons, StarRocksIcons } from '@/components/Icons/DBIcons'; import { DIALECT } from '@/services/constants'; +export const matchLanguage = (language = DIALECT.FLINK_SQL) => { + switch (language.toLowerCase()) { + case DIALECT.FLINK_SQL: + case DIALECT.FLINKSQLENV: + case DIALECT.FLINKJAR: + return DIALECT.FLINK_SQL; + case DIALECT.SQL: + case DIALECT.SQLSERVER: + case DIALECT.POSTGRESQL: + case DIALECT.HIVE: + case DIALECT.CLICKHOUSE: + case DIALECT.ORACLE: + case DIALECT.DORIS: + case DIALECT.PHOENIX: + case DIALECT.PRESTO: + case DIALECT.MYSQL: + case DIALECT.STARROCKS: + return DIALECT.SQL; + case DIALECT.PYTHON: + case DIALECT.PYTHON_LONG: + return DIALECT.PYTHON; + case DIALECT.SCALA: + return DIALECT.SCALA; + case DIALECT.JAVA: + return DIALECT.JAVA; + default: + return DIALECT.SQL; + } +}; +// export const getTabIcon = (type: string, size?: number) => { if (!type) { return ; @@ -78,6 +109,8 @@ export const getTabIcon = (type: string, size?: number) => { return ; case DIALECT.FLINKSQLENV: return ; + case DIALECT.SQL: + return ; case DIALECT.MYSQL: return ; case DIALECT.ORACLE: diff --git a/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/function.tsx b/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/function.tsx index 77a73d087d..c3835725c1 100644 --- a/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/function.tsx +++ b/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/function.tsx @@ -118,7 +118,7 @@ export const buildClusterConfigOptions = (current: any, clusterConfiguration: Cl /** * build env options */ -export const buildEnvOptions = (env: any[]) => { +export const buildEnvOptions = (env: any[], isDisabled: boolean) => { const envList: DefaultOptionType[] = [ { label: l('button.disable'), @@ -139,7 +139,8 @@ export const buildEnvOptions = (env: any[]) => { envList.push({ label: tag, value: item.id, - key: item.id + key: item.id, + disabled: !item.enabled || !isDisabled }); } return envList; diff --git a/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/index.tsx b/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/index.tsx index 2deb6ac4ba..bb824193e8 100644 --- a/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/index.tsx +++ b/dinky-web/src/pages/DataStudio/RightContainer/JobConfig/index.tsx @@ -33,7 +33,7 @@ import { calculatorWidth } from '@/pages/DataStudio/RightContainer/JobConfig/function'; import { AlertStateType, ALERT_MODEL_ASYNC } from '@/pages/RegCenter/Alert/AlertInstance/model'; -import { RUN_MODE, SWITCH_OPTIONS } from '@/services/constants'; +import { DIALECT, RUN_MODE, SWITCH_OPTIONS } from '@/services/constants'; import { l } from '@/utils/intl'; import { InfoCircleOutlined } from '@ant-design/icons'; import { @@ -46,7 +46,6 @@ import { ProFormText } from '@ant-design/pro-components'; import { Badge, Space, Typography } from 'antd'; -import { useForm } from 'antd/es/form/Form'; import { debounce } from 'lodash'; import { useEffect } from 'react'; import { connect } from 'umi'; @@ -171,6 +170,7 @@ const JobConfig = (props: any) => { className={'data-studio-form'} style={{ paddingInline: '15px', overflow: 'scroll' }} form={form} + initialValues={current} submitter={false} layout='vertical' onValuesChange={debounce(onValuesChange, 500)} @@ -211,7 +211,7 @@ const JobConfig = (props: any) => { name='envId' label={l('pages.datastudio.label.jobConfig.flinksql.env')} tooltip={l('pages.datastudio.label.jobConfig.flinksql.env.tip1')} - options={buildEnvOptions(env)} + options={buildEnvOptions(env, current?.dialect?.toLowerCase() === DIALECT.FLINK_SQL)} rules={[ { required: true, message: l('pages.datastudio.label.jobConfig.flinksql.env.tip1') } ]} @@ -227,17 +227,19 @@ const JobConfig = (props: any) => { max={9999} min={1} /> + {current?.dialect?.toLowerCase() === DIALECT.FLINK_SQL && ( + + }} + {...SWITCH_OPTIONS()} + /> + )} - - }} - {...SWITCH_OPTIONS()} - /> { > - {/* todo: 级联组件会受组件的 name 属性一致的影响,造成相同 name 属性值自动填充一样的值, 待寻找合适解决方案 */} - {/**/} + + {l('right.menu.closeAll')} + + ) }, { key: 'closeOther', - label: l('right.menu.closeOther') + label: ( + + + {l('right.menu.closeOther')} + + ) } ]; diff --git a/dinky-web/src/pages/DataStudio/route.tsx b/dinky-web/src/pages/DataStudio/route.tsx index a6b7faaf5c..81b44119ad 100644 --- a/dinky-web/src/pages/DataStudio/route.tsx +++ b/dinky-web/src/pages/DataStudio/route.tsx @@ -126,7 +126,7 @@ export const RightSide: TabProp[] = [ icon: , label: l('menu.datastudio.jobInfo'), children: , - isShow: (type) => type !== TabsPageType.None + isShow: (type) => type === TabsPageType.project } ]; diff --git a/dinky-web/src/pages/Metrics/Job/index.tsx b/dinky-web/src/pages/Metrics/Job/index.tsx index 8bc81ea79f..9d0a5cd015 100644 --- a/dinky-web/src/pages/Metrics/Job/index.tsx +++ b/dinky-web/src/pages/Metrics/Job/index.tsx @@ -19,9 +19,9 @@ import { ChartData, JobMetrics, MetricsLayout, SubTask, Task } from '@/pages/Metrics/Job/data'; import { - buildMetricsList, - buildRunningJobList, - buildSubTaskList + buildMetricsList, + buildRunningJobList, + buildSubTaskList } from '@/pages/Metrics/Job/function'; import { getFlinkRunTask, saveFlinkMetrics } from '@/pages/Metrics/Job/service'; import { getData } from '@/services/api'; @@ -33,274 +33,274 @@ import { useEffect, useState } from 'react'; import FlinkChart from '../../../components/FlinkChart'; const getJobMetrics = async (job: JobMetrics) => { - const url = - API_CONSTANTS.FLINK_PROXY + - '/' + - job.url + - '/jobs/' + - job.flinkJobId + - '/vertices/' + - job.subTaskId + - '/metrics' + - '?get=' + - encodeURIComponent(job.metrics); - const json = await getData(url); - json[0].time = new Date(); - return json[0] as ChartData; + const url = + API_CONSTANTS.FLINK_PROXY + + '/' + + job.url + + '/jobs/' + + job.flinkJobId + + '/vertices/' + + job.subTaskId + + '/metrics' + + '?get=' + + encodeURIComponent(job.metrics); + const json = await getData(url); + json[0].time = new Date(); + return json[0] as ChartData; }; const Job = () => { - const [metricsData, setMetricsData] = useState({ - url: '', - jid: '', - flinkName: '', - selectTaskId: 0, - selectSubTask: '', - selectMetrics: [] as string[] - }); + const [metricsData, setMetricsData] = useState({ + url: '', + jid: '', + flinkName: '', + selectTaskId: 0, + selectSubTask: '', + selectMetrics: [] as string[] + }); - const [subTaskList, setSubTaskList] = useState([]); - const [metrics, setMetrics] = useState([]); - const [taskData, setTaskData] = useState([]); - const [jobMetricsList, setJobMetricsList] = useState([]); - const [chartData, setChartData] = useState>({}); - const [layoutName, setLayoutName] = useState(''); - const [timers, setTimers] = useState>({}); + const [subTaskList, setSubTaskList] = useState([]); + const [metrics, setMetrics] = useState([]); + const [taskData, setTaskData] = useState([]); + const [jobMetricsList, setJobMetricsList] = useState([]); + const [chartData, setChartData] = useState>({}); + const [layoutName, setLayoutName] = useState(''); + const [timers, setTimers] = useState>({}); - useEffect(() => { - getFlinkRunTask().then((res) => { - setTaskData(res.data); - }); - }, []); + useEffect(() => { + getFlinkRunTask().then((res) => { + setTaskData(res.data); + }); + }, []); - useEffect(() => { - Object.keys(timers) - .filter((x) => !jobMetricsList.map((x) => x.metrics).includes(x)) - // @ts-ignore - .forEach((x) => clearInterval(timers[x])); - }, [jobMetricsList]); + useEffect(() => { + Object.keys(timers) + .filter((x) => !jobMetricsList.map((x) => x.metrics).includes(x)) + // @ts-ignore + .forEach((x) => clearInterval(timers[x])); + }, [jobMetricsList]); - /** - * query flink job detail - * @param {number} id - * @returns {Promise} - */ - const getFlinkTaskDetail = async (id: number) => { - return await getData(API_CONSTANTS.REFRESH_JOB_DETAIL, { id: id }); - }; + /** + * query flink job detail + * @param {number} id + * @returns {Promise} + */ + const getFlinkTaskDetail = async (id: number) => { + return await getData(API_CONSTANTS.REFRESH_JOB_DETAIL, { id: id }); + }; - /** - * query flink job sub task - * @param {string} url - * @param {string} jid - * @returns {Promise<[]>} - */ - const getFlinkJobSubTask = async (url: string, jid: string) => { - const flinkJobVertices = await getData(API_CONSTANTS.FLINK_PROXY + '/' + url + '/jobs/' + jid); - return flinkJobVertices.vertices as SubTask[]; - }; + /** + * query flink job sub task + * @param {string} url + * @param {string} jid + * @returns {Promise<[]>} + */ + const getFlinkJobSubTask = async (url: string, jid: string) => { + const flinkJobVertices = await getData(API_CONSTANTS.FLINK_PROXY + '/' + url + '/jobs/' + jid); + return flinkJobVertices.vertices as SubTask[]; + }; - /** - * query flink job metrics list - * @param {string} url - * @param {string} jid - * @param subTask - * @returns {Promise} - */ - const getFlinkJobMetrics = async (url: string, jid: string, subTask: string) => { - const flinkJobMetrics = await getData( - API_CONSTANTS.FLINK_PROXY + '/' + url + '/jobs/' + jid + '/vertices/' + subTask + '/metrics' - ); - return (flinkJobMetrics as any[]).map((x) => x.id as string); - }; + /** + * query flink job metrics list + * @param {string} url + * @param {string} jid + * @param subTask + * @returns {Promise} + */ + const getFlinkJobMetrics = async (url: string, jid: string, subTask: string) => { + const flinkJobMetrics = await getData( + API_CONSTANTS.FLINK_PROXY + '/' + url + '/jobs/' + jid + '/vertices/' + subTask + '/metrics' + ); + return (flinkJobMetrics as any[]).map((x) => x.id as string); + }; - /** - * 1 level , change running job - * @returns {Promise} - * @param taskId - */ - const handleRunningJobChange = async (taskId: number) => { - // query data of flink running job - const taskDetail = await getFlinkTaskDetail(taskId); - // 解构出 flink job url , job name , job id - const { - cluster: { hosts: url }, - instance: { name: flinkJobName, jid: flinkJobId } - } = taskDetail.data; - setMetricsData((prevState) => ({ - ...prevState, - url: url, - flinkName: flinkJobName, - jid: flinkJobId, - selectTaskId: taskId - })); - const subTasks = await getFlinkJobSubTask(url, flinkJobId); - setSubTaskList(subTasks); - }; + /** + * 1 level , change running job + * @returns {Promise} + * @param taskId + */ + const handleRunningJobChange = async (taskId: number) => { + // query data of flink running job + const taskDetail = await getFlinkTaskDetail(taskId); + // 解构出 flink job url , job name , job id + const { + cluster: { hosts: url }, + instance: { name: flinkJobName, jid: flinkJobId } + } = taskDetail.data; + setMetricsData((prevState) => ({ + ...prevState, + url: url, + flinkName: flinkJobName, + jid: flinkJobId, + selectTaskId: taskId + })); + const subTasks = await getFlinkJobSubTask(url, flinkJobId); + setSubTaskList(subTasks); + }; - /** - * 2 level , change subtask - * @returns {Promise} - * @param subTaskName - */ - const handleSubTaskChange = async (subTaskName: string) => { - setMetricsData((prevState) => ({ - ...prevState, - selectSubTask: subTaskName - })); - const jobMetricsDataList = await getFlinkJobMetrics( - metricsData.url, - metricsData.jid, - subTaskName - ); - setMetrics(jobMetricsDataList.sort()); - }; + /** + * 2 level , change subtask + * @returns {Promise} + * @param subTaskName + */ + const handleSubTaskChange = async (subTaskName: string) => { + setMetricsData((prevState) => ({ + ...prevState, + selectSubTask: subTaskName + })); + const jobMetricsDataList = await getFlinkJobMetrics( + metricsData.url, + metricsData.jid, + subTaskName + ); + setMetrics(jobMetricsDataList.sort()); + }; - /** - * 3 level , change metrics list - * @returns {Promise} - * @param selectList - */ - const handleMetricsChange = async (selectList: string[]) => { - setMetricsData((prevState) => ({ - ...prevState, - selectMetrics: selectList - })); + /** + * 3 level , change metrics list + * @returns {Promise} + * @param selectList + */ + const handleMetricsChange = async (selectList: string[]) => { + setMetricsData((prevState) => ({ + ...prevState, + selectMetrics: selectList + })); - const d: JobMetrics[] = selectList.map((item) => { - return { - taskId: metricsData.selectTaskId, - url: metricsData.url, - flinkJobId: metricsData.jid, - jobName: metricsData.flinkName, - subTaskId: metricsData.selectSubTask, - metrics: item, - layoutName: layoutName, - title: item, - showSize: '25%', - showType: 'Chart' - }; - }); - d.forEach((j) => { - const data: ChartData[] = []; - chartData[j.taskId + j.subTaskId + j.metrics] = data; - setChartData(chartData); - timers[j.metrics] = setInterval(() => { - getJobMetrics(j).then((res) => { - data.push(res); - }); - }, 1000); - setTimers(timers); + const d: JobMetrics[] = selectList.map((item) => { + return { + taskId: metricsData.selectTaskId, + url: metricsData.url, + flinkJobId: metricsData.jid, + jobName: metricsData.flinkName, + subTaskId: metricsData.selectSubTask, + metrics: item, + layoutName: layoutName, + title: item, + showSize: '25%', + showType: 'Chart' + }; + }); + d.forEach((j) => { + const data: ChartData[] = []; + chartData[j.taskId + j.subTaskId + j.metrics] = data; + setChartData(chartData); + timers[j.metrics] = setInterval(() => { + getJobMetrics(j).then((res) => { + data.push(res); }); - setJobMetricsList(d); - }; - /** - * render metrics card list - * @param {JobMetrics[]} metricsList - * @returns {JSX.Element} - */ - const renderMetricsCardList = (metricsList: JobMetrics[]) => { - return ( - <> - - {metricsList.map((j) => { - return ( - { - j.showSize = chartSize; - j.showType = chartType; - }} - data={chartData[j.taskId + j.subTaskId + j.metrics]} - title={j.metrics} - extraType={'size'} - /> - ); - })} - - - ); - }; - + }, 1000); + setTimers(timers); + }); + setJobMetricsList(d); + }; + /** + * render metrics card list + * @param {JobMetrics[]} metricsList + * @returns {JSX.Element} + */ + const renderMetricsCardList = (metricsList: JobMetrics[]) => { return ( - <> - setLayoutName(e.target.value)} - style={{ width: '100vh' }} - /> - } - extra={ - - } - > - handleRunningJobChange(value as number) }} - /> - {metricsData.selectTaskId !== 0 && ( - handleSubTaskChange(value as string) }} - /> - )} - {metricsData.selectSubTask !== '' && ( - handleMetricsChange(value as string[]) }} - /> - )} - {/* render metrics list */} - {jobMetricsList.length > 0 && renderMetricsCardList(jobMetricsList)} - - + <> + + {metricsList.map((j) => { + return ( + { + j.showSize = chartSize; + j.showType = chartType; + }} + data={chartData[j.taskId + j.subTaskId + j.metrics]} + title={j.metrics} + extraType={'size'} + /> + ); + })} + + ); + }; + + return ( + <> + setLayoutName(e.target.value)} + style={{ width: '100vh' }} + /> + } + extra={ + + } + > + handleRunningJobChange(value as number) }} + /> + {metricsData.selectTaskId !== 0 && ( + handleSubTaskChange(value as string) }} + /> + )} + {metricsData.selectSubTask !== '' && ( + handleMetricsChange(value as string[]) }} + /> + )} + {/* render metrics list */} + {jobMetricsList.length > 0 && renderMetricsCardList(jobMetricsList)} + + + ); }; export default Job; diff --git a/dinky-web/src/pages/RegCenter/Alert/AlertInstance/constans.ts b/dinky-web/src/pages/RegCenter/Alert/AlertInstance/constans.ts index b21eb260c8..ac97f6112a 100644 --- a/dinky-web/src/pages/RegCenter/Alert/AlertInstance/constans.ts +++ b/dinky-web/src/pages/RegCenter/Alert/AlertInstance/constans.ts @@ -1,18 +1,20 @@ /* - * 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 + * 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. * - * 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 { ALERT_TYPE } from '@/types/RegCenter/data.d'; @@ -43,7 +45,7 @@ export const ALERT_TYPE_LIST_OPTIONS: DefaultOptionType[] = [ { label: l('rc.ai.sms'), value: ALERT_TYPE.SMS, - disabled: false + disabled: true // todo: 短信功能暂时不实现, 禁用, 后续实现后再打开 } ]; diff --git a/dinky-web/src/pages/RegCenter/Cluster/Configuration/components/ConfigurationModal/ConfigurationForm/YarnConfig/index.tsx b/dinky-web/src/pages/RegCenter/Cluster/Configuration/components/ConfigurationModal/ConfigurationForm/YarnConfig/index.tsx index d531b925b2..509cf5c284 100644 --- a/dinky-web/src/pages/RegCenter/Cluster/Configuration/components/ConfigurationModal/ConfigurationForm/YarnConfig/index.tsx +++ b/dinky-web/src/pages/RegCenter/Cluster/Configuration/components/ConfigurationModal/ConfigurationForm/YarnConfig/index.tsx @@ -39,7 +39,7 @@ const YarnConfig = (props: { flinkConfigOptions: DefaultOptionType[] }) => { {l('rc.cc.hadoopConfig')} { {l('rc.cc.flinkConfig')} { />