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 6290498a UI prototype for #956 6290498a is described below commit 6290498a9b871b586b87bb1ff2e3757e8feaa71e Author: Marat Gubaidullin <ma...@talismancloud.io> AuthorDate: Tue Nov 28 23:45:12 2023 -0500 UI prototype for #956 --- karavan-space/src/designer/editor/CodeEditor.tsx | 9 +++-- karavan-space/src/designer/route/DslElement.css | 17 +++++++++- karavan-space/src/designer/route/DslElement.tsx | 39 +++++++++++++++++++--- .../main/webui/src/designer/editor/CodeEditor.tsx | 9 +++-- .../main/webui/src/designer/route/DslElement.css | 17 +++++++++- .../main/webui/src/designer/route/DslElement.tsx | 39 +++++++++++++++++++--- 6 files changed, 114 insertions(+), 16 deletions(-) diff --git a/karavan-space/src/designer/editor/CodeEditor.tsx b/karavan-space/src/designer/editor/CodeEditor.tsx index cd6a4f36..d421ecaa 100644 --- a/karavan-space/src/designer/editor/CodeEditor.tsx +++ b/karavan-space/src/designer/editor/CodeEditor.tsx @@ -29,8 +29,13 @@ export function CodeEditor () { const [code, setCode] = useState<string>(''); useEffect(() => { - const c = CamelDefinitionYaml.integrationToYaml(integration); - setCode(c); + try { + const c = CamelDefinitionYaml.integrationToYaml(integration); + setCode(c); + } catch (e: any) { + const message: string = e?.message ? e.message : e.reason; + setNotification(true, ['Error in YAML, Integration can not be saved!', message]); + } return () => { setNotification(false, ['', '']); } diff --git a/karavan-space/src/designer/route/DslElement.css b/karavan-space/src/designer/route/DslElement.css index 71621b45..d3ed7177 100644 --- a/karavan-space/src/designer/route/DslElement.css +++ b/karavan-space/src/designer/route/DslElement.css @@ -1,3 +1,18 @@ .disabled { opacity: 0.5; -} \ No newline at end of file +} +.menu-button { + position: absolute; + top: 26px; + line-height: 1; + border: 0; + padding: 0; + margin: 0 0 0 10px; + background: transparent; + color: var(--pf-v5-global--primary-color--100); + visibility: hidden; +} + +.dsl-element:hover .menu-button { + visibility: visible; +} diff --git a/karavan-space/src/designer/route/DslElement.tsx b/karavan-space/src/designer/route/DslElement.tsx index efeaeff8..e3dfdbfc 100644 --- a/karavan-space/src/designer/route/DslElement.tsx +++ b/karavan-space/src/designer/route/DslElement.tsx @@ -15,13 +15,13 @@ * limitations under the License. */ import React, {CSSProperties, useMemo, useState} from 'react'; -import { - Text, Tooltip, -} from '@patternfly/react-core'; +import {Menu, MenuContent, MenuItem, MenuList, Popover, Text, Tooltip,} from '@patternfly/react-core'; import '../karavan.css'; import './DslElement.css'; import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon"; import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-circle-icon"; +import SyncIcon from "@patternfly/react-icons/dist/js/icons/sync-icon"; +import TurnIcon from "@patternfly/react-icons/dist/js/icons/chevron-circle-right-icon"; import InsertIcon from "@patternfly/react-icons/dist/js/icons/arrow-alt-circle-right-icon"; import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition"; import {CamelUi} from "../utils/CamelUi"; @@ -222,7 +222,7 @@ export function DslElement(props: Props) { const headerClass = ['RouteConfigurationDefinition', 'RouteDefinition'].includes(step.dslName) ? "header-route" : "header" const headerClasses = isElementSelected() ? headerClass + " selected" : headerClass; return ( - <div className={headerClasses} style={getHeaderStyle()} ref={headerRef}> + <div className={"dsl-element " + headerClasses} style={getHeaderStyle()} ref={headerRef}> {!['RouteConfigurationDefinition', 'RouteDefinition'].includes(props.step.dslName) && <div ref={el => sendPosition(el)} @@ -237,6 +237,7 @@ export function DslElement(props: Props) { </div> {showInsertButton && getInsertElementButton()} {getDeleteButton()} + {/*{getMenuButton()}*/} {showAddButton && getAddElementButton()} </div> ) @@ -408,11 +409,39 @@ export function DslElement(props: Props) { return ( <Tooltip position={"right"} content={<div>{"Delete element"}</div>}> <button type="button" aria-label="Delete" onClick={e => onDeleteElement(e)} className="delete-button"> - <DeleteIcon/></button> + <DeleteIcon/> + </button> </Tooltip> ) } + function getMenuButton() { + return ( + <Popover + aria-label="Convert Popover" + hasNoPadding + position={"right"} + hideOnOutsideClick={true} + showClose={false} + bodyContent={ + <Menu activeItemId={''} onSelect={event => {}} isPlain> + <MenuContent> + <MenuList> + <MenuItem itemId={0} icon={<SyncIcon aria-hidden />}>Convert to SetHeader</MenuItem> + {/*<MenuItem itemId={1}>Action</MenuItem>*/} + {/*<MenuItem itemId={2}>Action</MenuItem>*/} + </MenuList> + </MenuContent> + </Menu> + } + > + <button type="button" aria-label="Menu" onClick={e => {}} className="menu-button"> + <TurnIcon/> + </button> + </Popover> + ) + } + const element: CamelElement = props.step; const className = "step-element" + (isElementSelected() ? " step-element-selected" : "") + (!props.step.showChildren ? " hidden-step" : "") diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/editor/CodeEditor.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/editor/CodeEditor.tsx index cd6a4f36..d421ecaa 100644 --- a/karavan-web/karavan-app/src/main/webui/src/designer/editor/CodeEditor.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/designer/editor/CodeEditor.tsx @@ -29,8 +29,13 @@ export function CodeEditor () { const [code, setCode] = useState<string>(''); useEffect(() => { - const c = CamelDefinitionYaml.integrationToYaml(integration); - setCode(c); + try { + const c = CamelDefinitionYaml.integrationToYaml(integration); + setCode(c); + } catch (e: any) { + const message: string = e?.message ? e.message : e.reason; + setNotification(true, ['Error in YAML, Integration can not be saved!', message]); + } return () => { setNotification(false, ['', '']); } diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.css b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.css index 71621b45..d3ed7177 100644 --- a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.css +++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.css @@ -1,3 +1,18 @@ .disabled { opacity: 0.5; -} \ No newline at end of file +} +.menu-button { + position: absolute; + top: 26px; + line-height: 1; + border: 0; + padding: 0; + margin: 0 0 0 10px; + background: transparent; + color: var(--pf-v5-global--primary-color--100); + visibility: hidden; +} + +.dsl-element:hover .menu-button { + visibility: visible; +} diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx index efeaeff8..e3dfdbfc 100644 --- a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx @@ -15,13 +15,13 @@ * limitations under the License. */ import React, {CSSProperties, useMemo, useState} from 'react'; -import { - Text, Tooltip, -} from '@patternfly/react-core'; +import {Menu, MenuContent, MenuItem, MenuList, Popover, Text, Tooltip,} from '@patternfly/react-core'; import '../karavan.css'; import './DslElement.css'; import AddIcon from "@patternfly/react-icons/dist/js/icons/plus-circle-icon"; import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-circle-icon"; +import SyncIcon from "@patternfly/react-icons/dist/js/icons/sync-icon"; +import TurnIcon from "@patternfly/react-icons/dist/js/icons/chevron-circle-right-icon"; import InsertIcon from "@patternfly/react-icons/dist/js/icons/arrow-alt-circle-right-icon"; import {CamelElement} from "karavan-core/lib/model/IntegrationDefinition"; import {CamelUi} from "../utils/CamelUi"; @@ -222,7 +222,7 @@ export function DslElement(props: Props) { const headerClass = ['RouteConfigurationDefinition', 'RouteDefinition'].includes(step.dslName) ? "header-route" : "header" const headerClasses = isElementSelected() ? headerClass + " selected" : headerClass; return ( - <div className={headerClasses} style={getHeaderStyle()} ref={headerRef}> + <div className={"dsl-element " + headerClasses} style={getHeaderStyle()} ref={headerRef}> {!['RouteConfigurationDefinition', 'RouteDefinition'].includes(props.step.dslName) && <div ref={el => sendPosition(el)} @@ -237,6 +237,7 @@ export function DslElement(props: Props) { </div> {showInsertButton && getInsertElementButton()} {getDeleteButton()} + {/*{getMenuButton()}*/} {showAddButton && getAddElementButton()} </div> ) @@ -408,11 +409,39 @@ export function DslElement(props: Props) { return ( <Tooltip position={"right"} content={<div>{"Delete element"}</div>}> <button type="button" aria-label="Delete" onClick={e => onDeleteElement(e)} className="delete-button"> - <DeleteIcon/></button> + <DeleteIcon/> + </button> </Tooltip> ) } + function getMenuButton() { + return ( + <Popover + aria-label="Convert Popover" + hasNoPadding + position={"right"} + hideOnOutsideClick={true} + showClose={false} + bodyContent={ + <Menu activeItemId={''} onSelect={event => {}} isPlain> + <MenuContent> + <MenuList> + <MenuItem itemId={0} icon={<SyncIcon aria-hidden />}>Convert to SetHeader</MenuItem> + {/*<MenuItem itemId={1}>Action</MenuItem>*/} + {/*<MenuItem itemId={2}>Action</MenuItem>*/} + </MenuList> + </MenuContent> + </Menu> + } + > + <button type="button" aria-label="Menu" onClick={e => {}} className="menu-button"> + <TurnIcon/> + </button> + </Popover> + ) + } + const element: CamelElement = props.step; const className = "step-element" + (isElementSelected() ? " step-element-selected" : "") + (!props.step.showChildren ? " hidden-step" : "")