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 2022/11/02 01:40:42 UTC

[incubator-streampark] branch dev updated: [Fix] Resolve ingress setup issues, project build issues, role bug (#1946)

This is an automated email from the ASF dual-hosted git repository.

benjobs 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 677d838b4 [Fix] Resolve ingress setup issues, project build issues, role bug (#1946)
677d838b4 is described below

commit 677d838b42ceb2a0eca3ef4a2a0d9a75c328c1cc
Author: Sizhu Wang <12...@qq.com>
AuthorDate: Wed Nov 2 09:40:37 2022 +0800

    [Fix] Resolve ingress setup issues, project build issues, role bug (#1946)
    
    * [Fix] Resolve ingress setup issues, project build issues, role modification issues
    
    * [Fix] change the order monaco dispose
---
 .../components/Form/src/components/ApiSelect.vue   | 10 ++++-
 .../components/Tree/src/components/TreeHeader.vue  |  4 +-
 .../src/hooks/web/useMonaco.ts                     |  3 +-
 .../layouts/default/header/components/Slogan.vue   | 22 ++++++++++-
 .../layouts/default/header/components/UserTeam.vue | 27 +++++++++----
 .../src/locales/lang/en/system/team.ts             |  2 +
 .../src/router/guard/index.ts                      |  2 +-
 .../src/settings/projectSetting.ts                 |  2 +-
 .../src/store/modules/user.ts                      |  2 +-
 .../src/utils/http/axios/errorHandle.ts            |  6 ++-
 .../src/views/base/login/LoginForm.vue             |  1 -
 .../src/views/base/login/useTeamModal.tsx          |  1 -
 .../src/views/flink/app/View.vue                   |  2 +-
 .../flink/app/components/AppView/LogModal.vue      | 13 +++++--
 .../src/views/flink/app/data/index.ts              | 32 +++-------------
 .../src/views/flink/app/hooks/useApp.tsx           |  4 +-
 .../src/views/flink/app/hooks/useAppTableAction.ts |  2 +-
 .../src/views/flink/app/hooks/useFlinkRender.tsx   |  2 +-
 .../src/views/flink/app/hooks/useLog.ts            | 41 +++++++++++++++++---
 .../views/flink/project/components/ListItem.vue    | 18 +++------
 .../views/flink/project/components/LogModal.vue    | 19 +++++++---
 .../views/flink/setting/components/SettingList.vue |  2 +-
 .../flink/setting/components/SystemSetting.vue     |  2 +-
 .../views/system/role/components/RoleDrawer.vue    | 44 +++++++++++-----------
 .../src/views/system/team/TeamDrawer.vue           | 11 +++++-
 25 files changed, 170 insertions(+), 104 deletions(-)

diff --git a/streampark-console/streampark-console-newui/src/components/Form/src/components/ApiSelect.vue b/streampark-console/streampark-console-newui/src/components/Form/src/components/ApiSelect.vue
index ab5729aae..e95066f2c 100644
--- a/streampark-console/streampark-console-newui/src/components/Form/src/components/ApiSelect.vue
+++ b/streampark-console/streampark-console-newui/src/components/Form/src/components/ApiSelect.vue
@@ -74,6 +74,10 @@
       valueField: propTypes.string.def('value'),
       immediate: propTypes.bool.def(true),
       alwaysLoad: propTypes.bool.def(false),
+      optionsData: {
+        type: Array as PropType<any[]>,
+        detail: () => [],
+      },
     },
     emits: ['options-change', 'change'],
     setup(props, { emit }) {
@@ -89,7 +93,6 @@
 
       const getOptions = computed(() => {
         const { labelField, valueField, numberToString } = props;
-
         return unref(options).reduce((prev, next: Recordable) => {
           if (next) {
             const value = next[valueField];
@@ -156,7 +159,10 @@
       function handleChange(_, ...args) {
         emitData.value = args;
       }
-
+      // set default options
+      if (props.immediate && props.alwaysLoad) {
+        options.value = props.optionsData || [];
+      }
       return { state, attrs, getOptions, loading, t, handleFetch, handleChange };
     },
   });
diff --git a/streampark-console/streampark-console-newui/src/components/Tree/src/components/TreeHeader.vue b/streampark-console/streampark-console-newui/src/components/Tree/src/components/TreeHeader.vue
index a07a2e436..106c22646 100644
--- a/streampark-console/streampark-console-newui/src/components/Tree/src/components/TreeHeader.vue
+++ b/streampark-console/streampark-console-newui/src/components/Tree/src/components/TreeHeader.vue
@@ -132,8 +132,8 @@
             divider: checkable,
           },
           ...defaultToolbarList,
-          { label: t('component.tree.checkStrictly'), value: ToolbarEnum.CHECK_STRICTLY },
-          { label: t('component.tree.checkUnStrictly'), value: ToolbarEnum.CHECK_UN_STRICTLY },
+          // { label: t('component.tree.checkStrictly'), value: ToolbarEnum.CHECK_STRICTLY },
+          // { label: t('component.tree.checkUnStrictly'), value: ToolbarEnum.CHECK_UN_STRICTLY },
         ]
       : defaultToolbarList;
   });
diff --git a/streampark-console/streampark-console-newui/src/hooks/web/useMonaco.ts b/streampark-console/streampark-console-newui/src/hooks/web/useMonaco.ts
index 025d27f77..ea23f14c1 100644
--- a/streampark-console/streampark-console-newui/src/hooks/web/useMonaco.ts
+++ b/streampark-console/streampark-console-newui/src/hooks/web/useMonaco.ts
@@ -148,6 +148,7 @@ export function useMonaco(
       });
     }
   };
+
   const disposeInstance = async () => {
     editor?.dispose();
   };
@@ -210,8 +211,8 @@ export function useMonaco(
 
   tryOnUnmounted(() => {
     stop();
-    disposeInstance();
     disposable?.dispose();
+    disposeInstance();
   });
 
   return {
diff --git a/streampark-console/streampark-console-newui/src/layouts/default/header/components/Slogan.vue b/streampark-console/streampark-console-newui/src/layouts/default/header/components/Slogan.vue
index 2ce8479f3..a3623fb2e 100755
--- a/streampark-console/streampark-console-newui/src/layouts/default/header/components/Slogan.vue
+++ b/streampark-console/streampark-console-newui/src/layouts/default/header/components/Slogan.vue
@@ -15,12 +15,21 @@
   limitations under the License.
 -->
 <script lang="ts" setup name="Slogan">
+  import { computed } from 'vue';
+  import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
   import { useDesign } from '/@/hooks/web/useDesign';
 
   const { prefixCls } = useDesign('slogan');
+  const { getCollapsed } = useMenuSetting();
+  const slognClass = computed(() => [
+    prefixCls,
+    {
+      'collapse-slogo': getCollapsed.value,
+    },
+  ]);
 </script>
 <template>
-  <div :class="`${prefixCls}`">
+  <div :class="slognClass">
     <span :class="`${prefixCls}-streampark`">
       Apache StreamPark,&nbsp; Make&nbsp; stream processing&nbsp;easier!
     </span>
@@ -57,4 +66,15 @@
       }
     }
   }
+
+  @media screen and (max-width: 1585px) {
+    .@{prefix-cls}:not(.collapse-slogo) {
+      display: none;
+    }
+  }
+  @media screen and (max-width: 1420px) {
+    .@{prefix-cls}.collapse-slogo {
+      display: none;
+    }
+  }
 </style>
diff --git a/streampark-console/streampark-console-newui/src/layouts/default/header/components/UserTeam.vue b/streampark-console/streampark-console-newui/src/layouts/default/header/components/UserTeam.vue
index 8367f24a3..5d04b6e35 100644
--- a/streampark-console/streampark-console-newui/src/layouts/default/header/components/UserTeam.vue
+++ b/streampark-console/streampark-console-newui/src/layouts/default/header/components/UserTeam.vue
@@ -15,31 +15,42 @@
   limitations under the License.
 -->
 <script setup lang="ts">
-  import { Select } from 'ant-design-vue';
+  import { ApiSelect } from '/@/components/Form';
   import { useUserStoreWithOut } from '/@/store/modules/user';
-  const SelectOption = Select.Option;
+  import { fetchUserTeam } from '/@/api/system/member';
 
   const userStore = useUserStoreWithOut();
 
   function handleSetTeamId(value: string) {
     userStore.setTeamId({ teamId: value });
   }
+
+  function handleOptionsChange(value: Recordable[]) {
+    const hasIn = value.find((r: Recordable) => r.value == userStore.getTeamId);
+    // select team not exist
+    if (!hasIn) {
+      handleSetTeamId(value[0].value);
+    }
+  }
 </script>
 
 <template>
   <div class="flex items-center min-w-160px">
     <span class="text-blue-500 pr-10px"> Team : </span>
-    <Select
+    <ApiSelect
+      :api="fetchUserTeam as any"
+      labelField="teamName"
+      valueField="id"
+      :params="{ userId: userStore.getUserInfo?.userId }"
+      :alwaysLoad="true"
       :allow-clear="false"
       class="flex-1"
+      :optionsData="userStore.getTeamList.map((t) => ({ teamName: t.label, id: t.value }))"
       @change="handleSetTeamId"
       :value="userStore.teamId"
       placeholder="Team"
+      @optionsChange="handleOptionsChange"
       size="small"
-    >
-      <SelectOption v-for="t in userStore.getTeamList" :key="t.value">
-        {{ t.label }}
-      </SelectOption>
-    </Select>
+    />
   </div>
 </template>
diff --git a/streampark-console/streampark-console-newui/src/locales/lang/en/system/team.ts b/streampark-console/streampark-console-newui/src/locales/lang/en/system/team.ts
index 3a381c8e1..0c066a046 100644
--- a/streampark-console/streampark-console-newui/src/locales/lang/en/system/team.ts
+++ b/streampark-console/streampark-console-newui/src/locales/lang/en/system/team.ts
@@ -25,9 +25,11 @@ export default {
   table: {
     title: 'Team List',
     teamName: 'Team Name',
+    teamNamePlaceholder: 'please enter Team Name',
     description: 'Description',
     createTime: 'Create Time',
     modifyTime: 'Modify Time',
     descriptionMessage: 'exceeds maximum length limit of 100 characters',
+    teamMessage: 'teamName must be at least 4 characters',
   },
 };
diff --git a/streampark-console/streampark-console-newui/src/router/guard/index.ts b/streampark-console/streampark-console-newui/src/router/guard/index.ts
index b43c2166d..7c9b323a4 100644
--- a/streampark-console/streampark-console-newui/src/router/guard/index.ts
+++ b/streampark-console/streampark-console-newui/src/router/guard/index.ts
@@ -88,7 +88,7 @@ function createPageLoadingGuard(router: Router) {
       // The timer simulates the loading time to prevent flashing too fast,
       setTimeout(() => {
         appStore.setPageLoading(false);
-      }, 220);
+      }, 200);
     }
     return true;
   });
diff --git a/streampark-console/streampark-console-newui/src/settings/projectSetting.ts b/streampark-console/streampark-console-newui/src/settings/projectSetting.ts
index 1168270d0..7dd2a2936 100644
--- a/streampark-console/streampark-console-newui/src/settings/projectSetting.ts
+++ b/streampark-console/streampark-console-newui/src/settings/projectSetting.ts
@@ -160,7 +160,7 @@ const setting: ProjectConfig = {
 
     // Whether to open page switching loading
     // Only open when enable=true
-    openPageLoading: false,
+    openPageLoading: true,
 
     // Whether to open the top progress bar
     openNProgress: true,
diff --git a/streampark-console/streampark-console-newui/src/store/modules/user.ts b/streampark-console/streampark-console-newui/src/store/modules/user.ts
index 2a6f3ed37..7ab760369 100644
--- a/streampark-console/streampark-console-newui/src/store/modules/user.ts
+++ b/streampark-console/streampark-console-newui/src/store/modules/user.ts
@@ -147,7 +147,7 @@ export const useUserStore = defineStore({
       this.setPermissions(permissions);
     },
     // set team
-    async setTeamId(data: { teamId: string; userId?: string }): Promise<boolean> {
+    async setTeamId(data: { teamId: string; userId?: string | number }): Promise<boolean> {
       try {
         const { refreshMenu } = usePermission();
 
diff --git a/streampark-console/streampark-console-newui/src/utils/http/axios/errorHandle.ts b/streampark-console/streampark-console-newui/src/utils/http/axios/errorHandle.ts
index 21be3bd3f..37b76e1dc 100644
--- a/streampark-console/streampark-console-newui/src/utils/http/axios/errorHandle.ts
+++ b/streampark-console/streampark-console-newui/src/utils/http/axios/errorHandle.ts
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 import { AxiosResponse } from 'axios';
+import { useI18n } from '/@/hooks/web/useI18n';
 import { SessionTimeoutProcessingEnum } from '/@/enums/appEnum';
 import { useMessage } from '/@/hooks/web/useMessage';
 import projectSetting from '/@/settings/projectSetting';
@@ -22,6 +23,7 @@ import { useUserStore } from '/@/store/modules/user';
 
 export function errorHandler(response: AxiosResponse<any>) {
   const { Swal, notification } = useMessage();
+  const { t } = useI18n();
   const stp = projectSetting.sessionTimeoutProcessing;
 
   if (response) {
@@ -79,8 +81,8 @@ export function errorHandler(response: AxiosResponse<any>) {
             break;
           default:
             notification.error({
-              message: errorMessage,
-              duration: 4,
+              message: errorMessage || t('sys.api.networkExceptionMsg'),
+              duration: 3,
             });
             break;
         }
diff --git a/streampark-console/streampark-console-newui/src/views/base/login/LoginForm.vue b/streampark-console/streampark-console-newui/src/views/base/login/LoginForm.vue
index f86fc1d70..e8b9b5a12 100644
--- a/streampark-console/streampark-console-newui/src/views/base/login/LoginForm.vue
+++ b/streampark-console/streampark-console-newui/src/views/base/login/LoginForm.vue
@@ -181,7 +181,6 @@
           createMessage.success(`${t('sys.login.loginSuccessTitle')} ${successText}`);
         }
       } catch (error: any) {
-        createMessage.error(error.response?.data?.data?.message || 'login failed');
         return Promise.reject(error);
       }
     } catch (error) {
diff --git a/streampark-console/streampark-console-newui/src/views/base/login/useTeamModal.tsx b/streampark-console/streampark-console-newui/src/views/base/login/useTeamModal.tsx
index 8cc969a48..79f68e973 100644
--- a/streampark-console/streampark-console-newui/src/views/base/login/useTeamModal.tsx
+++ b/streampark-console/streampark-console-newui/src/views/base/login/useTeamModal.tsx
@@ -16,7 +16,6 @@
  */
 import { Select } from 'ant-design-vue';
 import { ref } from 'vue';
-import { getTeamList } from '/@/api/system/team';
 import Icon from '/@/components/Icon';
 import { useMessage } from '/@/hooks/web/useMessage';
 import { useUserStore } from '/@/store/modules/user';
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/View.vue b/streampark-console/streampark-console-newui/src/views/flink/app/View.vue
index bb2faf41d..f9bcf7028 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/View.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/View.vue
@@ -148,7 +148,7 @@
   function handlePageDataReload() {
     nextTick(() => {
       appDashboardRef.value?.handleDashboard(false);
-      reload({ polling: true });
+      reload();
     });
   }
   const { start, stop } = useTimeoutFn(() => {
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue b/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue
index 154c4a008..c759c1491 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/components/AppView/LogModal.vue
@@ -39,7 +39,7 @@
     data && onReceiveModalData(data);
   });
 
-  const { setContent, logRef } = useLog();
+  const { setContent, logRef, handleRevealLine } = useLog();
 
   function onReceiveModalData(data) {
     Object.assign(app, unref(data.app));
@@ -68,6 +68,7 @@
       const status = data.status || 'error';
       if (status === 'success') {
         setContent(data.data);
+        handleRevealLine();
         logTime.value = formatToDateTime(new Date());
       }
     } catch (error) {
@@ -84,12 +85,18 @@
   }
 </script>
 <template>
-  <BasicModal @register="registerModal" width="80%" :after-close="handleClose">
+  <BasicModal
+    canFullscreen
+    :scrollTop="false"
+    @register="registerModal"
+    width="80%"
+    :after-close="handleClose"
+  >
     <template #title>
       <Icon icon="ant-design:code-outlined" style="color: #477de9" />&nbsp;
       <span> {{ t('flink.app.view.logTitle', [app.jobName]) }}</span>
     </template>
-    <div ref="logRef" class="h-600px"></div>
+    <div ref="logRef" class="h-full min-h-500px"></div>
     <template #footer>
       <div class="flex align-items-center">
         <div class="flex-1 text-left">{{ t('flink.app.view.refreshTime') }}:{{ logTime }}</div>
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/data/index.ts b/streampark-console/streampark-console-newui/src/views/flink/app/data/index.ts
index 9fe691425..28bfd8897 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/data/index.ts
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/data/index.ts
@@ -26,22 +26,9 @@ export const getAppColumns = (): BasicColumn[] => [
     fixed: 'left',
     width: 300,
   },
-  {
-    title: 'Tags',
-    ellipsis: true,
-    dataIndex: 'tags',
-    width: 150,
-  },
-  {
-    title: 'Owner',
-    dataIndex: 'nickName',
-    width: 100,
-  },
-  {
-    title: 'Flink Version',
-    dataIndex: 'flinkVersion',
-    width: 130,
-  },
+  { title: 'Tags', ellipsis: true, dataIndex: 'tags', width: 150 },
+  { title: 'Owner', dataIndex: 'nickName', width: 100 },
+  { title: 'Flink Version', dataIndex: 'flinkVersion', width: 130 },
   {
     title: 'Duration',
     dataIndex: 'duration',
@@ -49,12 +36,7 @@ export const getAppColumns = (): BasicColumn[] => [
     width: 150,
     customRender: ({ value }) => dateToDuration(value),
   },
-  {
-    title: 'Modified Time',
-    dataIndex: 'modifyTime',
-    sorter: true,
-    width: 170,
-  },
+  { title: 'Modified Time', dataIndex: 'modifyTime', sorter: true, width: 170 },
   {
     title: 'Run Status',
     dataIndex: 'state',
@@ -71,11 +53,7 @@ export const getAppColumns = (): BasicColumn[] => [
       { text: 'TERMINATED', value: '18' },
     ],
   },
-  {
-    title: 'Launch | Build',
-    dataIndex: 'launch',
-    width: 220,
-  },
+  { title: 'Launch | Build', dataIndex: 'launch', width: 220 },
 ];
 
 /* Get diff editor configuration */
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useApp.tsx b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useApp.tsx
index 19d62db69..c79c633d0 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useApp.tsx
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useApp.tsx
@@ -206,7 +206,7 @@ export const useFlinkApplication = (openStartModal: Fn) => {
       ],
       content: () => {
         return (
-          <Form class="!pt-20px">
+          <Form class="!pt-30px">
             <Form.Item
               label="Application Name"
               labelCol={{ lg: { span: 7 }, sm: { span: 7 } }}
@@ -278,7 +278,7 @@ export const useFlinkApplication = (openStartModal: Fn) => {
       content: () => {
         return (
           <Form
-            class="!mt-20px"
+            class="!pt-40px"
             ref={mappingRef}
             name="mappingForm"
             labelCol={{ lg: { span: 7 }, sm: { span: 7 } }}
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useAppTableAction.ts b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useAppTableAction.ts
index 53091b507..e4d87a998 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useAppTableAction.ts
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useAppTableAction.ts
@@ -223,7 +223,7 @@ export const useAppTableAction = (
       schemas: [
         {
           label: 'Tags',
-          field: 'tag',
+          field: 'tags',
           component: 'Select',
           componentProps: {
             placeholder: 'Tags',
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useFlinkRender.tsx b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useFlinkRender.tsx
index e577bb26a..8abf64e45 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useFlinkRender.tsx
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useFlinkRender.tsx
@@ -372,7 +372,7 @@ export const renderSqlHistory = (
       ),
       content: () => {
         return (
-          <Form>
+          <Form class="!pt-20px">
             <Form.Item
               label="Version"
               label-col={{ lg: { span: 5 }, sm: { span: 7 } }}
diff --git a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useLog.ts b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useLog.ts
index e4596fa87..7e2e8c09d 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useLog.ts
+++ b/streampark-console/streampark-console-newui/src/views/flink/app/hooks/useLog.ts
@@ -14,17 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { ref, unref } from 'vue';
+import { ref, watch } from 'vue';
 import { useMonaco, isDark } from '/@/hooks/web/useMonaco';
 
 export const useLog = () => {
   const logRef = ref();
-  const { setContent } = useMonaco(
+  const { setContent, getInstance, getMonacoInstance } = useMonaco(
     logRef,
     {
       language: 'log',
       options: {
-        theme: 'log',
+        theme: isDark.value ? 'log-dark' : 'log',
         readOnly: true,
         scrollBeyondLastLine: false,
         overviewRulerBorder: false, // Don't scroll bar borders
@@ -43,12 +43,24 @@ export const useLog = () => {
     },
     handleLogMonaco,
   );
+  watch(
+    isDark,
+    async () => {
+      const monacoInstance = await getMonacoInstance();
+      if (monacoInstance) {
+        if (isDark.value) monacoInstance.editor.setTheme('log-dark');
+        else monacoInstance.editor.setTheme('log');
+      }
+    },
+    { immediate: true },
+  );
   /* registered language */
   async function handleLogMonaco(monaco: any) {
     monaco.languages.register({ id: 'log' });
     monaco.languages.setMonarchTokensProvider('log', {
       tokenizer: {
         root: [
+          [/\[20\d+-\d+-\d+\s+\d+:\d+:\d+\d+|.\d+]/, 'custom-date-time'],
           [/\[error.*/, 'custom-error'],
           [/\[notice.*/, 'custom-notice'],
           [/\[info.*/, 'custom-info'],
@@ -57,8 +69,20 @@ export const useLog = () => {
       },
     });
 
+    monaco.editor.defineTheme('log-dark', {
+      base: 'vs-dark',
+      inherit: true,
+      colors: {},
+      rules: [
+        { token: 'custom-info', foreground: '808080' },
+        { token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
+        { token: 'custom-notice', foreground: 'FFA500' },
+        { token: 'custom-date', foreground: '008800' },
+        { token: 'custom-date-time', foreground: '008800' },
+      ],
+    });
     monaco.editor.defineTheme('log', {
-      base: unref(isDark) ? 'vs-dark' : 'vs',
+      base: 'vs',
       inherit: true,
       colors: {},
       rules: [
@@ -66,8 +90,15 @@ export const useLog = () => {
         { token: 'custom-error', foreground: 'ff0000', fontStyle: 'bold' },
         { token: 'custom-notice', foreground: 'FFA500' },
         { token: 'custom-date', foreground: '008800' },
+        { token: 'custom-date-time', foreground: '008800' },
       ],
     });
   }
-  return { setContent, logRef };
+  async function handleRevealLine() {
+    const editor = await getInstance();
+    if (editor) {
+      editor.revealLine(editor.getModel()?.getLineCount() || 0);
+    }
+  }
+  return { setContent, logRef, handleRevealLine };
 };
diff --git a/streampark-console/streampark-console-newui/src/views/flink/project/components/ListItem.vue b/streampark-console/streampark-console-newui/src/views/flink/project/components/ListItem.vue
index 431f020e7..3032a871e 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/project/components/ListItem.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/project/components/ListItem.vue
@@ -63,9 +63,9 @@
       </li>
     </ul>
     <div class="operation">
-      <a-tooltip title="See Build log" v-if="isBuilding">
-        <a-button type="link" @click="handleSeeLog">
-          <Icon spin icon="ant-design:sync-outlined" style="color: #4a9ff5" />
+      <a-tooltip title="See Build log">
+        <a-button shape="circle" @click="handleSeeLog">
+          <Icon icon="ant-design:eye-outlined" />
         </a-button>
       </a-tooltip>
 
@@ -77,7 +77,7 @@
             ok-text="Yes"
             @confirm="handleBuild"
           >
-            <a-button shape="circle" size="large" class="ml-8px" v-auth="'project:build'">
+            <a-button shape="circle" class="ml-8px" v-auth="'project:build'">
               <ThunderboltOutlined />
             </a-button>
           </a-popconfirm>
@@ -85,13 +85,7 @@
       </template>
 
       <a-tooltip title="Update Project">
-        <a-button
-          v-auth="'project:update'"
-          size="large"
-          @click="handleEdit"
-          shape="circle"
-          class="ml-8px"
-        >
+        <a-button v-auth="'project:update'" @click="handleEdit" shape="circle" class="ml-8px">
           <EditOutlined />
         </a-button>
       </a-tooltip>
@@ -102,7 +96,7 @@
           ok-text="Yes"
           @confirm="handleDelete"
         >
-          <a-button type="danger" shape="circle" size="large" style="margin-left: 8px">
+          <a-button type="danger" shape="circle" style="margin-left: 8px">
             <DeleteOutlined />
           </a-button>
         </a-popconfirm>
diff --git a/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue b/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue
index e26fa957a..70c5f9444 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/project/components/LogModal.vue
@@ -40,7 +40,7 @@
   const [registerModal, { changeLoading, closeModal }] = useModalInner((data) => {
     data && onReceiveModalData(data);
   });
-  const { setContent, logRef } = useLog();
+  const { setContent, logRef, handleRevealLine } = useLog();
   function onReceiveModalData(data: Recordable) {
     showRefresh.value = true;
     Object.assign(project, unref(data.project));
@@ -66,11 +66,14 @@
       if (data.readFinished === false) {
         showRefresh.value = true;
         start();
-        if (data.data) setContent(data.data);
-        logTime.value = formatToDateTime(new Date());
       } else {
         showRefresh.value = false;
       }
+      logTime.value = formatToDateTime(new Date());
+      if (data.data) {
+        setContent(data.data);
+        handleRevealLine();
+      }
     } catch (error) {
       closeModal();
       console.error('logModal error', error);
@@ -84,12 +87,18 @@
   }
 </script>
 <template>
-  <BasicModal @register="registerModal" width="80%" :after-close="handleClose">
+  <BasicModal
+    canFullscreen
+    :scrollTop="false"
+    @register="registerModal"
+    width="80%"
+    :after-close="handleClose"
+  >
     <template #title>
       <Icon icon="ant-design:code-outlined" style="color: #477de9" />&nbsp;
       <span>{{ project.projectName }} build Log </span>
     </template>
-    <div ref="logRef" class="h-600px"></div>
+    <div ref="logRef" class="h-full min-h-500px"></div>
     <template #footer>
       <div class="flex align-items-center">
         <div class="flex-1 text-left">{{ t('flink.app.view.refreshTime') }}:{{ logTime }}</div>
diff --git a/streampark-console/streampark-console-newui/src/views/flink/setting/components/SettingList.vue b/streampark-console/streampark-console-newui/src/views/flink/setting/components/SettingList.vue
index b9fa1218b..0e02b77d9 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/setting/components/SettingList.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/setting/components/SettingList.vue
@@ -109,7 +109,7 @@
                 placeholder="Please enter"
                 class="ant-input"
               />
-              <div v-else style="width: 100%; text-align: right">
+              <div v-else style="width: 100%">
                 <span v-if="isPassword(item) && item.settingValue !== null"> ******** </span>
                 <span v-else>{{ item.settingValue }}</span>
               </div>
diff --git a/streampark-console/streampark-console-newui/src/views/flink/setting/components/SystemSetting.vue b/streampark-console/streampark-console-newui/src/views/flink/setting/components/SystemSetting.vue
index 3d99bf080..e0461d619 100644
--- a/streampark-console/streampark-console-newui/src/views/flink/setting/components/SystemSetting.vue
+++ b/streampark-console/streampark-console-newui/src/views/flink/setting/components/SystemSetting.vue
@@ -66,7 +66,7 @@
         key: 5,
         title: 'Ingrsss Setting',
         isPassword: () => false,
-        data: filterValue('ingrsss.mode'),
+        data: filterValue('ingress.mode'),
       },
     ];
   });
diff --git a/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue b/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue
index d2c168a2b..d2c12c9ac 100644
--- a/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue
+++ b/streampark-console/streampark-console-newui/src/views/system/role/components/RoleDrawer.vue
@@ -26,9 +26,11 @@
     <BasicForm @register="registerForm" :schemas="formSchemas">
       <template #menu="{ model, field }">
         <BasicTree
+          :default-expand-level="1"
           v-model:value="model[field]"
           :treeData="treeData"
           :fieldNames="{ title: 'text', key: 'id' }"
+          v-if="treeData.length > 0"
           checkable
           toolbar
           title="menu assignment"
@@ -65,16 +67,12 @@
     setup(_, { emit }) {
       const formType = ref(FormTypeEnum.Edit);
       const treeData = ref<TreeItem[]>([]);
+      let singleNodeKeys: string[] = [];
       const isCreate = computed(() => unref(formType) === FormTypeEnum.Create);
 
       const formSchemas = computed((): FormSchema[] => {
         return [
-          {
-            field: 'roleId',
-            label: 'Role Id',
-            component: 'Input',
-            show: false,
-          },
+          { field: 'roleId', label: 'Role Id', component: 'Input', show: false },
           {
             field: 'roleName',
             label: 'Role Name',
@@ -84,11 +82,7 @@
               ? [{ required: true, validator: handleRoleCheck, trigger: 'blur' }]
               : [],
           },
-          {
-            label: 'Description',
-            field: 'remark',
-            component: 'InputTextArea',
-          },
+          { label: 'Description', field: 'remark', component: 'InputTextArea' },
           {
             label: 'permission',
             field: 'menuId',
@@ -105,6 +99,7 @@
       });
 
       const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+        // childrenNodeKeys = [];
         resetFields();
         setDrawerProps({
           confirmLoading: false,
@@ -112,30 +107,33 @@
         });
 
         formType.value = data.formType;
-        // You need to fill in treeData before setFieldsValue, otherwise the Tree component may report a key not exist warning
-        if (!unref(isCreate)) {
-          const res = await getRoleMenu({ roleId: data.record.roleId });
-          data.record.menuId = res || [];
+
+        function findSingleNode(data) {
+          data.map((item: Recordable) => {
+            if (item.children && item.children.length > 0) {
+              findSingleNode(item.children);
+            } else {
+              // Store all leaf nodes
+              singleNodeKeys.push(item.id);
+            }
+          });
         }
 
         if (unref(treeData).length === 0) {
           const res = await getMenuList();
           treeData.value = handleTreeIcon(res?.rows?.children);
+          findSingleNode(res?.rows?.children);
         }
-
         if (!unref(isCreate)) {
-          console.log('data.record', {
-            roleName: data.record.roleName,
-            roleId: data.record.roleId,
-            remark: data.record.remark,
-            menuId: [...data.record.menuId],
-          });
+          const res = await getRoleMenu({ roleId: data.record.roleId });
+          data.record.menuId = res || [];
+          const result = [...new Set(singleNodeKeys)].filter((item) => new Set(res).has(item));
           nextTick(() => {
             setFieldsValue({
               roleName: data.record.roleName,
               roleId: data.record.roleId,
               remark: data.record.remark,
-              menuId: [...data.record.menuId],
+              menuId: [...result],
             });
           });
         }
diff --git a/streampark-console/streampark-console-newui/src/views/system/team/TeamDrawer.vue b/streampark-console/streampark-console-newui/src/views/system/team/TeamDrawer.vue
index efdc9ca39..178bb14b6 100644
--- a/streampark-console/streampark-console-newui/src/views/system/team/TeamDrawer.vue
+++ b/streampark-console/streampark-console-newui/src/views/system/team/TeamDrawer.vue
@@ -47,8 +47,17 @@
             field: 'teamName',
             label: t('system.team.table.teamName'),
             component: 'Input',
-            componentProps: { disabled: isUpdate.value },
+            componentProps: {
+              disabled: isUpdate.value,
+              placeholder: t('system.team.table.teamNamePlaceholder'),
+            },
             required: !isUpdate.value,
+            dynamicRules: () => {
+              if (!isUpdate.value) {
+                return [{ required: true, min: 4, message: t('system.team.table.teamMessage') }];
+              }
+              return [];
+            },
           },
           {
             field: 'description',