From cf7ba3392f8911d3289fe1b016d0a79565016031 Mon Sep 17 00:00:00 2001 From: Christie Molloy Date: Wed, 8 Apr 2020 17:14:34 -0400 Subject: [PATCH 01/11] start create api --- .../services/src/api-services/api-services.ts | 12 +- packages/services/src/api-services/hub.ts | 37 ++++- packages/studio/src/app/app.css | 13 -- .../studio/src/app/pages/api/createApi.css | 52 +++++++ .../studio/src/app/pages/api/createApi.tsx | 134 ++++++++++++------ 5 files changed, 190 insertions(+), 58 deletions(-) create mode 100644 packages/studio/src/app/pages/api/createApi.css diff --git a/packages/services/src/api-services/api-services.ts b/packages/services/src/api-services/api-services.ts index addb0e1..3529b47 100644 --- a/packages/services/src/api-services/api-services.ts +++ b/packages/services/src/api-services/api-services.ts @@ -1,4 +1,4 @@ -import {Api} from "@apicurio/models"; +import {Api, NewApi} from "@apicurio/models"; import {AbstractHubService} from "./hub"; import {ConfigService} from "../config/config.service"; import {IAuthenticationService} from "../authentication/auth.service"; @@ -33,4 +33,14 @@ export class ApisService extends AbstractHubService { return apis; }) } + + public createApi(api: NewApi): Promise { + console.info("[ApisService] Creating the API via the hub API"); + + let createApiUrl: string = this.endpoint("/designs"); + let options: any = this.options({ "Accept": "application/json", "Content-Type": "application/json" }); + + console.info("[ApisService] Creating an API Design: %s", createApiUrl); + return this.httpPostWithReturn(createApiUrl, api, options); + } } diff --git a/packages/services/src/api-services/hub.ts b/packages/services/src/api-services/hub.ts index 77581e3..529e2fd 100644 --- a/packages/services/src/api-services/hub.ts +++ b/packages/services/src/api-services/hub.ts @@ -108,13 +108,46 @@ export abstract class AbstractHubService { return axios.request(config) .then(response => { if (successCallback) { - return successCallback(response); + return successCallback(response.body); } else { - return response; + return response.body; } }) .catch(error => console.log(error)); // handle error state } + protected httpPostWithReturn(url: string, body: I, options: AxiosRequestConfig, successCallback?: (data: O) => O): Promise { + + const config: AxiosRequestConfig = {...{ + method: 'post', + url, + body + }, ...options} + + return axios.request(config) + .then(response => { + let data: 0 = response.body; + if(successCallback) { + return successCallback(data); + } + else { + return response.body; + } + }) + .catch(error => console.log(error)); + } + + // protected httpPostWithReturn(url: string, body: I, options: any, successCallback?: (data: O) => O): Promise { + // options["observe"] = "response"; + // return HttpUtils.mappedPromise(this.http.post>(url, body, options).toPromise(), response => { + // let data: O = response.body; + // if (successCallback) { + // return successCallback(data); + // } else { + // return response.body; + // } + // }); + // } + } \ No newline at end of file diff --git a/packages/studio/src/app/app.css b/packages/studio/src/app/app.css index 8e0ac64..6ce8893 100644 --- a/packages/studio/src/app/app.css +++ b/packages/studio/src/app/app.css @@ -65,19 +65,6 @@ color: var(--pf-global--Color--100); } -.app-create-api-form { - width: 50%; -} - -.app-form-helper-text { - font-size: var(--pf-global--FontSize--sm); - color: var(--pf-global--Color--200); -} - -.app-form-helper-text-asterisk { - color: var(--pf-global--danger-color--100); -} - .app-import-api-split-layout > .pf-l-split__item { width: 50%; margin-right: var(--pf-global--spacer--xl); diff --git a/packages/studio/src/app/pages/api/createApi.css b/packages/studio/src/app/pages/api/createApi.css new file mode 100644 index 0000000..fdc4a97 --- /dev/null +++ b/packages/studio/src/app/pages/api/createApi.css @@ -0,0 +1,52 @@ +.app-create-api__form-card-text span { + margin-left: var(--pf-global--spacer--sm); +} + +.app-create-api__form-card { + box-shadow: none !important; +} + +.app-create-api__form-card:hover { + box-shadow: none !important; + color: var(--pf-global--primary-color--100); +} + + +.app-create-api__form-card::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ""; + border: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--100); +} + +.app-create-api__form-card:hover::after { + border-color: var(--pf-global--primary-color--100); +} + +.app-create-api__form-card-group { + display: grid; + grid-column-gap: var(--pf-global--spacer--sm); + grid-template-columns: 1fr 1fr 1fr; +} + +.app-create-api__form { + width: 100%; +} + +@media screen and (min-width: 768px) { + .app-create-api__form { + width: 50%; + } +} + +.app-form-helper-text { + font-size: var(--pf-global--FontSize--sm); + color: var(--pf-global--Color--200); +} + +.app-form-helper-text-asterisk { + color: var(--pf-global--danger-color--100); +} diff --git a/packages/studio/src/app/pages/api/createApi.tsx b/packages/studio/src/app/pages/api/createApi.tsx index 58c79d8..510cc83 100644 --- a/packages/studio/src/app/pages/api/createApi.tsx +++ b/packages/studio/src/app/pages/api/createApi.tsx @@ -1,51 +1,68 @@ -import React from 'react'; -import { Breadcrumb, BreadcrumbItem, Button, Form, FormGroup, TextInput, TextArea, FormSelectOption, FormSelect, ActionGroup, Title, PageSection, PageSectionVariants } from '@patternfly/react-core'; -import '../../app.css' +import React, {useState} from 'react'; +import { + Breadcrumb, + BreadcrumbItem, + Button, + Card, + CardBody, + Form, + FormGroup, + TextInput, + TextArea, + FormSelectOption, + FormSelect, + ActionGroup, + Title, + PageSection, + PageSectionVariants +} from '@patternfly/react-core'; +import '../../app.css'; +import { PlusCircleIcon } from '@patternfly/react-icons'; +import { PficonTemplateIcon } from '@patternfly/react-icons' +import { Services } from './../../common'; +import './createApi.css'; -interface CreateApiProps { - isActive: true -} +// interface CreateApiProps { +// isActive: true +// } -interface CreateApiState { - name: string, - description: string, - apiType: string -} +// interface CreateApiState { +// name: string, +// description: string, +// apiType: string +// } + +export const CreateApi = () => { -export class CreateApi extends React.Component { - constructor(props: CreateApiProps) { - super(props); - this.state = { - apiType: 'please choose', - description: '', - name: '' - }; - this.handleTextInputChangeName = this.handleTextInputChangeName.bind(this); - this.handleTextInputChangeDescription = this.handleTextInputChangeDescription.bind(this); - this.onChange = this.onChange.bind(this); - } + const [apiType, setApiType] = useState('Please choose'); + const [name, setName] = useState(''); + const [description, setDescription] = useState(''); + const [cardSelected, setCardSelected] = useState(null); // TO DO: Add more options here - options = [ - { value: 'Please choose', label: 'Please choose', disabled: false }, + const typeOptions = [ + { value: 'Open API 2.0 (Swagger)', label: 'Open API 2.0 (Swagger)', disabled: false }, { value: 'Open API 3.0.2', label: 'Open API 3.0.2', disabled: false } ]; - private onChange = (apiType: string) => { - this.setState({apiType}); + const onChange = (apiType: string) => { + setApiType(apiType); }; - private handleTextInputChangeName = (name: string) => { - this.setState({ name }); + const handleTextInputChangeName = (name: string) => { + setName(name); }; - private handleTextInputChangeDescription = (description: string) => { - this.setState({ description }); + const handleTextInputChangeDescription = (description: string) => { + setDescription(description); }; - render() { - const { name, description } = this.state; - return ( + const onClickCard = event => { + const newSelected = event.currentTarget.id === cardSelected ? null : event.currentTarget.id + setCardSelected(newSelected); + }; + + return ( @@ -63,7 +80,7 @@ export class CreateApi extends React.Component { -
+

Fields marked with * are required.

{ id="api-create-name" name="api-create-name" value={name} - onChange={this.handleTextInputChangeName} + onChange={handleTextInputChangeName} /> {