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

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git


The following commit(s) were added to refs/heads/main by this push:
     new 2131158  OpenAPi JSON import (#415)
2131158 is described below

commit 2131158bd635fd1c6e20782a6132e6abaa7835ef
Author: Marat Gubaidullin <marat.gubaidul...@gmail.com>
AuthorDate: Wed Jul 13 16:09:55 2022 -0400

    OpenAPi JSON import (#415)
---
 .../camel/karavan/api/ProjectFileResource.java     |  28 +++-
 karavan-app/src/main/webapp/src/Main.tsx           |   3 -
 karavan-app/src/main/webapp/src/api/KaravanApi.tsx |   8 +-
 .../main/webapp/src/integrations/DesignerPage.tsx  | 156 -------------------
 .../webapp/src/integrations/IntegrationCard.tsx    |  54 -------
 .../webapp/src/integrations/IntegrationPage.tsx    | 172 ---------------------
 .../main/webapp/src/integrations/OpenApiPage.tsx   |  89 -----------
 .../main/webapp/src/projects/CreateFileModal.tsx   |   6 +-
 .../src/main/webapp/src/projects/ProjectPage.tsx   |   4 +-
 .../src/main/webapp/src/projects/UploadModal.tsx   |  46 +++---
 karavan-builder/openshift/karavan-acl.yaml         |  22 ++-
 karavan-builder/openshift/karavan-app.yaml         |   3 +
 12 files changed, 81 insertions(+), 510 deletions(-)

diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java
 
b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java
index cf40128..0495efe 100644
--- 
a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java
+++ 
b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java
@@ -17,6 +17,7 @@
 package org.apache.camel.karavan.api;
 
 import org.apache.camel.karavan.model.ProjectFile;
+import org.apache.camel.karavan.service.GeneratorService;
 import org.apache.camel.karavan.service.InfinispanService;
 
 import javax.inject.Inject;
@@ -39,11 +40,14 @@ public class ProjectFileResource {
     @Inject
     InfinispanService infinispanService;
 
+    @Inject
+    GeneratorService generatorService;
+
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/{projectId}")
     public List<ProjectFile> get(@HeaderParam("username") String username,
-                                      @PathParam("projectId") String 
projectId) throws Exception {
+                                 @PathParam("projectId") String projectId) 
throws Exception {
         return infinispanService.getProjectFiles(projectId);
     }
 
@@ -59,11 +63,29 @@ public class ProjectFileResource {
     @Produces(MediaType.APPLICATION_JSON)
     @Path("/{project}/{filename}")
     public void delete(@HeaderParam("username") String username,
-                          @PathParam("project") String project,
-                            @PathParam("filename") String filename) throws 
Exception {
+                       @PathParam("project") String project,
+                       @PathParam("filename") String filename) throws 
Exception {
         infinispanService.deleteProjectFile(
                 URLDecoder.decode(project, StandardCharsets.UTF_8.toString()),
                 URLDecoder.decode(filename, StandardCharsets.UTF_8.toString())
         );
     }
+
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Path("/openapi/{generateRest}/{generateRoutes}/{integrationName}")
+    public ProjectFile saveOpenapi(@HeaderParam("username") String username,
+                                   @PathParam("integrationName") String 
integrationName,
+                                   @PathParam("generateRest") boolean 
generateRest,
+                                   @PathParam("generateRoutes") boolean 
generateRoutes, ProjectFile file) throws Exception {
+        infinispanService.saveProjectFile(file);
+        if (generateRest) {
+            String yaml = generatorService.generate(file.getCode(), 
generateRoutes);
+            ProjectFile integration = new ProjectFile(integrationName, yaml, 
file.getProjectId());
+            infinispanService.saveProjectFile(integration);
+            return file;
+        }
+        return file;
+    }
 }
\ No newline at end of file
diff --git a/karavan-app/src/main/webapp/src/Main.tsx 
b/karavan-app/src/main/webapp/src/Main.tsx
index f34cad6..4e718cf 100644
--- a/karavan-app/src/main/webapp/src/Main.tsx
+++ b/karavan-app/src/main/webapp/src/Main.tsx
@@ -23,7 +23,6 @@ import {ComponentApi} from 
"karavan-core/lib/api/ComponentApi";
 import Icon from "./Logo";
 import {ComponentsPage} from "./components/ComponentsPage";
 import {EipPage} from "./eip/EipPage";
-import {OpenApiPage} from "./integrations/OpenApiPage";
 import {ProjectsPage} from "./projects/ProjectsPage";
 import {Project} from "./models/ProjectModels";
 import {ProjectPage} from "./projects/ProjectPage";
@@ -232,8 +231,6 @@ export class Main extends React.Component<Props, State> {
                         {this.state.pageId === 'kamelets' && <KameletsPage 
dark={false}/>}
                         {this.state.pageId === 'components' && <ComponentsPage 
dark={false}/>}
                         {this.state.pageId === 'eip' && <EipPage 
dark={false}/>}
-                        {this.state.pageId === 'openapi' &&
-                            <OpenApiPage dark={false} 
openapi={this.state.openapi} filename={this.state.filename}/>}
                     </FlexItem>
                 </Flex>
                 <Modal
diff --git a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx 
b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
index 239d688..a1146bd 100644
--- a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
+++ b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
@@ -294,10 +294,10 @@ export const KaravanApi = {
         });
     },
 
-    postOpenApi: async (name: string, json: string, generateRest: boolean, 
generateRoutes: boolean, integrationName: string,  after: (res: 
AxiosResponse<any>) => void) => {
-        const uri = 
`/openapi/${name}/${generateRest}/${generateRoutes}/${integrationName}`;
-        axios.post(encodeURI(uri), json,
-            {headers: {'Accept': 'text/plain', 'Content-Type': 'text/plain', 
'username': 'cameleer'}})
+    postOpenApi: async (file: ProjectFile, generateRest: boolean, 
generateRoutes: boolean, integrationName: string,  after: (res: 
AxiosResponse<any>) => void) => {
+        const uri = 
`/file/openapi/${generateRest}/${generateRoutes}/${integrationName}`;
+        axios.post(encodeURI(uri), file,
+            {headers: {'Accept': 'application/json', 'Content-Type': 
'application/json', 'username': 'cameleer'}})
             .then(res => {
                 after(res);
             }).catch(err => {
diff --git a/karavan-app/src/main/webapp/src/integrations/DesignerPage.tsx 
b/karavan-app/src/main/webapp/src/integrations/DesignerPage.tsx
deleted file mode 100644
index 536e413..0000000
--- a/karavan-app/src/main/webapp/src/integrations/DesignerPage.tsx
+++ /dev/null
@@ -1,156 +0,0 @@
-import React from 'react';
-import {
-    Button, CodeBlock, CodeBlockCode,
-    PageSection, Text, TextContent, ToggleGroup, ToggleGroupItem, Toolbar, 
ToolbarContent, ToolbarItem
-} from '@patternfly/react-core';
-import PublishIcon from 
'@patternfly/react-icons/dist/esm/icons/openshift-icon';
-import DownloadIcon from 
'@patternfly/react-icons/dist/esm/icons/download-icon';
-import SaveIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon';
-import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';
-import '../designer/karavan.css';
-import {MainToolbar} from "../MainToolbar";
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
-import {KaravanApi} from "../api/KaravanApi";
-import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
-import {KaravanDesigner} from "../designer/KaravanDesigner";
-import FileSaver from "file-saver";
-import Editor from '@monaco-editor/react';
-
-interface Props {
-    integration: Integration,
-    mode: 'local' | 'gitops' | 'serverless',
-}
-
-interface State {
-    integration: Integration
-    view: "design" | "code"
-    name: string
-    yaml: string
-    key: string
-}
-
-export class DesignerPage extends React.Component<Props, State> {
-
-    public state: State = {
-        integration: this.props.integration, // CamelDefinitionYaml.demo(),
-        view: "design",
-        key: "",
-        name: this.props.integration.metadata.name,
-        yaml: CamelDefinitionYaml.integrationToYaml(this.props.integration)
-    };
-
-    componentDidMount() {
-    }
-
-    post = () => {
-        // KaravanApi.postIntegrations(this.state.integration.metadata.name, 
this.state.yaml, res => {
-        //     if (res.status === 200) {
-        //         console.log(res) //TODO show notification
-        //     } else {
-        //         console.log(res) //TODO show notification
-        //     }
-        // })
-    }
-
-    publish = () => {
-        // KaravanApi.publishIntegration(this.state.integration.metadata.name, 
this.state.yaml, res => {
-        //     if (res.status === 200) {
-        //         console.log(res) //TODO show notification
-        //     } else {
-        //         console.log(res) //TODO show notification
-        //     }
-        // })
-    }
-
-    copy = () => {
-        this.copyToClipboard(this.state.yaml);
-    }
-
-    copyToClipboard = (data: string) => {
-        navigator.clipboard.writeText(data);
-    }
-
-    changeView = (view: "design" | "code") => {
-        this.setState({view: view});
-    }
-
-    save = (name: string, yaml: string) => {
-        this.setState({name: name, yaml: yaml})
-    }
-
-    download = () => {
-        const file = new File([this.state.yaml], 
this.state.integration.metadata.name, {type: "application/yaml;charset=utf-8"});
-        FileSaver.saveAs(file);
-    }
-
-    tools = (view: "design" | "code") => (
-        <Toolbar id="toolbar-group-types">
-            <ToolbarContent>
-                <ToolbarItem>
-                    <Button variant="secondary" icon={<CopyIcon/>} onClick={e 
=> this.copy()}>Copy</Button>
-                </ToolbarItem>
-                <ToolbarItem>
-                    <Button variant="secondary" icon={<DownloadIcon/>} 
onClick={e => this.download()}>Download</Button>
-                </ToolbarItem>
-                {this.props.mode === 'gitops' &&
-                    <ToolbarItem>
-                        <Button variant="secondary" icon={<PublishIcon/>} 
onClick={e => this.publish()}>Publish</Button>
-                    </ToolbarItem>
-                }
-                {this.props.mode === 'serverless' &&
-                    <ToolbarItem>
-                        <Button variant="primary" icon={<PublishIcon/>} 
onClick={e => this.post()}>Apply</Button>
-                    </ToolbarItem>
-                }
-                {this.props.mode !== 'serverless' &&
-                    <ToolbarItem>
-                        <Button variant="secondary" icon={<SaveIcon/>} 
onClick={e => this.post()}>Save</Button>
-                    </ToolbarItem>
-                }
-            </ToolbarContent>
-        </Toolbar>);
-
-    title = (view: "design" | "code") => (
-        <div className="dsl-title">
-            <TextContent className="title">
-                <Text component="h1">Designer</Text>
-            </TextContent>
-            <ToggleGroup aria-label="Switch view" className="toggle">
-                <ToggleGroupItem text="Design" buttonId="design" 
isSelected={view === 'design'}
-                                 onChange={e => this.changeView('design')}/>
-                <ToggleGroupItem text="YAML" buttonId="yaml" isSelected={view 
=== 'code'}
-                                 onChange={e => this.changeView('code')}/>
-            </ToggleGroup>
-        </div>
-    );
-
-    render() {
-        const {view, yaml, name, key} = this.state;
-
-        return (<>
-                <MainToolbar title={this.title(view)}
-                             tools={this.tools(view)}/>
-                {view === 'code' &&
-                    <Editor
-                        height="100vh"
-                        defaultLanguage={'yaml'}
-                        theme={'light'}
-                        value={yaml}
-                        className={'code-editor'}
-                        onChange={(value, ev) => {if (value) 
this.setState({yaml: value})}}
-                    />
-                }
-                {view === 'design' &&
-                    <KaravanDesigner
-                        showStartHelp={false}
-                        dark={false}
-                        key={key}
-                        filename={name}
-                        yaml={yaml}
-                        onSave={(name, yaml) => this.save(name, yaml)}
-                    />
-                }
-            </>
-        );
-    }
-}
diff --git a/karavan-app/src/main/webapp/src/integrations/IntegrationCard.tsx 
b/karavan-app/src/main/webapp/src/integrations/IntegrationCard.tsx
deleted file mode 100644
index ef1142f..0000000
--- a/karavan-app/src/main/webapp/src/integrations/IntegrationCard.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import React from 'react';
-import {
-    CardHeader, Card, CardTitle, CardBody, Button, CardActions, CardFooter,
-} from '@patternfly/react-core';
-import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
-import '../designer/karavan.css';
-import {CamelUi} from "../designer/utils/CamelUi";
-import {getDesignerIcon} from "../designer/utils/KaravanIcons";
-
-interface Props {
-    name: string,
-    type: 'integration' | 'openapi',
-    status?: string,
-    onClick: (filename: string, type: 'integration' | 'openapi') => void
-    onDelete: (name: string, type: 'integration' | 'openapi') => void
-}
-
-interface State {
-}
-
-export class IntegrationCard extends React.Component<Props, State> {
-
-    public state: State = {
-    };
-
-    private click(evt: React.MouseEvent) {
-        evt.stopPropagation();
-        this.props.onClick.call(this, this.props.name, this.props.type)
-    }
-
-    private delete(evt: React.MouseEvent) {
-        evt.stopPropagation();
-        this.props.onDelete.call(this, this.props.name, this.props.type);
-    }
-
-    render() {
-        return (
-            <Card isCompact key={this.props.name} className="integration-card" 
onClick={event => this.click(event)}>
-                <CardHeader>
-                    {getDesignerIcon(this.props.type === 'integration' ? 
'routes' : 'rest')}
-                    <CardActions>
-                        <Button variant="link" className="delete-button" 
onClick={e => this.delete(e)}><DeleteIcon/></Button>
-                    </CardActions>
-                </CardHeader>
-                <CardTitle>{this.props.type === 'integration' ? 'Integration' 
: 'OpenAPI'}</CardTitle>
-                <CardTitle>{CamelUi.titleFromName(this.props.name)}</CardTitle>
-                <CardBody>{this.props.name}</CardBody>
-                <CardFooter className={this.props.status === 'Running' ? 
'running' : (this.props.status === 'Error' ? 'error' : 'normal')}>
-                    {this.props.status}
-                </CardFooter>
-            </Card>
-        );
-    }
-}
\ No newline at end of file
diff --git a/karavan-app/src/main/webapp/src/integrations/IntegrationPage.tsx 
b/karavan-app/src/main/webapp/src/integrations/IntegrationPage.tsx
deleted file mode 100644
index ebc9506..0000000
--- a/karavan-app/src/main/webapp/src/integrations/IntegrationPage.tsx
+++ /dev/null
@@ -1,172 +0,0 @@
-import React from 'react';
-import {
-    Toolbar,
-    ToolbarContent,
-    Gallery,
-    ToolbarItem,
-    TextInput,
-    PageSection,
-    TextContent,
-    Text,
-    Button, Modal, FormGroup, ModalVariant, Switch, Form, FormSelect, 
FormSelectOption, FileUpload
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import {IntegrationCard} from "./IntegrationCard";
-import {MainToolbar} from "../MainToolbar";
-import RefreshIcon from '@patternfly/react-icons/dist/esm/icons/sync-alt-icon';
-import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
-import UploadIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon';
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
-import {CamelUi} from "../designer/utils/CamelUi";
-import {UploadModal} from "../projects/UploadModal";
-
-interface Props {
-    integrations: Map<string, string>
-    openapis: Map<string, string>
-    onSelect: (filename: string, type: 'integration' | 'openapi') => void
-    onCreate: any
-    onDelete: (name: string, type: 'integration' | 'openapi') => void
-    onRefresh: any
-}
-
-interface State {
-    repository: string,
-    path: string,
-    integrations: Map<string, string>,
-    openapis: Map<string, string>,
-    isCreateModalOpen: boolean,
-    isUploadModalOpen: boolean,
-    newName: string
-    crd: boolean
-    data: string
-    filename: string
-    isLoading: boolean
-    isRejected: boolean
-    generateRest: boolean
-    generateRoutes: boolean
-}
-
-export class IntegrationPage extends React.Component<Props, State> {
-
-    public state: State = {
-        repository: '',
-        path: '',
-        integrations: this.props.integrations,
-        openapis: this.props.openapis,
-        isCreateModalOpen: false,
-        isUploadModalOpen: false,
-        newName: '',
-        crd: true,
-        data: '',
-        filename: '',
-        isLoading: false,
-        isRejected: false,
-        generateRest: true,
-        generateRoutes: true
-    };
-
-    tools = () => (<Toolbar id="toolbar-group-types">
-        <ToolbarContent>
-            <ToolbarItem>
-                <TextInput className="text-field" type="search" id="search" 
name="search"
-                           autoComplete="off" placeholder="Search by name"/>
-            </ToolbarItem>
-            <ToolbarItem>
-                <Button variant="secondary" icon={<RefreshIcon/>}
-                        onClick={e => 
this.props.onRefresh.call(this)}>Refresh</Button>
-            </ToolbarItem>
-            <ToolbarItem>
-                <Button variant="secondary" icon={<UploadIcon/>}
-                        onClick={e => this.setState({isUploadModalOpen: 
true})}>Upload</Button>
-            </ToolbarItem>
-            <ToolbarItem>
-                <Button icon={<PlusIcon/>} onClick={e => 
this.setState({isCreateModalOpen: true})}>Create</Button>
-            </ToolbarItem>
-        </ToolbarContent>
-    </Toolbar>);
-
-    title = () => (<TextContent>
-        <Text component="h1">Integrations</Text>
-    </TextContent>);
-
-    closeModal = () => {
-        this.setState({isCreateModalOpen: false, newName: "", 
isUploadModalOpen: false});
-        this.props.onRefresh.call(this);
-    }
-
-    saveAndCloseCreateModal = () => {
-        const name = CamelUi.nameFromTitle(this.state.newName) + ".yaml";
-        const i = Integration.createNew(name);
-        i.crd = this.state.crd;
-        this.props.onCreate.call(this, i);
-        this.setState({isCreateModalOpen: false, newName: ""});
-    }
-
-    onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {
-        if (event.key === 'Enter' && this.state.newName !== undefined) {
-            this.saveAndCloseCreateModal();
-        }
-    }
-
-    createModalForm() {
-        return (
-            <Modal
-                title="Create new Integration"
-                variant={ModalVariant.small}
-                isOpen={this.state.isCreateModalOpen}
-                onClose={this.closeModal}
-                onKeyDown={this.onKeyDown}
-                actions={[
-                    <Button key="confirm" variant="primary" 
onClick={this.saveAndCloseCreateModal}>Save</Button>,
-                    <Button key="cancel" variant="secondary" 
onClick={this.closeModal}>Cancel</Button>
-                ]}
-            >
-                <Form isHorizontal={true}>
-                    <FormGroup label="Title" fieldId="title" isRequired>
-                        <TextInput className="text-field" type="text" 
id="title" name="title"
-                                   value={this.state.newName}
-                                   onChange={e => this.setState({newName: 
e})}/>
-                    </FormGroup>
-                    <FormGroup label="Type" fieldId="crd" isRequired>
-                        <FormSelect value={this.state.crd}
-                                    onChange={value => this.setState({crd: 
Boolean(JSON.parse(value))})}
-                                    aria-label="FormSelect Input">
-                            <FormSelectOption key="crd" value="true" 
label="Camel-K CRD"/>
-                            <FormSelectOption key="plain" value="false" 
label="Plain YAML"/>
-                        </FormSelect>
-                    </FormGroup>
-                </Form>
-            </Modal>
-        )
-    }
-
-    render() {
-        return (
-            <PageSection padding={{default: 'noPadding'}}>
-                <MainToolbar title={this.title()} tools={this.tools()}/>
-                <PageSection isFilled className="integration-page">
-                    <Gallery hasGutter>
-                        {Array.from(this.state.integrations.keys()).map(key => 
(
-                            <IntegrationCard key={key}
-                                             name={key}
-                                             type={"integration"}
-                                             
status={this.state.integrations.get(key)}
-                                             onDelete={this.props.onDelete}
-                                             onClick={this.props.onSelect}/>
-                        ))}
-                        {Array.from(this.state.openapis.keys()).map(key => (
-                            <IntegrationCard key={key}
-                                             name={key}
-                                             type={"openapi"}
-                                             
status={this.state.openapis.get(key)}
-                                             onDelete={this.props.onDelete}
-                                             onClick={this.props.onSelect}/>
-                        ))}
-                    </Gallery>
-                </PageSection>
-                {this.createModalForm()}
-                <UploadModal isOpen={this.state.isUploadModalOpen} 
onClose={this.closeModal}/>
-            </PageSection>
-        );
-    }
-};
\ No newline at end of file
diff --git a/karavan-app/src/main/webapp/src/integrations/OpenApiPage.tsx 
b/karavan-app/src/main/webapp/src/integrations/OpenApiPage.tsx
deleted file mode 100644
index a976ebf..0000000
--- a/karavan-app/src/main/webapp/src/integrations/OpenApiPage.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import React from 'react';
-import {
-    Button, CodeBlock, CodeBlockCode,
-    PageSection, Text, TextContent, ToggleGroup, ToggleGroupItem, Toolbar, 
ToolbarContent, ToolbarItem
-} from '@patternfly/react-core';
-import PublishIcon from 
'@patternfly/react-icons/dist/esm/icons/openshift-icon';
-import DownloadIcon from 
'@patternfly/react-icons/dist/esm/icons/download-icon';
-import SaveIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon';
-import CopyIcon from '@patternfly/react-icons/dist/esm/icons/copy-icon';
-import '../designer/karavan.css';
-import {MainToolbar} from "../MainToolbar";
-import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
-import {KaravanApi} from "../api/KaravanApi";
-import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
-import {KaravanDesigner} from "../designer/KaravanDesigner";
-import FileSaver from "file-saver";
-import Editor from '@monaco-editor/react';
-
-interface Props {
-    openapi: string,
-    filename: string,
-    dark: boolean
-}
-
-interface State {
-}
-
-export class OpenApiPage extends React.Component<Props, State> {
-
-    public state: State = {
-    };
-
-    copy = () => {
-        this.copyToClipboard(this.props.openapi);
-    }
-
-    copyToClipboard = (data: string) => {
-        navigator.clipboard.writeText(data);
-    }
-
-    changeView = (view: "design" | "code") => {
-        this.setState({view: view});
-    }
-
-    save = (name: string, yaml: string) => {
-        this.setState({name: name, yaml: yaml})
-    }
-
-    download = () => {
-        const file = new File([this.props.openapi], this.props.filename, 
{type: "application/json;charset=utf-8"});
-        FileSaver.saveAs(file);
-    }
-
-    tools = () => (
-        <Toolbar id="toolbar-group-types">
-            <ToolbarContent>
-                <ToolbarItem>
-                    <Button variant="secondary" icon={<CopyIcon/>} onClick={e 
=> this.copy()}>Copy</Button>
-                </ToolbarItem>
-                <ToolbarItem>
-                    <Button variant="secondary" icon={<DownloadIcon/>} 
onClick={e => this.download()}>Download</Button>
-                </ToolbarItem>
-            </ToolbarContent>
-        </Toolbar>);
-
-    title = () => (
-        <div className="dsl-title">
-            <TextContent className="title">
-                <Text component="h1">OpenAPI</Text>
-            </TextContent>
-        </div>
-    );
-
-    render() {
-        return (<>
-                <MainToolbar title={this.title()}
-                             tools={this.tools()}/>
-                <Editor
-                    height="100vh"
-                    defaultLanguage={'json'}
-                    theme={'light'}
-                    value={this.props.openapi}
-                    className={'code-editor'}
-                    onChange={(value, ev) => {if (value) this.setState({yaml: 
value})}}
-                />
-            </>
-        );
-    }
-}
diff --git a/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx 
b/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx
index bcbf838..aaa5cae 100644
--- a/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx
+++ b/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx
@@ -41,10 +41,10 @@ export class CreateFileModal extends React.Component<Props, 
State> {
             const file = new ProjectFile(filename + '.' + extension, 
this.props.project.projectId, '');
             KaravanApi.postProjectFile(file, res => {
                 if (res.status === 200) {
-                    console.log(res) //TODO show notification
+                    // console.log(res) //TODO show notification
                     this.props.onClose?.call(this);
                 } else {
-                    console.log(res) //TODO show notification
+                    // console.log(res) //TODO show notification
                     this.props.onClose?.call(this);
                 }
             })
@@ -69,7 +69,7 @@ export class CreateFileModal extends React.Component<Props, 
State> {
                 <Form autoComplete="off" isHorizontal 
className="create-file-form">
                     <FormGroup label="Type" fieldId="type" isRequired>
                         <ToggleGroup aria-label="Type">
-                            {ProjectFileTypes.filter(p => p.name !== 
'PROPERTIES' && p.name !== 'LOG').map(p => {
+                            {ProjectFileTypes.filter(p => !['PROPERTIES', 
'LOG'].includes(p.name)).map(p => {
                                 const title = p.title + (p.name === 'CODE' ? ' 
(' + p.extension + ')' : '');
                                 return <ToggleGroupItem key={title} 
text={title} buttonId={p.name}
                                                         
isSelected={this.state.extension === p.extension}
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx 
b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
index a8dcf06..631434c 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
@@ -43,6 +43,7 @@ import {ProjectHeader} from "./ProjectHeader";
 import {ProjectModel, ProjectProperty} from 
"karavan-core/lib/model/ProjectModel";
 import {ProjectModelApi} from "karavan-core/lib/api/ProjectModelApi";
 import {KubernetesAPI} from "../designer/utils/KubernetesAPI";
+import {UploadModal} from "./UploadModal";
 
 interface Props {
     project: Project,
@@ -424,7 +425,7 @@ export class ProjectPage extends React.Component<Props, 
State> {
         const isYaml = file !== undefined && file.name.endsWith("yaml");
         const isProperties = file !== undefined && 
file.name.endsWith("properties");
         const isLog = file !== undefined && file.name.endsWith("log");
-        const isCode = file !== undefined && (file.name.endsWith("java") || 
file.name.endsWith("groovy"));
+        const isCode = file !== undefined && (file.name.endsWith("java") || 
file.name.endsWith("groovy") || file.name.endsWith("json"));
         const showDesigner = isYaml && mode === 'design';
         const showEditor = isCode || (isYaml && mode === 'code');
         return (
@@ -461,6 +462,7 @@ export class ProjectPage extends React.Component<Props, 
State> {
                     onEscapePress={e => this.setState({isDeleteModalOpen: 
false})}>
                     <div>{"Are you sure you want to delete the file " + 
this.state.fileToDelete?.name + "?"}</div>
                 </Modal>
+                <UploadModal projectId={this.props.project.projectId} 
isOpen={this.state.isUploadModalOpen} onClose={this.closeModal}/>
             </PageSection>
         )
     }
diff --git a/karavan-app/src/main/webapp/src/projects/UploadModal.tsx 
b/karavan-app/src/main/webapp/src/projects/UploadModal.tsx
index b67a783..d457c51 100644
--- a/karavan-app/src/main/webapp/src/projects/UploadModal.tsx
+++ b/karavan-app/src/main/webapp/src/projects/UploadModal.tsx
@@ -4,8 +4,11 @@ import {
     Button, Modal, FormGroup, ModalVariant, Switch, Form, FileUpload, Radio
 } from '@patternfly/react-core';
 import '../designer/karavan.css';
+import {KaravanApi} from "../api/KaravanApi";
+import {ProjectFile} from "../models/ProjectModels";
 
 interface Props {
+    projectId: string,
     isOpen: boolean,
     onClose: any
 }
@@ -40,27 +43,28 @@ export class UploadModal extends React.Component<Props, 
State> {
 
     saveAndCloseModal = () => {
         const state = this.state;
-        // if (this.state.type === "integration"){
-        //     KaravanApi.postIntegrations(state.filename, state.data, res => {
-        //         if (res.status === 200) {
-        //             console.log(res) //TODO show notification
-        //             this.props.onClose?.call(this);
-        //         } else {
-        //             console.log(res) //TODO show notification
-        //             this.props.onClose?.call(this);
-        //         }
-        //     })
-        // } else {
-        //     KaravanApi.postOpenApi(state.filename, state.data, 
state.generateRest, state.generateRoutes, state.integrationName, res => {
-        //         if (res.status === 200) {
-        //             console.log(res) //TODO show notification
-        //             this.props.onClose?.call(this);
-        //         } else {
-        //             console.log(res) //TODO show notification
-        //             this.props.onClose?.call(this);
-        //         }
-        //     })
-        // }
+        const file = new ProjectFile(state.filename, this.props.projectId, 
state.data);
+        if (this.state.type === "integration"){
+            KaravanApi.postProjectFile(file, res => {
+                if (res.status === 200) {
+                    //TODO show notification
+                    this.props.onClose?.call(this);
+                } else {
+                    // TODO show notification
+                    this.props.onClose?.call(this);
+                }
+            })
+        } else {
+            KaravanApi.postOpenApi(file, state.generateRest, 
state.generateRoutes, state.integrationName, res => {
+                if (res.status === 200) {
+                    console.log(res) //TODO show notification
+                    this.props.onClose?.call(this);
+                } else {
+                    console.log(res) //TODO show notification
+                    this.props.onClose?.call(this);
+                }
+            })
+        }
     }
 
     handleFileInputChange = (event: React.ChangeEvent<HTMLInputElement> | 
React.DragEvent<HTMLElement>, file: File) => this.setState({filename: 
file.name});
diff --git a/karavan-builder/openshift/karavan-acl.yaml 
b/karavan-builder/openshift/karavan-acl.yaml
index 88088a9..7670950 100644
--- a/karavan-builder/openshift/karavan-acl.yaml
+++ b/karavan-builder/openshift/karavan-acl.yaml
@@ -7,11 +7,11 @@ metadata:
     app.kubernetes.io/name: karavan
     app.openshift.io/runtime: camel
 ---
-# Role view-secrets
+# Role karavan-app
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
-  name: karavan-view-secrets
+  name: karavan-app
 rules:
   - apiGroups:
       - ""
@@ -21,6 +21,20 @@ rules:
     verbs:
       - get
       - list
+  - apiGroups:
+      - ""
+      - apps.openshift.io
+    resources:
+      - deploymentconfigs
+      - replicationcontrollers
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
 ---
 # Role tekton run pipeline
 kind: Role
@@ -68,11 +82,11 @@ subjects:
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
-  name: karavan-view-secrets
+  name: karavan-app
 roleRef:
   kind: Role
   apiGroup: rbac.authorization.k8s.io
-  name: karavan-view-secrets
+  name: karavan-app
 subjects:
   - kind: ServiceAccount
     name: karavan
diff --git a/karavan-builder/openshift/karavan-app.yaml 
b/karavan-builder/openshift/karavan-app.yaml
index a9acc04..bd9353b 100644
--- a/karavan-builder/openshift/karavan-app.yaml
+++ b/karavan-builder/openshift/karavan-app.yaml
@@ -43,6 +43,9 @@ spec:
           image: ghcr.io/apache/camel-karavan:0.0.16
           imagePullPolicy: Always
           name: karavan
+          resources:
+            requests:
+              memory: "2048Mi"
           volumeMounts:
             - name: karavan-data
               mountPath: /deployments/karavan-data

Reply via email to