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

lauraxia pushed a commit to branch antdUI-gravitino-base1.1.0
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/antdUI-gravitino-base1.1.0 by 
this push:
     new f3a2492429 refine build script and fix some issue
f3a2492429 is described below

commit f3a2492429eb1c72d88ea49fe84f20181f79352a
Author: Qian Xia <[email protected]>
AuthorDate: Tue Jan 20 14:40:13 2026 +0800

    refine build script and fix some issue
---
 README.md                                          |  12 +++
 build.gradle.kts                                   |  36 +------
 conf/gravitino-env.sh.template                     |   8 +-
 web/web/build.gradle.kts                           |  32 +++---
 .../app/catalogs/rightContent/CreateTableDialog.js |   1 -
 .../entitiesContent/TopicDetailsPage.js            |   4 +-
 web/web/src/app/jobs/CreateJobDialog.js            | 107 ++++++++++++---------
 web/web/src/app/metalakes/page.js                  |   2 +-
 web/web/src/app/rootLayout/UserSetting.js          |   8 +-
 web/web/src/lib/store/metalakes/index.js           |   4 +-
 10 files changed, 105 insertions(+), 109 deletions(-)

diff --git a/README.md b/README.md
index 26f9372a44..cdcfe27d8f 100644
--- a/README.md
+++ b/README.md
@@ -82,6 +82,18 @@ Clone or download the [Gravitino Playground 
repository](https://github.com/apach
 
 Press `CTRL+C` to stop.
 
+5. (Optional) Use the legacy UI
+
+  - To switch to the legacy UI at runtime: edit `conf/gravitino-env.sh` (or 
set the environment variable before starting) and set `GRAVITINO_USE_OLD_UI` to 
`true`:
+
+```bash
+export GRAVITINO_USE_OLD_UI=true
+./bin/gravitino.sh start
+```
+
+  - Alternatively, you can remove the `GRAVITINO_USE_OLD_UI=...` line from 
`conf/gravitino-env.sh` (the template defaults to `false`); removing that line 
will revert the service to the legacy UI behavior.
+
+
 ## 🧊 Iceberg REST Catalog
 
 Gravitino provides a native Iceberg REST catalog service.  
diff --git a/build.gradle.kts b/build.gradle.kts
index 6843804621..17444f1ea7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -94,15 +94,6 @@ project.extra["extraJvmArgs"] =
 val pythonVersion: String = project.properties["pythonVersion"] as? String ?: 
project.extra["pythonVersion"].toString()
 project.extra["pythonVersion"] = pythonVersion
 
-// If caller passed -PfrontendBuild=build:old, forward frontendDist=dist:old
-// into the :web project as early as possible so the :web build script
-// sees the property during its configuration phase.
-if (project.hasProperty("frontendBuild") && 
project.property("frontendBuild").toString() == "build:old") {
-  val fd = "dist:old"
-  println("root: detected -PfrontendBuild=build:old — forwarding 
frontendDist='$fd' to :web (early)")
-  project(":web").extensions.extraProperties.set("frontendDist", fd)
-}
-
 licenseReport {
   renderers = 
arrayOf<ReportRenderer>(InventoryHtmlReportRenderer("report.html", "Backend"))
   filters = arrayOf<DependencyFilter>(LicenseBundleNormalizer())
@@ -712,16 +703,6 @@ tasks {
   val outputDir = projectDir.dir("distribution")
 
   val compileDistribution by registering {
-    // Determine which web build task to depend on. If caller passed
-    // -PfrontendBuild=build:old, depend on the local `buildWebLegacy` task
-    // which sets the :web.frontendDist before invoking `:web:web:build`.
-    val webBuildDependency: String = if (project.hasProperty("frontendBuild") 
&& project.property("frontendBuild").toString() == "build:old") {
-      println("compileDistribution: using legacy web build task 
'buildWebLegacy'")
-      "buildWebLegacy"
-    } else {
-      ":web:web:build"
-    }
-
     dependsOn(
       "copyCatalogLibAndConfigs",
       "copySubprojectDependencies",
@@ -730,7 +711,7 @@ tasks {
       ":authorizations:copyLibAndConfig",
       ":iceberg:iceberg-rest-server:copyLibAndConfigs",
       ":lance:lance-rest-server:copyLibAndConfigs",
-      webBuildDependency
+      ":web:web:build"
     )
 
     group = "gravitino distribution"
@@ -780,21 +761,6 @@ tasks {
     }
   }
 
-  // Task to run the web subproject build using the legacy frontend dist script
-  // (sets :web frontendDist = "dist:old" before invoking :web:web:build).
-  val buildWebLegacy by registering {
-    group = "gravitino distribution"
-    description = "Build :web:web:build using legacy frontend 
(frontendDist=dist:old)"
-
-    doFirst {
-      val fd = "dist:old"
-      println("buildWebLegacy: setting :web frontendDist='$fd'")
-      project(":web").extensions.extraProperties.set("frontendDist", fd)
-    }
-
-    dependsOn(":web:web:build")
-  }
-
   val compileIcebergRESTServer by registering {
     
dependsOn("iceberg:iceberg-rest-server:copyLibAndConfigsToStandalonePackage")
     group = "gravitino distribution"
diff --git a/conf/gravitino-env.sh.template b/conf/gravitino-env.sh.template
index 8ce818e492..6b91b19842 100644
--- a/conf/gravitino-env.sh.template
+++ b/conf/gravitino-env.sh.template
@@ -32,5 +32,9 @@ GRAVITINO_VERSION=GRAVITINO_VERSION_PLACEHOLDER
 #                             # Default: -Xms1024m -Xmx1024m 
-XX:MaxMetaspaceSize=512m
 #                             # Appended to JAVA_OPTS by launch scripts; set 
GRAVITINO_MEM to change heap/metaspace sizes.
 
-# default use old UI, set GRAVITINO_USE_OLD_UI=false will use new UI
-# GRAVITINO_USE_OLD_UI=false
\ No newline at end of file
+# UI selection behaviour:
+# - By default the template sets `GRAVITINO_USE_OLD_UI=false` which forces the 
NEW UI.
+# - To enable the OLD UI you can EITHER remove this environment variable line 
from
+#   your env file (i.e. delete the `GRAVITINO_USE_OLD_UI=...` entry) OR set it 
to
+#   `true` (for example: `export GRAVITINO_USE_OLD_UI=true`).
+GRAVITINO_USE_OLD_UI=false
\ No newline at end of file
diff --git a/web/web/build.gradle.kts b/web/web/build.gradle.kts
index 140d25be72..a1edfef835 100644
--- a/web/web/build.gradle.kts
+++ b/web/web/build.gradle.kts
@@ -45,23 +45,9 @@ tasks {
     args = listOf("prettier:check")
   }
 
-  val webpack by registering(PnpmTask::class) {
-    dependsOn(lintCheck, prettierCheck)
-    // Allow overriding the frontend dist task via Gradle project property:
-    // -PfrontendDist=dist:old  -> run `pnpm run dist:old`
-    // -PfrontendDist=dist      -> run `pnpm run dist` (default)
-    val frontendDistArg: String = if (project.hasProperty("frontendDist")) {
-      project.property("frontendDist").toString()
-    } else {
-      "dist"
-    }
-    args = listOf(frontendDistArg)
-    environment.put("NODE_ENV", "production")
-  }
-
   // Separate webpack task for legacy frontend to produce the "old" dist.
   val webpackOld by registering(PnpmTask::class) {
-    dependsOn(installDeps)
+    dependsOn(lintCheck, prettierCheck)
     args = listOf("dist:old")
     environment.put("NODE_ENV", "production")
     doLast {
@@ -79,6 +65,20 @@ tasks {
     }
   }
 
+  val webpack by registering(PnpmTask::class) {
+    dependsOn(lintCheck, prettierCheck, webpackOld)
+    // Allow overriding the frontend dist task via Gradle project property:
+    // -PfrontendDist=dist:old  -> run `pnpm run dist:old`
+    // -PfrontendDist=dist      -> run `pnpm run dist` (default)
+    val frontendDistArg: String = if (project.hasProperty("frontendDist")) {
+      project.property("frontendDist").toString()
+    } else {
+      "dist"
+    }
+    args = listOf(frontendDistArg)
+    environment.put("NODE_ENV", "production")
+  }
+
   // War task for legacy frontend (produces classifier '-old')
   val buildWarOld by registering(War::class) {
     dependsOn(webpackOld)
@@ -109,7 +109,7 @@ tasks {
     if (project.hasProperty("frontendDist") && 
project.property("frontendDist").toString() == "dist:old") {
       dependsOn(buildWarOld)
     } else {
-      dependsOn(buildWarOld, buildWarNew)
+      dependsOn(buildWarNew, buildWarOld)
     }
   }
 
diff --git a/web/web/src/app/catalogs/rightContent/CreateTableDialog.js 
b/web/web/src/app/catalogs/rightContent/CreateTableDialog.js
index 67040e09bc..e29ff98af6 100644
--- a/web/web/src/app/catalogs/rightContent/CreateTableDialog.js
+++ b/web/web/src/app/catalogs/rightContent/CreateTableDialog.js
@@ -72,7 +72,6 @@ import { capitalizeFirstLetter, genUpdates } from 
'@/lib/utils'
 import { cn } from '@/lib/utils/tailwind'
 import { createTable, updateTable, getTableDetails } from 
'@/lib/store/metalakes'
 import { useAppDispatch } from '@/lib/hooks/useStore'
-import { includes } from 'lodash-es'
 
 const { Paragraph } = Typography
 const { TextArea } = Input
diff --git 
a/web/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js 
b/web/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js
index c5e7b6781c..c2d08e4eaa 100644
--- a/web/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js
+++ b/web/web/src/app/catalogs/rightContent/entitiesContent/TopicDetailsPage.js
@@ -27,7 +27,7 @@ import AssociatedTable from '@/components/AssociatedTable'
 import Tags from '@/components/CustomTags'
 import Policies from '@/components/PolicyTag'
 import Icons from '@/components/Icons'
-import PropertiesGrid from '@/components/PropertiesContent'
+import PropertiesContent from '@/components/PropertiesContent'
 import { cn } from '@/lib/utils/tailwind'
 import { useAppSelector, useAppDispatch } from '@/lib/hooks/useStore'
 import { useSearchParams } from 'next/navigation'
@@ -90,7 +90,7 @@ export default function TopicDetailsPage({ ...props }) {
   const properties = store.activatedDetails?.properties
 
   const propertyContent = (
-    <PropertiesGrid properties={properties} dataReferPrefix='props' 
contentDataRefer='properties-popover-content' />
+    <PropertiesContent properties={properties} dataReferPrefix='props' 
contentDataRefer='properties-popover-content' />
   )
   const tabOptions = [{ label: 'Associated roles', key: 'Associated roles' }]
 
diff --git a/web/web/src/app/jobs/CreateJobDialog.js 
b/web/web/src/app/jobs/CreateJobDialog.js
index ffd128512f..bac446c750 100644
--- a/web/web/src/app/jobs/CreateJobDialog.js
+++ b/web/web/src/app/jobs/CreateJobDialog.js
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import React, { useEffect, useState } from 'react'
+import React, { useEffect, useMemo, useState } from 'react'
 import dynamic from 'next/dynamic'
 import { ArrowRightOutlined, PlusOutlined } from '@ant-design/icons'
 import { Button, Divider, Flex, Form, Input, Modal, Select, Spin, Typography } 
from 'antd'
@@ -46,6 +46,8 @@ export default function CreateJobDialog({ ...props }) {
   const values = Form.useWatch([], form)
   const currentJobTemplate = Form.useWatch('jobTemplateName', form)
   const jobConfValues = Form?.useWatch('jobConf', form)
+  const [placeholderEntries, setPlaceholderEntries] = useState([])
+  const hasJobConfig = placeholderEntries.length > 0
   const [openTemplate, setOpenTemplate] = useState(false)
   const dispatch = useAppDispatch()
 
@@ -155,8 +157,9 @@ export default function CreateJobDialog({ ...props }) {
         const { payload: jobTemplate } = await dispatch(getJobTemplate({ 
metalake, jobTemplate: currentJobTemplate }))
         setIsLoading(false)
         setJobTemplateDetail(jobTemplate)
-        const placeholderEntries = getPlaceholderEntries(jobTemplate)
-        form.setFieldsValue({ jobConf: placeholderEntries })
+        const nextPlaceholderEntries = getPlaceholderEntries(jobTemplate)
+        setPlaceholderEntries(nextPlaceholderEntries)
+        form.setFieldsValue({ jobConf: nextPlaceholderEntries })
       } catch (error) {
         console.log(error)
         setIsLoading(false)
@@ -164,6 +167,8 @@ export default function CreateJobDialog({ ...props }) {
     }
     if (currentJobTemplate) {
       fetchJobTemplateDetails()
+    } else {
+      setPlaceholderEntries([])
     }
   }, [currentJobTemplate])
 
@@ -257,11 +262,15 @@ export default function CreateJobDialog({ ...props }) {
               />
             </Form.Item>
             <div className='relative rounded border border-gray-200'>
-              <div className='pointer-events-none absolute inset-y-0 left-1/2 
w-px -translate-x-1/2 bg-gray-200' />
-              <div className='pointer-events-none absolute left-1/2 top-1/2 
flex size-6 -translate-x-1/2 -translate-y-1/2 items-center justify-center 
rounded-full border border-gray-200 bg-white text-gray-500'>
-                <Icons.iconify icon='mdi:arrow-left' className='size-4' />
-              </div>
-              <div className='grid grid-cols-2 gap-6 p-4'>
+              {hasJobConfig && (
+                <>
+                  <div className='pointer-events-none absolute inset-y-0 
left-1/2 w-px -translate-x-1/2 bg-gray-200' />
+                  <div className='pointer-events-none absolute left-1/2 
top-1/2 flex size-6 -translate-x-1/2 -translate-y-1/2 items-center 
justify-center rounded-full border border-gray-200 bg-white text-gray-500'>
+                    <Icons.iconify icon='mdi:arrow-left' className='size-4' />
+                  </div>
+                </>
+              )}
+              <div className={cn('grid gap-6 p-4', hasJobConfig ? 
'grid-cols-2' : 'grid-cols-1')}>
                 <div className='space-y-2 max-h-[320px] overflow-y-auto pr-2'>
                   <Paragraph className='text-sm !mb-0'>Template 
Parameters</Paragraph>
                   <div>
@@ -297,7 +306,7 @@ export default function CreateJobDialog({ ...props }) {
                           ))}
                         </div>
                       ) : (
-                        <div className='text-sm text-gray-400'>No 
arguments</div>
+                        <div className='text-[12px] text-gray-400'>No 
arguments</div>
                       )}
                     </div>
                   </div>
@@ -423,45 +432,47 @@ export default function CreateJobDialog({ ...props }) {
                     </div>
                   )}
                 </div>
-                <div className='pl-2 max-h-[320px] overflow-y-auto pr-2'>
-                  <Form.Item label='Job Configuration'>
-                    <div className='flex flex-col gap-2'>
-                      <Form.List name='jobConf'>
-                        {fields => (
-                          <>
-                            {fields.map(({ key, name, ...restField }) => (
-                              <Form.Item label={null} 
className='align-items-center mb-0' key={key}>
-                                <Flex gap='small' align='start' key={key}>
-                                  <Form.Item
-                                    {...restField}
-                                    name={[name, 'key']}
-                                    rules={[{ required: true, message: 'Please 
enter the job config key!' }]}
-                                    className='mb-0 w-full grow'
-                                  >
-                                    <Input disabled placeholder='Job Config 
Key' />
-                                  </Form.Item>
-                                  <Form.Item
-                                    {...restField}
-                                    name={[name, 'value']}
-                                    rules={[{ required: true, message: 'Please 
enter the job config value!' }]}
-                                    className='mb-0 w-full grow'
-                                  >
-                                    <Input
-                                      placeholder={
-                                        form.getFieldValue(['jobConf', name, 
'template']) || 'Job Config Value'
-                                      }
-                                      onChange={e => updateOnChange(name, 
e.target.value)}
-                                    />
-                                  </Form.Item>
-                                </Flex>
-                              </Form.Item>
-                            ))}
-                          </>
-                        )}
-                      </Form.List>
-                    </div>
-                  </Form.Item>
-                </div>
+                {hasJobConfig && (
+                  <div className='pl-2 max-h-[320px] overflow-y-auto pr-2'>
+                    <Form.Item label='Job Configuration'>
+                      <div className='flex flex-col gap-2'>
+                        <Form.List name='jobConf'>
+                          {fields => (
+                            <>
+                              {fields.map(({ key, name, ...restField }) => (
+                                <Form.Item label={null} 
className='align-items-center mb-0' key={key}>
+                                  <Flex gap='small' align='start' key={key}>
+                                    <Form.Item
+                                      {...restField}
+                                      name={[name, 'key']}
+                                      rules={[{ required: true, message: 
'Please enter the job config key!' }]}
+                                      className='mb-0 w-full grow'
+                                    >
+                                      <Input disabled placeholder='Job Config 
Key' />
+                                    </Form.Item>
+                                    <Form.Item
+                                      {...restField}
+                                      name={[name, 'value']}
+                                      rules={[{ required: true, message: 
'Please enter the job config value!' }]}
+                                      className='mb-0 w-full grow'
+                                    >
+                                      <Input
+                                        placeholder={
+                                          form.getFieldValue(['jobConf', name, 
'template']) || 'Job Config Value'
+                                        }
+                                        onChange={e => updateOnChange(name, 
e.target.value)}
+                                      />
+                                    </Form.Item>
+                                  </Flex>
+                                </Form.Item>
+                              ))}
+                            </>
+                          )}
+                        </Form.List>
+                      </div>
+                    </Form.Item>
+                  </div>
+                )}
               </div>
             </div>
           </Form>
diff --git a/web/web/src/app/metalakes/page.js 
b/web/web/src/app/metalakes/page.js
index 19061d48a8..486a083b32 100644
--- a/web/web/src/app/metalakes/page.js
+++ b/web/web/src/app/metalakes/page.js
@@ -75,8 +75,8 @@ const MetalakeList = () => {
   const [tableData, setTableData] = useState([])
 
   useEffect(() => {
-    dispatch(fetchMetalakes())
     dispatch(resetMetalakeStore())
+    dispatch(fetchMetalakes())
   }, [dispatch])
 
   useEffect(() => {
diff --git a/web/web/src/app/rootLayout/UserSetting.js 
b/web/web/src/app/rootLayout/UserSetting.js
index 22b533ea73..634ce931aa 100644
--- a/web/web/src/app/rootLayout/UserSetting.js
+++ b/web/web/src/app/rootLayout/UserSetting.js
@@ -111,10 +111,12 @@ export default function UserSetting() {
                   params.set('metalake', metalake.name)
 
                   // Reset metalake store to avoid data inconsistency
-                  dispatch(resetMetalakeStore())
+                  dispatch(resetMetalakeStore({ isCacheMetalakes: true }))
 
-                  // Preserve pathname and only update metalake in query string
-                  router.push(`${pathname}?${params.toString()}`)
+                  // Preserve pathname and only update metalake in query 
string, catalogs page goes to catalogs route
+                  isCatalogsPage
+                    ? 
router.push(`/catalogs?metalake=${metalake.name}&catalogType=relational`)
+                    : router.push(`${pathname}?${params.toString()}`)
                 }}
               >
                 <span
diff --git a/web/web/src/lib/store/metalakes/index.js 
b/web/web/src/lib/store/metalakes/index.js
index 764dcb60ee..37f64f3326 100644
--- a/web/web/src/lib/store/metalakes/index.js
+++ b/web/web/src/lib/store/metalakes/index.js
@@ -1755,7 +1755,9 @@ export const appMetalakesSlice = createSlice({
       state.tableProps = action.payload
     },
     resetMetalakeStore(state, action) {
-      state.metalakes = []
+      if (!action.payload?.isCacheMetalakes) {
+        state.metalakes = []
+      }
       state.filteredMetalakes = []
       state.tableData = []
       state.tableProps = []

Reply via email to