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 4501666 Update
4501666 is described below
commit 450166678ce4ab113f72e112d977fced625bcc5b
Author: JB Onofré <[email protected]>
AuthorDate: Mon Oct 27 07:43:03 2025 +0100
Update
---
ui/src/catalog.tsx | 93 +++++++++++++++++++++++++++++++++-------------------
ui/src/home.tsx | 65 ++++++++++++++----------------------
ui/src/workspace.tsx | 69 +++++++++++++++++++-------------------
3 files changed, 120 insertions(+), 107 deletions(-)
diff --git a/ui/src/catalog.tsx b/ui/src/catalog.tsx
index 551a466..70540ff 100644
--- a/ui/src/catalog.tsx
+++ b/ui/src/catalog.tsx
@@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Link } from 'react-router-dom';
-import { Breadcrumb, Card, Form, Input, Select, Tabs, Collapse, Divider,
Button, Space } from 'antd';
+import { Link, Redirect } from 'react-router-dom';
+import { Breadcrumb, Card, Form, Input, Select, Tabs, Collapse, Divider,
Button, Space, message } from 'antd';
import { HomeOutlined, ApartmentOutlined, AmazonOutlined, GoogleOutlined,
CloudOutlined, FileSyncOutlined, SaveOutlined, PauseCircleOutlined } from
'@ant-design/icons';
function S3() {
@@ -97,11 +97,7 @@ function Azure() {
}
-export default function Catalog(props) {
-
- const bearer = 'Bearer ' + props.token;
-
- const [ catalogForm ] = Form.useForm();
+function StorageConfig() {
const tabItems = [
{
@@ -124,10 +120,39 @@ export default function Catalog(props) {
}
];
+ return(
+ <>
+ <Form.Item name="storageType" label="Storage Type" rules={[{ required:
true, message: 'The storage type is required' }]}>
+ <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" rules={[{
required: true, message: 'The storage location is required' }]}>
+ <Input allowClear={true} />
+ </Form.Item>
+ <Form.Item name="allowedLocations" label="Allowed locations">
+ <Select mode="tags" />
+ </Form.Item>
+ <Tabs centered items={tabItems} />
+ </>
+ );
+
+}
+
+export default function Catalog(props) {
+
+ const bearer = 'Bearer ' + props.token;
+
+ const [ catalogForm ] = Form.useForm();
+
const onFinish = (values) => {
const request = {
'catalog': {
'name': values.name,
+ 'type': values.type,
'properties': {
'default-base-location': values.location
},
@@ -137,20 +162,30 @@ export default function Catalog(props) {
}
}
};
- const createCatalog = () => {
- fetch('/api/management/v1/catalogs', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Polaris-Realm': 'POLARIS',
- 'Authorization': bearer
- }
- })
- .then((response) => {
-
- })
- };
- console.log(request);
+ fetch('/api/management/v1/catalogs', {
+ method: 'POST',
+ body: JSON.stringify(request),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Polaris-Realm': 'POLARIS',
+ 'Authorization': bearer
+ }
+ })
+ .then((response) => {
+ if(!response.ok) {
+ throw new Error(response.status);
+ }
+ return response.json();
+ })
+ .then((data) => {
+ console.log(data);
+ message.info('Catalog ' + data.name + ' created.');
+ props.fetchCatalogs();
+ })
+ .catch((error) => {
+ message.error('An error occurred: ' + error.message);
+ console.error(error);
+ });
};
return(
@@ -164,22 +199,14 @@ export default function Catalog(props) {
<Form.Item name="name" label="Name" rules={[{ required: true,
message: 'The catalog name is required' }]}>
<Input allowClear={true} />
</Form.Item>
- <Form.Item name="storageType" label="Storage Type" rules={[{
required: true, message: 'The storage type is required' }]}>
+ <Form.Item name="type" label="Type" rules={[{ required: true,
message: 'The catalog type is required' }]}>
<Select options={[
- { value: 'S3', label: 'S3' },
- { value: 'GCP', label: 'GCP' },
- { value: 'AZURE', label: 'Azure' },
- { value: 'FILE', label: 'File' }
+ { value: 'INTERNAL', label: 'Internal' },
+ { value: 'EXTERNAL', label: 'External' }
]}/>
</Form.Item>
- <Form.Item name="location" label="Default Base Location">
- <Input allowClear={true} />
- </Form.Item>
- <Form.Item name="allowedLocations" label="Allowed locations">
- <Select mode="tags" />
- </Form.Item>
<Collapse items={[
- { key: '1', label: 'Storage specific configuration', children:
<Tabs centered items={tabItems} /> }
+ { key: '1', label: 'Storage specific configuration', children:
<StorageConfig /> }
]}/>
<Divider />
<Collapse items={[
diff --git a/ui/src/home.tsx b/ui/src/home.tsx
index 84c3f07..4568650 100644
--- a/ui/src/home.tsx
+++ b/ui/src/home.tsx
@@ -23,64 +23,49 @@ import { HomeOutlined, EditOutlined, DeleteOutlined } from
'@ant-design/icons';
export default function Home(props) {
- const [ catalogs, setCatalogs] = useState();
- const [ principals, setPrincipals ] = useState();
-
const bearer = 'Bearer ' + props.token;
- const fetchCatalogs = () => {
- fetch('./api/management/v1/catalogs', {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': bearer,
- }
- })
- .then((response) => {
- if (!response.ok) {
- throw new Error(response.status);
- }
- return response.json();
- })
- .then((data) => {
- console.log(data);
- setCatalogs(data.catalogs);
- })
- .catch((error) => {
- message.error('An error occurred: ' + error.message);
- console.error(error);
- })
+ const deleteCatalog = (catalog) => {
+ fetch('/api/management/v1/catalogs/' + catalog, {
+ method: 'DELETE',
+ headers: {
+ 'Authorization': bearer
+ }
+ })
+ .then((response) => {
+ if (!response.ok) {
+ throw new Error(response.status);
+ }
+ return response;
+ })
+ .then((data) => {
+ message.info('Catalog ' + catalog + ' has been removed');
+ props.fetchCatalogs();
+ })
+ .catch((error) => {
+ message.error('An error occurred: ' + error.message);
+ console.error(error);
+ })
};
- useEffect(fetchCatalogs, []);
-
- if (!catalogs) {
- return(<Spin/>);
- }
-
const catalogColumns = [
{
title: 'Catalog',
- dataIndex: 'catalog',
- key: 'catalog'
+ dataIndex: 'name',
+ key: 'name'
},
{
title: 'Type',
dataIndex: 'type',
key: 'type'
},
- {
- title: 'Base Location',
- dataIndex: 'location',
- key: 'location'
- },
{
title: '',
key: 'action',
render: (_,record) => (
<Space>
<Button><EditOutlined/></Button>
- <Button><DeleteOutlined/></Button>
+ <Button><DeleteOutlined onClick={() =>
deleteCatalog(record.name)}/></Button>
</Space>
)
}
@@ -92,7 +77,7 @@ export default function Home(props) {
<Card title="Overview" style={{ width: '100%' }}>
<Row gutter={[16,16]}>
<Col span={24}>
- <Table columns={catalogColumns} dataSource={catalogs} />
+ <Table columns={catalogColumns}
dataSource={props.catalogs} />
</Col>
</Row>
</Card>
diff --git a/ui/src/workspace.tsx b/ui/src/workspace.tsx
index 8451afd..b555b05 100644
--- a/ui/src/workspace.tsx
+++ b/ui/src/workspace.tsx
@@ -29,38 +29,8 @@ import Catalog from './catalog.tsx';
function SideMenu(props) {
const[ collapsed, setCollapsed ] = useState(false);
- const[ catalogs, setCatalogs ] = useState();
- const bearer = 'Bearer ' + props.token;
-
- const fetchCatalogs = () => {
- fetch('/api/management/v1/catalogs', {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': bearer
- }
- })
- .then((response) => {
- if (!response.ok) {
- throw new Error(response.status);
- }
- return response.json();
- })
- .then((data) => setCatalogs(data.catalogs))
- .catch((error) => {
- message.error('An error occured: ' + error.message);
- console.error(error);
- });
- };
-
- useEffect(fetchCatalogs, []);
-
- if (!catalogs) {
- return(<Spin/>);
- }
-
- const catalogElementsMenu = catalogs.map((element) => {
+ const catalogElementsMenu = props.catalogs.map((element) => {
return({
key: element.name,
label: element.name,
@@ -127,19 +97,50 @@ function Header(props) {
}
export default function Workspace(props) {
+
+ const [ catalogs, setCatalogs ] = useState();
+
+ const bearer = 'Bearer ' + props.token;
+ const fetchCatalogs = () => {
+ fetch('/api/management/v1/catalogs', {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': bearer
+ }
+ })
+ .then((response) => {
+ if (!response.ok) {
+ throw new Error(response.status);
+ }
+ return response.json();
+ })
+ .then((data) => setCatalogs(data.catalogs))
+ .catch((error) => {
+ message.error('An error occurred: ' + error.message);
+ console.error(error);
+ });
+ };
+
+ useEffect(fetchCatalogs, []);
+
+ if (!catalogs) {
+ return(<Spin/>);
+ }
+
return(
<Layout style={{ height: "105vh" }}>
<Header user={props.user} setUser={props.setUser} />
<Layout hasSider={true}>
<Router>
- <SideMenu token={props.token} />
+ <SideMenu catalogs={catalogs} />
<Layout.Content style={{ margin: "15px" }}>
<Switch>
<Route path="/" key="home" exact={true}>
- <Home user={props.user} token={props.token} />
+ <Home catalogs={catalogs} token={props.token}
fetchCatalogs={fetchCatalogs} />
</Route>
<Route path="/catalog/create" key="catalog-create"
exact={true}>
- <Catalog token={props.token} />
+ <Catalog token={props.token}
fetchCatalogs={fetchCatalogs} />
</Route>
</Switch>
</Layout.Content>