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

imbajin pushed a commit to branch hubble-dev
in repository https://gitbox.apache.org/repos/asf/hugegraph-toolchain.git


The following commit(s) were added to refs/heads/hubble-dev by this push:
     new c171baed fix(hubble): address review feedback
c171baed is described below

commit c171baed970ee4f23835e9aae7b85d75516c1800
Author: imbajin <[email protected]>
AuthorDate: Sun Jul 12 21:48:32 2026 +0800

    fix(hubble): address review feedback
    
    - align favorite-name validation across all editors
    - show localized validation guidance for invalid names
    - allow navigation rows to grow for disabled reasons
    - add Kotlin dependency to the packaged license
    - cover all favorite creation and rename flows
---
 hugegraph-dist/release-docs/LICENSE                |   1 +
 .../src/components/FavoriteNameInput/index.js      |  46 +++++++++
 .../src/components/FavoriteNameInput/index.test.js |  44 ++++++++
 .../algorithm/LogsDetail/ExecuteLog/index.js       |  13 +--
 .../modules/algorithm/LogsDetail/Favorite/index.js |  10 +-
 .../analysis/LogsDetail/ExecuteLog/index.js        |  13 +--
 .../modules/analysis/LogsDetail/Favorite/index.js  |  10 +-
 .../analysis/QueryBar/ContentCommon/index.js       |   9 +-
 .../analysis/QueryBar/ContentCommon/index.test.js  |   3 +
 .../src/modules/favorite-name-validation.test.js   | 113 +++++++++++++++++++++
 .../src/modules/navigation/Home/index.module.scss  |   2 +-
 hugegraph-hubble/hubble-fe/src/utils/rules.test.js |   1 +
 12 files changed, 230 insertions(+), 35 deletions(-)

diff --git a/hugegraph-dist/release-docs/LICENSE 
b/hugegraph-dist/release-docs/LICENSE
index 7543d082..6b0c88c0 100644
--- a/hugegraph-dist/release-docs/LICENSE
+++ b/hugegraph-dist/release-docs/LICENSE
@@ -484,6 +484,7 @@ See licenses/ for text of these licenses.
        hugegraph-hubble/ui/favicon.ico
        (Apache License, Version 2.0) * kotlin-stdlib 
(org.jetbrains.kotlin:kotlin-stdlib:1.6.20 - 
https://github.com/JetBrains/kotlin)
        (Apache License, Version 2.0) * kotlin-stdlib-common 
(org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31 - 
https://github.com/JetBrains/kotlin)
+       (Apache License, Version 2.0) * kotlin-stdlib-common 
(org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20 - 
https://github.com/JetBrains/kotlin)
        (Apache License, Version 2.0) * kotlin-stdlib-jdk7 
(org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 - 
https://github.com/JetBrains/kotlin)
        (Apache License, Version 2.0) * kotlin-stdlib-jdk7 
(org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10 - 
https://github.com/JetBrains/kotlin)
        (Apache License, Version 2.0) * kotlin-stdlib-jdk8 
(org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.71 - 
https://github.com/JetBrains/kotlin)
diff --git 
a/hugegraph-hubble/hubble-fe/src/components/FavoriteNameInput/index.js 
b/hugegraph-hubble/hubble-fe/src/components/FavoriteNameInput/index.js
new file mode 100644
index 00000000..cb1915d5
--- /dev/null
+++ b/hugegraph-hubble/hubble-fe/src/components/FavoriteNameInput/index.js
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {Input} from 'antd';
+import {useTranslation} from 'react-i18next';
+
+import {isValidFavoriteName} from '../../utils/rules';
+
+const FavoriteNameInput = props => {
+    const {t} = useTranslation();
+    const {value, ...inputProps} = props;
+    const invalid = value && !isValidFavoriteName(value);
+
+    return (
+        <>
+            <Input
+                {...inputProps}
+                value={value}
+                showCount
+                maxLength={48}
+                status={invalid ? 'error' : undefined}
+            />
+            {invalid && (
+                <div role='alert' style={{color: '#ff4d4f', fontSize: '12px'}}>
+                    {t('common.validation.favorite_name_rule')}
+                </div>
+            )}
+        </>
+    );
+};
+
+export default FavoriteNameInput;
diff --git 
a/hugegraph-hubble/hubble-fe/src/components/FavoriteNameInput/index.test.js 
b/hugegraph-hubble/hubble-fe/src/components/FavoriteNameInput/index.test.js
new file mode 100644
index 00000000..ee6a6de8
--- /dev/null
+++ b/hugegraph-hubble/hubble-fe/src/components/FavoriteNameInput/index.test.js
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {fireEvent, render, screen} from '@testing-library/react';
+import {useCallback, useState} from 'react';
+
+import FavoriteNameInput from './index';
+
+jest.mock('react-i18next', () => ({
+    initReactI18next: {type: '3rdParty', init: jest.fn()},
+    useTranslation: () => ({t: key => key}),
+}));
+
+test('explains invalid favorite names and clears the error for valid names', 
() => {
+    const FavoriteNameEditor = () => {
+        const [name, setName] = useState('');
+        const onChange = useCallback(e => setName(e.target.value), []);
+        return <FavoriteNameInput value={name} onChange={onChange} />;
+    };
+    render(<FavoriteNameEditor />);
+
+    const input = screen.getByRole('textbox');
+    fireEvent.change(input, {target: {value: 'query-name'}});
+    expect(screen.getByRole('alert')).toHaveTextContent(
+        'common.validation.favorite_name_rule'
+    );
+
+    fireEvent.change(input, {target: {value: 'query_name'}});
+    expect(screen.queryByRole('alert')).not.toBeInTheDocument();
+});
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/ExecuteLog/index.js
 
b/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/ExecuteLog/index.js
index 310309e0..d4cf55c0 100644
--- 
a/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/ExecuteLog/index.js
+++ 
b/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/ExecuteLog/index.js
@@ -22,8 +22,10 @@
 
 import React, {useState, useCallback} from 'react';
 import {useTranslation} from 'react-i18next';
-import {Button, Table, Space, Tag, Input, Popconfirm} from 'antd';
+import {Button, Table, Space, Tag, Popconfirm} from 'antd';
 import ExecutionContent from '../../../../components/ExecutionContent';
+import FavoriteNameInput from '../../../../components/FavoriteNameInput';
+import {isValidFavoriteName} from '../../../../utils/rules';
 import c from './index.module.scss';
 
 const EXECUTE_TYPE_KEY = {
@@ -67,17 +69,14 @@ const ExecuteLog = props => {
     } = props;
 
     const [favoriteName, setFavoriteName] = useState();
-    const [disabledFavorite, setDisabledFavorite]  = useState(true);
 
     const onFavoraiteName = useCallback(
         e => {
             setFavoriteName(e.target.value);
-            e.target.value ? setDisabledFavorite(false) : 
setDisabledFavorite(true);
         }, []);
 
     const onFavoriteCard = useCallback(() => {
         setFavoriteName('');
-        setDisabledFavorite(true);
     }, []);
 
     const updateAddCollection = useCallback(
@@ -97,11 +96,9 @@ const ExecuteLog = props => {
             <div style={{marginBottom: '16px'}}>
                 {t('analysis.logs.favorite_statement')}
             </div>
-            <Input
+            <FavoriteNameInput
                 style={{marginBottom: '18px'}}
                 placeholder={t('analysis.logs.favorite_name_placeholder')}
-                showCount
-                maxLength={48}
                 value={favoriteName}
                 onChange={onFavoraiteName}
             />
@@ -169,7 +166,7 @@ const ExecuteLog = props => {
                             placement="left"
                             title={favoriteContent(rowData)}
                             onConfirm={createValueHandler(onAddFavorite, 
rowData.content)}
-                            okButtonProps={{disabled: disabledFavorite}}
+                            okButtonProps={{disabled: 
!isValidFavoriteName(favoriteName)}}
                             okText={t('analysis.logs.action.favorite')}
                             cancelText={t('common.action.cancel')}
                         >
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/Favorite/index.js 
b/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/Favorite/index.js
index dbbbe8ae..7a90e519 100644
--- 
a/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/Favorite/index.js
+++ 
b/hugegraph-hubble/hubble-fe/src/modules/algorithm/LogsDetail/Favorite/index.js
@@ -25,6 +25,8 @@ import {useTranslation} from 'react-i18next';
 import Highlighter from 'react-highlight-words';
 import {Button, Table, Input, Popconfirm, Modal} from 'antd';
 import ExecutionContent from '../../../../components/ExecutionContent';
+import FavoriteNameInput from '../../../../components/FavoriteNameInput';
+import {isValidFavoriteName} from '../../../../utils/rules';
 import c from './index.module.scss';
 
 const createValueHandler = (handler, value) => () => handler(value);
@@ -48,7 +50,6 @@ const Favorite = props => {
     const [favoriteName, setFavoriteName] = useState();
     const [searchCache, setSearchCache] = useState('');
     const [search, setSearch] = useState('');
-    const [isDisabledName, setDisabledName]  = useState(false);
 
     const changeCollection = useCallback(
         rowData => {
@@ -72,7 +73,6 @@ const Favorite = props => {
     const onChangeFavoraiteName = useCallback(
         e => {
             setFavoriteName(e.target.value);
-            e.target.value ? setDisabledName(false) : setDisabledName(true);
         }, []);
 
     const onConfirm = id => {
@@ -90,11 +90,9 @@ const Favorite = props => {
             <div style={{marginBottom: '16px'}}>
                 {t('analysis.logs.edit_name')}
             </div>
-            <Input
+            <FavoriteNameInput
                 style={{marginBottom: '18px'}}
                 placeholder={t('analysis.logs.favorite_name_placeholder')}
-                showCount
-                maxLength={48}
                 value={favoriteName}
                 onChange={onChangeFavoraiteName}
             />
@@ -159,7 +157,7 @@ const Favorite = props => {
                             title={editFavoriteForm}
                             onConfirm={createValueHandler(onSaveEditFavorite, 
rowData)}
                             okText={t('analysis.logs.action.save')}
-                            okButtonProps={{disabled: isDisabledName}}
+                            okButtonProps={{disabled: 
!isValidFavoriteName(favoriteName)}}
                             cancelText={t('common.action.cancel')}
                         >
                             <Button
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/ExecuteLog/index.js
 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/ExecuteLog/index.js
index 2dcb9a94..b29f02dc 100644
--- 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/ExecuteLog/index.js
+++ 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/ExecuteLog/index.js
@@ -22,8 +22,10 @@
 
 import {useState, useCallback} from 'react';
 import {useTranslation} from 'react-i18next';
-import {Button, Table, Space, Tag, Input, Popconfirm} from 'antd';
+import {Button, Table, Space, Tag, Popconfirm} from 'antd';
 import ExecutionContent from '../../../../components/ExecutionContent';
+import FavoriteNameInput from '../../../../components/FavoriteNameInput';
+import {isValidFavoriteName} from '../../../../utils/rules';
 import c from './index.module.scss';
 
 const EXECUTE_TYPE_KEY = {
@@ -116,7 +118,6 @@ const ExecuteLog = props => {
     } = props;
 
     const [favoriteName, setFavoriteName] = useState();
-    const [disabledFavorite, setDisabledFavorite]  = useState(true);
 
     const loadStatements = useCallback(
         (text, rowData, index) => {
@@ -130,7 +131,6 @@ const ExecuteLog = props => {
     const onFavoraiteName = useCallback(
         e => {
             setFavoriteName(e.target.value);
-            e.target.value ? setDisabledFavorite(false) : 
setDisabledFavorite(true);
         },
         []
     );
@@ -138,7 +138,6 @@ const ExecuteLog = props => {
     const onFavoriteCard = useCallback(
         () => {
             setFavoriteName('');
-            setDisabledFavorite(true);
         },
         []
     );
@@ -163,11 +162,9 @@ const ExecuteLog = props => {
                 <div style={{marginBottom: '16px'}}>
                     {t('analysis.logs.favorite_statement')}
                 </div>
-                <Input
+                <FavoriteNameInput
                     style={{marginBottom: '18px'}}
                     placeholder={t('analysis.logs.favorite_name_placeholder')}
-                    showCount
-                    maxLength={48}
                     value={favoriteName}
                     onChange={onFavoraiteName}
                 />
@@ -254,7 +251,7 @@ const ExecuteLog = props => {
                         onAddFavorite={onAddFavorite}
                         onFavoriteCard={onFavoriteCard}
                         loadStatements={loadStatements}
-                        disabledFavorite={disabledFavorite}
+                        disabledFavorite={!isValidFavoriteName(favoriteName)}
                         t={t}
                     />
                 );
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/Favorite/index.js 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/Favorite/index.js
index ae6d74f4..5da1be01 100644
--- 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/Favorite/index.js
+++ 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/LogsDetail/Favorite/index.js
@@ -24,6 +24,8 @@ import React, {useState, useCallback} from 'react';
 import {useTranslation} from 'react-i18next';
 import {Button, Table, Input, Popconfirm, Modal} from 'antd';
 import ExecutionContent from '../../../../components/ExecutionContent';
+import FavoriteNameInput from '../../../../components/FavoriteNameInput';
+import {isValidFavoriteName} from '../../../../utils/rules';
 import Highlighter from 'react-highlight-words';
 import c from './index.module.scss';
 
@@ -98,7 +100,6 @@ const Favorite = props => {
     const [favoriteName, setFavoriteName] = useState();
     const [searchCache, setSearchCache] = useState('');
     const [search, setSearch] = useState('');
-    const [isDisabledName, setDisabledName]  = useState(false);
 
     const loadStatements = useCallback(
         (content, index) => {
@@ -135,7 +136,6 @@ const Favorite = props => {
     const onChangeFavoraiteName = useCallback(
         e => {
             setFavoriteName(e.target.value);
-            e.target.value ? setDisabledName(false) : setDisabledName(true);
         },
         []
     );
@@ -155,11 +155,9 @@ const Favorite = props => {
             <div style={{marginBottom: '16px'}}>
                 {t('analysis.logs.edit_name')}
             </div>
-            <Input
+            <FavoriteNameInput
                 style={{marginBottom: '18px'}}
                 placeholder={t('analysis.logs.favorite_name_placeholder')}
-                showCount
-                maxLength={48}
                 value={favoriteName}
                 onChange={onChangeFavoraiteName}
             />
@@ -225,7 +223,7 @@ const Favorite = props => {
                         onEditFavorite={onEditFavorite}
                         onConfirm={onConfirm}
                         editFavoriteForm={editFavoriteForm}
-                        isDisabledName={isDisabledName}
+                        isDisabledName={!isValidFavoriteName(favoriteName)}
                         t={t}
                     />
                 );
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.js
 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.js
index a06e2d03..7fe4dd4a 100644
--- 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.js
+++ 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.js
@@ -22,12 +22,13 @@
 
 import React, {useCallback, useState, useContext} from 'react';
 import {useTranslation} from 'react-i18next';
-import {Button, Tooltip, Dropdown, Input, Popover, message, Space} from 'antd';
+import {Button, Tooltip, Dropdown, Popover, message, Space} from 'antd';
 import {UpOutlined, DownOutlined, QuestionCircleOutlined} from 
'@ant-design/icons';
 import {GREMLIN_EXECUTES_MODE} from '../../../../utils/constants';
 import GraphAnalysisContext from '../../../Context';
 import classnames from 'classnames';
 import {isValidFavoriteName} from '../../../../utils/rules';
+import FavoriteNameInput from '../../../../components/FavoriteNameInput';
 import c from './index.module.scss';
 import * as api from '../../../../api/index';
 import KeyboardAction from '../../../../components/KeyboardAction';
@@ -147,14 +148,10 @@ const ContentCommon = props => {
 
     const favoriteContent = (
         <>
-            <Input
+            <FavoriteNameInput
                 placeholder={t('analysis.query.favorite_name_placeholder')}
-                showCount
-                maxLength={48}
                 value={favoriteName}
                 onChange={onChangeFavoraiteName}
-                status={favoriteName && !isValidFavoriteName(favoriteName)
-                    ? 'error' : undefined}
             />
             <Space style={{marginTop: '24px'}}>
                 <Button type='primary' onClick={onOkFavorite} 
disabled={disabledFavorite}>
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.test.js
 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.test.js
index 836da74c..aac91325 100644
--- 
a/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.test.js
+++ 
b/hugegraph-hubble/hubble-fe/src/modules/analysis/QueryBar/ContentCommon/index.test.js
@@ -64,6 +64,9 @@ test('keeps favorite submission disabled until the name is 
backend-compatible',
 
     fireEvent.change(input, {target: {value: 'query-name'}});
     expect(submit).toBeDisabled();
+    expect(screen.getByRole('alert')).toHaveTextContent(
+        'common.validation.favorite_name_rule'
+    );
     fireEvent.click(submit);
     expect(api.analysis.addFavoriate).not.toHaveBeenCalled();
 
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/favorite-name-validation.test.js 
b/hugegraph-hubble/hubble-fe/src/modules/favorite-name-validation.test.js
new file mode 100644
index 00000000..fcfe9b36
--- /dev/null
+++ b/hugegraph-hubble/hubble-fe/src/modules/favorite-name-validation.test.js
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {fireEvent, render, screen} from '@testing-library/react';
+
+import AlgorithmExecuteLog from './algorithm/LogsDetail/ExecuteLog';
+import AlgorithmFavorite from './algorithm/LogsDetail/Favorite';
+import AnalysisExecuteLog from './analysis/LogsDetail/ExecuteLog';
+import AnalysisFavorite from './analysis/LogsDetail/Favorite';
+
+jest.mock('react-i18next', () => ({
+    initReactI18next: {type: '3rdParty', init: jest.fn()},
+    useTranslation: () => ({t: key => key}),
+}));
+jest.mock('../components/ExecutionContent', () => () => <div />);
+
+beforeEach(() => {
+    window.matchMedia = jest.fn().mockImplementation(query => ({
+        matches: false,
+        media: query,
+        addListener: jest.fn(),
+        removeListener: jest.fn(),
+    }));
+});
+
+const executeRecord = {
+    id: 1,
+    content: 'g.V()',
+    status: 'SUCCESS',
+    type: 'GREMLIN',
+};
+const favoriteRecord = {
+    id: 1,
+    name: 'valid_name',
+    content: 'g.V()',
+};
+
+const assertInvalidNameDisablesConfirm = async (actionName, confirmName) => {
+    fireEvent.click(screen.getByRole('button', {name: actionName}));
+    const input = await screen.findByPlaceholderText(
+        'analysis.logs.favorite_name_placeholder'
+    );
+    fireEvent.change(input, {target: {value: 'invalid-name'}});
+    const confirm = screen.getAllByRole('button', {name: confirmName})
+        .find(button => button.disabled);
+    expect(confirm).toBeDefined();
+};
+
+test.each([
+    ['analysis', AnalysisExecuteLog, {
+        executeLogsDataRecords: [executeRecord],
+        executeLogsDataTotal: 1,
+        onLoadContent: jest.fn(),
+    }],
+    ['algorithm', AlgorithmExecuteLog, {
+        executionLogsDataRecords: [executeRecord],
+        executionLogsDataTotal: 1,
+    }],
+])('%s execution log rejects invalid favorite names', async (_, Component, 
dataProps) => {
+    render(<Component
+        {...dataProps}
+        pageExecute={1}
+        pageSize={10}
+        onExecutePageChange={jest.fn()}
+        onAddCollection={jest.fn()}
+    />);
+
+    await assertInvalidNameDisablesConfirm(
+        'analysis.logs.action.favorite',
+        'analysis.logs.action.favorite'
+    );
+});
+
+test.each([
+    ['analysis', AnalysisFavorite, {
+        onChangeSearchValue: jest.fn(),
+        onLoadContent: jest.fn(),
+    }],
+    ['algorithm', AlgorithmFavorite, {
+        onChangeFavorSearch: jest.fn(),
+    }],
+])('%s favorite editor rejects invalid renamed favorites', async (_, 
Component, dataProps) => {
+    render(<Component
+        {...dataProps}
+        favoriteQueriesDataRecords={[favoriteRecord]}
+        favoriteQueriesDataTotal={1}
+        pageFavorite={1}
+        pageSize={10}
+        onFavoritePageChange={jest.fn()}
+        onSortChange={jest.fn()}
+        onEditCollection={jest.fn()}
+        onDel={jest.fn()}
+    />);
+
+    await assertInvalidNameDisablesConfirm(
+        'analysis.logs.action.edit_name',
+        'analysis.logs.action.save'
+    );
+});
diff --git 
a/hugegraph-hubble/hubble-fe/src/modules/navigation/Home/index.module.scss 
b/hugegraph-hubble/hubble-fe/src/modules/navigation/Home/index.module.scss
index e5e17415..06c7e6d5 100644
--- a/hugegraph-hubble/hubble-fe/src/modules/navigation/Home/index.module.scss
+++ b/hugegraph-hubble/hubble-fe/src/modules/navigation/Home/index.module.scss
@@ -28,7 +28,7 @@
 }
 
 .container {
-    height: 230px;
+    min-height: 230px;
     display: flex;
     column-gap: 20px;
     align-items: center;
diff --git a/hugegraph-hubble/hubble-fe/src/utils/rules.test.js 
b/hugegraph-hubble/hubble-fe/src/utils/rules.test.js
index 8128fc93..c99754a0 100644
--- a/hugegraph-hubble/hubble-fe/src/utils/rules.test.js
+++ b/hugegraph-hubble/hubble-fe/src/utils/rules.test.js
@@ -178,6 +178,7 @@ describe('rules i18n defaults', () => {
             [rules.isNoramlName(), '只能包含中文、字母、数字、_, 不能超过20个字符'],
             [rules.isJDBC(), '请输入正确的jdbc url, 
例如:jdbc:mysql://127.0.0.1:3306/db_name'],
             [rules.isAccountName(), '账号名不超过16个字符,且不能以下划线开始和结尾'],
+            [rules.isFavoriteName(), '只能包含中文、字母、数字、_, 不能超过48个字符'],
             [rules.isUUID(), '非法的数据格式'],
             [rules.isInt(), '非法的数据格式'],
         ];

Reply via email to