blob: b7bba3a93e8918913c66f66b4fdce330a2a6b096 [file] [log] [blame]
/*
* 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 * as React from "react";
import {
Alert,
AlertActionCloseButton, AlertGroup,
Bullseye, Button, Divider, Flex, FlexItem,
Page, Spinner, Tooltip,
} from "@patternfly/react-core";
import {KameletApi} from "karavan-core/lib/api/KameletApi";
import {ComponentApi} from "karavan-core/lib/api/ComponentApi";
import {KameletsPage} from "./kamelets/KameletsPage";
import {ComponentsPage} from "./components/ComponentsPage";
import {EipPage} from "./eip/EipPage";
import {BlueprintIcon} from "@patternfly/react-icons";
import KameletsIcon from "@patternfly/react-icons/dist/js/icons/registry-icon";
import EipIcon from "@patternfly/react-icons/dist/js/icons/topology-icon";
import ComponentsIcon from "@patternfly/react-icons/dist/js/icons/module-icon";
import {KaravanIcon} from "./designer/utils/KaravanIcons";
import './designer/karavan.css';
import {DesignerPage} from "./DesignerPage";
import {TemplateApi} from "karavan-core/lib/api/TemplateApi";
import {DataMapper} from "./data/DataMapper";
class ToastMessage {
id: string = ''
text: string = ''
title: string = ''
variant?: 'success' | 'danger' | 'warning' | 'info' | 'default';
constructor(title: string, text: string, variant: 'success' | 'danger' | 'warning' | 'info' | 'default') {
this.id = Date.now().toString().concat(Math.random().toString());
this.title = title;
this.text = text;
this.variant = variant;
}
}
class MenuItem {
pageId: string = '';
tooltip: string = '';
icon: any;
constructor(pageId: string, tooltip: string, icon: any) {
this.pageId = pageId;
this.tooltip = tooltip;
this.icon = icon;
}
}
interface Props {
}
interface State {
name: string
yaml: string
key: string
loaded?: boolean,
pageId: string,
alerts: ToastMessage[],
}
class App extends React.Component<Props, State> {
public state: State = {
pageId: "datamapper",
alerts: [],
name: 'example.yaml',
key: '',
yaml: ''
}
toast = (title: string, text: string, variant: 'success' | 'danger' | 'warning' | 'info' | 'default') => {
const mess = [];
mess.push(...this.state.alerts, new ToastMessage(title, text, variant));
this.setState({alerts: mess})
}
deleteErrorMessage = (id: string) => {
this.setState({alerts: this.state.alerts.filter(a => a.id !== id)})
}
componentDidMount() {
Promise.all([
fetch("kamelets/kamelets.yaml"),
fetch("components/components.json"),
fetch("snippets/org.apache.camel.AggregationStrategy"),
fetch("snippets/org.apache.camel.Processor")
// fetch("components/supported-components.json"),
]).then(responses =>
Promise.all(responses.map(response => response.text()))
).then(data => {
const kamelets: string[] = [];
data[0].split("\n---\n").map(c => c.trim()).forEach(z => kamelets.push(z));
KameletApi.saveKamelets(kamelets, true);
// this.toast("Success", "Loaded " + kamelets.length + " kamelets", 'success');
const jsons: string[] = [];
JSON.parse(data[1]).forEach((c: any) => jsons.push(JSON.stringify(c)));
ComponentApi.saveComponents(jsons, true);
// this.toast("Success", "Loaded " + jsons.length + " components", 'success');
this.setState({loaded: true});
TemplateApi.saveTemplate("org.apache.camel.AggregationStrategy", data[2]);
TemplateApi.saveTemplate("org.apache.camel.Processor", data[3]);
if (data[4]) {
ComponentApi.saveSupportedComponents(data[4]);
ComponentApi.setSupportedOnly(true);
}
}).catch(err =>
this.toast("Error", err.text, 'danger')
);
}
save(filename: string, yaml: string, propertyOnly: boolean) {
this.setState({name: filename, yaml: yaml});
// console.log(yaml);
}
getSpinner() {
return (
<Bullseye className="loading-page">
<Spinner className="progress-stepper" isSVG diameter="80px" aria-label="Loading..."/>
</Bullseye>
)
}
pageNav = () => {
const {pageId} = this.state;
const pages: MenuItem[] = [
new MenuItem("designer", "Designer", <BlueprintIcon/>),
new MenuItem("eip", "Enterprise Integration Patterns", <EipIcon/>),
new MenuItem("kamelets", "Kamelets", <KameletsIcon/>),
new MenuItem("components", "Components", <ComponentsIcon/>),
new MenuItem("datamapper", "Data Mapper", <ComponentsIcon/>),
]
return (<Flex className="nav-buttons" direction={{default: "column"}} style={{height: "100%"}}
spaceItems={{default: "spaceItemsNone"}}>
<FlexItem alignSelf={{default: "alignSelfCenter"}}>
<Tooltip className="logo-tooltip" content={"Apache Camel Karavan"}
position={"right"}>
{KaravanIcon()}
</Tooltip>
</FlexItem>
{pages.map(page =>
<FlexItem key={page.pageId} className={pageId === page.pageId ? "nav-button-selected" : ""}>
<Tooltip content={page.tooltip} position={"right"}>
<Button id={page.pageId} icon={page.icon} variant={"plain"}
className={pageId === page.pageId ? "nav-button-selected" : ""}
onClick={event => this.setState({pageId: page.pageId})}
/>
</Tooltip>
</FlexItem>
)}
<FlexItem flex={{default: "flex_2"}} alignSelf={{default: "alignSelfCenter"}}>
<Divider/>
</FlexItem>
</Flex>)
}
getPage() {
const {key, name, yaml, pageId} = this.state;
const dark = document.body.className.includes('vscode-dark');
switch (pageId) {
case "designer":
return (
<DesignerPage
name={name}
yaml={yaml}
onSave={(filename, yaml1, propertyOnly) => this.save(filename, yaml1, propertyOnly)}
dark={dark}/>
)
case "kamelets":
return (
<KameletsPage dark={dark}/>
)
case "components":
return (
<ComponentsPage dark={dark}/>
)
case "eip":
return (
<EipPage dark={dark}/>
)
case "datamapper":
return (
<DataMapper dark={dark}/>
)
}
}
public render() {
const {loaded} = this.state;
return (
<Page className="karavan">
<AlertGroup isToast isLiveRegion>
{this.state.alerts.map((e: ToastMessage) => (
<Alert key={e.id} className="main-alert" variant={e.variant} title={e.title}
timeout={e.variant === "success" ? 2000 : 10000}
actionClose={<AlertActionCloseButton onClose={() => this.deleteErrorMessage(e.id)}/>}>
{e.text}
</Alert>
))}
</AlertGroup>
<>
<Flex direction={{default: "row"}} style={{width: "100%", height: "100%"}}
alignItems={{default: "alignItemsStretch"}} spaceItems={{default: 'spaceItemsNone'}}>
<FlexItem>
{this.pageNav()}
</FlexItem>
<FlexItem flex={{default: "flex_2"}} style={{height: "100%"}}>
{loaded !== true && this.getSpinner()}
{loaded === true && this.getPage()}
</FlexItem>
</Flex>
</>
</Page>
)
}
}
export default App;