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

qiuxiafan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git


The following commit(s) were added to refs/heads/main by this push:
     new f088cbb3 Use Fetch request to instead of Axios request and remove 
Axios (#820)
f088cbb3 is described below

commit f088cbb3af9945f0e96a52df6964f6a81c0b1267
Author: Fine0830 <[email protected]>
AuthorDate: Wed Oct 22 16:08:04 2025 +0800

    Use Fetch request to instead of Axios request and remove Axios (#820)
---
 CHANGES.md                                         |   1 +
 dist/LICENSE                                       |  23 --
 dist/licenses/ui-licenses/license-asynckit.txt     |  21 --
 dist/licenses/ui-licenses/license-axios.txt        |   7 -
 .../license-call-bind-apply-helpers.txt            |  21 --
 .../ui-licenses/license-combined-stream.txt        |  19 --
 .../ui-licenses/license-delayed-stream.txt         |  19 --
 dist/licenses/ui-licenses/license-dunder-proto.txt |  21 --
 .../ui-licenses/license-es-define-property.txt     |  21 --
 dist/licenses/ui-licenses/license-es-errors.txt    |  21 --
 .../ui-licenses/license-es-object-atoms.txt        |  21 --
 .../ui-licenses/license-es-set-tostringtag.txt     |  21 --
 .../ui-licenses/license-follow-redirects.txt       |  18 --
 dist/licenses/ui-licenses/license-form-data.txt    |  19 --
 .../licenses/ui-licenses/license-function-bind.txt |  20 --
 .../licenses/ui-licenses/license-get-intrinsic.txt |  21 --
 dist/licenses/ui-licenses/license-get-proto.txt    |  21 --
 dist/licenses/ui-licenses/license-gopd.txt         |  21 --
 dist/licenses/ui-licenses/license-has-symbols.txt  |  21 --
 .../ui-licenses/license-has-tostringtag.txt        |  21 --
 dist/licenses/ui-licenses/license-hasown.txt       |  21 --
 .../ui-licenses/license-math-intrinsics.txt        |  21 --
 dist/licenses/ui-licenses/license-mime-db.txt      |  23 --
 dist/licenses/ui-licenses/license-mime-types.txt   |  23 --
 .../ui-licenses/license-proxy-from-env.txt         |  20 --
 ui/LICENSE                                         |  23 --
 ui/package-lock.json                               | 264 +---------------
 ui/package.json                                    |   3 +-
 ui/src/api/index.js                                | 122 ++++----
 ui/src/components/Editor/fieldsEditor.vue          |   3 +-
 ui/src/components/Editor/index.vue                 | 176 +++++------
 ui/src/components/Editor/tagEditor.vue             |   6 +-
 ui/src/components/GroupTree/data.js                |   4 +-
 ui/src/components/GroupTree/index.vue              | 334 +++++++++++----------
 ui/src/components/Header/components/header.vue     |   3 +-
 ui/src/components/IndexRule/Editor.vue             | 127 ++++----
 ui/src/components/IndexRule/index.vue              |   7 +-
 ui/src/components/IndexRuleBinding/Editor.vue      | 125 ++++----
 ui/src/components/IndexRuleBinding/index.vue       |  35 +--
 ui/src/components/Property/Editor.vue              |  84 +++---
 ui/src/components/Property/PropertyEditor.vue      |  45 ++-
 ui/src/components/Property/PropertyRead.vue        |  77 ++---
 ui/src/components/Property/PropertyValueReader.vue |   1 +
 ui/src/components/Property/TagEditor.vue           |   1 -
 ui/src/components/Read/index.vue                   |  78 +++--
 ui/src/components/Start/index.vue                  |   1 +
 ui/src/components/TopNAggregation/Editor.vue       | 131 ++++----
 ui/src/components/TopNAggregation/index.vue        |  13 +-
 ui/src/components/TopNav/index.vue                 |   3 +-
 ui/src/components/Trace/Editor.vue                 |   5 +-
 ui/src/components/Trace/TraceRead.vue              |  19 +-
 ui/src/main.js                                     |   2 -
 ui/src/plugins/axios.js                            |  80 -----
 ui/src/utils/axios.js                              |  89 ------
 ui/src/views/Dashboard/index.vue                   |  18 +-
 ui/src/views/Measure/index.vue                     |   3 +-
 ui/src/views/Property/index.vue                    |   5 +-
 ui/src/views/Stream/index.vue                      |   5 +-
 ui/src/views/Trace/index.vue                       |   5 +-
 59 files changed, 670 insertions(+), 1713 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 47d9f5e7..65ed2863 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -49,6 +49,7 @@ Release Notes.
   - Add comprehensive disk management documentation with configuration guides 
and troubleshooting
 - Implement cluster mode for trace.
 - Implement Trace views.
+- Use Fetch request to instead of axios request and remove axios.
 
 ### Bug Fixes
 
diff --git a/dist/LICENSE b/dist/LICENSE
index f867851b..adcc39ef 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -537,35 +537,16 @@ MIT licenses
     @vueuse/metadata 9.13.0 MIT
     @vueuse/shared 9.13.0 MIT
     async-validator 4.2.5 MIT
-    asynckit 0.4.0 MIT
-    axios 1.12.2 MIT
     braces 3.0.3 MIT
-    call-bind-apply-helpers 1.0.2 MIT
     chokidar 4.0.3 MIT
     codemirror 5.65.20 MIT
-    combined-stream 1.0.8 MIT
     core-util-is 1.0.3 MIT
     csstype 3.1.3 MIT
     dayjs 1.11.18 MIT
-    delayed-stream 1.0.0 MIT
-    dunder-proto 1.0.1 MIT
     element-plus 2.11.3 MIT
-    es-define-property 1.0.1 MIT
-    es-errors 1.3.0 MIT
-    es-object-atoms 1.1.1 MIT
-    es-set-tostringtag 2.1.0 MIT
     escape-html 1.0.3 MIT
     estree-walker 2.0.2 MIT
     fill-range 7.1.1 MIT
-    follow-redirects 1.15.11 MIT
-    form-data 4.0.4 MIT
-    function-bind 1.1.2 MIT
-    get-intrinsic 1.3.0 MIT
-    get-proto 1.0.1 MIT
-    gopd 1.2.0 MIT
-    has-symbols 1.1.0 MIT
-    has-tostringtag 1.0.2 MIT
-    hasown 2.0.2 MIT
     immediate 3.0.6 MIT
     immutable 5.1.3 MIT
     is-extglob 2.1.1 MIT
@@ -579,11 +560,8 @@ MIT licenses
     lodash-es 4.17.21 MIT
     lodash-unified 1.0.3 MIT
     magic-string 0.30.19 MIT
-    math-intrinsics 1.1.0 MIT
     memoize-one 6.0.0 MIT
     micromatch 4.0.8 MIT
-    mime-db 1.52.0 MIT
-    mime-types 2.1.35 MIT
     mitt 3.0.1 MIT
     nanoid 3.3.11 MIT
     node-addon-api 7.1.1 MIT
@@ -591,7 +569,6 @@ MIT licenses
     pinia 2.3.1 MIT
     postcss 8.5.6 MIT
     process-nextick-args 2.0.1 MIT
-    proxy-from-env 1.1.0 MIT
     readable-stream 2.3.8 MIT
     readdirp 4.1.2 MIT
     safe-buffer 5.1.2 MIT
diff --git a/dist/licenses/ui-licenses/license-asynckit.txt 
b/dist/licenses/ui-licenses/license-asynckit.txt
deleted file mode 100644
index c9eca5dd..00000000
--- a/dist/licenses/ui-licenses/license-asynckit.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Alex Indigo
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-axios.txt 
b/dist/licenses/ui-licenses/license-axios.txt
deleted file mode 100644
index 05006a51..00000000
--- a/dist/licenses/ui-licenses/license-axios.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) 2014-present Matt Zabriskie & Collaborators
-
-Permission is hereby granted, free of charge, to any person obtaining a copy 
of this software and associated documentation files (the "Software"), to deal 
in the Software without restriction, including without limitation the rights to 
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
of the Software, and to permit persons to whom the Software is furnished to do 
so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all 
copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-call-bind-apply-helpers.txt 
b/dist/licenses/ui-licenses/license-call-bind-apply-helpers.txt
deleted file mode 100644
index f82f3896..00000000
--- a/dist/licenses/ui-licenses/license-call-bind-apply-helpers.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-combined-stream.txt 
b/dist/licenses/ui-licenses/license-combined-stream.txt
deleted file mode 100644
index 4804b7ab..00000000
--- a/dist/licenses/ui-licenses/license-combined-stream.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011 Debuggable Limited <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-delayed-stream.txt 
b/dist/licenses/ui-licenses/license-delayed-stream.txt
deleted file mode 100644
index 4804b7ab..00000000
--- a/dist/licenses/ui-licenses/license-delayed-stream.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2011 Debuggable Limited <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-dunder-proto.txt 
b/dist/licenses/ui-licenses/license-dunder-proto.txt
deleted file mode 100644
index 34995e79..00000000
--- a/dist/licenses/ui-licenses/license-dunder-proto.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 ECMAScript Shims
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-es-define-property.txt 
b/dist/licenses/ui-licenses/license-es-define-property.txt
deleted file mode 100644
index f82f3896..00000000
--- a/dist/licenses/ui-licenses/license-es-define-property.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-es-errors.txt 
b/dist/licenses/ui-licenses/license-es-errors.txt
deleted file mode 100644
index f82f3896..00000000
--- a/dist/licenses/ui-licenses/license-es-errors.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-es-object-atoms.txt 
b/dist/licenses/ui-licenses/license-es-object-atoms.txt
deleted file mode 100644
index f82f3896..00000000
--- a/dist/licenses/ui-licenses/license-es-object-atoms.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-es-set-tostringtag.txt 
b/dist/licenses/ui-licenses/license-es-set-tostringtag.txt
deleted file mode 100644
index c2a8460a..00000000
--- a/dist/licenses/ui-licenses/license-es-set-tostringtag.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2022 ECMAScript Shims
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-follow-redirects.txt 
b/dist/licenses/ui-licenses/license-follow-redirects.txt
deleted file mode 100644
index 742cbada..00000000
--- a/dist/licenses/ui-licenses/license-follow-redirects.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright 2014–present Olivier Lalonde <[email protected]>, James Talmage 
<[email protected]>, Ruben Verborgh
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-form-data.txt 
b/dist/licenses/ui-licenses/license-form-data.txt
deleted file mode 100644
index c7ff12a2..00000000
--- a/dist/licenses/ui-licenses/license-form-data.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2012 Felix Geisendörfer ([email protected]) and contributors
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-function-bind.txt 
b/dist/licenses/ui-licenses/license-function-bind.txt
deleted file mode 100644
index 62d6d237..00000000
--- a/dist/licenses/ui-licenses/license-function-bind.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2013 Raynos.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/dist/licenses/ui-licenses/license-get-intrinsic.txt 
b/dist/licenses/ui-licenses/license-get-intrinsic.txt
deleted file mode 100644
index 48f05d01..00000000
--- a/dist/licenses/ui-licenses/license-get-intrinsic.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-get-proto.txt 
b/dist/licenses/ui-licenses/license-get-proto.txt
deleted file mode 100644
index eeabd1c3..00000000
--- a/dist/licenses/ui-licenses/license-get-proto.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2025 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-gopd.txt 
b/dist/licenses/ui-licenses/license-gopd.txt
deleted file mode 100644
index 6abfe143..00000000
--- a/dist/licenses/ui-licenses/license-gopd.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2022 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-has-symbols.txt 
b/dist/licenses/ui-licenses/license-has-symbols.txt
deleted file mode 100644
index df31cbf3..00000000
--- a/dist/licenses/ui-licenses/license-has-symbols.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2016 Jordan Harband
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-has-tostringtag.txt 
b/dist/licenses/ui-licenses/license-has-tostringtag.txt
deleted file mode 100644
index 7948bc02..00000000
--- a/dist/licenses/ui-licenses/license-has-tostringtag.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2021 Inspect JS
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-hasown.txt 
b/dist/licenses/ui-licenses/license-hasown.txt
deleted file mode 100644
index 03149290..00000000
--- a/dist/licenses/ui-licenses/license-hasown.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) Jordan Harband and contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-math-intrinsics.txt 
b/dist/licenses/ui-licenses/license-math-intrinsics.txt
deleted file mode 100644
index 34995e79..00000000
--- a/dist/licenses/ui-licenses/license-math-intrinsics.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 ECMAScript Shims
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-mime-db.txt 
b/dist/licenses/ui-licenses/license-mime-db.txt
deleted file mode 100644
index 0751cb10..00000000
--- a/dist/licenses/ui-licenses/license-mime-db.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Jonathan Ong <[email protected]>
-Copyright (c) 2015-2022 Douglas Christopher Wilson <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-mime-types.txt 
b/dist/licenses/ui-licenses/license-mime-types.txt
deleted file mode 100644
index 06166077..00000000
--- a/dist/licenses/ui-licenses/license-mime-types.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 Jonathan Ong <[email protected]>
-Copyright (c) 2015 Douglas Christopher Wilson <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/dist/licenses/ui-licenses/license-proxy-from-env.txt 
b/dist/licenses/ui-licenses/license-proxy-from-env.txt
deleted file mode 100644
index 8f25097d..00000000
--- a/dist/licenses/ui-licenses/license-proxy-from-env.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License
-
-Copyright (C) 2016-2018 Rob Wu <[email protected]>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ui/LICENSE b/ui/LICENSE
index 5ff3897a..578c0445 100644
--- a/ui/LICENSE
+++ b/ui/LICENSE
@@ -90,35 +90,16 @@ MIT licenses
     @vueuse/metadata 9.13.0 MIT
     @vueuse/shared 9.13.0 MIT
     async-validator 4.2.5 MIT
-    asynckit 0.4.0 MIT
-    axios 1.12.2 MIT
     braces 3.0.3 MIT
-    call-bind-apply-helpers 1.0.2 MIT
     chokidar 4.0.3 MIT
     codemirror 5.65.20 MIT
-    combined-stream 1.0.8 MIT
     core-util-is 1.0.3 MIT
     csstype 3.1.3 MIT
     dayjs 1.11.18 MIT
-    delayed-stream 1.0.0 MIT
-    dunder-proto 1.0.1 MIT
     element-plus 2.11.3 MIT
-    es-define-property 1.0.1 MIT
-    es-errors 1.3.0 MIT
-    es-object-atoms 1.1.1 MIT
-    es-set-tostringtag 2.1.0 MIT
     escape-html 1.0.3 MIT
     estree-walker 2.0.2 MIT
     fill-range 7.1.1 MIT
-    follow-redirects 1.15.11 MIT
-    form-data 4.0.4 MIT
-    function-bind 1.1.2 MIT
-    get-intrinsic 1.3.0 MIT
-    get-proto 1.0.1 MIT
-    gopd 1.2.0 MIT
-    has-symbols 1.1.0 MIT
-    has-tostringtag 1.0.2 MIT
-    hasown 2.0.2 MIT
     immediate 3.0.6 MIT
     immutable 5.1.3 MIT
     is-extglob 2.1.1 MIT
@@ -132,11 +113,8 @@ MIT licenses
     lodash-es 4.17.21 MIT
     lodash-unified 1.0.3 MIT
     magic-string 0.30.19 MIT
-    math-intrinsics 1.1.0 MIT
     memoize-one 6.0.0 MIT
     micromatch 4.0.8 MIT
-    mime-db 1.52.0 MIT
-    mime-types 2.1.35 MIT
     mitt 3.0.1 MIT
     nanoid 3.3.11 MIT
     node-addon-api 7.1.1 MIT
@@ -144,7 +122,6 @@ MIT licenses
     pinia 2.3.1 MIT
     postcss 8.5.6 MIT
     process-nextick-args 2.0.1 MIT
-    proxy-from-env 1.1.0 MIT
     readable-stream 2.3.8 MIT
     readdirp 4.1.2 MIT
     safe-buffer 5.1.2 MIT
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 1f4b6df6..1d667065 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -9,7 +9,6 @@
       "version": "0.1.0",
       "dependencies": {
         "@element-plus/icons-vue": "^2.3.1",
-        "axios": "^1.12.0",
         "codemirror": "^5.65.16",
         "echarts": "^5.5.0",
         "element-plus": "^2.11.3",
@@ -26,7 +25,7 @@
       },
       "devDependencies": {
         "@vitejs/plugin-vue": "^5.0.4",
-        "prettier": "^3.4.2",
+        "prettier": "^3.6.2",
         "unplugin-auto-import": "^0.17.5",
         "unplugin-vue-components": "^0.26.0",
         "vite": "^6.4.1"
@@ -1494,23 +1493,6 @@
       "integrity": 
"sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
       "license": "MIT"
     },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz";,
-      "integrity": 
"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-      "license": "MIT"
-    },
-    "node_modules/axios": {
-      "version": "1.12.2",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz";,
-      "integrity": 
"sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
-      "license": "MIT",
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.4",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": 
"https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz";,
@@ -1554,19 +1536,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/call-bind-apply-helpers": {
-      "version": "1.0.2",
-      "resolved": 
"https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz";,
-      "integrity": 
"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "function-bind": "^1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/chokidar": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz";,
@@ -1588,18 +1557,6 @@
       "integrity": 
"sha512-i5dLDDxwkFCbhjvL2pNjShsojoL3XHyDwsGv1jqETUoW+lzpBKKqNTUWgQwVAOa0tUm4BwekT455ujafi8payA==",
       "license": "MIT"
     },
-    "node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": 
"https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz";,
-      "integrity": 
"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "license": "MIT",
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/confbox": {
       "version": "0.1.8",
       "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz";,
@@ -1642,15 +1599,6 @@
         }
       }
     },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": 
"https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz";,
-      "integrity": 
"sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/detect-libc": {
       "version": "1.0.3",
       "resolved": 
"https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz";,
@@ -1664,20 +1612,6 @@
         "node": ">=0.10"
       }
     },
-    "node_modules/dunder-proto": {
-      "version": "1.0.1",
-      "resolved": 
"https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz";,
-      "integrity": 
"sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind-apply-helpers": "^1.0.1",
-        "es-errors": "^1.3.0",
-        "gopd": "^1.2.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/echarts": {
       "version": "5.6.0",
       "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.6.0.tgz";,
@@ -1726,51 +1660,6 @@
         "url": "https://github.com/fb55/entities?sponsor=1";
       }
     },
-    "node_modules/es-define-property": {
-      "version": "1.0.1",
-      "resolved": 
"https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz";,
-      "integrity": 
"sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-errors": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz";,
-      "integrity": 
"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-object-atoms": {
-      "version": "1.1.1",
-      "resolved": 
"https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz";,
-      "integrity": 
"sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
-    "node_modules/es-set-tostringtag": {
-      "version": "2.1.0",
-      "resolved": 
"https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz";,
-      "integrity": 
"sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
-      "license": "MIT",
-      "dependencies": {
-        "es-errors": "^1.3.0",
-        "get-intrinsic": "^1.2.6",
-        "has-tostringtag": "^1.0.2",
-        "hasown": "^2.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/esbuild": {
       "version": "0.25.10",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz";,
@@ -1885,42 +1774,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/follow-redirects": {
-      "version": "1.15.11",
-      "resolved": 
"https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz";,
-      "integrity": 
"sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh";
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/form-data": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz";,
-      "integrity": 
"sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
-      "license": "MIT",
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "es-set-tostringtag": "^2.1.0",
-        "hasown": "^2.0.2",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/fsevents": {
       "version": "2.3.3",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz";,
@@ -1940,48 +1793,12 @@
       "version": "1.1.2",
       "resolved": 
"https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz";,
       "integrity": 
"sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "dev": true,
       "license": "MIT",
       "funding": {
         "url": "https://github.com/sponsors/ljharb";
       }
     },
-    "node_modules/get-intrinsic": {
-      "version": "1.3.0",
-      "resolved": 
"https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz";,
-      "integrity": 
"sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
-      "license": "MIT",
-      "dependencies": {
-        "call-bind-apply-helpers": "^1.0.2",
-        "es-define-property": "^1.0.1",
-        "es-errors": "^1.3.0",
-        "es-object-atoms": "^1.1.1",
-        "function-bind": "^1.1.2",
-        "get-proto": "^1.0.1",
-        "gopd": "^1.2.0",
-        "has-symbols": "^1.1.0",
-        "hasown": "^2.0.2",
-        "math-intrinsics": "^1.1.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb";
-      }
-    },
-    "node_modules/get-proto": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz";,
-      "integrity": 
"sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
-      "license": "MIT",
-      "dependencies": {
-        "dunder-proto": "^1.0.1",
-        "es-object-atoms": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/glob-parent": {
       "version": "5.1.2",
       "resolved": 
"https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz";,
@@ -1995,18 +1812,6 @@
         "node": ">= 6"
       }
     },
-    "node_modules/gopd": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz";,
-      "integrity": 
"sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb";
-      }
-    },
     "node_modules/graceful-fs": {
       "version": "4.2.11",
       "resolved": 
"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz";,
@@ -2014,37 +1819,11 @@
       "license": "ISC",
       "optional": true
     },
-    "node_modules/has-symbols": {
-      "version": "1.1.0",
-      "resolved": 
"https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz";,
-      "integrity": 
"sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb";
-      }
-    },
-    "node_modules/has-tostringtag": {
-      "version": "1.0.2",
-      "resolved": 
"https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz";,
-      "integrity": 
"sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
-      "license": "MIT",
-      "dependencies": {
-        "has-symbols": "^1.0.3"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb";
-      }
-    },
     "node_modules/hasown": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz";,
       "integrity": 
"sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "function-bind": "^1.1.2"
@@ -2235,15 +2014,6 @@
         "@jridgewell/sourcemap-codec": "^1.5.5"
       }
     },
-    "node_modules/math-intrinsics": {
-      "version": "1.1.0",
-      "resolved": 
"https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz";,
-      "integrity": 
"sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/memoize-one": {
       "version": "6.0.0",
       "resolved": 
"https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz";,
@@ -2274,27 +2044,6 @@
         "node": ">=8.6"
       }
     },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz";,
-      "integrity": 
"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": 
"https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz";,
-      "integrity": 
"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "license": "MIT",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
     "node_modules/minimatch": {
       "version": "9.0.5",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz";,
@@ -2483,7 +2232,6 @@
       "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz";,
       "integrity": 
"sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
       "dev": true,
-      "license": "MIT",
       "bin": {
         "prettier": "bin/prettier.cjs"
       },
@@ -2499,12 +2247,6 @@
       "resolved": 
"https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz";,
       "integrity": 
"sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
-    "node_modules/proxy-from-env": {
-      "version": "1.1.0",
-      "resolved": 
"https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz";,
-      "integrity": 
"sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
-      "license": "MIT"
-    },
     "node_modules/quansync": {
       "version": "0.2.11",
       "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz";,
diff --git a/ui/package.json b/ui/package.json
index c3fd10ea..ac7afd31 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -12,7 +12,6 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
-    "axios": "^1.12.0",
     "codemirror": "^5.65.16",
     "echarts": "^5.5.0",
     "element-plus": "^2.11.3",
@@ -29,7 +28,7 @@
   },
   "devDependencies": {
     "@vitejs/plugin-vue": "^5.0.4",
-    "prettier": "^3.4.2",
+    "prettier": "^3.6.2",
     "unplugin-auto-import": "^0.17.5",
     "unplugin-vue-components": "^0.26.0",
     "vite": "^6.4.1"
diff --git a/ui/src/api/index.js b/ui/src/api/index.js
index db4c56bf..eeb693bb 100644
--- a/ui/src/api/index.js
+++ b/ui/src/api/index.js
@@ -17,182 +17,178 @@
  * under the License.
  */
 
-// api file
-
-import request from '@/utils/axios';
 import { httpQuery } from './base';
 
-// Some request methods
 export function getGroupList() {
-  return request({
+  return httpQuery({
     url: '/api/v1/group/schema/lists',
-    method: 'get',
+    method: 'GET',
   });
 }
 
 export function getAllTypesOfResourceList(type, name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema/lists/${name}`,
-    method: 'get',
+    method: 'GET',
   });
 }
 
-export function getStreamOrMeasure(type, group, name) {
-  return request({
+export function getResourceOfAllType(type, group, name) {
+  return httpQuery({
     url: `/api/v1/${type}/schema/${group}/${name}`,
-    method: 'get',
+    method: 'GET',
   });
 }
 
 export function getTableList(data, type) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/data`,
-    data: data,
-    method: 'post',
+    json: data,
+    method: 'POST',
   });
 }
 
 export function deleteAllTypesOfResource(type, group, name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema/${group}/${name}`,
-    method: 'delete',
+    method: 'DELETE',
   });
 }
 
 export function deleteGroup(group) {
-  return request({
+  return httpQuery({
     url: `/api/v1/group/schema/${group}`,
-    method: 'delete',
+    method: 'DELETE',
   });
 }
 
 export function createGroup(data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/group/schema`,
-    method: 'post',
-    data: data,
+    method: 'POST',
+    json: data,
   });
 }
 
 export function editGroup(group, data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/group/schema/${group}`,
-    method: 'put',
-    data: data,
+    method: 'PUT',
+    json: data,
   });
 }
 
 export function createResources(type, data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema`,
-    method: 'post',
-    data: data,
+    method: 'POST',
+    json: data,
   });
 }
 
 export function editResources(type, group, name, data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema/${group}/${name}`,
-    method: 'put',
-    data: data,
+    method: 'PUT',
+    json: data,
   });
 }
 
 export function getindexRuleList(name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/index-rule/schema/lists/${name}`,
-    method: 'get',
+    method: 'GET',
   });
 }
 
 export function getindexRuleBindingList(name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/index-rule-binding/schema/lists/${name}`,
-    method: 'get',
+    method: 'GET',
   });
 }
 
 export function getTopNAggregationList(name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/topn-agg/schema/lists/${name}`,
-    method: 'get',
+    method: 'GET',
   });
 }
 
 export function getTopNAggregationData(data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/measure/topn`,
-    data,
-    method: 'post',
+    json: data,
+    method: 'POST',
   });
 }
 
 export function getSecondaryDataModel(type, group, name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema/${group}/${name}`,
-    method: 'get',
+    method: 'GET',
   });
 }
 
 export function createSecondaryDataModel(type, data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema`,
-    method: 'post',
-    data: data,
+    method: 'POST',
+    json: data,
   });
 }
 
 export function updateSecondaryDataModel(type, group, name, data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema/${group}/${name}`,
-    method: 'put',
-    data: data,
+    method: 'PUT',
+    json: data,
   });
 }
 
 export function deleteSecondaryDataModel(type, group, name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/${type}/schema/${group}/${name}`,
-    method: 'delete',
+    method: 'DELETE',
   });
 }
 
 export function fetchProperties(data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/property/data/query`,
-    method: 'post',
-    data,
+    method: 'POST',
+    json: data,
   });
 }
 
 export function deleteProperty(group, name) {
-  return request({
+  return httpQuery({
     url: `/api/v1/property/schema/${group}/${name}`,
-    method: 'delete',
+    method: 'DELETE',
   });
 }
 
 export function updateProperty(group, name, data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/property/schema/${group}/${name}`,
-    method: 'put',
-    data: data,
+    method: 'PUT',
+    json: data,
   });
 }
 
 export function createProperty(data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/property/schema`,
-    method: 'post',
-    data: data,
+    method: 'POST',
+    json: data,
   });
 }
 
 export function applyProperty(group, name, id, data) {
-  return request({
+  return httpQuery({
     url: `/api/v1/property/data/${group}/${name}/${id}`,
-    method: 'put',
-    data: data,
+    method: 'PUT',
+    json: data,
   });
 }
 
diff --git a/ui/src/components/Editor/fieldsEditor.vue 
b/ui/src/components/Editor/fieldsEditor.vue
index af941ace..9747213b 100644
--- a/ui/src/components/Editor/fieldsEditor.vue
+++ b/ui/src/components/Editor/fieldsEditor.vue
@@ -18,9 +18,8 @@
 -->
 
 <script lang="ts" setup>
-  import { reactive } from '@vue/reactivity';
   import type { FormInstance } from 'element-plus';
-  import { ref } from 'vue';
+  import { ref, reactive } from 'vue';
 
   const ruleFormRef = ref<FormInstance>();
   const data = reactive({
diff --git a/ui/src/components/Editor/index.vue 
b/ui/src/components/Editor/index.vue
index 417a2fe5..3af3b9ec 100644
--- a/ui/src/components/Editor/index.vue
+++ b/ui/src/components/Editor/index.vue
@@ -18,14 +18,13 @@
 -->
 
 <script lang="ts" setup>
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
-  import { reactive, ref } from 'vue';
+  import { reactive, ref, watch, getCurrentInstance } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
   import TagEditor from './tagEditor.vue';
   import FieldsEditor from './fieldsEditor.vue';
   import type { FormInstance } from 'element-plus';
   import { ElMessage } from 'element-plus';
-  import { createResources, editResources, getStreamOrMeasure } from 
'@/api/index';
+  import { createResources, editResources, getResourceOfAllType } from 
'@/api/index';
   import FormHeader from '../common/FormHeader.vue';
 
   const $loadingCreate = 
getCurrentInstance().appContext.config.globalProperties.$loadingCreate;
@@ -103,7 +102,7 @@
   );
   const submit = async (formEl: FormInstance | undefined) => {
     if (!formEl) return;
-    await formEl.validate((valid) => {
+    await formEl.validate(async (valid) => {
       if (valid) {
         const arr = tagEditorRef.value.getTagFamilies();
         const tagFamilies = [];
@@ -166,41 +165,42 @@
         }
         $loadingCreate();
         let params = {};
-        params[data.type + ''] = form;
+        params[data.type.toString()] = form;
         if (data.operator === 'edit' && data.form.group && data.form.name) {
-          return editResources(data.type, data.form.group, data.form.name, 
params)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'Edit successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteResource', data.form.name);
-                openResourses();
-              }
-            })
-            .finally(() => {
-              $loadingClose();
+          const res = await editResources(data.type, data.form.group, 
data.form.name, params);
+          $loadingClose();
+          if (res.error) {
+            ElMessage({
+              message: `Edit failed: ${res.error.message}`,
+              type: 'error',
             });
+            return;
+          }
+          ElMessage({
+            message: 'Edit successed',
+            type: 'success',
+          });
+          $bus.emit('refreshAside');
+          $bus.emit('deleteResource', data.form.name);
+          openResourses();
+          return;
         }
-        createResources(data.type, params)
-          .then((res) => {
-            if (res.status === 200) {
-              ElMessage({
-                message: 'Create successed',
-                type: 'success',
-                duration: 5000,
-              });
-              $bus.emit('refreshAside');
-              $bus.emit('deleteGroup', data.form.group);
-              openResourses();
-            }
-          })
-          .finally(() => {
-            $loadingClose();
+        const res = await createResources(data.type, params);
+        $loadingClose();
+        if (res.error) {
+          ElMessage({
+            message: `Create failed: ${res.error.message}`,
+            type: 'error',
           });
+          return;
+        }
+        ElMessage({
+          message: 'Create successed',
+          type: 'success',
+        });
+        $bus.emit('refreshAside');
+        $bus.emit('deleteGroup', data.form.group);
+        openResourses();
       }
     });
   };
@@ -222,60 +222,62 @@
     };
     $bus.emit('AddTabs', add);
   }
-  function initData() {
-    if (data.operator === 'edit' && data.form.group && data.form.name) {
-      $loadingCreate();
-      getStreamOrMeasure(data.type, data.form.group, data.form.name)
-        .then((res) => {
-          if (res.status === 200) {
-            data.form.indexMode = res.data[String(data.type)]?.indexMode || 
false;
-            const tagFamilies = res.data[String(data.type)]?.tagFamilies || [];
-            const entity = res.data[String(data.type)]?.entity?.tagNames || [];
-            const shardingKey = 
res.data[String(data.type)]?.shardingKey?.tagNames || [];
-            const arr = [];
-            tagFamilies.forEach((item) => {
-              item.tags.forEach((tag) => {
-                const entityIndex = entity.findIndex((entityItem) => {
-                  return entityItem === tag.name;
-                });
-                const shardingKeyIndex = 
shardingKey.findIndex((shardingKeyItem) => {
-                  return shardingKeyItem === tag.name;
-                });
-                const obj = {
-                  tagFamily: item.name,
-                  tag: tag.name,
-                  type: tag.type,
-                  entity: entityIndex >= 0 ? true : false,
-                  shardingKey: shardingKeyIndex >= 0 ? true : false,
-                };
-                arr.push(obj);
-              });
-            });
-            tagEditorRef.value.setTagFamilies(arr);
-            if (data.type === 'measure') {
-              const fields = res.data[data.type + ''].fields;
-              const intervalArr = res.data[data.type + ''].interval.split('');
-              let interval = 0;
-              let intervalUnit = '';
-              intervalArr.forEach((char) => {
-                let code = char.charCodeAt();
-                if (code >= 48 && code < 58) {
-                  interval = interval * 10 + (char - 0);
-                } else {
-                  intervalUnit = intervalUnit + char;
-                }
-              });
-              data.form.interval = interval;
-              data.form.intervalUnit = intervalUnit;
-              fieldEditorRef.value.setFields(fields);
-            }
-            data.form.modRevision = res.data[data.type + 
''].metadata.modRevision;
-          }
-        })
-        .finally(() => {
-          $loadingClose();
+  async function initData() {
+    if (data.operator !== 'edit' || !data.form.group || !data.form.name) {
+      return;
+    }
+    $loadingCreate();
+    const res = await getResourceOfAllType(data.type, data.form.group, 
data.form.name);
+    $loadingClose();
+    if (res.error) {
+      ElMessage({
+        message: `Get ${data.type} detail failed: ${res.error.message}`,
+        type: 'error',
+      });
+      return;
+    }
+    data.form.indexMode = res[String(data.type)]?.indexMode || false;
+    const tagFamilies = res[String(data.type)]?.tagFamilies || [];
+    const entity = res[String(data.type)]?.entity?.tagNames || [];
+    const shardingKey = res[String(data.type)]?.shardingKey?.tagNames || [];
+    const arr = [];
+    tagFamilies.forEach((item) => {
+      item.tags.forEach((tag) => {
+        const entityIndex = entity.findIndex((entityItem) => {
+          return entityItem === tag.name;
         });
+        const shardingKeyIndex = shardingKey.findIndex((shardingKeyItem) => {
+          return shardingKeyItem === tag.name;
+        });
+        const obj = {
+          tagFamily: item.name,
+          tag: tag.name,
+          type: tag.type,
+          entity: entityIndex >= 0 ? true : false,
+          shardingKey: shardingKeyIndex >= 0 ? true : false,
+        };
+        arr.push(obj);
+      });
+    });
+    tagEditorRef.value.setTagFamilies(arr);
+    if (data.type === 'measure') {
+      const fields = res[data.type.toString()].fields;
+      const intervalArr = res[data.type.toString()].interval.split('');
+      let interval = 0;
+      let intervalUnit = '';
+      intervalArr.forEach((char) => {
+        let code = char.charCodeAt();
+        if (code >= 48 && code < 58) {
+          interval = interval * 10 + (char - 0);
+        } else {
+          intervalUnit = intervalUnit + char;
+        }
+      });
+      data.form.interval = interval;
+      data.form.intervalUnit = intervalUnit;
+      fieldEditorRef.value.setFields(fields);
     }
+    data.form.modRevision = res[data.type.toString()].metadata.modRevision;
   }
 </script>
 
diff --git a/ui/src/components/Editor/tagEditor.vue 
b/ui/src/components/Editor/tagEditor.vue
index 5e483d06..d04fc3ee 100644
--- a/ui/src/components/Editor/tagEditor.vue
+++ b/ui/src/components/Editor/tagEditor.vue
@@ -18,10 +18,8 @@
 -->
 
 <script lang="ts" setup>
-  import { reactive } from '@vue/reactivity';
-  import { watch } from '@vue/runtime-core';
-  import type { TableColumnCtx, FormInstance, FormRules } from 'element-plus';
-  import { ref } from 'vue';
+  import type { TableColumnCtx, FormInstance } from 'element-plus';
+  import { ref, reactive, watch } from 'vue';
 
   const ruleFormRef = ref<FormInstance>();
   const data = reactive({
diff --git a/ui/src/components/GroupTree/data.js 
b/ui/src/components/GroupTree/data.js
index f480b65a..7b336cc5 100644
--- a/ui/src/components/GroupTree/data.js
+++ b/ui/src/components/GroupTree/data.js
@@ -109,7 +109,7 @@ export const TargetTypes = {
 export const CatalogToGroupType = {
   CATALOG_MEASURE: 'measure',
   CATALOG_STREAM: 'stream',
-  CATALOG_PROPERTIES: 'properties',
+  CATALOG_PROPERTY: 'property',
   CATALOG_TRACE: 'trace',
 };
 
@@ -117,7 +117,7 @@ export const CatalogToGroupType = {
 export const GroupTypeToCatalog = {
   measure: 'CATALOG_MEASURE',
   stream: 'CATALOG_STREAM',
-  properties: 'CATALOG_PROPERTIES',
+  property: 'CATALOG_PROPERTY',
   trace: 'CATALOG_TRACE',
 };
 
diff --git a/ui/src/components/GroupTree/index.vue 
b/ui/src/components/GroupTree/index.vue
index 1867a121..f1bdb9ba 100644
--- a/ui/src/components/GroupTree/index.vue
+++ b/ui/src/components/GroupTree/index.vue
@@ -18,6 +18,10 @@
 -->
 
 <script setup>
+  import { ref, reactive, onMounted, computed, watch, getCurrentInstance } 
from 'vue';
+  import { ElMessage, ElMessageBox } from 'element-plus';
+  import { useRouter, useRoute } from 'vue-router';
+  import { Search } from '@element-plus/icons-vue';
   import {
     deleteSecondaryDataModel,
     getindexRuleList,
@@ -30,11 +34,6 @@
     createGroup,
     editGroup,
   } from '@/api/index';
-  import { ElMessage, ElMessageBox } from 'element-plus';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
-  import { useRouter, useRoute } from 'vue-router';
-  import { ref, reactive, onMounted, computed } from 'vue';
-  import { Search } from '@element-plus/icons-vue';
   import StageEditor from './StageEditor.vue';
   import {
     StageFields,
@@ -140,99 +139,80 @@
   });
 
   // init data
-  function getGroupLists() {
+  async function getGroupLists() {
     filterText.value = '';
     loading.value = true;
-    getGroupList().then((res) => {
-      if (res.status === 200) {
-        data.groupLists = res.data.group.filter((d) => 
CatalogToGroupType[d.catalog] === props.type);
-        let promise = data.groupLists.map((item) => {
-          const type = props.type;
-          const name = item.metadata.name;
-          return new Promise((resolve, reject) => {
-            getAllTypesOfResourceList(type, name)
-              .then((res) => {
-                if (res.status === 200) {
-                  item.children = res.data[type];
-                  resolve();
-                }
-              })
-              .catch((err) => {
-                reject(err);
-              });
-          });
-        });
-        if (SupportedIndexRuleTypes.includes(props.type)) {
-          const promiseIndexRule = data.groupLists.map((item) => {
-            const name = item.metadata.name;
-            return new Promise((resolve, reject) => {
-              getindexRuleList(name)
-                .then((res) => {
-                  if (res.status === 200) {
-                    item.indexRule = res.data.indexRule;
-                    resolve();
-                  }
-                })
-                .catch((err) => {
-                  reject(err);
-                });
-            });
-          });
-          const promiseIndexRuleBinding = data.groupLists.map((item) => {
-            const name = item.metadata.name;
-            return new Promise((resolve, reject) => {
-              getindexRuleBindingList(name)
-                .then((res) => {
-                  if (res.status === 200) {
-                    item.indexRuleBinding = res.data.indexRuleBinding;
-                    resolve();
-                  }
-                })
-                .catch((err) => {
-                  reject(err);
-                });
-            });
-          });
-          promise = promise.concat(promiseIndexRule);
-          promise = promise.concat(promiseIndexRuleBinding);
-        }
-        if (props.type === 'measure') {
-          const TopNAggregationRule = data.groupLists.map((item) => {
-            const name = item.metadata.name;
-            return new Promise((resolve, reject) => {
-              getTopNAggregationList(name)
-                .then((res) => {
-                  if (res.status === 200) {
-                    item.topNAggregation = res.data.topNAggregation;
-                    resolve();
-                  }
-                })
-                .catch((err) => {
-                  reject(err);
-                });
-            });
-          });
-          promise = promise.concat(TopNAggregationRule);
+    const res = await getGroupList();
+    if (res.error) {
+      loading.value = false;
+      return;
+    }
+    data.groupLists = res.group.filter((d) => CatalogToGroupType[d.catalog] 
=== props.type);
+    let promise = data.groupLists.map((item) => {
+      const name = item.metadata.name;
+      return (async () => {
+        const response = await getAllTypesOfResourceList(props.type, name);
+        if (response.error) {
+          ElMessage.error(response.error.message);
         }
-        Promise.all(promise)
-          .then(() => {
-            data.groupLists = processGroupTree();
-            initActiveNode();
-          })
-          .catch((err) => {
-            ElMessage({
-              message: `An error occurred while obtaining group data. Please 
refresh and try again. Error: ${err}`,
-              type: 'error',
-              duration: 3000,
-            });
-          })
-          .finally(() => {
-            loading.value = false;
-          });
-      } else {
-        loading.value = false;
-      }
+        const key = props.type === CatalogToGroupType.CATALOG_PROPERTY ? 
'properties' : props.type;
+        item.children = response[key];
+      })();
     });
+    if (SupportedIndexRuleTypes.includes(props.type)) {
+      const promiseIndexRule = data.groupLists.map((item) => {
+        const name = item.metadata.name;
+        return (async () => {
+          const res = await getindexRuleList(name);
+          if (res.error) {
+            ElMessage.error(res.error.message);
+            return;
+          }
+          item.indexRule = res.indexRule;
+        })();
+      });
+      const promiseIndexRuleBinding = data.groupLists.map((item) => {
+        const name = item.metadata.name;
+        return (async () => {
+          const res = await getindexRuleBindingList(name);
+          if (res.error) {
+            ElMessage.error(res.error.message);
+            return;
+          }
+          item.indexRuleBinding = res.indexRuleBinding;
+        })();
+      });
+      promise = promise.concat(promiseIndexRule);
+      promise = promise.concat(promiseIndexRuleBinding);
+    }
+    if (props.type === CatalogToGroupType.CATALOG_MEASURE) {
+      const TopNAggregationRule = data.groupLists.map((item) => {
+        const name = item.metadata.name;
+        return (async () => {
+          const res = await getTopNAggregationList(name);
+          if (res.error) {
+            ElMessage.error(res.error.message);
+          }
+          item.topNAggregation = res.topNAggregation;
+        })();
+      });
+      promise = promise.concat(TopNAggregationRule);
+    }
+    Promise.all(promise)
+      .then(() => {
+        data.groupLists = processGroupTree();
+        initActiveNode();
+      })
+      .catch((err) => {
+        ElMessage({
+          message: `An error occurred while obtaining group data. Please 
refresh and try again. Error: ${err}`,
+          type: 'error',
+          duration: 3000,
+        });
+      })
+      .finally(() => {
+        loading.value = false;
+      });
   }
 
   function processGroupTree() {
@@ -486,52 +466,62 @@
       return deleteResource();
     });
   }
-  function deleteSecondaryDataModelFunction(param) {
-    deleteSecondaryDataModel(param, currentNode.value.group, 
currentNode.value.type).then((res) => {
-      if (res.status === 200) {
-        if (res.data.deleted) {
-          ElMessage({
-            message: 'Delete succeeded',
-            type: 'success',
-            duration: 5000,
-          });
-          getGroupLists();
-          $bus.emit('deleteResource', currentNode.value.type);
-        }
-      }
-    });
+  async function deleteSecondaryDataModelFunction(param) {
+    const res = await deleteSecondaryDataModel(param, currentNode.value.group, 
currentNode.value.type);
+    if (res.error) {
+      ElMessage({
+        message: `Delete failed: ${res.error.message}`,
+        type: 'error',
+      });
+      return;
+    }
+    if (res.deleted) {
+      ElMessage({
+        message: 'Delete succeeded',
+        type: 'success',
+      });
+      getGroupLists();
+      $bus.emit('deleteResource', currentNode.value.type);
+    }
   }
-  function deleteGroupFunction() {
+  async function deleteGroupFunction() {
     // delete group
-    deleteGroup(currentNode.value.name).then((res) => {
-      if (res.status === 200) {
-        if (res.data.deleted) {
-          ElMessage({
-            message: 'Delete succeeded',
-            type: 'success',
-            duration: 5000,
-          });
-          getGroupLists();
-        }
-        $bus.emit('deleteGroup', currentNode.value.name);
-      }
-    });
+    const res = await deleteGroup(currentNode.value.name);
+    if (res.error) {
+      ElMessage({
+        message: `Delete failed: ${res.error.message}`,
+        type: 'error',
+      });
+      return;
+    }
+    if (res.deleted) {
+      ElMessage({
+        message: 'Delete succeeded',
+        type: 'success',
+      });
+      getGroupLists();
+    }
+    $bus.emit('deleteGroup', currentNode.value.name);
   }
-  function deleteResource() {
+  async function deleteResource() {
     // delete Resources
-    deleteAllTypesOfResource(props.type, currentNode.value.group, 
currentNode.value.name).then((res) => {
-      if (res.status === 200) {
-        if (res.data.deleted) {
-          ElMessage({
-            message: 'Delete succeeded',
-            type: 'success',
-            duration: 5000,
-          });
-          getGroupLists();
-        }
-        $bus.emit('deleteResource', currentNode.value.name);
-      }
-    });
+    const res = await deleteAllTypesOfResource(props.type, 
currentNode.value.group, currentNode.value.name);
+    if (res.error) {
+      ElMessage({
+        message: `Delete failed: ${res.error.message}`,
+        type: 'error',
+      });
+      return;
+    }
+    if (res.deleted) {
+      ElMessage({
+        message: 'Delete succeeded',
+        type: 'success',
+        duration: 5000,
+      });
+      getGroupLists();
+      $bus.emit('deleteResource', currentNode.value.name);
+    }
   }
 
   // create/edit group
@@ -540,43 +530,43 @@
   }
 
   function createGroupFunction() {
-    ruleForm.value.validate((valid) => {
+    ruleForm.value.validate(async (valid) => {
       if (valid) {
-        createGroup(getGroupForm.value)
-          .then((res) => {
-            if (res.status === 200) {
-              getGroupLists();
-              ElMessage({
-                message: 'Created successfully',
-                type: 'success',
-                duration: 3000,
-              });
-            }
-          })
-          .finally(() => {
-            data.dialogGroupVisible = false;
+        const res = await createGroup(getGroupForm.value);
+        data.dialogGroupVisible = false;
+        if (res.error) {
+          ElMessage({
+            message: `Create failed: ${res.error.message}`,
+            type: 'error',
           });
+          return;
+        }
+        getGroupLists();
+        ElMessage({
+          message: 'Created successfully',
+          type: 'success',
+        });
       }
     });
   }
   function editGroupFunction() {
     const name = currentNode.value.name;
-    ruleForm.value.validate((valid) => {
+    ruleForm.value.validate(async (valid) => {
       if (valid) {
-        editGroup(name, getGroupForm.value)
-          .then((res) => {
-            if (res.status === 200) {
-              getGroupLists();
-              ElMessage({
-                message: 'Update succeeded',
-                type: 'success',
-                duration: 3000,
-              });
-            }
-          })
-          .finally(() => {
-            data.dialogGroupVisible = false;
+        const res = await editGroup(name, getGroupForm.value);
+        data.dialogGroupVisible = false;
+        if (res.error) {
+          ElMessage({
+            message: `Update failed: ${res.error.message}`,
+            type: 'error',
           });
+          return;
+        }
+        getGroupLists();
+        ElMessage({
+          message: 'Update succeeded',
+          type: 'success',
+        });
       }
     });
   }
@@ -656,6 +646,22 @@
   watch(filterText, (val) => {
     treeRef.value?.filter(val);
   });
+
+  // Watch route changes to update active node without reloading the tree
+  watch(
+    () => route.params,
+    (newParams) => {
+      const { group, name, type } = newParams;
+      if (group && name && type) {
+        data.activeNode = `${group}_${type}_${name}`;
+        // Expand and highlight the node
+        if (treeRef.value) {
+          treeRef.value.setCurrentKey(data.activeNode);
+        }
+      }
+    },
+    { deep: true },
+  );
 </script>
 
 <template>
diff --git a/ui/src/components/Header/components/header.vue 
b/ui/src/components/Header/components/header.vue
index 5900ec24..6c5c17bb 100644
--- a/ui/src/components/Header/components/header.vue
+++ b/ui/src/components/Header/components/header.vue
@@ -18,10 +18,9 @@
 -->
 
 <script setup>
-  import { reactive } from 'vue';
+  import { reactive, watch, getCurrentInstance } from 'vue';
   import { ElImage, ElMenu, ElMenuItem } from 'element-plus';
   import { useRoute } from 'vue-router';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
   import userImg from '@/assets/banyandb_small.jpg';
 
   // Eventbus
diff --git a/ui/src/components/IndexRule/Editor.vue 
b/ui/src/components/IndexRule/Editor.vue
index 7d22ba8b..0f350df7 100644
--- a/ui/src/components/IndexRule/Editor.vue
+++ b/ui/src/components/IndexRule/Editor.vue
@@ -18,12 +18,11 @@
 -->
 
 <script lang="ts" setup>
-  import { reactive, ref } from 'vue';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
+  import { reactive, ref, watch, getCurrentInstance } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
   import type { FormInstance } from 'element-plus';
-  import { createSecondaryDataModel, getSecondaryDataModel, 
updateSecondaryDataModel } from '@/api/index';
   import { ElMessage } from 'element-plus';
+  import { createSecondaryDataModel, getSecondaryDataModel, 
updateSecondaryDataModel } from '@/api/index';
   import FormHeader from '../common/FormHeader.vue';
 
   const $loadingCreate = 
getCurrentInstance().appContext.config.globalProperties.$loadingCreate;
@@ -141,7 +140,7 @@
   );
   const submit = async (formEl: FormInstance | undefined) => {
     if (!formEl) return;
-    await formEl.validate((valid) => {
+    await formEl.validate(async (valid) => {
       if (valid) {
         const param = {
           indexRule: {
@@ -156,54 +155,42 @@
         };
         $loadingCreate();
         if (data.operator === 'create') {
-          return createSecondaryDataModel('index-rule', param)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'Create successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteGroup', data.form.group);
-                openIndexRule();
-              }
-            })
-            .catch((err) => {
-              ElMessage({
-                message: 'Please refresh and try again. Error: ' + err,
-                type: 'error',
-                duration: 3000,
-              });
-            })
-            .finally(() => {
-              $loadingClose();
-            });
-        } else {
-          return updateSecondaryDataModel('index-rule', data.form.group, 
data.form.name, param)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'Edit successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteResource', data.form.group);
-                openIndexRule();
-              }
-            })
-            .catch((err) => {
-              ElMessage({
-                message: 'Please refresh and try again. Error: ' + err,
-                type: 'error',
-                duration: 3000,
-              });
-            })
-            .finally(() => {
-              $loadingClose();
+          const res = await createSecondaryDataModel('index-rule', param);
+          $loadingClose();
+          if (res.error) {
+            ElMessage({
+              message: `Failed to create index rule: ${res.error.message}`,
+              type: 'error',
             });
+            return;
+          }
+          ElMessage({
+            message: 'Create successed',
+            type: 'success',
+            duration: 5000,
+          });
+          $bus.emit('refreshAside');
+          $bus.emit('deleteGroup', data.form.group);
+          openIndexRule();
+          return;
+        }
+        const res = await updateSecondaryDataModel('index-rule', 
data.form.group, data.form.name, param);
+        $loadingClose();
+        if (res.error) {
+          ElMessage({
+            message: `Failed to update index rule: ${res.error.message}`,
+            type: 'error',
+          });
+          return;
         }
+        ElMessage({
+          message: 'Edit successed',
+          type: 'success',
+          duration: 5000,
+        });
+        $bus.emit('refreshAside');
+        $bus.emit('deleteResource', data.form.group);
+        openIndexRule();
       }
     });
   };
@@ -227,32 +214,26 @@
     $bus.emit('AddTabs', add);
   }
 
-  function initData() {
+  async function initData() {
     if (data.operator === 'edit' && data.form.group && data.form.name) {
       $loadingCreate();
-      getSecondaryDataModel('index-rule', data.form.group, data.form.name)
-        .then((res) => {
-          if (res.status === 200) {
-            const indexRule = res.data.indexRule;
-            data.form = {
-              group: indexRule.metadata.group,
-              name: indexRule.metadata.name,
-              analyzer: indexRule.analyzer,
-              tags: indexRule.tags,
-              type: indexRule.type,
-            };
-          }
-        })
-        .catch((err) => {
-          ElMessage({
-            message: 'Please refresh and try again. Error: ' + err,
-            type: 'error',
-            duration: 3000,
-          });
-        })
-        .finally(() => {
-          $loadingClose();
+      const res = await getSecondaryDataModel('index-rule', data.form.group, 
data.form.name);
+      $loadingClose();
+      if (res.error) {
+        ElMessage({
+          message: `Failed to fetch index rule: ${res.error.message}`,
+          type: 'error',
         });
+        return;
+      }
+      const indexRule = res.indexRule;
+      data.form = {
+        group: indexRule.metadata.group,
+        name: indexRule.metadata.name,
+        analyzer: indexRule.analyzer,
+        tags: indexRule.tags,
+        type: indexRule.type,
+      };
     }
   }
 </script>
diff --git a/ui/src/components/IndexRule/index.vue 
b/ui/src/components/IndexRule/index.vue
index 7ab02ce7..09cf7f42 100644
--- a/ui/src/components/IndexRule/index.vue
+++ b/ui/src/components/IndexRule/index.vue
@@ -18,8 +18,7 @@
 -->
 
 <script setup>
-  import { reactive } from 'vue';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
+  import { reactive, watch, getCurrentInstance } from 'vue';
   import { useRoute } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import { getSecondaryDataModel } from '@/api/index';
@@ -61,7 +60,7 @@
     $loadingCreate();
     const result = await getSecondaryDataModel(data.type, data.group, 
data.name);
     $loadingClose();
-    if (!(result.data && result.data.indexRule)) {
+    if (!result.indexRule) {
       ElMessage({
         message: `Please refresh and try again.`,
         type: 'error',
@@ -69,7 +68,7 @@
       });
       return;
     }
-    data.indexRule = { ...result.data.indexRule, noSort: 
String(result.data.indexRule.noSort) };
+    data.indexRule = { ...result.indexRule, noSort: 
String(result.indexRule.noSort) };
   }
 </script>
 
diff --git a/ui/src/components/IndexRuleBinding/Editor.vue 
b/ui/src/components/IndexRuleBinding/Editor.vue
index 26b4e5e9..c9321713 100644
--- a/ui/src/components/IndexRuleBinding/Editor.vue
+++ b/ui/src/components/IndexRuleBinding/Editor.vue
@@ -18,12 +18,11 @@
 -->
 
 <script lang="ts" setup>
-  import { reactive, ref } from 'vue';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
+  import { reactive, ref, watch, getCurrentInstance } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
   import type { FormInstance } from 'element-plus';
-  import { createSecondaryDataModel, getSecondaryDataModel, 
updateSecondaryDataModel } from '@/api/index';
   import { ElMessage } from 'element-plus';
+  import { createSecondaryDataModel, getSecondaryDataModel, 
updateSecondaryDataModel } from '@/api/index';
   import FormHeader from '../common/FormHeader.vue';
 
   const $loadingCreate = 
getCurrentInstance().appContext.config.globalProperties.$loadingCreate;
@@ -94,7 +93,7 @@
   );
   const submit = async (formEl: FormInstance | undefined) => {
     if (!formEl) return;
-    await formEl.validate((valid) => {
+    await formEl.validate(async (valid) => {
       if (valid) {
         const param = {
           indexRuleBinding: {
@@ -113,54 +112,40 @@
         };
         $loadingCreate();
         if (data.operator === 'create') {
-          return createSecondaryDataModel('index-rule-binding', param)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'Create successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteGroup', data.form.group);
-                openIndexRuleBinding();
-              }
-            })
-            .catch((err) => {
-              ElMessage({
-                message: 'Please refresh and try again. Error: ' + err,
-                type: 'error',
-                duration: 3000,
-              });
-            })
-            .finally(() => {
-              $loadingClose();
-            });
-        } else {
-          return updateSecondaryDataModel('index-rule-binding', 
data.form.group, data.form.name, param)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'Edit successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteResource', data.form.group);
-                openIndexRuleBinding();
-              }
-            })
-            .catch((err) => {
-              ElMessage({
-                message: 'Please refresh and try again. Error: ' + err,
-                type: 'error',
-                duration: 3000,
-              });
-            })
-            .finally(() => {
-              $loadingClose();
+          const response = await 
createSecondaryDataModel('index-rule-binding', param);
+          $loadingClose();
+          if (response.error) {
+            ElMessage({
+              message: `Failed to create index rule binding: 
${response.error.message}`,
+              type: 'error',
             });
+            return;
+          }
+          ElMessage({
+            message: 'Create successed',
+            type: 'success',
+          });
+          $bus.emit('refreshAside');
+          $bus.emit('deleteGroup', data.form.group);
+          openIndexRuleBinding();
+          return;
+        }
+        const response = await updateSecondaryDataModel('index-rule-binding', 
data.form.group, data.form.name, param);
+        $loadingClose();
+        if (response.error) {
+          ElMessage({
+            message: `Failed to update index rule binding: 
${response.error.message}`,
+            type: 'error',
+          });
+          return;
         }
+        ElMessage({
+          message: 'Update successed',
+          type: 'success',
+        });
+        $bus.emit('refreshAside');
+        $bus.emit('deleteResource', data.form.group);
+        openIndexRuleBinding();
       }
     });
   };
@@ -184,32 +169,26 @@
     $bus.emit('AddTabs', add);
   }
 
-  function initData() {
+  async function initData() {
     if (data.operator === 'edit' && data.form.group && data.form.name) {
       $loadingCreate();
-      getSecondaryDataModel('index-rule-binding', data.form.group, 
data.form.name)
-        .then((res) => {
-          if (res.status === 200) {
-            const indexRuleBinding = res.data.indexRuleBinding;
-            data.form = {
-              group: indexRuleBinding.metadata.group,
-              name: indexRuleBinding.metadata.name,
-              beginAt: indexRuleBinding.beginAt,
-              expireAt: indexRuleBinding.expireAt,
-              rules: indexRuleBinding.rules,
-            };
-          }
-        })
-        .catch((err) => {
-          ElMessage({
-            message: 'Please refresh and try again. Error: ' + err,
-            type: 'error',
-            duration: 3000,
-          });
-        })
-        .finally(() => {
-          $loadingClose();
+      const response = await getSecondaryDataModel('index-rule-binding', 
data.form.group, data.form.name);
+      $loadingClose();
+      if (response.error) {
+        ElMessage.error({
+          message: `Failed to fetch index rule binding: 
${response.error.message}`,
+          type: 'error',
         });
+        return;
+      }
+      const indexRuleBinding = response.indexRuleBinding;
+      data.form = {
+        group: indexRuleBinding.metadata.group,
+        name: indexRuleBinding.metadata.name,
+        beginAt: indexRuleBinding.beginAt,
+        expireAt: indexRuleBinding.expireAt,
+        rules: indexRuleBinding.rules,
+      };
     }
   }
 </script>
diff --git a/ui/src/components/IndexRuleBinding/index.vue 
b/ui/src/components/IndexRuleBinding/index.vue
index 1ee933aa..d0356112 100644
--- a/ui/src/components/IndexRuleBinding/index.vue
+++ b/ui/src/components/IndexRuleBinding/index.vue
@@ -18,8 +18,7 @@
 -->
 
 <script setup>
-  import { reactive } from 'vue';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
+  import { reactive, watch, getCurrentInstance } from 'vue';
   import { useRoute } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import { getSecondaryDataModel } from '@/api/index';
@@ -54,27 +53,23 @@
     },
   );
 
-  function initData() {
-    if (data.type && data.group && data.name) {
-      $loadingCreate();
-      getSecondaryDataModel(data.type, data.group, data.name)
-        .then((result) => {
-          data.indexRuleBinding = result.data.indexRuleBinding;
-        })
-        .catch((err) => {
-          ElMessage({
-            message: 'Please refresh and try again. Error: ' + err,
-            type: 'error',
-            duration: 3000,
-          });
-        })
-        .finally(() => {
-          $loadingClose();
-        });
+  async function initData() {
+    if (!(data.type && data.group && data.name)) {
+      return;
     }
+    $loadingCreate();
+    const response = await getSecondaryDataModel('index-rule-binding', 
data.group, data.name);
+    $loadingClose();
+    if (response.error) {
+      ElMessage.error({
+        message: `Failed to fetch index rule binding: 
${response.error.message}`,
+        type: 'error',
+      });
+      return;
+    }
+    data.indexRuleBinding = response.indexRuleBinding;
   }
 </script>
-
 <template>
   <div>
     <el-card>
diff --git a/ui/src/components/Property/Editor.vue 
b/ui/src/components/Property/Editor.vue
index 2cdc3b7a..2909a4aa 100644
--- a/ui/src/components/Property/Editor.vue
+++ b/ui/src/components/Property/Editor.vue
@@ -17,12 +17,10 @@
   ~ under the License.
 -->
 <script setup>
-  import { reactive, ref, onMounted } from 'vue';
+  import { reactive, ref, onMounted, getCurrentInstance } from 'vue';
   import { ElMessage } from 'element-plus';
-  import { getCurrentInstance } from '@vue/runtime-core';
   import { useRoute, useRouter } from 'vue-router';
-  import { updateProperty, createProperty } from '@/api';
-  import { getStreamOrMeasure } from '@/api/index';
+  import { updateProperty, createProperty, getResourceOfAllType } from 
'@/api/index';
   import TagEditor from './TagEditor.vue';
   import { rules, strategyGroup, formConfig } from './data';
 
@@ -46,7 +44,7 @@
   function initProperty() {
     if (operator === 'edit') {
       $loadingCreate();
-      getStreamOrMeasure(type, group, name)
+      getResourceOfAllType(type, group, name)
         .then((res) => {
           if (res.status === 200) {
             const { property } = res.data;
@@ -78,7 +76,7 @@
   };
   const submit = async () => {
     if (!ruleForm.value) return;
-    await ruleForm.value.validate((valid) => {
+    await ruleForm.value.validate(async (valid) => {
       if (valid) {
         $loadingCreate();
         const param = {
@@ -93,54 +91,40 @@
           },
         };
         if (operator === 'create') {
-          createProperty(param)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteGroup', formData.group);
-                openResourses();
-              }
-            })
-            .catch((err) => {
-              ElMessage({
-                message: 'Please refresh and try again. Error: ' + err,
-                type: 'error',
-                duration: 3000,
-              });
-            })
-            .finally(() => {
-              $loadingClose();
+          const response = await createProperty(param);
+          $loadingClose();
+          if (response.error) {
+            ElMessage.error({
+              message: `Failed to create property: ${response.error.message}`,
+              type: 'error',
             });
+            return;
+          }
+          ElMessage.success({
+            message: 'Create successed',
+            type: 'success',
+          });
+          $bus.emit('refreshAside');
+          $bus.emit('deleteResource', formData.name);
+          openResourses();
           return;
         }
-        updateProperty(formData.group, formData.name, param)
-          .then((res) => {
-            if (res.status === 200) {
-              ElMessage({
-                message: 'successed',
-                type: 'success',
-                duration: 5000,
-              });
-              $bus.emit('refreshAside');
-              $bus.emit('deleteResource', formData.name);
-              openResourses();
-            }
-          })
-          .catch((err) => {
-            ElMessage({
-              message: 'Please refresh and try again. Error: ' + err,
-              type: 'error',
-              duration: 3000,
-            });
-          })
-          .finally(() => {
-            $loadingClose();
+        const response = await updateProperty(formData.group, formData.name, 
param);
+        $loadingClose();
+        if (response.error) {
+          ElMessage.error({
+            message: `Failed to update property: ${response.error.message}`,
+            type: 'error',
           });
+          return;
+        }
+        ElMessage.success({
+          message: 'Update successed',
+          type: 'success',
+        });
+        $bus.emit('refreshAside');
+        $bus.emit('deleteResource', formData.name);
+        openResourses();
       }
     });
   };
diff --git a/ui/src/components/Property/PropertyEditor.vue 
b/ui/src/components/Property/PropertyEditor.vue
index e6ae4aa7..39226ba1 100644
--- a/ui/src/components/Property/PropertyEditor.vue
+++ b/ui/src/components/Property/PropertyEditor.vue
@@ -18,12 +18,12 @@
 -->
 
 <script setup>
-  import { applyProperty } from '@/api';
-  import { reactive, ref } from 'vue';
-  import { getCurrentInstance } from '@vue/runtime-core';
-  import TagEditor from './TagEditor.vue';
+  import { reactive, ref, getCurrentInstance } from 'vue';
   import { ElMessage } from 'element-plus';
+  import TagEditor from './TagEditor.vue';
+  import { applyProperty } from '@/api';
   import { rules, strategyGroup, formConfig } from './data';
+
   const $loadingCreate = 
getCurrentInstance().appContext.config.globalProperties.$loadingCreate;
   const $loadingClose = 
getCurrentInstance().appContext.config.globalProperties.$loadingClose;
   const showDialog = ref(false);
@@ -70,7 +70,7 @@
   };
   const confirmApply = async () => {
     if (!ruleForm.value) return;
-    await ruleForm.value.validate((valid) => {
+    await ruleForm.value.validate(async (valid) => {
       if (valid) {
         $loadingCreate();
         const param = {
@@ -91,28 +91,21 @@
             }),
           },
         };
-        applyProperty(formData.group, formData.name, formData.id, param)
-          .then((res) => {
-            if (res.status === 200) {
-              ElMessage({
-                message: 'successed',
-                type: 'success',
-                duration: 5000,
-              });
-              showDialog.value = false;
-              promiseResolve();
-            }
-          })
-          .catch((err) => {
-            ElMessage({
-              message: 'Please refresh and try again. Error: ' + err,
-              type: 'error',
-              duration: 3000,
-            });
-          })
-          .finally(() => {
-            $loadingClose();
+        const response = await applyProperty(formData.group, formData.name, 
formData.id, param);
+        $loadingClose();
+        if (response.error) {
+          ElMessage({
+            message: `Failed to apply property: ${response.error.message}`,
+            type: 'error',
           });
+          return;
+        }
+        ElMessage({
+          message: 'successed',
+          type: 'success',
+        });
+        showDialog.value = false;
+        promiseResolve();
       }
     });
   };
diff --git a/ui/src/components/Property/PropertyRead.vue 
b/ui/src/components/Property/PropertyRead.vue
index 354fe550..309f7cf0 100644
--- a/ui/src/components/Property/PropertyRead.vue
+++ b/ui/src/components/Property/PropertyRead.vue
@@ -18,13 +18,13 @@
 -->
 
 <script setup>
-  import { fetchProperties, deleteProperty } from '@/api/index';
-  import { getCurrentInstance } from '@vue/runtime-core';
   import { useRoute } from 'vue-router';
   import { ElMessage } from 'element-plus';
-  import { reactive, ref, watch, onMounted } from 'vue';
+  import { reactive, ref, watch, onMounted, getCurrentInstance } from 'vue';
   import { RefreshRight, Search } from '@element-plus/icons-vue';
+  import { fetchProperties, deleteProperty } from '@/api/index';
   import { yamlToJson } from '@/utils/yaml';
+  import CodeMirror from '@/components/CodeMirror/index.vue';
   import PropertyEditor from './PropertyEditor.vue';
   import PropertyValueReader from './PropertyValueReader.vue';
   import FormHeader from '../common/FormHeader.vue';
@@ -44,29 +44,23 @@
   });
   const yamlCode = ref(`name: ${data.name}
 limit: 10`);
-  const getProperties = (params) => {
+  const getProperties = async (params) => {
     $loadingCreate();
-    fetchProperties({ groups: [data.group], name: data.name, limit: 10, 
...params })
-      .then((res) => {
-        if (res.status === 200) {
-          data.tableData = res.data.properties.map((item) => {
-            item.tags.forEach((tag) => {
-              tag.value = JSON.stringify(tag.value);
-            });
-            return item;
-          });
-        }
-      })
-      .catch((err) => {
-        ElMessage({
-          message: 'An error occurred while obtaining group data. Please 
refresh and try again. Error: ' + err,
-          type: 'error',
-          duration: 3000,
-        });
-      })
-      .finally(() => {
-        $loadingClose();
+    const res = await fetchProperties({ groups: [data.group], name: data.name, 
limit: 10, ...params });
+    $loadingClose();
+    if (res.error) {
+      ElMessage({
+        message: `Failed to fetch properties: ${res.error.message}`,
+        type: 'error',
+      });
+      return;
+    }
+    data.tableData = (res.properties || []).map((item) => {
+      item.tags.forEach((tag) => {
+        tag.value = JSON.stringify(tag.value);
       });
+      return item;
+    });
   };
   const openPropertyView = (data) => {
     propertyValueViewerRef?.value.openDialog(data);
@@ -107,30 +101,23 @@ limit: 10`);
         });
       });
   }
-  const deleteTableData = (index) => {
+  const deleteTableData = async (index) => {
     const item = data.tableData[index];
     $loadingCreate();
-    deleteProperty(item.metadata.group, item.metadata.name, item.id)
-      .then((res) => {
-        if (res.status === 200) {
-          ElMessage({
-            message: 'successed',
-            type: 'success',
-            duration: 5000,
-          });
-          getProperties();
-        }
-      })
-      .catch((err) => {
-        ElMessage({
-          message: 'Please refresh and try again. Error: ' + err,
-          type: 'error',
-          duration: 3000,
-        });
-      })
-      .finally(() => {
-        $loadingClose();
+    const response = await deleteProperty(item.metadata.group, 
item.metadata.name, item.id);
+    $loadingClose();
+    if (response.error) {
+      ElMessage({
+        message: `Failed to delete property: ${response.error.message}`,
+        type: 'error',
       });
+      return;
+    }
+    ElMessage({
+      message: 'successed',
+      type: 'success',
+    });
+    getProperties();
   };
   onMounted(() => {
     getProperties();
diff --git a/ui/src/components/Property/PropertyValueReader.vue 
b/ui/src/components/Property/PropertyValueReader.vue
index 1f63c99f..7bcf9f5f 100644
--- a/ui/src/components/Property/PropertyValueReader.vue
+++ b/ui/src/components/Property/PropertyValueReader.vue
@@ -19,6 +19,7 @@
 
 <script setup>
   import { reactive, ref } from 'vue';
+
   const showDialog = ref(false);
   const title = ref('');
   const valueData = reactive({
diff --git a/ui/src/components/Property/TagEditor.vue 
b/ui/src/components/Property/TagEditor.vue
index c35335f5..19c2b756 100644
--- a/ui/src/components/Property/TagEditor.vue
+++ b/ui/src/components/Property/TagEditor.vue
@@ -21,7 +21,6 @@
   import { reactive, ref } from 'vue';
 
   const showDialog = ref(false);
-  //const editValue = ref(false)
   const ruleForm = ref();
   const title = ref('');
   const formData = reactive({
diff --git a/ui/src/components/Read/index.vue b/ui/src/components/Read/index.vue
index bfea6477..f6231c14 100644
--- a/ui/src/components/Read/index.vue
+++ b/ui/src/components/Read/index.vue
@@ -18,15 +18,13 @@
 -->
 
 <script setup>
-  import { reactive, ref } from 'vue';
+  import { reactive, ref, watch, getCurrentInstance, computed } from 'vue';
   import { useRoute } from 'vue-router';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
-  import { getStreamOrMeasure, getTableList } from '@/api/index';
+  import { ElMessage } from 'element-plus';
   import { Search, RefreshRight } from '@element-plus/icons-vue';
+  import { getResourceOfAllType, getTableList } from '@/api/index';
   import { jsonToYaml, yamlToJson } from '@/utils/yaml';
   import CodeMirror from '@/components/CodeMirror/index.vue';
-  import { ElMessage } from 'element-plus';
-  import { computed } from '@vue/runtime-core';
   import FormHeader from '../common/FormHeader.vue';
   import { Shortcuts, Last15Minutes } from '../common/data';
 
@@ -82,10 +80,6 @@
     timeValue: null,
     loading: false,
     total: 100,
-    /* queryInfo: {
-        pagenum: 1,
-        pagesize: 100
-    }, */
     tableTags: [],
     tableData: [],
     code: null,
@@ -173,29 +167,30 @@ orderBy:
     json.data.timeRange.end = data.timeValue ? new Date(data.timeValue[1]) : 
null;
     data.code = jsonToYaml(json.data).data;
   }
-  function initData() {
+  async function initData() {
     $loadingCreate();
-    getStreamOrMeasure(data.type, data.group, data.name)
-      .then((res) => {
-        if (res.status === 200) {
-          data.resourceData = res.data[data.type];
-          data.tableTags = res.data[data.type].tagFamilies[0].tags.map((item) 
=> {
-            item.label = item.name;
-            return item;
-          });
-          data.options = res.data[data.type].tagFamilies.map((item, index) => {
-            return { label: item.name, value: index };
-          });
-          data.tagFamily = 0;
-          data.fields = res.data[data.type].fields ? 
res.data[data.type].fields : [];
-          handleCodeData();
-        }
-      })
-      .finally(() => {
-        $loadingClose();
+    const response = await getResourceOfAllType(data.type, data.group, 
data.name);
+    $loadingClose();
+    if (response.error) {
+      ElMessage({
+        message: `Get ${data.type} failed: ${response.error.message}`,
+        type: 'error',
       });
+      return;
+    }
+    data.resourceData = response[data.type];
+    data.tableTags = response[data.type].tagFamilies[0].tags.map((item) => {
+      item.label = item.name;
+      return item;
+    });
+    data.options = response[data.type].tagFamilies.map((item, index) => {
+      return { label: item.name, value: index };
+    });
+    data.tagFamily = 0;
+    data.fields = response[data.type].fields ? response[data.type].fields : [];
+    handleCodeData();
   }
-  function getTableData() {
+  async function getTableData() {
     data.tableData = [];
     data.loading = true;
     setTableFilterConfig();
@@ -211,19 +206,20 @@ orderBy:
     }
     paramList.name = data.resourceData.metadata.name;
     paramList.groups = [data.resourceData.metadata.group];
-    getTableList(paramList, data.type)
-      .then((res) => {
-        if (res.status === 200) {
-          if (data.type === 'stream') {
-            setTableData(res.data.elements);
-          } else {
-            setTableData(res.data.dataPoints);
-          }
-        }
-      })
-      .catch(() => {
-        data.loading = false;
+    const res = await getTableList(paramList, data.type);
+    data.loading = false;
+    if (res.error) {
+      ElMessage({
+        message: `Get ${data.type} failed: ${res.error.message}`,
+        type: 'error',
       });
+      return;
+    }
+    if (data.type === 'stream') {
+      setTableData(res.elements);
+    } else {
+      setTableData(res.dataPoints);
+    }
   }
   function setTableData(elements) {
     const tags = data.resourceData.tagFamilies[data.tagFamily].tags;
diff --git a/ui/src/components/Start/index.vue 
b/ui/src/components/Start/index.vue
index 5bcaf392..6e5de70f 100644
--- a/ui/src/components/Start/index.vue
+++ b/ui/src/components/Start/index.vue
@@ -20,6 +20,7 @@
 <script setup>
   import { reactive } from 'vue';
   import { useRoute } from 'vue-router';
+
   const route = useRoute();
   const data = reactive({
     type: '',
diff --git a/ui/src/components/TopNAggregation/Editor.vue 
b/ui/src/components/TopNAggregation/Editor.vue
index 98967b61..c5c0ee5a 100644
--- a/ui/src/components/TopNAggregation/Editor.vue
+++ b/ui/src/components/TopNAggregation/Editor.vue
@@ -18,8 +18,7 @@
 -->
 
 <script lang="ts" setup>
-  import { reactive, ref } from 'vue';
-  import { watch, getCurrentInstance } from '@vue/runtime-core';
+  import { reactive, ref, watch, getCurrentInstance } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
   import type { FormInstance } from 'element-plus';
   import { createSecondaryDataModel, getSecondaryDataModel, 
updateSecondaryDataModel } from '@/api/index';
@@ -159,7 +158,7 @@
   );
   const submit = async (formEl: FormInstance | undefined) => {
     if (!formEl) return;
-    await formEl.validate((valid) => {
+    await formEl.validate(async (valid) => {
       if (valid) {
         const param = {
           top_n_aggregation: {
@@ -180,54 +179,40 @@
         };
         $loadingCreate();
         if (data.operator === 'create') {
-          return createSecondaryDataModel('topn-agg', param)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'Create successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteGroup', data.form.group);
-                openTopNAgg();
-              }
-            })
-            .catch((err) => {
-              ElMessage({
-                message: 'Please refresh and try again. Error: ' + err,
-                type: 'error',
-                duration: 3000,
-              });
-            })
-            .finally(() => {
-              $loadingClose();
-            });
-        } else {
-          return updateSecondaryDataModel('topn-agg', data.form.group, 
data.form.name, param)
-            .then((res) => {
-              if (res.status === 200) {
-                ElMessage({
-                  message: 'Edit successed',
-                  type: 'success',
-                  duration: 5000,
-                });
-                $bus.emit('refreshAside');
-                $bus.emit('deleteResource', data.form.group);
-                openTopNAgg();
-              }
-            })
-            .catch((err) => {
-              ElMessage({
-                message: 'Please refresh and try again. Error: ' + err,
-                type: 'error',
-                duration: 3000,
-              });
-            })
-            .finally(() => {
-              $loadingClose();
+          const response = await createSecondaryDataModel('topn-agg', param);
+          $loadingClose();
+          if (response.error) {
+            ElMessage.error({
+              message: `Failed to create topN aggregation: 
${response.error.message}`,
+              type: 'error',
             });
+            return;
+          }
+          ElMessage.success({
+            message: 'Create successed',
+            type: 'success',
+          });
+          $bus.emit('refreshAside');
+          $bus.emit('deleteGroup', data.form.group);
+          openTopNAgg();
+          return;
         }
+        const response = await updateSecondaryDataModel('topn-agg', 
data.form.group, data.form.name, param);
+        $loadingClose();
+        if (response.error) {
+          ElMessage.error({
+            message: `Failed to update topN aggregation: 
${response.error.message}`,
+            type: 'error',
+          });
+          return;
+        }
+        ElMessage({
+          message: 'Edit successed',
+          type: 'success',
+        });
+        $bus.emit('refreshAside');
+        $bus.emit('deleteResource', data.form.group);
+        openTopNAgg();
       }
     });
   };
@@ -251,36 +236,30 @@
     $bus.emit('AddTabs', add);
   }
 
-  function initData() {
+  async function initData() {
     if (data.operator === 'edit' && data.form.group && data.form.name) {
       $loadingCreate();
-      getSecondaryDataModel('topn-agg', data.form.group, data.form.name)
-        .then((res) => {
-          if (res.status === 200) {
-            const topNAggregation = res.data.topNAggregation;
-            data.form = {
-              group: topNAggregation.metadata.group,
-              name: topNAggregation.metadata.name,
-              sourceMeasureGroup: topNAggregation.sourceMeasure.group,
-              sourceMeasureName: topNAggregation.sourceMeasure.name,
-              fieldName: topNAggregation.fieldName,
-              fieldValueSort: topNAggregation.fieldValueSort,
-              groupByTagNames: topNAggregation.groupByTagNames,
-              countersNumber: topNAggregation.countersNumber,
-              lruSize: topNAggregation.lruSize,
-            };
-          }
-        })
-        .catch((err) => {
-          ElMessage({
-            message: 'Please refresh and try again. Error: ' + err,
-            type: 'error',
-            duration: 3000,
-          });
-        })
-        .finally(() => {
-          $loadingClose();
+      const response = await getSecondaryDataModel('topn-agg', 
data.form.group, data.form.name);
+      $loadingClose();
+      if (response.error) {
+        ElMessage.error({
+          message: `Failed to fetch topN aggregation: 
${response.error.message}`,
+          type: 'error',
         });
+        return;
+      }
+      const topNAggregation = response.topNAggregation;
+      data.form = {
+        group: topNAggregation.metadata.group,
+        name: topNAggregation.metadata.name,
+        sourceMeasureGroup: topNAggregation.sourceMeasure.group,
+        sourceMeasureName: topNAggregation.sourceMeasure.name,
+        fieldName: topNAggregation.fieldName,
+        fieldValueSort: topNAggregation.fieldValueSort,
+        groupByTagNames: topNAggregation.groupByTagNames,
+        countersNumber: topNAggregation.countersNumber,
+        lruSize: topNAggregation.lruSize,
+      };
     }
   }
 </script>
diff --git a/ui/src/components/TopNAggregation/index.vue 
b/ui/src/components/TopNAggregation/index.vue
index e4650c4f..fdf6c5ae 100644
--- a/ui/src/components/TopNAggregation/index.vue
+++ b/ui/src/components/TopNAggregation/index.vue
@@ -18,13 +18,13 @@
 -->
 
 <script setup>
-  import { reactive, ref } from 'vue';
-  import { watch } from '@vue/runtime-core';
+  import { reactive, ref, watch } from 'vue';
   import { useRoute } from 'vue-router';
   import { ElMessage } from 'element-plus';
   import { jsonToYaml, yamlToJson } from '@/utils/yaml';
   import { Search, RefreshRight } from '@element-plus/icons-vue';
   import { getTopNAggregationData } from '@/api/index';
+  import CodeMirror from '@/components/CodeMirror/index.vue';
   import FormHeader from '../common/FormHeader.vue';
   import { Shortcuts, Last15Minutes } from '../common/data';
 
@@ -72,15 +72,14 @@ fieldValueSort: 1`;
       ...param,
     });
     loading.value = false;
-    if (!result.data) {
-      ElMessage({
-        message: `Please refresh and try again. Error: ${err}`,
+    if (result.error) {
+      ElMessage.error({
+        message: `Failed to fetch topN aggregation data: 
${result.error.message}`,
         type: 'error',
-        duration: 3000,
       });
       return;
     }
-    data.lists = result.data.lists
+    data.lists = (result.lists || [])
       .map((d) => d.items.map((item) => ({ label: 
item.entity[0].value.str.value, value: item.value.int.value })))
       .flat();
     changePage(0);
diff --git a/ui/src/components/TopNav/index.vue 
b/ui/src/components/TopNav/index.vue
index 58c77494..42fb99df 100644
--- a/ui/src/components/TopNav/index.vue
+++ b/ui/src/components/TopNav/index.vue
@@ -18,9 +18,8 @@
 -->
 
 <script setup>
-  import { reactive } from 'vue';
+  import { reactive, getCurrentInstance } from 'vue';
   import { useRouter, useRoute } from 'vue-router';
-  import { getCurrentInstance } from '@vue/runtime-core';
 
   const router = useRouter();
   const route = useRoute();
diff --git a/ui/src/components/Trace/Editor.vue 
b/ui/src/components/Trace/Editor.vue
index c7f2d4b0..eea064cc 100644
--- a/ui/src/components/Trace/Editor.vue
+++ b/ui/src/components/Trace/Editor.vue
@@ -17,9 +17,8 @@
   ~ under the License.
 -->
 <script setup>
-  import { reactive, ref, onMounted } from 'vue';
+  import { reactive, ref, onMounted, getCurrentInstance } from 'vue';
   import { ElMessage } from 'element-plus';
-  import { getCurrentInstance } from 'vue';
   import { useRoute, useRouter } from 'vue-router';
   import { updateTrace, createTrace, getTrace } from '@/api';
   import FormHeader from '../common/FormHeader.vue';
@@ -54,7 +53,6 @@
         ElMessage({
           message: response.error.message,
           type: 'error',
-          duration: 3000,
         });
         return;
       }
@@ -128,7 +126,6 @@
           ElMessage({
             message: response.error.message,
             type: 'error',
-            duration: 3000,
           });
           return;
         }
diff --git a/ui/src/components/Trace/TraceRead.vue 
b/ui/src/components/Trace/TraceRead.vue
index cc523c64..2d342672 100644
--- a/ui/src/components/Trace/TraceRead.vue
+++ b/ui/src/components/Trace/TraceRead.vue
@@ -90,20 +90,19 @@
     if (!data.group) {
       return;
     }
-    try {
-      const response = await getindexRuleList(data.group);
-      if (response.status === 200 && response.data.indexRule && 
response.data.indexRule.length > 0) {
-        data.indexRule = response.data.indexRule[0];
-      } else {
-        data.indexRule = null;
-      }
-    } catch (err) {
+    const response = await getindexRuleList(data.group);
+    if (response.error) {
       data.indexRule = null;
       ElMessage({
-        message: 'Failed to fetch index rule: ' + (err?.message || 
String(err)),
+        message: 'Failed to fetch index rule: ' + (response.error?.message || 
String(response.error)),
         type: 'error',
-        duration: 3000,
       });
+      return;
+    }
+    if (response.indexRule?.length) {
+      data.indexRule = response.indexRule[0];
+    } else {
+      data.indexRule = null;
     }
   };
 
diff --git a/ui/src/main.js b/ui/src/main.js
index 3d4bcac5..dc0dea61 100644
--- a/ui/src/main.js
+++ b/ui/src/main.js
@@ -23,7 +23,6 @@ import { createPinia } from 'pinia';
 import App from './App.vue';
 import router from './router';
 
-import axios from 'axios';
 import mitt from 'mitt';
 
 import * as echarts from 'echarts/core';
@@ -61,7 +60,6 @@ echarts.use([
   UniversalTransition,
   CanvasRenderer,
 ]);
-app.config.globalProperties.$http = axios;
 app.config.globalProperties.$loading = ElLoading;
 app.config.globalProperties.$loadingCreate = () => {
   app.config.globalProperties.instance = ElLoading.service({
diff --git a/ui/src/plugins/axios.js b/ui/src/plugins/axios.js
deleted file mode 100644
index d0088b4b..00000000
--- a/ui/src/plugins/axios.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to 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. Apache Software Foundation (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.
- */
-
-'use strict';
-
-import Vue from 'vue';
-import axios from 'axios';
-
-// Full config:  https://github.com/axios/axios#request-config
-// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
-// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
-// axios.defaults.headers.post['Content-Type'] = 
'application/x-www-form-urlencoded';
-
-let config = {
-  baseURL: '/api/v1',
-  // timeout: 60 * 1000, // Timeout
-  // withCredentials: true, // Check cross-site Access-Control
-};
-
-const _axios = axios.create(config);
-
-_axios.interceptors.request.use(
-  function (config) {
-    // Do something before request is sent
-    return config;
-  },
-  function (error) {
-    // Do something with request error
-    return Promise.reject(error);
-  },
-);
-
-// Add a response interceptor
-_axios.interceptors.response.use(
-  function (response) {
-    // Do something with response data
-    return response;
-  },
-  function (error) {
-    // Do something with response error
-    return Promise.reject(error);
-  },
-);
-
-Plugin.install = function (Vue, options) {
-  Vue.axios = _axios;
-  window.axios = _axios;
-  Object.defineProperties(Vue.prototype, {
-    axios: {
-      get() {
-        return _axios;
-      },
-    },
-    $axios: {
-      get() {
-        return _axios;
-      },
-    },
-  });
-};
-
-Vue.use(Plugin);
-
-export default Plugin;
diff --git a/ui/src/utils/axios.js b/ui/src/utils/axios.js
deleted file mode 100644
index 80b1f0ab..00000000
--- a/ui/src/utils/axios.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to 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. Apache Software Foundation (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.
- */
-
-// axios response interceptors file
-
-import axios from 'axios';
-import { ElMessage } from 'element-plus';
-
-const axiosService = axios.create({
-  // baseURL: "http://34.92.85.178:18913",// process.env.VUE_APP_BASE_API,
-  timeout: 30000,
-});
-
-axiosService.interceptors.request.use(
-  (config) => {
-    /**
-     * TODO
-     * Configuration before request
-     */
-
-    return config;
-  },
-  (error) => {
-    /**
-     * TODO
-     * do some error handling
-     */
-    return Promise.reject(error);
-  },
-);
-
-// re request
-function reRequest(err) {
-  let againReq = new Promise((resolve) => {
-    resolve();
-  });
-  return againReq.then(() => {
-    return axiosService(err.config);
-  });
-}
-
-// axios response interceptors
-axiosService.interceptors.response.use(
-  (response) => {
-    const res = response.data;
-    /**
-     * TODO
-     * Data processing operation
-     */
-    if (response.status === 200) {
-      return Promise.resolve(response);
-    } else {
-      return Promise.reject(response);
-    }
-  },
-  (error) => {
-    /**
-     * TODO
-     * do some error handling
-     */
-    const resErr = error.data;
-    let msg = error.data && error.data.message ? error.data.message : 
error.message;
-    ElMessage({
-      dangerouslyUseHTMLString: true,
-      message: `${msg}<br/>Error:${error.response.data.message}`,
-      type: 'error',
-      duration: 3000,
-    });
-    return Promise.reject(error);
-  },
-);
-
-export default axiosService;
diff --git a/ui/src/views/Dashboard/index.vue b/ui/src/views/Dashboard/index.vue
index 14536b82..ef5e626f 100644
--- a/ui/src/views/Dashboard/index.vue
+++ b/ui/src/views/Dashboard/index.vue
@@ -19,6 +19,7 @@
 
 <script setup>
   import { ref, watchEffect, computed } from 'vue';
+  import { ElMessage } from 'element-plus';
   import { getGroupList, getTableList } from '@/api/index';
   import { Shortcuts } from '../../components/common/data';
 
@@ -216,19 +217,20 @@
       end: utcTime.value.end,
     };
     params.tagProjection = tagProjection;
-    const res = await getTableList(params, 'measure');
-    if (res.status === 200) {
-      return res.data.dataPoints;
+    const response = await getTableList(params, 'measure');
+    if (response.error) {
+      return null;
     }
-    return null;
+    return response.dataPoints;
   }
 
   async function fetchGroupList() {
-    const res = await getGroupList();
-    if (res.status === 200) {
-      return res.data;
+    const response = await getGroupList();
+
+    if (response.error) {
+      return ElMessage.error(response.error.message || 'Failed to fetch group 
list');
     }
-    return null;
+    return response;
   }
 
   function groupBy(data, key) {
diff --git a/ui/src/views/Measure/index.vue b/ui/src/views/Measure/index.vue
index 0f71ecd5..b5ce2f50 100644
--- a/ui/src/views/Measure/index.vue
+++ b/ui/src/views/Measure/index.vue
@@ -21,6 +21,7 @@
   import GroupTree from '@/components/GroupTree/index.vue';
   import TopNav from '@/components/TopNav/index.vue';
   import { reactive } from 'vue';
+  import { CatalogToGroupType } from '@/components/GroupTree/data';
 
   const data = reactive({
     width: '200px',
@@ -35,7 +36,7 @@
   <div class="size">
     <el-container>
       <el-aside :width="data.width" class="bd-top flex" style="position: 
relative; background-color: white">
-        <GroupTree type="measure" @setWidth="setWidth" />
+        <GroupTree :type="CatalogToGroupType.CATALOG_MEASURE" 
@setWidth="setWidth" />
       </el-aside>
       <el-main>
         <TopNav></TopNav>
diff --git a/ui/src/views/Property/index.vue b/ui/src/views/Property/index.vue
index 540e4089..4f15c1ab 100644
--- a/ui/src/views/Property/index.vue
+++ b/ui/src/views/Property/index.vue
@@ -18,9 +18,10 @@
 -->
 
 <script setup>
+  import { reactive } from 'vue';
   import GroupTree from '@/components/GroupTree/index.vue';
   import TopNav from '@/components/TopNav/index.vue';
-  import { reactive } from 'vue';
+  import { CatalogToGroupType } from '@/components/GroupTree/data';
 
   const data = reactive({
     width: '200px',
@@ -35,7 +36,7 @@
   <div class="size">
     <el-container>
       <el-aside :width="data.width" class="bd-top flex" style="position: 
relative; background-color: white">
-        <GroupTree type="property" @setWidth="setWidth" />
+        <GroupTree :type="CatalogToGroupType.CATALOG_PROPERTY" 
@setWidth="setWidth" />
       </el-aside>
       <el-main>
         <TopNav></TopNav>
diff --git a/ui/src/views/Stream/index.vue b/ui/src/views/Stream/index.vue
index 564cde57..1a842a39 100644
--- a/ui/src/views/Stream/index.vue
+++ b/ui/src/views/Stream/index.vue
@@ -18,9 +18,10 @@
 -->
 
 <script setup>
+  import { reactive } from 'vue';
   import GroupTree from '@/components/GroupTree/index.vue';
   import TopNav from '@/components/TopNav/index.vue';
-  import { reactive } from 'vue';
+  import { CatalogToGroupType } from '@/components/GroupTree/data';
 
   const data = reactive({
     width: '200px',
@@ -35,7 +36,7 @@
   <div class="size">
     <el-container>
       <el-aside :width="data.width" class="bd-top flex box-shadow" 
style="position: relative; background-color: white">
-        <GroupTree type="stream" @setWidth="setWidth" />
+        <GroupTree :type="CatalogToGroupType.CATALOG_STREAM" 
@setWidth="setWidth" />
       </el-aside>
       <el-main>
         <TopNav></TopNav>
diff --git a/ui/src/views/Trace/index.vue b/ui/src/views/Trace/index.vue
index 8fd3fa63..34342c0b 100644
--- a/ui/src/views/Trace/index.vue
+++ b/ui/src/views/Trace/index.vue
@@ -18,9 +18,10 @@
 -->
 
 <script setup>
+  import { reactive } from 'vue';
   import GroupTree from '@/components/GroupTree/index.vue';
   import TopNav from '@/components/TopNav/index.vue';
-  import { reactive } from 'vue';
+  import { CatalogToGroupType } from '@/components/GroupTree/data';
 
   const data = reactive({
     width: '200px',
@@ -35,7 +36,7 @@
   <div class="size">
     <el-container>
       <el-aside :width="data.width" class="bd-top flex" style="position: 
relative; background-color: white">
-        <GroupTree type="trace" @setWidth="setWidth" />
+        <GroupTree :type="CatalogToGroupType.CATALOG_TRACE" 
@setWidth="setWidth" />
       </el-aside>
       <el-main>
         <TopNav></TopNav>

Reply via email to