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 d14e09e  Saas feature38 (#435)
d14e09e is described below

commit d14e09e8ffd6f9cf676ba52bb226180b6212f173
Author: Marat Gubaidullin <marat.gubaidul...@gmail.com>
AuthorDate: Thu Jul 28 21:45:00 2022 -0400

    Saas feature38 (#435)
    
    * Rollback errorrously deleted Project Classes
    
    * Cleanup
---
 karavan-app/src/main/webapp/package-lock.json      |   6 +-
 karavan-app/src/main/webapp/package.json           |   2 +-
 karavan-designer/src/App.tsx                       |  16 --
 karavan-designer/src/builder/BuilderPage.tsx       | 298 ---------------------
 karavan-designer/src/builder/FileSelector.tsx      |  97 -------
 karavan-designer/src/builder/ProfileSelector.tsx   | 148 ----------
 karavan-designer/src/builder/PropertiesTable.tsx   | 148 ----------
 karavan-vscode/package.json                        |   2 +-
 karavan-vscode/webview/builder/BuilderPage.tsx     | 298 ---------------------
 karavan-vscode/webview/builder/FileSelector.tsx    |  97 -------
 karavan-vscode/webview/builder/ProfileSelector.tsx | 148 ----------
 karavan-vscode/webview/builder/PropertiesTable.tsx | 148 ----------
 12 files changed, 5 insertions(+), 1403 deletions(-)

diff --git a/karavan-app/src/main/webapp/package-lock.json 
b/karavan-app/src/main/webapp/package-lock.json
index f397c3c..ed941bd 100644
--- a/karavan-app/src/main/webapp/package-lock.json
+++ b/karavan-app/src/main/webapp/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "karavan",
-  "version": "0.0.16",
+  "version": "3.18.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "karavan",
-      "version": "0.0.16",
+      "version": "3.18.0",
       "dependencies": {
         "@monaco-editor/react": "4.3.1",
         "@patternfly/patternfly": "4.194.4",
@@ -40,7 +40,7 @@
       }
     },
     "../../../../karavan-core": {
-      "version": "0.0.16",
+      "version": "3.18.0",
       "license": "Apache-2.0",
       "dependencies": {
         "@types/js-yaml": "^4.0.5",
diff --git a/karavan-app/src/main/webapp/package.json 
b/karavan-app/src/main/webapp/package.json
index e066815..1e64f4a 100644
--- a/karavan-app/src/main/webapp/package.json
+++ b/karavan-app/src/main/webapp/package.json
@@ -3,7 +3,7 @@
   "version": "3.18.0",
   "private": true,
   "scripts": {
-    "copy-designer": "cp -r ../../../../karavan-designer/src/designer src && 
cp -r ../../../../karavan-designer/src/kamelets src && cp -r 
../../../../karavan-designer/src/components src && cp -r 
../../../../karavan-designer/src/eip src && cp -r 
../../../../karavan-designer/src/builder src",
+    "copy-designer": "cp -r ../../../../karavan-designer/src/designer src && 
cp -r ../../../../karavan-designer/src/kamelets src && cp -r 
../../../../karavan-designer/src/components src && cp -r 
../../../../karavan-designer/src/eip src",
     "start": "npm run copy-designer && react-scripts start",
     "build": "npm run copy-designer && react-scripts build",
     "prod": "npm run copy-designer && react-scripts build --dest && rsync -a 
build/* ../resources/META-INF/resources"
diff --git a/karavan-designer/src/App.tsx b/karavan-designer/src/App.tsx
index af4a5a8..35930b4 100644
--- a/karavan-designer/src/App.tsx
+++ b/karavan-designer/src/App.tsx
@@ -24,8 +24,6 @@ import {KaravanDesigner} from "./designer/KaravanDesigner";
 import {KameletsPage} from "./kamelets/KameletsPage";
 import {ComponentsPage} from "./components/ComponentsPage";
 import {EipPage} from "./eip/EipPage";
-import {BuilderPage} from "./builder/BuilderPage";
-import {ProjectModel, StepStatus} from "karavan-core/lib/model/ProjectModel";
 
 interface Props {
     page: "designer" | "kamelets" | "components" | "eip" | "builder";
@@ -127,14 +125,6 @@ class App extends React.Component<Props, State> {
     }
 
     public render() {
-        const project = ProjectModel.createNew({});
-        // project.properties.set("message", "Hello Placeholder!")
-        // project.properties.set("camel.jbang.classpathFiles", 
"application.properties")
-        // project.properties.set("camel.main.routesIncludePattern", 
"file:demo.yaml")
-        // project.properties.set("camel.component.properties.location", 
"file:application.properties")
-        project.status.active = true;
-        project.status.export = new StepStatus({status:"progress"});
-        project.status.package = new StepStatus({status:"progress"});
         return (
             <Page className="karavan">
                 {this.props.page === "designer" && <KaravanDesigner 
key={this.state.key} filename={this.state.name} yaml={this.state.yaml}
@@ -144,12 +134,6 @@ class App extends React.Component<Props, State> {
                 {this.props.page === "kamelets" && <KameletsPage 
dark={document.body.className.includes('vscode-dark')} />}
                 {this.props.page === "components" && <ComponentsPage 
dark={document.body.className.includes('vscode-dark')} />}
                 {this.props.page === "eip" && <EipPage 
dark={document.body.className.includes('vscode-dark')} />}
-                {this.props.page === "builder" && <BuilderPage 
dark={document.body.className.includes('vscode-dark')} project={project}
-                                                               
onChange={project => {
-                                                                   // 
console.log("routesIncludePattern", project.routesIncludePattern);
-                                                                   // 
console.log("classpathFiles", project.classpathFiles);
-                                                               }}
-                                                               
files={'demo.yaml,CustomProcessor.java,script.groovy,docker-compose.yaml,README.MD'}/>}
             </Page>
         );
     }
diff --git a/karavan-designer/src/builder/BuilderPage.tsx 
b/karavan-designer/src/builder/BuilderPage.tsx
deleted file mode 100644
index 43c27d5..0000000
--- a/karavan-designer/src/builder/BuilderPage.tsx
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Badge,
-    Button,
-    Card,
-    CardBody,
-    CardHeader,
-    CardHeaderMain,
-    CardTitle,
-    Flex,
-    FlexItem,
-    Form,
-    FormGroup,
-    InputGroup,
-    PageSection,
-    PageSectionVariants,
-    Popover,
-    PopoverPosition,
-    ProgressStep,
-    ProgressStepper,
-    Spinner,
-    Text,
-    TextContent,
-    TextInput,
-    Toolbar,
-    ToolbarContent,
-    ToolbarItem,
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import InProgressIcon from 
'@patternfly/react-icons/dist/esm/icons/in-progress-icon';
-import AutomationIcon from 
'@patternfly/react-icons/dist/esm/icons/bundle-icon';
-import PendingIcon from '@patternfly/react-icons/dist/esm/icons/pending-icon';
-import ExclamationCircleIcon from 
'@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
-import CheckCircleIcon from 
'@patternfly/react-icons/dist/esm/icons/check-circle-icon';
-import ProjectIcon from '@patternfly/react-icons/dist/esm/icons/cubes-icon';
-import ClipboardIcon from 
'@patternfly/react-icons/dist/esm/icons/clipboard-icon';
-import RunIcon from '@patternfly/react-icons/dist/esm/icons/play-circle-icon';
-import {ProjectModel, StepStatus} from "karavan-core/lib/model/ProjectModel";
-import {PropertiesTable} from "./PropertiesTable";
-
-interface Props {
-    project: ProjectModel,
-    dark: boolean
-    files: string
-    onChange?: (project: ProjectModel) => void
-    onAction?: (action: "start" | "stop" | "undeploy" | "run", project: 
ProjectModel) => void
-}
-
-interface State {
-    project: ProjectModel,
-    key?: string,
-    isOpen?: boolean
-}
-
-export class BuilderPage extends React.Component<Props, State> {
-
-    public state: State = {
-        project: this.props.project,
-    };
-    interval: any;
-
-    componentDidUpdate = (prevProps: Readonly<Props>, prevState: 
Readonly<State>, snapshot?: any) => {
-        const project = this.state.project;
-        if (project) this.props.onChange?.call(this, project);
-    }
-
-    componentDidMount() {
-        this.interval = setInterval(() => this.setState(state => ({key: 
Math.random().toString()})), 1000);
-    }
-
-    componentWillUnmount() {
-        clearInterval(this.interval);
-    }
-
-    getHelp(text: string) {
-        return <Popover
-            aria-label={text}
-            position={PopoverPosition.left}
-            bodyContent={text}>
-            <Button variant="plain" onClick={e => {
-            }}>
-                <HelpIcon/>
-            </Button>
-        </Popover>
-    }
-
-    getField(name: string, label: string, type: 'text' | 'date' | 
'datetime-local' | 'email' | 'month' | 'number' | 'password' | 'search' | 'tel' 
| 'time' | 'url',
-             value: any, help: string, onChange: (val: any) => void, 
isRequired: boolean = false, enabled: boolean = true) {
-        return <FormGroup label={label} fieldId={name} isRequired={isRequired}>
-            <InputGroup>
-                <TextInput isRequired={isRequired} isDisabled={!enabled} 
className="text-field" type={type} id={name} name={name} value={value}
-                           onChange={val => onChange?.call(this, val)}/>
-                {this.getHelp(help)}
-            </InputGroup>
-        </FormGroup>
-    }
-
-    getCardHeader(title: string, icon: any) {
-        return <CardHeader>
-            <CardHeaderMain>
-                <CardTitle className="card-header">
-                    {icon}{title}
-                </CardTitle>
-            </CardHeaderMain>
-        </CardHeader>
-    }
-
-    getProjectForm() {
-        return (
-            <Card className="builder-card" isCompact style={{width: "100%"}}>
-                {this.getCardHeader("Artifact", <ProjectIcon/>)}
-                <CardBody>
-                    <Form isHorizontal>
-                        {/*{this.getField("name", "Name", "text", 
this.state.profile.project.name, "Project name",*/}
-                        {/*    val => this.setState(state => 
{state.profile.project.name= val; return state}), true)}*/}
-                        {/*{this.getField("version", "Version", "text", 
this.state.profile.project.version, "Project version",*/}
-                        {/*    val => this.setState(state => 
{state.profile.project.version= val; return state}), true)}*/}
-                    </Form>
-                </CardBody>
-            </Card>
-        )
-    }
-
-    getProgressIcon(status?: 'pending' | 'progress' | 'done' | 'error') {
-        switch (status) {
-            case "pending":
-                return <PendingIcon/>;
-            case "progress":
-                return <Spinner isSVG size="md"/>
-            case "done":
-                return <CheckCircleIcon/>;
-            case "error":
-                return <ExclamationCircleIcon/>;
-            default:
-                return undefined;
-        }
-    }
-
-    getDescription(stepStatus?: StepStatus) {
-        const now = Date.now();
-        let time = 0;
-        if (stepStatus?.status === 'progress') {
-            time = stepStatus?.startTime ? (now - stepStatus.startTime) / 1000 
: 0;
-        } else if (stepStatus?.status === 'done' && stepStatus?.endTime) {
-            time = (stepStatus?.endTime - stepStatus.startTime) / 1000
-        }
-        return time === 0 ? "" : Math.round(time) + "s";
-    }
-
-    getProgress() {
-        const {status} = this.state.project;
-        return (
-            <ProgressStepper isCenterAligned style={{visibility: "visible"}}>
-                <ProgressStep variant="pending" id="export" titleId="export" 
aria-label="export"
-                              description={this.getDescription(status.export)}
-                              
icon={this.getProgressIcon(status.export?.status)}>Export
-                </ProgressStep>
-                <ProgressStep variant="pending" isCurrent id="package" 
titleId="package" aria-label="package"
-                              description={this.getDescription(status.package)}
-                              
icon={this.getProgressIcon(status.package?.status)}>Package
-                </ProgressStep>
-            </ProgressStepper>
-        )
-    }
-
-    getHeader() {
-        return (
-            <PageSection className="tools-section" variant={this.props.dark ? 
PageSectionVariants.darker : PageSectionVariants.light}>
-                <Flex className="tools" direction={{default: 'row'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}} spaceItems={{default: 
'spaceItemsLg'}}>
-                    <FlexItem>
-                        <TextContent className="header">
-                            <Text component="h2">Build Runner</Text>
-                            <Badge isRead className="labels">Powered by Camel 
JBang & Maven</Badge>
-                        </TextContent>
-                    </FlexItem>
-                    <FlexItem>
-                        <Toolbar id="toolbar-group-types">
-                            <ToolbarContent>
-                                <ToolbarItem>
-                                    {/*<ProfileSelector 
profiles={profiles.map(p => p.name)}*/}
-                                    {/*                 
profile={profile.name}*/}
-                                    {/*                 onDelete={profile => 
{*/}
-                                    {/*                     
this.setState(state => {*/}
-                                    {/*                         
state.profiles.splice(state.profiles.findIndex(p => p.name === profile), 1);*/}
-                                    {/*                         return {*/}
-                                    {/*                             profiles: 
state.profiles,*/}
-                                    {/*                             profile: 
this.props.profiles.at(0) || Profile.createNew("application"),*/}
-                                    {/*                             tab: 
state.tab*/}
-                                    {/*                         };*/}
-                                    {/*                     })*/}
-                                    {/*                 }}*/}
-                                    {/*                 onChange={profileName 
=> {*/}
-                                    {/*                     const prof = 
profiles.find(p => p.name === profileName);*/}
-                                    {/*                     if (prof) {*/}
-                                    {/*                         
this.setState({profile: prof, key: Math.random().toString()});*/}
-                                    {/*                     } else {*/}
-                                    {/*                         
this.setState(state => {*/}
-                                    {/*                             const 
newProfile = Profile.createNew(profileName);*/}
-                                    {/*                             
newProfile.project = new ProjectModel(this.state.profile.project);*/}
-                                    {/*                             
state.profiles.push(newProfile);*/}
-                                    {/*                             return 
{profiles: state.profiles, profile: newProfile, tab: state.tab};*/}
-                                    {/*                         })*/}
-                                    {/*                     }*/}
-                                    {/*                 }}/>*/}
-                                </ToolbarItem>
-                            </ToolbarContent>
-                        </Toolbar>
-                    </FlexItem>
-                </Flex>
-            </PageSection>
-        )
-    }
-
-    onButtonClick(action: "start" | "stop" | "undeploy" | "run") {
-        this.props.onAction?.call(this, action, this.state.project);
-    }
-
-    getFooter() {
-        const active = false;
-        const label = active ? "Stop" : "Package";
-        const icon = active ? <InProgressIcon/> : <AutomationIcon/>;
-        return <div key={this.state.key} className="footer">
-            <div className="progress">
-                {active && this.getProgress()}
-            </div>
-            <div className="buttons">
-                <Toolbar id="toolbar-items">
-                    <ToolbarContent>
-                        {!active && <ToolbarItem>
-                            <Button variant="secondary" isSmall onClick={event 
=> this.onButtonClick("undeploy")}>Undeploy</Button>
-                        </ToolbarItem>}
-                        <ToolbarItem>
-                            <Button variant="primary" isSmall icon={icon} 
onClick={event => this.onButtonClick(active ? "stop" : 
"start")}>{label}</Button>
-                        </ToolbarItem>
-                        <ToolbarItem>
-                            <Button variant="primary" isSmall 
icon={<RunIcon/>} onClick={event => this.onButtonClick("run")}>Run</Button>
-                        </ToolbarItem>
-                    </ToolbarContent>
-                </Toolbar>
-            </div>
-        </div>
-    }
-
-    getPropertiesForm() {
-        return (
-            <div className="center">
-                <div className="center-column">
-                    <Card className="builder-card" isCompact style={{width: 
"100%"}}>
-                        {this.getCardHeader("Properties", <ClipboardIcon/>)}
-                        <CardBody>
-                            <PropertiesTable 
properties={this.state.project.properties}
-                                             onChange={properties => 
this.setState(state => {
-                                                 state.project.properties = 
properties;
-                                                 return state
-                                             })}/>
-                        </CardBody>
-                    </Card>
-                </div>
-            </div>
-        )
-    }
-
-    render() {
-        return (
-            <PageSection className="project-builder" variant={this.props.dark 
? PageSectionVariants.darker : PageSectionVariants.light}
-                         padding={{default: 'noPadding'}}>
-                <div style={{height: "100%", display: "flex", flexDirection: 
"column"}}>
-                    <div>
-                        {this.getHeader()}
-                    </div>
-                    <div style={{overflow: "auto", flexGrow: 1}}>
-                        {this.getPropertiesForm()}
-                    </div>
-                    <div>
-                        {this.getFooter()}
-                    </div>
-                </div>
-            </PageSection>
-        )
-    }
-}
\ No newline at end of file
diff --git a/karavan-designer/src/builder/FileSelector.tsx 
b/karavan-designer/src/builder/FileSelector.tsx
deleted file mode 100644
index ead44b9..0000000
--- a/karavan-designer/src/builder/FileSelector.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Button,
-    FormGroup,
-    Checkbox, PopoverPosition, Popover, InputGroup
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-
-interface Props {
-    label: string
-    help: string
-    files: string
-    filesSelected: string
-    onChange: (files: string) => void
-    source: boolean
-}
-
-interface State {
-    selected: []
-}
-
-export class FileSelector extends React.Component<Props, State> {
-
-    public state: State = {
-        selected: []
-    };
-
-    isChecked(file: string) {
-        const finalFile = this.props.source ? "file:" + file : file;
-        const s = this.props.filesSelected ? 
this.props.filesSelected.split(",").map(value => value.trim()) : [];
-        return s.includes(finalFile);
-    }
-
-    onChange(file: string, checked: boolean) {
-        const finalFile = this.props.source ? "file:" + file : file;
-        const s = this.props.filesSelected.split(",").map(f => 
f.trim()).filter(f => f.length > 0);
-        const already = s.includes(finalFile);
-        if (checked && !already) {
-            s.push(finalFile);
-            this.props.onChange?.call(this, s.join(","));
-        } else if (!checked) {
-            const result = s.filter(f => f !== finalFile);
-            this.props.onChange?.call(this, result.join(","));
-        }
-    }
-
-    getFiles(): string[] {
-        const allFiles = (this.props.files ? this.props.files.split(",") : []);
-        if (this.props.source){
-            const extensions = ['yaml', 'yml', 'java', 'js', 'kt', 'groovy', 
'xml'];
-            return  allFiles.filter(file => {
-                const extension = file.split(".").pop() || '';
-                return extensions.includes(extension);
-            }).map(file => file.replace("file:", ""))
-        }
-        return allFiles;
-    }
-
-    render() {
-        const files = this.getFiles();
-        return (
-            <FormGroup label={this.props.label} fieldId="files">
-                <InputGroup>
-                    <div style={{width:"100%"}}>
-                        {files.map(file => {
-                            const key = file + this.props.source;
-                            return <Checkbox key={key} label={file} 
isChecked={this.isChecked(file)} onChange={checked => this.onChange(file, 
checked)} id={key} name={key}/>
-                        })}
-                    </div>
-                    <Popover aria-label="files" position={PopoverPosition.left}
-                             bodyContent={this.props.help}>
-                        <Button variant="plain" onClick={e => {}}>
-                            <HelpIcon/>
-                        </Button>
-                    </Popover>
-                </InputGroup>
-            </FormGroup>
-        )
-    }
-};
\ No newline at end of file
diff --git a/karavan-designer/src/builder/ProfileSelector.tsx 
b/karavan-designer/src/builder/ProfileSelector.tsx
deleted file mode 100644
index ef140a4..0000000
--- a/karavan-designer/src/builder/ProfileSelector.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Button,
-    Flex,
-    FlexItem, Form, FormGroup, InputGroup, Modal, ModalVariant, Tab, Tabs, 
TextInput, ToggleGroup, ToggleGroupItem, Tooltip, TooltipPosition
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
-import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
-
-interface Props {
-    profiles: string[]
-    profile: string
-    onChange?: (profile: string) => void
-    onDelete?: (profile: string) => void
-}
-
-interface State {
-    isSelectorOpen?: boolean
-    showDeleteConfirmation?: boolean
-    showCreate?: boolean
-    newProfile?: string
-}
-
-export class ProfileSelector extends React.Component<Props, State> {
-
-    public state: State = {
-        isSelectorOpen: false,
-    };
-
-    onSelect(profile?: string){
-        if (profile) this.props.onChange?.call(this, profile);
-        this.setState({isSelectorOpen: false});
-    }
-
-    deleteProfile(){
-        if (this.props.profile) this.props.onDelete?.call(this, 
this.props.profile);
-        this.setState({showDeleteConfirmation: false});
-    }
-
-    saveAndCloseCreateModal = () => {
-        if (this.state.newProfile && this.state.newProfile.length > 0) 
this.props.onChange?.call(this, this.state.newProfile);
-        this.closeModal();
-    }
-
-    closeModal = () => {
-        this.setState({showCreate: false, newProfile: undefined});
-    }
-
-    onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {
-        if (event.key === 'Enter' && this.state.newProfile !== undefined) {
-            this.saveAndCloseCreateModal();
-        }
-    }
-
-    createModalForm() {
-        return (
-            <Modal
-                title="Create new profile"
-                className='profile-modal'
-                variant={ModalVariant.small}
-                isOpen={this.state.showCreate}
-                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>
-                    <FormGroup label="Profile" fieldId="profile" isRequired>
-                        <TextInput className="text-field" type="text" 
id="profile" name="profile"
-                                   value={this.state.newProfile}
-                                   onChange={e => this.setState({newProfile: 
e})}/>
-                    </FormGroup>
-                </Form>
-            </Modal>
-        )
-    }
-
-    getDeleteConfirmation() {
-        return (<Modal
-            className="modal-delete"
-            title="Confirmation"
-            isOpen={this.state.showDeleteConfirmation}
-            onClose={() => this.setState({showDeleteConfirmation: false})}
-            actions={[
-                <Button key="confirm" variant="primary" onClick={e => 
this.deleteProfile()}>Delete</Button>,
-                <Button key="cancel" variant="link"
-                        onClick={e => this.setState({showDeleteConfirmation: 
false})}>Cancel</Button>
-            ]}
-            onEscapePress={e => this.setState({showDeleteConfirmation: 
false})}>
-            <div>Delete profile {this.props.profile}</div>
-        </Modal>)
-    }
-
-    render() {
-        const profile = this.props.profile;
-        const tabs = this.props.profiles.map(p =>
-            <ToggleGroupItem key={p} text={p} buttonId={p} isSelected={profile 
=== p}
-                             onChange={selected => selected ? this.onSelect(p) 
: {}}/>
-        );
-        return (
-            <Flex>
-                <FlexItem>
-                    <p className="profile-caption">Profile:</p>
-                </FlexItem>
-                <FlexItem>
-                    <InputGroup>
-                        <Tooltip
-                            aria-label="Add profile"
-                            position={TooltipPosition.bottom}
-                            content="Create new profile">
-                            <Button variant={"plain"} icon={<AddIcon/>} 
onClick={event => this.setState({showCreate: true})}/>
-                        </Tooltip>
-                        <ToggleGroup aria-label="Select target">
-                            {tabs}
-                        </ToggleGroup>
-                        {this.props.profiles.length > 1 &&  <Tooltip
-                            aria-label="Delete profile"
-                            position={TooltipPosition.bottomEnd}
-                            content="Delete selected profile">
-                            <Button variant={"plain"} icon={<DeleteIcon/>} 
onClick={event => this.setState({showDeleteConfirmation: true})}/>
-                        </Tooltip>}
-                    </InputGroup>
-                </FlexItem>
-                {this.createModalForm()}
-                {this.getDeleteConfirmation()}
-            </Flex>
-        )
-    }
-}
\ No newline at end of file
diff --git a/karavan-designer/src/builder/PropertiesTable.tsx 
b/karavan-designer/src/builder/PropertiesTable.tsx
deleted file mode 100644
index e3f5958..0000000
--- a/karavan-designer/src/builder/PropertiesTable.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Button, Flex, FlexItem,
-    Modal,
-    PageSection,
-    Panel,
-    PanelMain,
-    PanelMainBody,
-    TextInput
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import {TableComposable, Tbody, Td, Th, Thead, Tr} from 
"@patternfly/react-table";
-import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
-import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {ProjectProperty} from "karavan-core/lib/model/ProjectModel";
-
-interface Props {
-    properties: ProjectProperty[]
-    onChange?: (properties: ProjectProperty[]) => void
-}
-
-interface State {
-    properties: ProjectProperty[]
-    showDeleteConfirmation: boolean
-    deleteId?: string
-}
-
-export class PropertiesTable extends React.Component<Props, State> {
-
-    public state: State = {
-        properties: this.props.properties,
-        showDeleteConfirmation: false,
-    };
-
-    sendUpdate = (props: ProjectProperty[]) => {
-        this.props.onChange?.call(this, props);
-    }
-
-    changeProperty(p: ProjectProperty, field: "key" | "value", val?: string) {
-        const key: string = field === 'key' && val !== undefined ? val : p.key;
-        const value: any = field === 'value' ? val : p.value;
-        const property: ProjectProperty = {id: p.id, key: key, value: value};
-        const props = this.state.properties.map(prop => prop.id === 
property.id ? property : prop);
-        this.setState({properties: props});
-        this.sendUpdate(props);
-    }
-
-    startDelete(id: string) {
-        this.setState({showDeleteConfirmation: true, deleteId: id});
-    }
-
-    confirmDelete() {
-        const props = this.state.properties.filter(p => p.id !== 
this.state.deleteId);
-        this.setState({properties: props, showDeleteConfirmation: false, 
deleteId: undefined});
-        this.sendUpdate(props);
-    }
-
-    addProperty() {
-        const props = [...this.state.properties];
-        props.push(ProjectProperty.createNew("", ""))
-        this.setState({properties: props, showDeleteConfirmation: false, 
deleteId: undefined});
-        this.sendUpdate(props);
-    }
-
-    getDeleteConfirmation() {
-        return (<Modal
-            className="modal-delete"
-            title="Confirmation"
-            isOpen={this.state.showDeleteConfirmation}
-            onClose={() => this.setState({showDeleteConfirmation: false})}
-            actions={[
-                <Button key="confirm" variant="primary" onClick={e => 
this.confirmDelete()}>Delete</Button>,
-                <Button key="cancel" variant="link"
-                        onClick={e => this.setState({showDeleteConfirmation: 
false})}>Cancel</Button>
-            ]}
-            onEscapePress={e => this.setState({showDeleteConfirmation: 
false})}>
-            <div>Delete property?</div>
-        </Modal>)
-    }
-
-    getTextInputField(property: ProjectProperty, field: "key" | "value", 
readOnly: boolean) {
-        return (<TextInput isDisabled={readOnly} isRequired={true} 
className="text-field" type={"text"} id={"key"} name={"key"}
-                           value={field === "key" ? property.key : 
property.value}
-                           onChange={val => this.changeProperty(property, 
field, val)}/>)
-    }
-
-    render() {
-        const properties = this.state.properties;
-        return (
-            <PageSection padding={{default: "noPadding"}}>
-                {properties.length > 0 &&
-                    <TableComposable aria-label="Property table" 
variant='compact' borders={false}
-                                     className="project-properties">
-                        <Thead>
-                            <Tr>
-                                <Th key='name'>Name</Th>
-                                <Th key='value'>Value</Th>
-                                <Td></Td>
-                            </Tr>
-                        </Thead>
-                        <Tbody>
-                            {properties.map((property, idx: number) => {
-                                const readOnly = 
property.key.startsWith("camel.jbang");
-                                return (
-                                    <Tr key={property.id}>
-                                        <Td noPadding width={20} 
dataLabel="key">{this.getTextInputField(property, "key", readOnly)}</Td>
-                                        <Td noPadding width={10} 
dataLabel="value">{this.getTextInputField(property, "value", readOnly)}</Td>
-                                        <Td noPadding isActionCell 
dataLabel="delete">
-                                            {!readOnly && <Button 
variant={"plain"} icon={<DeleteIcon/>} className={"delete-button"}
-                                                                  
onClick={event => this.startDelete(property.id)}/>}
-                                        </Td>
-                                    </Tr>
-                                )})}
-                        </Tbody>
-                    </TableComposable>}
-                <Panel>
-                    <PanelMain>
-                        <PanelMainBody>
-                            <Flex direction={{default:"row"}} >
-                                <FlexItem align={{ default: 'alignRight' }}>
-                                    <Button isInline variant={"primary"} 
icon={<PlusIcon/>}
-                                            className={"add-button"}
-                                            onClick={event => 
this.addProperty()}>Add property</Button>
-                                </FlexItem>
-                            </Flex>
-                        </PanelMainBody>
-                    </PanelMain>
-                </Panel>
-            </PageSection>
-        )
-    }
-}
\ No newline at end of file
diff --git a/karavan-vscode/package.json b/karavan-vscode/package.json
index 1cc46e5..135ec8e 100644
--- a/karavan-vscode/package.json
+++ b/karavan-vscode/package.json
@@ -381,7 +381,7 @@
     ]
   },
   "scripts": {
-    "copy-designer": "cp -r ../karavan-designer/src/designer webview && cp -r 
../karavan-designer/src/kamelets webview && cp -r 
../karavan-designer/src/components webview && cp -r ../karavan-designer/src/eip 
webview && cp -r ../karavan-designer/src/builder webview",
+    "copy-designer": "cp -r ../karavan-designer/src/designer webview && cp -r 
../karavan-designer/src/kamelets webview && cp -r 
../karavan-designer/src/components webview && cp -r ../karavan-designer/src/eip 
webview",
     "vscode:prepublish": "npm run copy-designer && npm run package",
     "compile": "npm run copy-designer && cross-env NODE_ENV=development 
webpack --progress",
     "watch": "npm run copy-designer && cross-env NODE_ENV=development webpack 
--progress --watch",
diff --git a/karavan-vscode/webview/builder/BuilderPage.tsx 
b/karavan-vscode/webview/builder/BuilderPage.tsx
deleted file mode 100644
index 43c27d5..0000000
--- a/karavan-vscode/webview/builder/BuilderPage.tsx
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Badge,
-    Button,
-    Card,
-    CardBody,
-    CardHeader,
-    CardHeaderMain,
-    CardTitle,
-    Flex,
-    FlexItem,
-    Form,
-    FormGroup,
-    InputGroup,
-    PageSection,
-    PageSectionVariants,
-    Popover,
-    PopoverPosition,
-    ProgressStep,
-    ProgressStepper,
-    Spinner,
-    Text,
-    TextContent,
-    TextInput,
-    Toolbar,
-    ToolbarContent,
-    ToolbarItem,
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-import InProgressIcon from 
'@patternfly/react-icons/dist/esm/icons/in-progress-icon';
-import AutomationIcon from 
'@patternfly/react-icons/dist/esm/icons/bundle-icon';
-import PendingIcon from '@patternfly/react-icons/dist/esm/icons/pending-icon';
-import ExclamationCircleIcon from 
'@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon';
-import CheckCircleIcon from 
'@patternfly/react-icons/dist/esm/icons/check-circle-icon';
-import ProjectIcon from '@patternfly/react-icons/dist/esm/icons/cubes-icon';
-import ClipboardIcon from 
'@patternfly/react-icons/dist/esm/icons/clipboard-icon';
-import RunIcon from '@patternfly/react-icons/dist/esm/icons/play-circle-icon';
-import {ProjectModel, StepStatus} from "karavan-core/lib/model/ProjectModel";
-import {PropertiesTable} from "./PropertiesTable";
-
-interface Props {
-    project: ProjectModel,
-    dark: boolean
-    files: string
-    onChange?: (project: ProjectModel) => void
-    onAction?: (action: "start" | "stop" | "undeploy" | "run", project: 
ProjectModel) => void
-}
-
-interface State {
-    project: ProjectModel,
-    key?: string,
-    isOpen?: boolean
-}
-
-export class BuilderPage extends React.Component<Props, State> {
-
-    public state: State = {
-        project: this.props.project,
-    };
-    interval: any;
-
-    componentDidUpdate = (prevProps: Readonly<Props>, prevState: 
Readonly<State>, snapshot?: any) => {
-        const project = this.state.project;
-        if (project) this.props.onChange?.call(this, project);
-    }
-
-    componentDidMount() {
-        this.interval = setInterval(() => this.setState(state => ({key: 
Math.random().toString()})), 1000);
-    }
-
-    componentWillUnmount() {
-        clearInterval(this.interval);
-    }
-
-    getHelp(text: string) {
-        return <Popover
-            aria-label={text}
-            position={PopoverPosition.left}
-            bodyContent={text}>
-            <Button variant="plain" onClick={e => {
-            }}>
-                <HelpIcon/>
-            </Button>
-        </Popover>
-    }
-
-    getField(name: string, label: string, type: 'text' | 'date' | 
'datetime-local' | 'email' | 'month' | 'number' | 'password' | 'search' | 'tel' 
| 'time' | 'url',
-             value: any, help: string, onChange: (val: any) => void, 
isRequired: boolean = false, enabled: boolean = true) {
-        return <FormGroup label={label} fieldId={name} isRequired={isRequired}>
-            <InputGroup>
-                <TextInput isRequired={isRequired} isDisabled={!enabled} 
className="text-field" type={type} id={name} name={name} value={value}
-                           onChange={val => onChange?.call(this, val)}/>
-                {this.getHelp(help)}
-            </InputGroup>
-        </FormGroup>
-    }
-
-    getCardHeader(title: string, icon: any) {
-        return <CardHeader>
-            <CardHeaderMain>
-                <CardTitle className="card-header">
-                    {icon}{title}
-                </CardTitle>
-            </CardHeaderMain>
-        </CardHeader>
-    }
-
-    getProjectForm() {
-        return (
-            <Card className="builder-card" isCompact style={{width: "100%"}}>
-                {this.getCardHeader("Artifact", <ProjectIcon/>)}
-                <CardBody>
-                    <Form isHorizontal>
-                        {/*{this.getField("name", "Name", "text", 
this.state.profile.project.name, "Project name",*/}
-                        {/*    val => this.setState(state => 
{state.profile.project.name= val; return state}), true)}*/}
-                        {/*{this.getField("version", "Version", "text", 
this.state.profile.project.version, "Project version",*/}
-                        {/*    val => this.setState(state => 
{state.profile.project.version= val; return state}), true)}*/}
-                    </Form>
-                </CardBody>
-            </Card>
-        )
-    }
-
-    getProgressIcon(status?: 'pending' | 'progress' | 'done' | 'error') {
-        switch (status) {
-            case "pending":
-                return <PendingIcon/>;
-            case "progress":
-                return <Spinner isSVG size="md"/>
-            case "done":
-                return <CheckCircleIcon/>;
-            case "error":
-                return <ExclamationCircleIcon/>;
-            default:
-                return undefined;
-        }
-    }
-
-    getDescription(stepStatus?: StepStatus) {
-        const now = Date.now();
-        let time = 0;
-        if (stepStatus?.status === 'progress') {
-            time = stepStatus?.startTime ? (now - stepStatus.startTime) / 1000 
: 0;
-        } else if (stepStatus?.status === 'done' && stepStatus?.endTime) {
-            time = (stepStatus?.endTime - stepStatus.startTime) / 1000
-        }
-        return time === 0 ? "" : Math.round(time) + "s";
-    }
-
-    getProgress() {
-        const {status} = this.state.project;
-        return (
-            <ProgressStepper isCenterAligned style={{visibility: "visible"}}>
-                <ProgressStep variant="pending" id="export" titleId="export" 
aria-label="export"
-                              description={this.getDescription(status.export)}
-                              
icon={this.getProgressIcon(status.export?.status)}>Export
-                </ProgressStep>
-                <ProgressStep variant="pending" isCurrent id="package" 
titleId="package" aria-label="package"
-                              description={this.getDescription(status.package)}
-                              
icon={this.getProgressIcon(status.package?.status)}>Package
-                </ProgressStep>
-            </ProgressStepper>
-        )
-    }
-
-    getHeader() {
-        return (
-            <PageSection className="tools-section" variant={this.props.dark ? 
PageSectionVariants.darker : PageSectionVariants.light}>
-                <Flex className="tools" direction={{default: 'row'}} 
justifyContent={{default: 'justifyContentSpaceBetween'}} spaceItems={{default: 
'spaceItemsLg'}}>
-                    <FlexItem>
-                        <TextContent className="header">
-                            <Text component="h2">Build Runner</Text>
-                            <Badge isRead className="labels">Powered by Camel 
JBang & Maven</Badge>
-                        </TextContent>
-                    </FlexItem>
-                    <FlexItem>
-                        <Toolbar id="toolbar-group-types">
-                            <ToolbarContent>
-                                <ToolbarItem>
-                                    {/*<ProfileSelector 
profiles={profiles.map(p => p.name)}*/}
-                                    {/*                 
profile={profile.name}*/}
-                                    {/*                 onDelete={profile => 
{*/}
-                                    {/*                     
this.setState(state => {*/}
-                                    {/*                         
state.profiles.splice(state.profiles.findIndex(p => p.name === profile), 1);*/}
-                                    {/*                         return {*/}
-                                    {/*                             profiles: 
state.profiles,*/}
-                                    {/*                             profile: 
this.props.profiles.at(0) || Profile.createNew("application"),*/}
-                                    {/*                             tab: 
state.tab*/}
-                                    {/*                         };*/}
-                                    {/*                     })*/}
-                                    {/*                 }}*/}
-                                    {/*                 onChange={profileName 
=> {*/}
-                                    {/*                     const prof = 
profiles.find(p => p.name === profileName);*/}
-                                    {/*                     if (prof) {*/}
-                                    {/*                         
this.setState({profile: prof, key: Math.random().toString()});*/}
-                                    {/*                     } else {*/}
-                                    {/*                         
this.setState(state => {*/}
-                                    {/*                             const 
newProfile = Profile.createNew(profileName);*/}
-                                    {/*                             
newProfile.project = new ProjectModel(this.state.profile.project);*/}
-                                    {/*                             
state.profiles.push(newProfile);*/}
-                                    {/*                             return 
{profiles: state.profiles, profile: newProfile, tab: state.tab};*/}
-                                    {/*                         })*/}
-                                    {/*                     }*/}
-                                    {/*                 }}/>*/}
-                                </ToolbarItem>
-                            </ToolbarContent>
-                        </Toolbar>
-                    </FlexItem>
-                </Flex>
-            </PageSection>
-        )
-    }
-
-    onButtonClick(action: "start" | "stop" | "undeploy" | "run") {
-        this.props.onAction?.call(this, action, this.state.project);
-    }
-
-    getFooter() {
-        const active = false;
-        const label = active ? "Stop" : "Package";
-        const icon = active ? <InProgressIcon/> : <AutomationIcon/>;
-        return <div key={this.state.key} className="footer">
-            <div className="progress">
-                {active && this.getProgress()}
-            </div>
-            <div className="buttons">
-                <Toolbar id="toolbar-items">
-                    <ToolbarContent>
-                        {!active && <ToolbarItem>
-                            <Button variant="secondary" isSmall onClick={event 
=> this.onButtonClick("undeploy")}>Undeploy</Button>
-                        </ToolbarItem>}
-                        <ToolbarItem>
-                            <Button variant="primary" isSmall icon={icon} 
onClick={event => this.onButtonClick(active ? "stop" : 
"start")}>{label}</Button>
-                        </ToolbarItem>
-                        <ToolbarItem>
-                            <Button variant="primary" isSmall 
icon={<RunIcon/>} onClick={event => this.onButtonClick("run")}>Run</Button>
-                        </ToolbarItem>
-                    </ToolbarContent>
-                </Toolbar>
-            </div>
-        </div>
-    }
-
-    getPropertiesForm() {
-        return (
-            <div className="center">
-                <div className="center-column">
-                    <Card className="builder-card" isCompact style={{width: 
"100%"}}>
-                        {this.getCardHeader("Properties", <ClipboardIcon/>)}
-                        <CardBody>
-                            <PropertiesTable 
properties={this.state.project.properties}
-                                             onChange={properties => 
this.setState(state => {
-                                                 state.project.properties = 
properties;
-                                                 return state
-                                             })}/>
-                        </CardBody>
-                    </Card>
-                </div>
-            </div>
-        )
-    }
-
-    render() {
-        return (
-            <PageSection className="project-builder" variant={this.props.dark 
? PageSectionVariants.darker : PageSectionVariants.light}
-                         padding={{default: 'noPadding'}}>
-                <div style={{height: "100%", display: "flex", flexDirection: 
"column"}}>
-                    <div>
-                        {this.getHeader()}
-                    </div>
-                    <div style={{overflow: "auto", flexGrow: 1}}>
-                        {this.getPropertiesForm()}
-                    </div>
-                    <div>
-                        {this.getFooter()}
-                    </div>
-                </div>
-            </PageSection>
-        )
-    }
-}
\ No newline at end of file
diff --git a/karavan-vscode/webview/builder/FileSelector.tsx 
b/karavan-vscode/webview/builder/FileSelector.tsx
deleted file mode 100644
index ead44b9..0000000
--- a/karavan-vscode/webview/builder/FileSelector.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Button,
-    FormGroup,
-    Checkbox, PopoverPosition, Popover, InputGroup
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import HelpIcon from "@patternfly/react-icons/dist/js/icons/help-icon";
-
-interface Props {
-    label: string
-    help: string
-    files: string
-    filesSelected: string
-    onChange: (files: string) => void
-    source: boolean
-}
-
-interface State {
-    selected: []
-}
-
-export class FileSelector extends React.Component<Props, State> {
-
-    public state: State = {
-        selected: []
-    };
-
-    isChecked(file: string) {
-        const finalFile = this.props.source ? "file:" + file : file;
-        const s = this.props.filesSelected ? 
this.props.filesSelected.split(",").map(value => value.trim()) : [];
-        return s.includes(finalFile);
-    }
-
-    onChange(file: string, checked: boolean) {
-        const finalFile = this.props.source ? "file:" + file : file;
-        const s = this.props.filesSelected.split(",").map(f => 
f.trim()).filter(f => f.length > 0);
-        const already = s.includes(finalFile);
-        if (checked && !already) {
-            s.push(finalFile);
-            this.props.onChange?.call(this, s.join(","));
-        } else if (!checked) {
-            const result = s.filter(f => f !== finalFile);
-            this.props.onChange?.call(this, result.join(","));
-        }
-    }
-
-    getFiles(): string[] {
-        const allFiles = (this.props.files ? this.props.files.split(",") : []);
-        if (this.props.source){
-            const extensions = ['yaml', 'yml', 'java', 'js', 'kt', 'groovy', 
'xml'];
-            return  allFiles.filter(file => {
-                const extension = file.split(".").pop() || '';
-                return extensions.includes(extension);
-            }).map(file => file.replace("file:", ""))
-        }
-        return allFiles;
-    }
-
-    render() {
-        const files = this.getFiles();
-        return (
-            <FormGroup label={this.props.label} fieldId="files">
-                <InputGroup>
-                    <div style={{width:"100%"}}>
-                        {files.map(file => {
-                            const key = file + this.props.source;
-                            return <Checkbox key={key} label={file} 
isChecked={this.isChecked(file)} onChange={checked => this.onChange(file, 
checked)} id={key} name={key}/>
-                        })}
-                    </div>
-                    <Popover aria-label="files" position={PopoverPosition.left}
-                             bodyContent={this.props.help}>
-                        <Button variant="plain" onClick={e => {}}>
-                            <HelpIcon/>
-                        </Button>
-                    </Popover>
-                </InputGroup>
-            </FormGroup>
-        )
-    }
-};
\ No newline at end of file
diff --git a/karavan-vscode/webview/builder/ProfileSelector.tsx 
b/karavan-vscode/webview/builder/ProfileSelector.tsx
deleted file mode 100644
index ef140a4..0000000
--- a/karavan-vscode/webview/builder/ProfileSelector.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Button,
-    Flex,
-    FlexItem, Form, FormGroup, InputGroup, Modal, ModalVariant, Tab, Tabs, 
TextInput, ToggleGroup, ToggleGroupItem, Tooltip, TooltipPosition
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon";
-import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
-
-interface Props {
-    profiles: string[]
-    profile: string
-    onChange?: (profile: string) => void
-    onDelete?: (profile: string) => void
-}
-
-interface State {
-    isSelectorOpen?: boolean
-    showDeleteConfirmation?: boolean
-    showCreate?: boolean
-    newProfile?: string
-}
-
-export class ProfileSelector extends React.Component<Props, State> {
-
-    public state: State = {
-        isSelectorOpen: false,
-    };
-
-    onSelect(profile?: string){
-        if (profile) this.props.onChange?.call(this, profile);
-        this.setState({isSelectorOpen: false});
-    }
-
-    deleteProfile(){
-        if (this.props.profile) this.props.onDelete?.call(this, 
this.props.profile);
-        this.setState({showDeleteConfirmation: false});
-    }
-
-    saveAndCloseCreateModal = () => {
-        if (this.state.newProfile && this.state.newProfile.length > 0) 
this.props.onChange?.call(this, this.state.newProfile);
-        this.closeModal();
-    }
-
-    closeModal = () => {
-        this.setState({showCreate: false, newProfile: undefined});
-    }
-
-    onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {
-        if (event.key === 'Enter' && this.state.newProfile !== undefined) {
-            this.saveAndCloseCreateModal();
-        }
-    }
-
-    createModalForm() {
-        return (
-            <Modal
-                title="Create new profile"
-                className='profile-modal'
-                variant={ModalVariant.small}
-                isOpen={this.state.showCreate}
-                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>
-                    <FormGroup label="Profile" fieldId="profile" isRequired>
-                        <TextInput className="text-field" type="text" 
id="profile" name="profile"
-                                   value={this.state.newProfile}
-                                   onChange={e => this.setState({newProfile: 
e})}/>
-                    </FormGroup>
-                </Form>
-            </Modal>
-        )
-    }
-
-    getDeleteConfirmation() {
-        return (<Modal
-            className="modal-delete"
-            title="Confirmation"
-            isOpen={this.state.showDeleteConfirmation}
-            onClose={() => this.setState({showDeleteConfirmation: false})}
-            actions={[
-                <Button key="confirm" variant="primary" onClick={e => 
this.deleteProfile()}>Delete</Button>,
-                <Button key="cancel" variant="link"
-                        onClick={e => this.setState({showDeleteConfirmation: 
false})}>Cancel</Button>
-            ]}
-            onEscapePress={e => this.setState({showDeleteConfirmation: 
false})}>
-            <div>Delete profile {this.props.profile}</div>
-        </Modal>)
-    }
-
-    render() {
-        const profile = this.props.profile;
-        const tabs = this.props.profiles.map(p =>
-            <ToggleGroupItem key={p} text={p} buttonId={p} isSelected={profile 
=== p}
-                             onChange={selected => selected ? this.onSelect(p) 
: {}}/>
-        );
-        return (
-            <Flex>
-                <FlexItem>
-                    <p className="profile-caption">Profile:</p>
-                </FlexItem>
-                <FlexItem>
-                    <InputGroup>
-                        <Tooltip
-                            aria-label="Add profile"
-                            position={TooltipPosition.bottom}
-                            content="Create new profile">
-                            <Button variant={"plain"} icon={<AddIcon/>} 
onClick={event => this.setState({showCreate: true})}/>
-                        </Tooltip>
-                        <ToggleGroup aria-label="Select target">
-                            {tabs}
-                        </ToggleGroup>
-                        {this.props.profiles.length > 1 &&  <Tooltip
-                            aria-label="Delete profile"
-                            position={TooltipPosition.bottomEnd}
-                            content="Delete selected profile">
-                            <Button variant={"plain"} icon={<DeleteIcon/>} 
onClick={event => this.setState({showDeleteConfirmation: true})}/>
-                        </Tooltip>}
-                    </InputGroup>
-                </FlexItem>
-                {this.createModalForm()}
-                {this.getDeleteConfirmation()}
-            </Flex>
-        )
-    }
-}
\ No newline at end of file
diff --git a/karavan-vscode/webview/builder/PropertiesTable.tsx 
b/karavan-vscode/webview/builder/PropertiesTable.tsx
deleted file mode 100644
index e3f5958..0000000
--- a/karavan-vscode/webview/builder/PropertiesTable.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-import React from 'react';
-import {
-    Button, Flex, FlexItem,
-    Modal,
-    PageSection,
-    Panel,
-    PanelMain,
-    PanelMainBody,
-    TextInput
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import {TableComposable, Tbody, Td, Th, Thead, Tr} from 
"@patternfly/react-table";
-import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
-import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {ProjectProperty} from "karavan-core/lib/model/ProjectModel";
-
-interface Props {
-    properties: ProjectProperty[]
-    onChange?: (properties: ProjectProperty[]) => void
-}
-
-interface State {
-    properties: ProjectProperty[]
-    showDeleteConfirmation: boolean
-    deleteId?: string
-}
-
-export class PropertiesTable extends React.Component<Props, State> {
-
-    public state: State = {
-        properties: this.props.properties,
-        showDeleteConfirmation: false,
-    };
-
-    sendUpdate = (props: ProjectProperty[]) => {
-        this.props.onChange?.call(this, props);
-    }
-
-    changeProperty(p: ProjectProperty, field: "key" | "value", val?: string) {
-        const key: string = field === 'key' && val !== undefined ? val : p.key;
-        const value: any = field === 'value' ? val : p.value;
-        const property: ProjectProperty = {id: p.id, key: key, value: value};
-        const props = this.state.properties.map(prop => prop.id === 
property.id ? property : prop);
-        this.setState({properties: props});
-        this.sendUpdate(props);
-    }
-
-    startDelete(id: string) {
-        this.setState({showDeleteConfirmation: true, deleteId: id});
-    }
-
-    confirmDelete() {
-        const props = this.state.properties.filter(p => p.id !== 
this.state.deleteId);
-        this.setState({properties: props, showDeleteConfirmation: false, 
deleteId: undefined});
-        this.sendUpdate(props);
-    }
-
-    addProperty() {
-        const props = [...this.state.properties];
-        props.push(ProjectProperty.createNew("", ""))
-        this.setState({properties: props, showDeleteConfirmation: false, 
deleteId: undefined});
-        this.sendUpdate(props);
-    }
-
-    getDeleteConfirmation() {
-        return (<Modal
-            className="modal-delete"
-            title="Confirmation"
-            isOpen={this.state.showDeleteConfirmation}
-            onClose={() => this.setState({showDeleteConfirmation: false})}
-            actions={[
-                <Button key="confirm" variant="primary" onClick={e => 
this.confirmDelete()}>Delete</Button>,
-                <Button key="cancel" variant="link"
-                        onClick={e => this.setState({showDeleteConfirmation: 
false})}>Cancel</Button>
-            ]}
-            onEscapePress={e => this.setState({showDeleteConfirmation: 
false})}>
-            <div>Delete property?</div>
-        </Modal>)
-    }
-
-    getTextInputField(property: ProjectProperty, field: "key" | "value", 
readOnly: boolean) {
-        return (<TextInput isDisabled={readOnly} isRequired={true} 
className="text-field" type={"text"} id={"key"} name={"key"}
-                           value={field === "key" ? property.key : 
property.value}
-                           onChange={val => this.changeProperty(property, 
field, val)}/>)
-    }
-
-    render() {
-        const properties = this.state.properties;
-        return (
-            <PageSection padding={{default: "noPadding"}}>
-                {properties.length > 0 &&
-                    <TableComposable aria-label="Property table" 
variant='compact' borders={false}
-                                     className="project-properties">
-                        <Thead>
-                            <Tr>
-                                <Th key='name'>Name</Th>
-                                <Th key='value'>Value</Th>
-                                <Td></Td>
-                            </Tr>
-                        </Thead>
-                        <Tbody>
-                            {properties.map((property, idx: number) => {
-                                const readOnly = 
property.key.startsWith("camel.jbang");
-                                return (
-                                    <Tr key={property.id}>
-                                        <Td noPadding width={20} 
dataLabel="key">{this.getTextInputField(property, "key", readOnly)}</Td>
-                                        <Td noPadding width={10} 
dataLabel="value">{this.getTextInputField(property, "value", readOnly)}</Td>
-                                        <Td noPadding isActionCell 
dataLabel="delete">
-                                            {!readOnly && <Button 
variant={"plain"} icon={<DeleteIcon/>} className={"delete-button"}
-                                                                  
onClick={event => this.startDelete(property.id)}/>}
-                                        </Td>
-                                    </Tr>
-                                )})}
-                        </Tbody>
-                    </TableComposable>}
-                <Panel>
-                    <PanelMain>
-                        <PanelMainBody>
-                            <Flex direction={{default:"row"}} >
-                                <FlexItem align={{ default: 'alignRight' }}>
-                                    <Button isInline variant={"primary"} 
icon={<PlusIcon/>}
-                                            className={"add-button"}
-                                            onClick={event => 
this.addProperty()}>Add property</Button>
-                                </FlexItem>
-                            </Flex>
-                        </PanelMainBody>
-                    </PanelMain>
-                </Panel>
-            </PageSection>
-        )
-    }
-}
\ No newline at end of file

Reply via email to