This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch ui
in repository https://gitbox.apache.org/repos/asf/polaris-tools.git
The following commit(s) were added to refs/heads/ui by this push:
new fab7c8a Update
fab7c8a is described below
commit fab7c8a20db502418f70e8bf9ab60cded2a9c0d1
Author: JB Onofré <[email protected]>
AuthorDate: Sun Oct 26 17:42:44 2025 +0100
Update
---
ui/README.md | 63 ++++++++++++++++++++++++++
ui/src/catalog.tsx | 126 +++++++++++++++++++++++++++++++++++++++++++--------
ui/src/workspace.tsx | 14 +-----
3 files changed, 172 insertions(+), 31 deletions(-)
diff --git a/ui/README.md b/ui/README.md
new file mode 100644
index 0000000..0bf270c
--- /dev/null
+++ b/ui/README.md
@@ -0,0 +1,63 @@
+<!--
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -->
+
+# Apache Polaris UI
+
+The Apache Polaris UI is a web console allowing you to manage a Polaris server.
+It allows you to manage Polaris catalogs, principals, catalog roles, ...
+
+You can also browse the catalog entities (namespaces, tables, ...).
+
+## Prerequisite
+
+The Polaris UI is using `yarn` or `npm` to be built.
+
+You have to install `yarn` or `npm` using your OS package manager (e.g. `brew
install yarn`).
+
+## Configuring the UI to connect to a Polaris server
+
+By default, the Polaris UI connects to a local Polaris server on the port 8181
(`http://localhost:8181`).
+
+If the Polaris server is not located on `localhost:8181`, you have to update
the UI `proxy` configuration in the `package.json`:
+
+```
+"proxy": "http://localhost:8181"
+```
+
+## Downloading the UI dependencies
+
+The Polaris UI uses React (https://react.dev/) and Ant Design
(https://ant.design/) frameworks, with transitive dependencies.
+
+To download the Polaris UI dependencies, you can just do:
+
+```
+yarn
+```
+
+## Starting the UI
+
+```
+yarn start
+```
+
+## Building static UI
+
+```
+yarn build
+```
\ No newline at end of file
diff --git a/ui/src/catalog.tsx b/ui/src/catalog.tsx
index ad058de..c3774c1 100644
--- a/ui/src/catalog.tsx
+++ b/ui/src/catalog.tsx
@@ -17,9 +17,86 @@
* under the License.
*/
import { Link } from 'react-router-dom';
-import { Breadcrumb, Card, Form, Input, Tabs, Collapse, Divider, Button, Space
} from 'antd';
+import { Breadcrumb, Card, Form, Input, Select, Tabs, Collapse, Divider,
Button, Space } from 'antd';
import { HomeOutlined, ApartmentOutlined, AmazonOutlined, GoogleOutlined,
CloudOutlined, FileSyncOutlined, SaveOutlined, PauseCircleOutlined } from
'@ant-design/icons';
+function S3() {
+
+ return(
+ <>
+ <Form.Item name="s3.roleArn" label="Role ARN">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.externalId" label="External ID">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.userArn" label="User ARN">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.region" label="Region">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.endpoint" label="Endpoint">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.endpointInternal" label="Endpoint internal">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.pathStyleAccess" label="Path style access">
+ <Select options={[
+ { value: 'true', label: 'Enabled' },
+ { value: 'false', label: 'Disabled' }
+ ]} />
+ </Form.Item>
+ <Form.Item name="s3.stsUnavailable" label="STS">
+ <Select options={[
+ { value: 'false', label: 'Enabled' },
+ { value: 'true', label: 'Disabled' }
+ ]} />
+ </Form.Item>
+ <Form.Item name="s3.stsEndpoint" label="STS endpoint">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.accountId" label="Account ID">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="s3.partition" label="Partition">
+ <Input allowClear={true} />
+ </Form.Item>
+ </>
+ );
+}
+
+function GCP() {
+
+ return(
+ <>
+ <Form.Item name="gcp.serviceAccount" label="Service account">
+ <Input allowClear={true} />
+ </Form.Item>
+ </>
+ );
+
+}
+
+function Azure() {
+
+ return(
+ <>
+ <Form.Item name="azure.tenantId" label="Tenant ID">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="azure.multiTenantAppName" label="Multi tenant app
name">
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="azure.consentUrl" label="Consent URL">
+ <Input allowClear={true} />
+ </Form.Item>
+ </>
+ );
+
+}
+
export default function Catalog(props) {
const [ catalogForm ] = Form.useForm();
@@ -27,54 +104,65 @@ export default function Catalog(props) {
const tabItems = [
{
key: 's3',
- label: 'AWS S3',
+ label: 'S3',
icon: <AmazonOutlined/>,
- children: <p>S3</p>
+ children: <S3/>
},
{
key: 'gcp',
label: 'GCP',
icon: <GoogleOutlined/>,
- children: <p>GCP</p>
+ children: <GCP/>
},
{
key: 'azure',
label: 'Azure',
icon: <CloudOutlined/>,
- children: <p>Azure</p>
- },
- {
- key: 'local',
- label: 'Local',
- icon: <FileSyncOutlined/>,
- children: <p>File</p>
+ children: <Azure/>
}
];
+ const onFinish = (values) => {
+ console.log(values);
+ };
+
return(
<>
<Breadcrumb items={[ { title: <Link to="/"><HomeOutlined/></Link> }, {
title: <ApartmentOutlined/> } ]} />
<Card title="Create Catalog" style={{ width: '100%' }}>
<Form name="catalog" form={catalogForm} labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
- style={{ width: '100%' }}>
+ style={{ width: '100%' }}
+ onFinish={onFinish}>
<Form.Item name="name" label="Name">
<Input allowClear={true} />
</Form.Item>
+ <Form.Item name="storageType" label="Storage Type">
+ <Select options={[
+ { value: 's3', label: 'S3' },
+ { value: 'gcp', label: 'GCP' },
+ { value: 'azure', label: 'Azure' },
+ { value: 'file', label: 'File' }
+ ]}/>
+ </Form.Item>
<Form.Item name="location" label="Default Base Location">
<Input allowClear={true} />
</Form.Item>
- <Divider/>
- <Tabs centered items={tabItems} />
- <Divider/>
+ <Form.Item name="allowedLocations" label="Allowed locations">
+ <Select mode="tags" />
+ </Form.Item>
+ <Collapse items={[
+ { key: '1', label: 'Storage configuration', children: <Tabs
centered items={tabItems} /> }
+ ]}/>
+ <Divider />
<Collapse items={[
- { key: '1', label: 'Properties', children: <p>Properties</p> }
+ { key: '1', label: 'Properties', children: <Form.Item
name="properties" label="Additional properties"><Select
mode="tags"/></Form.Item> }
]}/>
- <Divider/>
+ <Divider />
<Form.Item label={null}>
<Space>
- <Button type="primary" icon={<SaveOutlined/>}>Save</Button>
- <Button icon={<PauseCircleOutlined/>}>Cancel</Button>
+ <Button type="primary" icon={<SaveOutlined/>} onClick={()
=> catalogForm.submit()}>Save</Button>
+ <Button icon={<PauseCircleOutlined/>} onClick={() =>
catalogForm.resetFields()}>Cancel</Button>
</Space>
</Form.Item>
</Form>
diff --git a/ui/src/workspace.tsx b/ui/src/workspace.tsx
index b81d467..8451afd 100644
--- a/ui/src/workspace.tsx
+++ b/ui/src/workspace.tsx
@@ -85,22 +85,12 @@ function SideMenu(props) {
{ key: 'principal_roles', label: 'Principal Roles', icon:
<TeamOutlined/> },
{ key: 'catalog_roles', label: 'Catalog Roles', icon:
<BuildOutlined/> },
{ key: 'privileges', label: 'Privileges', icon: <CrownOutlined/> }
- ]},
- { key: 'policies', label: 'Policies & TMS', icon:
<CheckSquareOutlined/> },
- { key: 'observe', label: 'Observability', icon: <DashboardOutlined/>,
children: [
- { key: 'metrics', label: 'Metrics', icon: <AreaChartOutlined/> },
- { key: 'events', label: 'Events', icon: <NotificationOutlined/> }
- ]},
- { key: 'profiles', label: 'Profiles', icon: <ProfileOutlined/> },
- { key: 'settings', label: 'Settings', icon: <SettingOutlined/>,
children: [
- { key: 'bootstrap', label: 'Bootstrap', icon:
<PlayCircleOutlined/> },
- { key: 'purge', label: 'Purge', icon: <DeleteOutlined/> }
- ] }
+ ]}
];
return(
<Layout.Sider collapsible={true} collapsed={collapsed}
onCollapse={newValue => setCollapsed(newValue)}>
- <Menu items={mainMenu} mode="inline"/>
+ <Menu items={mainMenu} mode="inline" defaultOpenKeys={[
'catalogs', 'governance' ]}/>
</Layout.Sider>
);