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 7a62be7 Saas feature32 (#423) 7a62be7 is described below commit 7a62be79beae316a1e07d6f91b792bff18adef61 Author: Marat Gubaidullin <marat.gubaidul...@gmail.com> AuthorDate: Mon Jul 25 17:38:38 2022 -0400 Saas feature32 (#423) * Vs code sync * Selectors Improvement --- .../org/apache/camel/karavan/api/GitResource.java | 5 - .../camel/karavan/api/KubernetesResource.java | 22 +- .../apache/camel/karavan/api/OpenApiResource.java | 91 ------- .../camel/karavan/service/GeneratorService.java | 3 +- .../camel/karavan/service/KubernetesService.java | 24 ++ karavan-builder/openshift/karavan-acl.yaml | 23 ++ .../openshift/karavan-quarkus-task.yaml | 3 - karavan-demo/postman/docs/README.md | 6 +- .../openshift-manifests/instances/amq-broker.yaml | 2 - .../openshift-manifests/instances/amq-streams.yaml | 1 - .../instances/kustomization.yaml | 1 - .../openshift-manifests/instances/postgresql.yaml | 2 - .../postman/openshift-manifests/kustomization.yaml | 8 - .../operators/kustomization.yaml | 1 - .../openshift-manifests/operators/namespace.yaml | 7 - .../operators/operator-group.yaml | 4 +- karavan-designer/src/designer/karavan.css | 1 + .../src/designer/route/DslSelector.tsx | 73 ++++-- .../src/designer/route/RouteDesigner.tsx | 54 ++-- .../designer/route/property/DslPropertyField.tsx | 12 +- .../route/property/KameletPropertyField.tsx | 12 +- .../designer/route/property/KubernetesSelector.tsx | 282 ++++++++++++--------- karavan-vscode/webview/builder/BuilderPage.tsx | 16 ++ karavan-vscode/webview/builder/FileSelector.tsx | 16 ++ karavan-vscode/webview/builder/ProfileSelector.tsx | 16 ++ karavan-vscode/webview/builder/PropertiesTable.tsx | 18 +- .../webview/components/ComponentCard.tsx | 17 +- .../webview/components/ComponentModal.tsx | 16 ++ .../webview/components/ComponentsPage.tsx | 16 ++ karavan-vscode/webview/eip/EipCard.tsx | 16 ++ karavan-vscode/webview/eip/EipModal.tsx | 16 ++ karavan-vscode/webview/eip/EipPage.tsx | 16 ++ karavan-vscode/webview/kamelets/KameletCard.tsx | 16 ++ karavan-vscode/webview/kamelets/KameletModal.tsx | 16 ++ karavan-vscode/webview/kamelets/KameletsPage.tsx | 16 ++ 35 files changed, 540 insertions(+), 308 deletions(-) diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java index 1907537..713d09b 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java @@ -16,7 +16,6 @@ */ package org.apache.camel.karavan.api; -import io.vertx.core.Vertx; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.model.ProjectFile; import org.apache.camel.karavan.service.GitService; @@ -37,10 +36,6 @@ public class GitResource { @Inject InfinispanService infinispanService; - - @Inject - Vertx vertx; - @Inject GitService gitService; diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java index 1a0476f..5654cf5 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java @@ -16,6 +16,10 @@ */ package org.apache.camel.karavan.api; +import io.smallrye.mutiny.Multi; +import io.vertx.core.json.JsonObject; +import io.vertx.mutiny.core.eventbus.EventBus; +import io.vertx.mutiny.core.eventbus.Message; import org.apache.camel.karavan.model.KaravanConfiguration; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.service.InfinispanService; @@ -33,12 +37,14 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.List; import java.util.Optional; @Path("/kubernetes") public class KubernetesResource { + @Inject + EventBus eventBus; + @Inject InfinispanService infinispanService; @@ -184,4 +190,18 @@ public class KubernetesResource { } return Response.noContent().build(); } + + // TODO: implement log watch + @GET + @Path("/container/log/watch/{environment}/{name}") + @Produces(MediaType.SERVER_SENT_EVENTS) + public Multi<String> getContainerLogWatch(@HeaderParam("username") String username, @PathParam("environment") String environment, @PathParam("name") String name){ + LOGGER.info("Start sourcing"); + Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); + if (env.isPresent()) { +// eventBus.publish(podName + "-" + namespace, new String(is.readNBytes(i))); +// kubernetesService.startContainerLogWatch(name, env.get().namespace()); + } + return eventBus.<String>consumer(name + "-" + env.get().namespace()).toMulti().map(Message::body); + } } \ No newline at end of file diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/OpenApiResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/OpenApiResource.java deleted file mode 100644 index 2dd93d4..0000000 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/OpenApiResource.java +++ /dev/null @@ -1,91 +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. - */ -package org.apache.camel.karavan.api; - -import org.apache.camel.karavan.service.GeneratorService; -import org.apache.camel.karavan.service.GitService; -import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.microprofile.config.inject.ConfigProperty; - -import javax.inject.Inject; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import java.io.IOException; -import java.util.Map; -import java.util.stream.Collectors; - -@Path("/openapi") -public class OpenApiResource { - - private static final String GITOPS_MODE = "gitops"; - private static final String SERVERLESS_MODE = "serverless"; - - @ConfigProperty(name = "karavan.mode", defaultValue = "local") - String mode; - -// @Inject -// FileSystemService fileSystemService; - - @Inject - GeneratorService generatorService; - - @Inject - GitService gitService; - -// @GET -// @Produces(MediaType.APPLICATION_JSON) -// public Map<String, String> getList(@HeaderParam("username") String username) throws GitAPIException { -// if (mode.endsWith(GITOPS_MODE)) { -// String dir = gitService.pullIntegrations(username); -// return fileSystemService.getOpenApiList(dir).stream().collect(Collectors.toMap(s -> s, s-> "")); -// } else { -// return fileSystemService.getOpenApiList().stream().collect(Collectors.toMap(s -> s, s-> "")); -// } -// } -// -// @GET -// @Produces(MediaType.TEXT_PLAIN) -// @Path("/{name}") -// public String getJson(@HeaderParam("username") String username, @PathParam("name") String name) throws GitAPIException { -// switch (mode){ -// case GITOPS_MODE: -// String dir = gitService.pullIntegrations(username); -// return fileSystemService.getFile(dir, name); -// default: -// return fileSystemService.getIntegrationsFile(name); -// } -// } -// -// @POST -// @Produces(MediaType.TEXT_PLAIN) -// @Consumes(MediaType.TEXT_PLAIN) -// @Path("/{name}/{generateRest}/{generateRoutes}/{integrationName}") -// public String save(@HeaderParam("username") String username, -// @PathParam("name") String name, -// @PathParam("integrationName") String integrationName, -// @PathParam("generateRest") boolean generateRest, -// @PathParam("generateRoutes") boolean generateRoutes, -// String json) throws Exception { -// fileSystemService.saveIntegrationsFile(name, json); -// if (generateRest) { -// String yaml = generatorService.generate(json, generateRoutes); -// fileSystemService.saveIntegrationsFile(integrationName, yaml); -// return yaml; -// } -// return json; -// } -} \ No newline at end of file diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java index ffcae12..c8227f2 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java @@ -71,11 +71,12 @@ public class GeneratorService { s.append("camel.health.enabled=true").append(System.lineSeparator()); s.append("camel.health.exposure-level=full").append(System.lineSeparator()); + s.append("quarkus.kubernetes-client.trust-certs=true").append(System.lineSeparator()); s.append("quarkus.container-image.group=").append(imageGroup).append(System.lineSeparator()); s.append("quarkus.container-image.name=").append(project.getProjectId()).append(System.lineSeparator()); s.append("quarkus.openshift.route.expose=false").append(System.lineSeparator()); s.append("quarkus.openshift.part-of=").append(project.getProjectId()).append(System.lineSeparator()); - s.append("quarkus.kubernetes-client.trust-certs=true").append(System.lineSeparator()); + s.append("quarkus.openshift.replicas=1").append(System.lineSeparator()); return s.toString(); } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java index 4e76a63..efa64f5 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java @@ -22,6 +22,7 @@ import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.dsl.LogWatch; import io.fabric8.openshift.api.model.DeploymentConfig; import io.fabric8.openshift.api.model.ImageStream; import io.fabric8.openshift.client.OpenShiftClient; @@ -34,6 +35,8 @@ import io.fabric8.tekton.pipeline.v1beta1.PipelineRunBuilder; import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpec; import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpecBuilder; import io.fabric8.tekton.pipeline.v1beta1.WorkspaceBindingBuilder; +import io.vertx.core.json.JsonObject; +import io.vertx.mutiny.core.eventbus.EventBus; import org.apache.camel.karavan.model.DeploymentStatus; import org.apache.camel.karavan.model.PipelineRunLog; import org.apache.camel.karavan.model.PodStatus; @@ -43,6 +46,9 @@ import org.jboss.logging.Logger; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; +import javax.inject.Inject; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -53,6 +59,9 @@ import java.util.stream.Collectors; @ApplicationScoped public class KubernetesService { + @Inject + EventBus eventBus; + @ConfigProperty(name = "kubernetes.namespace", defaultValue = "localhost") String currentNamespace; @@ -116,6 +125,21 @@ public class KubernetesService { return logText; } + + // TODO: implement log watch + public void startContainerLogWatch(String podName, String namespace) { + LogWatch logWatch = kubernetesClient().pods().inNamespace(namespace).withName(podName).watchLog(); + InputStream is = logWatch.getOutput(); + Integer i; + try { + while ((i = is.available()) != null) { + eventBus.publish(podName + "-" + namespace, new String(is.readNBytes(i))); + } + } catch (IOException e){ + LOGGER.error(e); + } + } + public List<PipelineRunLog> getPipelineRunLog(String pipelineRuneName, String namespace) { List<PipelineRunLog> result = new ArrayList<>(1); PipelineRun pipelineRun = getPipelineRun(pipelineRuneName, namespace); diff --git a/karavan-builder/openshift/karavan-acl.yaml b/karavan-builder/openshift/karavan-acl.yaml index eb86382..ec92c7f 100644 --- a/karavan-builder/openshift/karavan-acl.yaml +++ b/karavan-builder/openshift/karavan-acl.yaml @@ -77,4 +77,27 @@ roleRef: subjects: - kind: ServiceAccount name: karavan + namespace: karavan +--- +# Pipeline shoulf have access to create rolebindings +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: karavan-pipeline-rolebindings +rules: + - apiGroups: ["", "rbac.authorization.k8s.io"] + resources: ["rolebindings"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: karavan-pipeline-rolebindings +roleRef: + kind: Role + apiGroup: rbac.authorization.k8s.io + name: karavan-pipeline-rolebindings +subjects: + - kind: ServiceAccount + name: pipeline namespace: karavan \ No newline at end of file diff --git a/karavan-builder/openshift/karavan-quarkus-task.yaml b/karavan-builder/openshift/karavan-quarkus-task.yaml index 1acfe14..f58101f 100644 --- a/karavan-builder/openshift/karavan-quarkus-task.yaml +++ b/karavan-builder/openshift/karavan-quarkus-task.yaml @@ -12,9 +12,6 @@ spec: #!/usr/bin/env bash CHECKOUT_DIR="/scripts" - ls -la $(workspaces.m2-cache.path) - ls -la $(workspaces.jbang-cache.path) - if [[ $GIT_REPOSITORY == https* ]] ; then replacer=https://$GIT_PASSWORD@ diff --git a/karavan-demo/postman/docs/README.md b/karavan-demo/postman/docs/README.md index 7b4bb6d..fc9b2b6 100644 --- a/karavan-demo/postman/docs/README.md +++ b/karavan-demo/postman/docs/README.md @@ -58,7 +58,7 @@ Send message to `payments` queue ### Install AMQ and AMQ Streams Operators -Also creates `postman` namespace required for the demo +Also creates `karavan` namespace required for the demo ``` cd ../openshift-manifests oc login --token=... --server=... @@ -69,7 +69,7 @@ Check that operators are succesfully installed ### Create AMQ, Kafka and Postgres demo instances ``` -oc apply -k instances +oc apply -k instances -n karavan ``` ### Package, build and deploy project @@ -86,7 +86,7 @@ oc apply -k instances ``` appsurl=$(oc get ingresses.config.openshift.io cluster -o template --template '{{.spec.domain}}') -curl -X POST -H "Content-Type: application/json" --data '{"id":"1","address":"666 Sin Street, Holy City"}' http://postman-postman.$appsurl/parcels +curl -X POST -H "Content-Type: application/json" --data '{"id":"1","address":"666 Sin Street, Holy City"}' http://postman-karavan.$appsurl/parcels ``` ### Publish payment Open AMQ7 Broker Management diff --git a/karavan-demo/postman/openshift-manifests/instances/amq-broker.yaml b/karavan-demo/postman/openshift-manifests/instances/amq-broker.yaml index e83b987..7d307bb 100644 --- a/karavan-demo/postman/openshift-manifests/instances/amq-broker.yaml +++ b/karavan-demo/postman/openshift-manifests/instances/amq-broker.yaml @@ -3,7 +3,6 @@ kind: ActiveMQArtemis metadata: name: amq application: amq - namespace: postman spec: acceptors: - port: 61616 @@ -39,7 +38,6 @@ kind: Route apiVersion: route.openshift.io/v1 metadata: name: console - namespace: amq spec: to: kind: Service diff --git a/karavan-demo/postman/openshift-manifests/instances/amq-streams.yaml b/karavan-demo/postman/openshift-manifests/instances/amq-streams.yaml index bd1ba85..be6dda8 100644 --- a/karavan-demo/postman/openshift-manifests/instances/amq-streams.yaml +++ b/karavan-demo/postman/openshift-manifests/instances/amq-streams.yaml @@ -2,7 +2,6 @@ kind: Kafka apiVersion: kafka.strimzi.io/v1beta2 metadata: name: kafka - namespace: postman spec: kafka: version: 3.1.0 diff --git a/karavan-demo/postman/openshift-manifests/instances/kustomization.yaml b/karavan-demo/postman/openshift-manifests/instances/kustomization.yaml index e0c09bd..70b1557 100644 --- a/karavan-demo/postman/openshift-manifests/instances/kustomization.yaml +++ b/karavan-demo/postman/openshift-manifests/instances/kustomization.yaml @@ -1,6 +1,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namespace: postman resources: - postgresql.yaml - amq-broker.yaml diff --git a/karavan-demo/postman/openshift-manifests/instances/postgresql.yaml b/karavan-demo/postman/openshift-manifests/instances/postgresql.yaml index fe33b72..caed382 100644 --- a/karavan-demo/postman/openshift-manifests/instances/postgresql.yaml +++ b/karavan-demo/postman/openshift-manifests/instances/postgresql.yaml @@ -9,7 +9,6 @@ metadata: app.openshift.io/runtime: postgres deploymentconfig: postgres name: postgres - namespace: postman annotations: argocd.argoproj.io/sync-options: Validate=false spec: @@ -154,7 +153,6 @@ metadata: app.kubernetes.io/instance: postgres app.kubernetes.io/part-of: postgres name: postgres - namespace: postman spec: ports: - name: postgresql diff --git a/karavan-demo/postman/openshift-manifests/kustomization.yaml b/karavan-demo/postman/openshift-manifests/kustomization.yaml deleted file mode 100644 index e011f60..0000000 --- a/karavan-demo/postman/openshift-manifests/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - namespace.yaml - - ./operators - # - ../postgres - - ./amq - - ./amq-streams diff --git a/karavan-demo/postman/openshift-manifests/operators/kustomization.yaml b/karavan-demo/postman/openshift-manifests/operators/kustomization.yaml index 01a6fbb..28eb264 100644 --- a/karavan-demo/postman/openshift-manifests/operators/kustomization.yaml +++ b/karavan-demo/postman/openshift-manifests/operators/kustomization.yaml @@ -2,7 +2,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - namespace.yaml - operator-group.yaml - amq-operator.yaml - amq-streams-operator.yaml diff --git a/karavan-demo/postman/openshift-manifests/operators/namespace.yaml b/karavan-demo/postman/openshift-manifests/operators/namespace.yaml deleted file mode 100644 index 6a1655c..0000000 --- a/karavan-demo/postman/openshift-manifests/operators/namespace.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - annotations: - openshift.io/description: postman - openshift.io/display-name: postman - name: postman diff --git a/karavan-demo/postman/openshift-manifests/operators/operator-group.yaml b/karavan-demo/postman/openshift-manifests/operators/operator-group.yaml index 09b869c..fbbcc6c 100644 --- a/karavan-demo/postman/openshift-manifests/operators/operator-group.yaml +++ b/karavan-demo/postman/openshift-manifests/operators/operator-group.yaml @@ -1,7 +1,7 @@ apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: - name: postman + name: karavan spec: targetNamespaces: - - postman + - karavan diff --git a/karavan-designer/src/designer/karavan.css b/karavan-designer/src/designer/karavan.css index bf5ba84..edad6d2 100644 --- a/karavan-designer/src/designer/karavan.css +++ b/karavan-designer/src/designer/karavan.css @@ -489,6 +489,7 @@ .karavan .dsl-page .flows { width: 100%; position: relative; + margin-bottom: 80px; } .karavan .dsl-page .flows .add-flow { diff --git a/karavan-designer/src/designer/route/DslSelector.tsx b/karavan-designer/src/designer/route/DslSelector.tsx index 54612c8..73b5c35 100644 --- a/karavan-designer/src/designer/route/DslSelector.tsx +++ b/karavan-designer/src/designer/route/DslSelector.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { Badge, - Card, CardBody, CardFooter, CardHeader, Form, FormGroup, Gallery, PageSection, + Card, CardBody, CardFooter, CardHeader, Flex, FlexItem, Form, FormGroup, Gallery, Modal, PageSection, Tab, Tabs, TabTitleText, Text, TextInput, } from '@patternfly/react-core'; @@ -28,10 +28,12 @@ import {CamelUtil} from "karavan-core/lib/api/CamelUtil"; interface Props { onDslSelect: (dsl: DslMetaModel, parentId: string, position?: number | undefined) => void, + onClose?: () => void, parentId: string, parentDsl?: string, showSteps: boolean, dark: boolean, + isOpen: boolean, position?: number tabIndex?: string | number } @@ -45,10 +47,11 @@ export class DslSelector extends React.Component<Props, State> { public state: State = { tabIndex: this.props.tabIndex ? this.props.tabIndex : CamelUi.getSelectorModelTypes(this.props.parentDsl, this.props.showSteps)[0][0], - }; + } selectTab = (evt: React.MouseEvent<HTMLElement, MouseEvent>, eventKey: string | number) => { + console.log(eventKey) this.setState({tabIndex: eventKey}) } @@ -103,7 +106,8 @@ export class DslSelector extends React.Component<Props, State> { </div>} {dsl.navigation.toLowerCase() === "component" && <div className="footer" style={{justifyContent: "flex-start"}}> - {dsl.labels.split(',').map((s: string) => <Badge key={s} isRead className="labels">{s}</Badge>)} + {dsl.labels.split(',').map((s: string, i: number) => <Badge key={s + i} isRead + className="labels">{s}</Badge>)} <Badge isRead className="version">{dsl.version}</Badge> </div> } @@ -114,26 +118,49 @@ export class DslSelector extends React.Component<Props, State> { render() { const parentDsl = this.props.parentDsl; + const title = parentDsl === undefined ? "Select source/from" : "Select step"; + const labelText: string = this.state.tabIndex ? this.state.tabIndex.toString() : ""; return ( - <PageSection variant={this.props.dark ? "darker" : "light"}> - {this.searchInput()} - <Tabs data-tour="selector-tabs" style={{overflow: 'hidden'}} activeKey={this.state.tabIndex} onSelect={this.selectTab}> - {CamelUi.getSelectorModelTypes(parentDsl, this.props.showSteps).map((label: [string, number], index: number) => { - const labelText = label[0]; - const count = label[1]; - const title = ['kamelet', 'component'].includes(labelText.toLowerCase()) ? labelText+"s (" + count + ")" : labelText; - return ( - <Tab eventKey={labelText} key={"tab-" + labelText} title={<TabTitleText>{CamelUtil.capitalizeName(title)}</TabTitleText>}> - <Gallery key={"gallery-" + labelText} hasGutter className="dsl-gallery"> - {CamelUi.getSelectorModelsForParentFiltered(parentDsl, labelText, this.props.showSteps) - .filter((dsl: DslMetaModel) => this.checkFilter(dsl)) - .map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))} - </Gallery> - </Tab> - ) - })} - </Tabs> - </PageSection> - ); + <Modal + aria-label={title} + data-tour="selector" + width={'90%'} + className='dsl-modal' + isOpen={this.props.isOpen} + onClose={this.props.onClose} + header={ + <Flex direction={{default: "column"}}> + <FlexItem> + <h3>{title}</h3> + {this.searchInput()} + </FlexItem> + <FlexItem> + <Tabs data-tour="selector-tabs" style={{overflow: 'hidden'}} activeKey={this.state.tabIndex} + onSelect={this.selectTab}> + {CamelUi.getSelectorModelTypes(parentDsl, this.props.showSteps).map((label: [string, number], index: number) => { + const labelText = label[0]; + const count = label[1]; + const title = ['kamelet', 'component'].includes(labelText.toLowerCase()) ? labelText + "s (" + count + ")" : labelText; + return ( + <Tab eventKey={labelText} key={"tab-" + labelText} + title={<TabTitleText>{CamelUtil.capitalizeName(title)}</TabTitleText>}> + </Tab> + ) + })} + </Tabs> + </FlexItem> + </Flex> + } + actions={{}}> + <PageSection variant={this.props.dark ? "darker" : "light"}> + + <Gallery key={"gallery-" + labelText} hasGutter className="dsl-gallery"> + {CamelUi.getSelectorModelsForParentFiltered(parentDsl, labelText, this.props.showSteps) + .filter((dsl: DslMetaModel) => this.checkFilter(dsl)) + .map((dsl: DslMetaModel, index: number) => this.getCard(dsl, index))} + </Gallery> + </PageSection> + </Modal> + ) } } \ No newline at end of file diff --git a/karavan-designer/src/designer/route/RouteDesigner.tsx b/karavan-designer/src/designer/route/RouteDesigner.tsx index 85dbad7..bae6794 100644 --- a/karavan-designer/src/designer/route/RouteDesigner.tsx +++ b/karavan-designer/src/designer/route/RouteDesigner.tsx @@ -21,7 +21,7 @@ import { DrawerContent, DrawerContentBody, Button, Modal, - PageSection + PageSection, Flex, FlexItem, Text } from '@patternfly/react-core'; import '../karavan.css'; import {DslSelector} from "./DslSelector"; @@ -124,15 +124,22 @@ export class RouteDesigner extends React.Component<Props, State> { this.openSelector(step?.uuid, !step?.dslName ? undefined : "FromDefinition", true, undefined, event.selectorTabIndex) break; case "closeSelector": - if (event.step){ + if (event.step) { const clone = CamelUtil.cloneIntegration(this.props.integration); - this.setState({integration: clone, key: Math.random().toString(), showSelector: false, selectedStep: event.step, selectedUuid: event.step.uuid, propertyOnly: false }); + this.setState({ + integration: clone, + key: Math.random().toString(), + showSelector: false, + selectedStep: event.step, + selectedUuid: event.step.uuid, + propertyOnly: false + }); } else { this.setState({showSelector: false, key: Math.random().toString()}); } break; case "selectElement": - if (event.step) this.selectElement( event.step); + if (event.step) this.selectElement(event.step); break; } } @@ -223,7 +230,14 @@ export class RouteDesigner extends React.Component<Props, State> { } openSelector = (parentId: string | undefined, parentDsl: string | undefined, showSteps: boolean = true, position?: number | undefined, selectorTabIndex?: string | number) => { - this.setState({showSelector: true, parentId: parentId || '', parentDsl: parentDsl, showSteps: showSteps, selectedPosition: position, selectorTabIndex: selectorTabIndex}) + this.setState({ + showSelector: true, + parentId: parentId || '', + parentDsl: parentDsl, + showSteps: showSteps, + selectedPosition: position, + selectorTabIndex: selectorTabIndex + }) } closeDslSelector = () => { @@ -295,23 +309,16 @@ export class RouteDesigner extends React.Component<Props, State> { getSelectorModal() { return ( - <Modal - data-tour="selector" - title={this.state.parentDsl === undefined ? "Select source/from" : "Select step"} - width={'90%'} - className='dsl-modal' + <DslSelector isOpen={this.state.showSelector} onClose={() => this.closeDslSelector()} - actions={{}}> - <DslSelector - dark={this.props.dark} - parentId={this.state.parentId} - parentDsl={this.state.parentDsl} - showSteps={this.state.showSteps} - position={this.state.selectedPosition} - tabIndex={this.state.selectorTabIndex} - onDslSelect={this.onDslSelect}/> - </Modal>) + dark={this.props.dark} + parentId={this.state.parentId} + parentDsl={this.state.parentDsl} + showSteps={this.state.showSteps} + position={this.state.selectedPosition} + tabIndex={this.state.selectorTabIndex} + onDslSelect={this.onDslSelect}/>) } getDeleteConfirmation() { @@ -335,7 +342,9 @@ export class RouteDesigner extends React.Component<Props, State> { getPropertiesPanel() { return ( - <DrawerPanelContent onResize={width => this.setState({key: Math.random().toString(1)})} style={{transform: "initial"}} isResizable hasNoBorder defaultSize={'400px'} maxSize={'800px'} minSize={'300px'}> + <DrawerPanelContent onResize={width => this.setState({key: Math.random().toString(1)})} + style={{transform: "initial"}} isResizable hasNoBorder defaultSize={'400px'} + maxSize={'800px'} minSize={'300px'}> <DslProperties ref={this.state.ref} integration={this.state.integration} step={this.state.selectedStep} @@ -353,7 +362,8 @@ export class RouteDesigner extends React.Component<Props, State> { const routes = CamelUi.getRoutes(this.state.integration); return ( <div className="graph"> - <DslConnections height={this.state.height} width={this.state.width} top={this.state.top} left={this.state.left} integration={this.state.integration}/> + <DslConnections height={this.state.height} width={this.state.width} top={this.state.top} + left={this.state.left} integration={this.state.integration}/> <div className="flows" data-click="FLOWS" onClick={event => this.unselectElement(event)} ref={el => this.onResizePage(el)}> {routes?.map((route: any, index: number) => ( diff --git a/karavan-designer/src/designer/route/property/DslPropertyField.tsx b/karavan-designer/src/designer/route/property/DslPropertyField.tsx index 9141da0..fb74c51 100644 --- a/karavan-designer/src/designer/route/property/DslPropertyField.tsx +++ b/karavan-designer/src/designer/route/property/DslPropertyField.tsx @@ -169,17 +169,11 @@ export class DslPropertyField extends React.Component<Props, State> { getKubernetesSelectorModal() { return ( - <Modal - title="Select from Kubernetes" - width={'50%'} - className='dsl-modal' + <KubernetesSelector + dark={false} isOpen={this.state.showKubernetesSelector} onClose={() => this.closeKubernetesSelector()} - actions={{}}> - <KubernetesSelector - dark={false} - onSelect={this.selectKubernetes}/> - </Modal>) + onSelect={this.selectKubernetes}/>) } getStringInput = (property: PropertyMeta, value: any) => { diff --git a/karavan-designer/src/designer/route/property/KameletPropertyField.tsx b/karavan-designer/src/designer/route/property/KameletPropertyField.tsx index e48b23c..eb2be0a 100644 --- a/karavan-designer/src/designer/route/property/KameletPropertyField.tsx +++ b/karavan-designer/src/designer/route/property/KameletPropertyField.tsx @@ -84,17 +84,11 @@ export class KameletPropertyField extends React.Component<Props, State> { getKubernetesSelectorModal() { return ( - <Modal - title="Select from Kubernetes" - width={'50%'} - className='dsl-modal' + <KubernetesSelector + dark={false} isOpen={this.state.showKubernetesSelector} onClose={() => this.closeKubernetesSelector()} - actions={{}}> - <KubernetesSelector - dark={false} - onSelect={this.selectKubernetes}/> - </Modal>) + onSelect={this.selectKubernetes}/>) } getStringInput() { diff --git a/karavan-designer/src/designer/route/property/KubernetesSelector.tsx b/karavan-designer/src/designer/route/property/KubernetesSelector.tsx index 88c97b7..99ee3ba 100644 --- a/karavan-designer/src/designer/route/property/KubernetesSelector.tsx +++ b/karavan-designer/src/designer/route/property/KubernetesSelector.tsx @@ -17,16 +17,20 @@ import React from 'react'; import { Badge, - Button, - Form, FormGroup, PageSection, + Button, Flex, FlexItem, + Form, FormGroup, Modal, PageSection, Tab, Tabs, TabTitleText, TextInput, } from '@patternfly/react-core'; import '../../karavan.css'; import {TableComposable, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table"; import {KubernetesAPI} from "../../utils/KubernetesAPI"; +import {CamelUi} from "../../utils/CamelUi"; +import {CamelUtil} from "../../../../../../../../karavan-core/lib/api/CamelUtil"; interface Props { onSelect: (value: string) => void, + onClose?: () => void, + isOpen: boolean, dark: boolean, } @@ -71,123 +75,171 @@ export class KubernetesSelector extends React.Component<Props, State> { ) } - render() { + getConfigMapTable() { const configMaps = this.state.configMaps; - console.log(configMaps); - const secrets = this.state.secrets; - const services = this.state.services; - console.log(services); return ( - <PageSection variant={this.props.dark ? "darker" : "light"}> - {this.searchInput()} - <Tabs data-tour="selector-tabs" style={{overflow: 'hidden'}} activeKey={this.state.tabIndex} onSelect={this.selectTab}> - <Tab eventKey={"configMap"} key={"configMap"} title={<TabTitleText>ConfigMaps</TabTitleText>}> - <TableComposable variant='compact' borders={false}> - <Thead> - <Tr> - <Th/> - <Th key='name'>Name</Th> - <Th key='data'>Data</Th> + <TableComposable variant='compact' borders={false}> + <Thead> + <Tr> + <Th/> + <Th key='name'>Name</Th> + <Th key='data'>Data</Th> + </Tr> + </Thead> + <Tbody> + {configMaps + .filter(name => this.checkFilter(name)) + .map((name, idx: number) => { + const configMapName = name.split("/")[0]; + const data = name.split("/")[1]; + return ( + <Tr key={name}> + <Td noPadding isActionCell> + <Badge>CM</Badge> + </Td> + <Td noPadding> + {configMapName} + </Td> + <Td noPadding> + <Button style={{padding: '6px'}} variant={"link"} onClick={ + e => this.props.onSelect?.call(this, "configmap:" + name)}> + {data} + </Button> + </Td> </Tr> - </Thead> - <Tbody> - {configMaps - .filter(name => this.checkFilter(name)) - .map((name, idx: number) => { - const configMapName = name.split("/")[0]; - const data = name.split("/")[1]; - return ( - <Tr key={name}> - <Td noPadding isActionCell> - <Badge>CM</Badge> - </Td> - <Td noPadding> - {configMapName} - </Td> - <Td noPadding> - <Button style={{padding: '6px'}} variant={"link"} onClick={ - e => this.props.onSelect?.call(this, "configmap:" + name)}> - {data} - </Button> - </Td> - </Tr> - ) - })} - </Tbody> - </TableComposable> - </Tab> - <Tab eventKey={"secret"} key={"secret"} title={<TabTitleText>Secrets</TabTitleText>}> - <TableComposable variant='compact' borders={false}> - <Thead> - <Tr> - <Th/> - <Th key='name'>Name</Th> - <Th key='data'>Data</Th> + ) + })} + </Tbody> + </TableComposable> + ) + } + + getSecretsTable() { + const secrets = this.state.secrets; + return ( + <TableComposable variant='compact' borders={false}> + <Thead> + <Tr> + <Th/> + <Th key='name'>Name</Th> + <Th key='data'>Data</Th> + </Tr> + </Thead> + <Tbody> + {secrets + .filter(name => this.checkFilter(name)) + .map((name, idx: number) => { + const configMapName = name.split("/")[0]; + const data = name.split("/")[1]; + return ( + <Tr key={name}> + <Td noPadding isActionCell> + <Badge>S</Badge> + </Td> + <Td noPadding> + {configMapName} + </Td> + <Td noPadding> + <Button style={{padding: '6px'}} variant={"link"} onClick={ + e => this.props.onSelect?.call(this, "secret:" + name)}> + {data} + </Button> + </Td> </Tr> - </Thead> - <Tbody> - {secrets - .filter(name => this.checkFilter(name)) - .map((name, idx: number) => { - const configMapName = name.split("/")[0]; - const data = name.split("/")[1]; - return ( - <Tr key={name}> - <Td noPadding isActionCell> - <Badge>S</Badge> - </Td> - <Td noPadding> - {configMapName} - </Td> - <Td noPadding> - <Button style={{padding: '6px'}} variant={"link"} onClick={ - e => this.props.onSelect?.call(this, "secret:" + name)}> - {data} - </Button> - </Td> - </Tr> - ) - })} - </Tbody> - </TableComposable> - </Tab> - <Tab eventKey={"service"} key={"service"} title={<TabTitleText>Services</TabTitleText>}> - <TableComposable variant='compact' borders={false}> - <Thead> - <Tr> - <Th/> - <Th key='name'>Name</Th> - <Th key='host'>Host:Port</Th> + ) + })} + </Tbody> + </TableComposable> + ) + } + + getServicesTable() { + const services = this.state.services; + return ( + <TableComposable variant='compact' borders={false}> + <Thead> + <Tr> + <Th/> + <Th key='name'>Name</Th> + {/*<Th key='hostPort'>Host:Port</Th>*/} + <Th key='host'>Host</Th> + <Th key='port'>Port</Th> + </Tr> + </Thead> + <Tbody> + {services + .filter(name => this.checkFilter(name)) + .map((name, idx: number) => { + const serviceName = name.split("|")[0]; + const hostPort = name.split("|")[1]; + const host = hostPort.split(":")[0]; + const port = hostPort.split(":")[1]; + return ( + <Tr key={name}> + <Td noPadding isActionCell> + <Badge>S</Badge> + </Td> + <Td noPadding> + {serviceName} + </Td> + {/*<Td noPadding>*/} + {/* <Button style={{padding: '6px'}} variant={"link"} onClick={*/} + {/* e => this.props.onSelect?.call(this, hostPort)}>*/} + {/* {hostPort}*/} + {/* </Button>*/} + {/*</Td>*/} + <Td noPadding> + <Button style={{padding: '6px'}} variant={"link"} onClick={ + e => this.props.onSelect?.call(this, host)}> + {host} + </Button> + </Td> + <Td noPadding> + <Button style={{padding: '6px'}} variant={"link"} onClick={ + e => this.props.onSelect?.call(this, port)}> + {port} + </Button> + </Td> </Tr> - </Thead> - <Tbody> - {services - .filter(name => this.checkFilter(name)) - .map((name, idx: number) => { - const serviceName = name.split("|")[0]; - const hostPort = name.split("|")[1]; - return ( - <Tr key={name}> - <Td noPadding isActionCell> - <Badge>S</Badge> - </Td> - <Td noPadding> - {serviceName} - </Td> - <Td noPadding> - <Button style={{padding: '6px'}} variant={"link"} onClick={ - e => this.props.onSelect?.call(this, hostPort)}> - {hostPort} - </Button> - </Td> - </Tr> - ) - })} - </Tbody> - </TableComposable> - </Tab> - </Tabs> - </PageSection> - ); + ) + })} + </Tbody> + </TableComposable> + ) + } + + render() { + const tabIndex = this.state.tabIndex; + return ( + <Modal + aria-label="Select from Kubernetes" + width={'50%'} + className='dsl-modal' + isOpen={this.props.isOpen} + onClose={this.props.onClose} + header={ + <Flex direction={{default: "column"}}> + <FlexItem> + <h3>{"Select from Kubernetes"}</h3> + {this.searchInput()} + </FlexItem> + <FlexItem> + <Tabs data-tour="selector-tabs" style={{overflow: 'hidden'}} activeKey={this.state.tabIndex} onSelect={this.selectTab}> + <Tab eventKey={"configMap"} key={"configMap"} title={<TabTitleText>ConfigMaps</TabTitleText>} /> + <Tab eventKey={"secret"} key={"secret"} title={<TabTitleText>Secrets</TabTitleText>} /> + <Tab eventKey={"service"} key={"service"} title={<TabTitleText>Services</TabTitleText>} /> + </Tabs> + </FlexItem> + </Flex> + } + actions={{}}> + <PageSection variant={this.props.dark ? "darker" : "light"}> + {this.searchInput()} + {tabIndex === 'configMap' && this.getConfigMapTable()} + {tabIndex === 'secret' && this.getSecretsTable()} + {tabIndex === 'service' && this.getServicesTable()} + </PageSection> + </Modal> + ) } } \ No newline at end of file diff --git a/karavan-vscode/webview/builder/BuilderPage.tsx b/karavan-vscode/webview/builder/BuilderPage.tsx index 5ffeed0..605521c 100644 --- a/karavan-vscode/webview/builder/BuilderPage.tsx +++ b/karavan-vscode/webview/builder/BuilderPage.tsx @@ -1,3 +1,19 @@ +/* + * 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, diff --git a/karavan-vscode/webview/builder/FileSelector.tsx b/karavan-vscode/webview/builder/FileSelector.tsx index 2d0f2ab..ead44b9 100644 --- a/karavan-vscode/webview/builder/FileSelector.tsx +++ b/karavan-vscode/webview/builder/FileSelector.tsx @@ -1,3 +1,19 @@ +/* + * 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, diff --git a/karavan-vscode/webview/builder/ProfileSelector.tsx b/karavan-vscode/webview/builder/ProfileSelector.tsx index b5f4351..ef140a4 100644 --- a/karavan-vscode/webview/builder/ProfileSelector.tsx +++ b/karavan-vscode/webview/builder/ProfileSelector.tsx @@ -1,3 +1,19 @@ +/* + * 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, diff --git a/karavan-vscode/webview/builder/PropertiesTable.tsx b/karavan-vscode/webview/builder/PropertiesTable.tsx index 27d5a88..e3f5958 100644 --- a/karavan-vscode/webview/builder/PropertiesTable.tsx +++ b/karavan-vscode/webview/builder/PropertiesTable.tsx @@ -1,3 +1,19 @@ +/* + * 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, @@ -100,7 +116,7 @@ export class PropertiesTable extends React.Component<Props, State> { </Thead> <Tbody> {properties.map((property, idx: number) => { - const readOnly = ["camel.jbang.gav", "camel.jbang.runtime"].includes(property.key); + const readOnly = property.key.startsWith("camel.jbang"); return ( <Tr key={property.id}> <Td noPadding width={20} dataLabel="key">{this.getTextInputField(property, "key", readOnly)}</Td> diff --git a/karavan-vscode/webview/components/ComponentCard.tsx b/karavan-vscode/webview/components/ComponentCard.tsx index 925c720..6d465f3 100644 --- a/karavan-vscode/webview/components/ComponentCard.tsx +++ b/karavan-vscode/webview/components/ComponentCard.tsx @@ -1,9 +1,24 @@ +/* + * 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 { CardHeader, Card, CardTitle, CardBody, CardActions, CardFooter,Badge } from '@patternfly/react-core'; import '../designer/karavan.css'; -import {KameletModel} from "karavan-core/lib/model/KameletModels"; import {camelIcon, CamelUi} from "../designer/utils/CamelUi"; import {Component} from "karavan-core/lib/model/ComponentModels"; diff --git a/karavan-vscode/webview/components/ComponentModal.tsx b/karavan-vscode/webview/components/ComponentModal.tsx index 04ad022..0e73bc4 100644 --- a/karavan-vscode/webview/components/ComponentModal.tsx +++ b/karavan-vscode/webview/components/ComponentModal.tsx @@ -1,3 +1,19 @@ +/* + * 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, diff --git a/karavan-vscode/webview/components/ComponentsPage.tsx b/karavan-vscode/webview/components/ComponentsPage.tsx index f1b5dc8..182ce03 100644 --- a/karavan-vscode/webview/components/ComponentsPage.tsx +++ b/karavan-vscode/webview/components/ComponentsPage.tsx @@ -1,3 +1,19 @@ +/* + * 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 { Toolbar, diff --git a/karavan-vscode/webview/eip/EipCard.tsx b/karavan-vscode/webview/eip/EipCard.tsx index 310d429..0fab47e 100644 --- a/karavan-vscode/webview/eip/EipCard.tsx +++ b/karavan-vscode/webview/eip/EipCard.tsx @@ -1,3 +1,19 @@ +/* + * 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 { CardHeader, Card, CardTitle, CardBody, CardFooter,Badge diff --git a/karavan-vscode/webview/eip/EipModal.tsx b/karavan-vscode/webview/eip/EipModal.tsx index f6ee6d9..34777ca 100644 --- a/karavan-vscode/webview/eip/EipModal.tsx +++ b/karavan-vscode/webview/eip/EipModal.tsx @@ -1,3 +1,19 @@ +/* + * 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, diff --git a/karavan-vscode/webview/eip/EipPage.tsx b/karavan-vscode/webview/eip/EipPage.tsx index dd6e301..352d59a 100644 --- a/karavan-vscode/webview/eip/EipPage.tsx +++ b/karavan-vscode/webview/eip/EipPage.tsx @@ -1,3 +1,19 @@ +/* + * 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 { Toolbar, diff --git a/karavan-vscode/webview/kamelets/KameletCard.tsx b/karavan-vscode/webview/kamelets/KameletCard.tsx index 3708af8..31ac3c6 100644 --- a/karavan-vscode/webview/kamelets/KameletCard.tsx +++ b/karavan-vscode/webview/kamelets/KameletCard.tsx @@ -1,3 +1,19 @@ +/* + * 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 { CardHeader, Card, CardTitle, CardBody, CardActions, CardFooter,Badge diff --git a/karavan-vscode/webview/kamelets/KameletModal.tsx b/karavan-vscode/webview/kamelets/KameletModal.tsx index fb9532d..270683a 100644 --- a/karavan-vscode/webview/kamelets/KameletModal.tsx +++ b/karavan-vscode/webview/kamelets/KameletModal.tsx @@ -1,3 +1,19 @@ +/* + * 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, {Component} from 'react'; import { Button, diff --git a/karavan-vscode/webview/kamelets/KameletsPage.tsx b/karavan-vscode/webview/kamelets/KameletsPage.tsx index f4c26ce..9176532 100644 --- a/karavan-vscode/webview/kamelets/KameletsPage.tsx +++ b/karavan-vscode/webview/kamelets/KameletsPage.tsx @@ -1,3 +1,19 @@ +/* + * 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 { Toolbar,