diff --git a/dashboard/config/routes.ts b/dashboard/config/routes.ts
index 3501e39b5..2770ca914 100644
--- a/dashboard/config/routes.ts
+++ b/dashboard/config/routes.ts
@@ -9,6 +9,12 @@
path: `/applications`,
component: './Application',
},
+ /* Application Create should be moved to /Application */
+ {
+ name: 'create_application',
+ path: '/applications/create',
+ component: './CreateApplication'
+ },
{
name: 'capability',
icon: 'AppstoreAddOutlined',
diff --git a/dashboard/package.json b/dashboard/package.json
index d478d2d76..36236f18b 100644
--- a/dashboard/package.json
+++ b/dashboard/package.json
@@ -54,6 +54,7 @@
"@umijs/route-utils": "^1.0.33",
"antd": "^4.9.4",
"classnames": "^2.2.6",
+ "form-render": "^0.9.0",
"dayjs": "^1.9.7",
"lodash": "^4.17.11",
"moment": "^2.25.3",
@@ -63,6 +64,7 @@
"react-dev-inspector": "^1.1.1",
"react-dom": "^17.0.0",
"react-helmet-async": "^1.0.4",
+ "react-router-dom": "^5.2.0",
"umi": "^3.2.14",
"umi-request": "^1.0.8",
"use-merge-value": "^1.0.1"
@@ -100,7 +102,8 @@
"pro-download": "1.0.1",
"puppeteer-core": "^5.0.0",
"stylelint": "^13.0.0",
- "typescript": "^4.1.2"
+ "typescript": "^4.1.2",
+ "webpack-plugin-fr-theme": "^0.2.0"
},
"engines": {
"node": ">=10.0.0"
diff --git a/dashboard/src/models/useTraitsModel.ts b/dashboard/src/models/useTraitsModel.ts
index c326aefe1..739729ba4 100644
--- a/dashboard/src/models/useTraitsModel.ts
+++ b/dashboard/src/models/useTraitsModel.ts
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
-import * as api from '@/services/traits';
+import * as api from '@/services/capability';
interface State {
loading?: boolean;
diff --git a/dashboard/src/models/useWorkloadsModel.ts b/dashboard/src/models/useWorkloadsModel.ts
index b2b6bf03f..aafa55bea 100644
--- a/dashboard/src/models/useWorkloadsModel.ts
+++ b/dashboard/src/models/useWorkloadsModel.ts
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
-import * as api from '@/services/workloads';
+import * as api from '@/services/capability';
interface State {
loading?: boolean;
diff --git a/dashboard/src/pages/Application/index.tsx b/dashboard/src/pages/Application/index.tsx
index 9c1652d0e..43bc85383 100644
--- a/dashboard/src/pages/Application/index.tsx
+++ b/dashboard/src/pages/Application/index.tsx
@@ -6,6 +6,8 @@ import { Link, useModel, useRequest } from 'umi';
import { deleteApplication, getApplications } from '@/services/application';
import { PlusOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-layout';
+// @ts-ignore
+import { Link as ReactLink } from "react-router-dom";
export default () => {
const { currentEnvironment } = useModel('useEnvironmentModel');
@@ -42,7 +44,8 @@ export default () => {
}>
- Create
+ Create
+
diff --git a/dashboard/src/pages/CreateApplication/index.tsx b/dashboard/src/pages/CreateApplication/index.tsx
new file mode 100644
index 000000000..892c7ea73
--- /dev/null
+++ b/dashboard/src/pages/CreateApplication/index.tsx
@@ -0,0 +1,192 @@
+import React, {useState} from 'react';
+import {Input, Dropdown, Menu, Button, Divider, Row, Col} from 'antd';
+import {useModel} from "@@/plugin-model/useModel";
+import {DownOutlined, UserOutlined} from '@ant-design/icons';
+import FormRender from 'form-render/lib/antd';
+import {getCapabilityOpenAPISchema} from "@/services/capability";
+// prevent Ant design style from being overridden
+import 'antd/dist/antd.css';
+
+
+export default (): React.ReactNode => {
+ // @ts-ignore
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const {workloadsLoading, workloadList} = useModel('useWorkloadsModel');
+ // @ts-ignore
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const {traitsLoading, traitsList} = useModel('useTraitsModel');
+
+ const workloadMenuList = workloadList?.map((i) =>
+ } onClick={() => handleMenuClick("workload_type", i.name)}>
+ {i.name}
+
+ )
+
+ const traitMenuList = traitsList?.map((i) =>
+ } onClick={() => handleMenuClick("trait", i.name)}>
+ {i.name}
+
+ )
+
+ const workloadsMenu = (
+
+ );
+
+ const traitsMenu = (
+
+ );
+
+
+ // Capability parameters form render
+ const [formData, setData] = useState({});
+ // schema is OpenAPI Schema JSON data
+ const [workloadSchema, setWorkloadSchema] = useState({})
+ const [traitSchema, setTraitSchema] = useState({})
+ const [valid, setValid] = useState([]);
+
+ function handleMenuClick(capabilityType: string, capabilityName: string) {
+ console.log('click', capabilityName);
+ getCapabilityOpenAPISchema(capabilityName).then((result) => {
+ const data = JSON.parse(result.data)
+ if (capabilityType === "workload_type") {
+ setWorkloadSchema(data)
+ } else if (capabilityType === "trait") {
+ setTraitSchema(data)
+ }
+ })
+ }
+
+ const onSubmit = () => {
+ // valid == 0: validation passed
+ if (valid.length > 0) {
+ alert(`invalid:${valid.toString()}`);
+ } else {
+ alert(JSON.stringify(formData, null, 2));
+ }
+ };
+
+ return (
+
+
+
+ Application
+
+
+
+
+
+
+ Name:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services
+
+
+
+
+
+
+ Name:
+
+
+
+
+
+
+
+
+
+ Type:
+
+
+
+
+ Select
+
+
+
+
+
+
+
+ Settings:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Traits
+
+
+
+
+
+
+ Type:
+
+
+
+ e.preventDefault()}>
+ Select
+
+
+
+
+
+
+
+ Properties:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/dashboard/src/services/capability.ts b/dashboard/src/services/capability.ts
new file mode 100644
index 000000000..bdb9efb3e
--- /dev/null
+++ b/dashboard/src/services/capability.ts
@@ -0,0 +1,23 @@
+import { request } from 'umi';
+
+
+/*
+ * workload type list: get /api/workloads/
+ */
+export async function getWorkloads(): Promise> {
+ return request( '/api/workloads');
+}
+
+
+/*
+ * trait list: get /api/traits/
+ */
+export async function getTraits(): Promise> {
+ return request('/api/traits');
+}
+
+export async function getCapabilityOpenAPISchema(
+ capabilityName: string,
+): Promise> {
+ return request(`/api/definitions/${capabilityName}`, { method: 'get' });
+}
diff --git a/dashboard/src/services/traits.ts b/dashboard/src/services/traits.ts
deleted file mode 100644
index 5eb008b1a..000000000
--- a/dashboard/src/services/traits.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { request } from 'umi';
-
-const BASE_PATH = '/api/traits';
-
-/*
- * trait 列表: get /api/traits/
- */
-export async function getTraits(): Promise> {
- return request(BASE_PATH);
-}
diff --git a/dashboard/src/services/workloads.ts b/dashboard/src/services/workloads.ts
deleted file mode 100644
index 2fe0533a2..000000000
--- a/dashboard/src/services/workloads.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { request } from 'umi';
-
-const BASE_PATH = '/api/workloads';
-
-/*
- * workload 列表: get /api/workloads/
- */
-export async function getWorkloads(): Promise> {
- return request(BASE_PATH);
-}