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

commit 12f357320435bd6a5faabd61f936999a5865d432
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Sun Aug 25 12:45:04 2024 -0400

    Frontend fixes
---
 karavan-app/src/main/webui/src/api/KaravanApi.tsx  |  4 +-
 .../src/main/webui/src/project/DevModeToolbar.tsx  |  5 +-
 .../src/main/webui/src/project/ProjectToolbar.tsx  |  8 +--
 .../main/webui/src/project/builder/BuildPanel.tsx  | 11 ++--
 .../main/webui/src/project/builder/ImagesPanel.tsx | 12 +++--
 .../src/project/container/ContainerButtons.tsx     |  2 +-
 .../src/project/container/DeploymentPanel.tsx      | 61 +++++++++++++++++++---
 .../webui/src/project/files/CreateFileModal.tsx    |  4 +-
 8 files changed, 78 insertions(+), 29 deletions(-)

diff --git a/karavan-app/src/main/webui/src/api/KaravanApi.tsx 
b/karavan-app/src/main/webui/src/api/KaravanApi.tsx
index 9a8e0f34..e883e424 100644
--- a/karavan-app/src/main/webui/src/api/KaravanApi.tsx
+++ b/karavan-app/src/main/webui/src/api/KaravanApi.tsx
@@ -478,7 +478,7 @@ export class KaravanApi {
         });
     }
 
-    static async startDevModeContainer(project: Project, verbose: boolean, 
after: (res: AxiosResponse<string>) => void) {
+    static async startDevModeContainer(project: Project, verbose: boolean, 
after: (res: AxiosResponse<any>) => void) {
         instance.post('/ui/devmode' + (verbose ? '/--verbose' : ''), project)
             .then(res => {
                 after(res);
@@ -604,7 +604,7 @@ export class KaravanApi {
                                  type: 'devmode' | 'devservice' | 'project' | 
'internal' | 'build' | 'unknown',
                                  name: string,
                                  command: 'deploy' | 'run' | 'pause' | 'stop' 
| 'delete',
-                                 pullImage: boolean,
+                                 pullImage: 'always' | 'ifNotExists' | 'never',
                                  after: (res: AxiosResponse<any> | any) => 
void) {
         instance.post('/ui/container/' + projectId + '/' + type + "/" + name, 
{command: command, pullImage: pullImage})
             .then(res => {
diff --git a/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx 
b/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
index f98fda4a..e8af4bcc 100644
--- a/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
+++ b/karavan-app/src/main/webui/src/project/DevModeToolbar.tsx
@@ -31,7 +31,7 @@ import '../designer/karavan.css';
 import RocketIcon from "@patternfly/react-icons/dist/esm/icons/rocket-icon";
 import ReloadIcon from "@patternfly/react-icons/dist/esm/icons/bolt-icon";
 import DeleteIcon from "@patternfly/react-icons/dist/esm/icons/trash-icon";
-import {useAppConfigStore, useLogStore, useProjectStore, useStatusesStore} 
from "../api/ProjectStore";
+import {useLogStore, useProjectStore, useStatusesStore} from 
"../api/ProjectStore";
 import {ProjectService} from "../api/ProjectService";
 import {shallow} from "zustand/shallow";
 import UpIcon from "@patternfly/react-icons/dist/esm/icons/running-icon";
@@ -45,13 +45,12 @@ interface Props {
 
 export function DevModeToolbar(props: Props) {
 
-    const [config] = useAppConfigStore((state) => [state.config], shallow)
     const [project, refreshTrace] = useProjectStore((state) => [state.project, 
state.refreshTrace], shallow)
     const [containers] = useStatusesStore((state) => [state.containers], 
shallow);
     const [verbose, setVerbose] = useState(false);
     const [showSpinner, setShowSpinner] = useState(false);
     const [setShowLog] = useLogStore((s) => [s.setShowLog], shallow);
-    const [currentContainerStatus, setCurrentContainerStatus] = 
useState<ContainerStatus>();
+    const [currentContainerStatus] = useState<ContainerStatus>();
 
     const containerStatuses = containers.filter(c => c.projectId === 
project.projectId) || [];
 
diff --git a/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx 
b/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
index 56e16d33..5b1f4d6b 100644
--- a/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
+++ b/karavan-app/src/main/webui/src/project/ProjectToolbar.tsx
@@ -22,7 +22,7 @@ import {
 } from '@patternfly/react-core';
 import '../designer/karavan.css';
 import {DevModeToolbar} from "./DevModeToolbar";
-import {useFileStore, useProjectStore} from "../api/ProjectStore";
+import {useAppConfigStore, useFileStore, useProjectStore} from 
"../api/ProjectStore";
 import {shallow} from "zustand/shallow";
 import {EditorToolbar} from "../editor/EditorToolbar";
 import {BUILD_IN_PROJECTS,} from "../api/ProjectModels";
@@ -32,6 +32,8 @@ export function ProjectToolbar() {
 
     const [project] = useProjectStore((s) => [s.project, s.tabIndex], shallow)
     const [file] = useFileStore((state) => [state.file], shallow)
+    const [config] = useAppConfigStore((s) => [s.config], shallow);
+    const isDev = config.environment === 'dev';
 
     const isBuildInProject = BUILD_IN_PROJECTS.includes(project.projectId);
 
@@ -46,8 +48,8 @@ export function ProjectToolbar() {
     function getProjectToolbar() {
         return (<Toolbar id="toolbar-group-types">
             <ToolbarContent>
-                {!isBuildInProject && <DevModeToolbar/>}
-                {isBuildInProject && <ResourceToolbar/>}
+                {!isBuildInProject && isDev && <DevModeToolbar/>}
+                {(isBuildInProject || !isDev) && <ResourceToolbar/>}
             </ToolbarContent>
         </Toolbar>)
     }
diff --git a/karavan-app/src/main/webui/src/project/builder/BuildPanel.tsx 
b/karavan-app/src/main/webui/src/project/builder/BuildPanel.tsx
index aee7a37c..a771a9be 100644
--- a/karavan-app/src/main/webui/src/project/builder/BuildPanel.tsx
+++ b/karavan-app/src/main/webui/src/project/builder/BuildPanel.tsx
@@ -31,14 +31,13 @@ import DownIcon from 
"@patternfly/react-icons/dist/esm/icons/error-circle-o-icon
 import ClockIcon from "@patternfly/react-icons/dist/esm/icons/clock-icon";
 import TagIcon from "@patternfly/react-icons/dist/esm/icons/tag-icon";
 import DeleteIcon from 
"@patternfly/react-icons/dist/esm/icons/times-circle-icon";
-import {useAppConfigStore, useLogStore, useProjectStore, useStatusesStore} 
from "../../api/ProjectStore";
+import {useLogStore, useProjectStore, useStatusesStore} from 
"../../api/ProjectStore";
 import {shallow} from "zustand/shallow";
 import {EventBus} from "../../designer/utils/EventBus";
 import {getShortCommit} from "../../util/StringUtils";
 
 export function BuildPanel () {
 
-    const [config] = useAppConfigStore((state) => [state.config], shallow);
     const [project] = useProjectStore((s) => [s.project], shallow);
     const [setShowLog] = useLogStore((s) => [s.setShowLog], shallow);
     const [containers, deployments, camels] =
@@ -52,7 +51,7 @@ export function BuildPanel () {
     function deleteEntity() {
         const buildName = getBuildName();
         if (buildName) {
-            KaravanApi.manageContainer(project.projectId, 'build', buildName, 
'delete', false,res => {
+            KaravanApi.manageContainer(project.projectId, 'build', buildName, 
'delete', 'never',res => {
                 EventBus.sendAlert("Container deleted", "Container " + 
buildName + " deleted", 'info')
                 setShowLog(false, 'container', undefined)
             });
@@ -75,9 +74,7 @@ export function BuildPanel () {
     function buildButton() {
         const status = containers.filter(c => c.projectId === 
project.projectId && c.type === 'build').at(0);
         const isRunning = status?.state === 'running';
-        const tooltip = config.infrastructure === 'kubernetes' ? "Build and 
Deploy project" : "Build project"
-        const buttonTitle = config.infrastructure === 'kubernetes' ? "Deploy" 
: "Build"
-        return (<Tooltip content={tooltip} position={"left"}>
+        return (<Tooltip content={"Build project"} position={"left"}>
             <Button isLoading={isBuilding ? true : undefined}
                     isDisabled={isBuilding || isRunning || isPushing}
                     size="sm"
@@ -85,7 +82,7 @@ export function BuildPanel () {
                     className="project-button dev-action-button"
                     icon={!isBuilding ? <BuildIcon/> : <div></div>}
                     onClick={e => build()}>
-                {isBuilding ? "..." : buttonTitle}
+                {isBuilding ? "..." : "Build"}
             </Button>
         </Tooltip>)
     }
diff --git a/karavan-app/src/main/webui/src/project/builder/ImagesPanel.tsx 
b/karavan-app/src/main/webui/src/project/builder/ImagesPanel.tsx
index b4dea27d..1d137edf 100644
--- a/karavan-app/src/main/webui/src/project/builder/ImagesPanel.tsx
+++ b/karavan-app/src/main/webui/src/project/builder/ImagesPanel.tsx
@@ -37,7 +37,7 @@ import {
     CardBody, CardHeader, HelperTextItem, HelperText
 } from '@patternfly/react-core';
 import '../../designer/karavan.css';
-import {useFilesStore, useProjectStore} from "../../api/ProjectStore";
+import {useAppConfigStore, useFilesStore, useProjectStore} from 
"../../api/ProjectStore";
 import {shallow} from "zustand/shallow";
 import {Table} from "@patternfly/react-table/deprecated";
 import {Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
@@ -61,6 +61,8 @@ export function ImagesPanel() {
     const [imageName, setImageName] = useState<string>();
     const [commitChanges, setCommitChanges] = useState<boolean>(false);
     const [commitMessage, setCommitMessage] = useState('');
+    const [config] = useAppConfigStore((s) => [s.config], shallow);
+    const isDev = config.environment === 'dev';
 
     function setProjectImage() {
         if (imageName) {
@@ -247,10 +249,10 @@ export function ImagesPanel() {
                                               spaceItems={{default: 
'spaceItemsNone'}}>
                                             <FlexItem>
                                                 <Tooltip content={"Delete 
image"} position={"bottom"}>
-                                                    <Button variant={"plain"}
+                                                    <Button variant={"link"}
                                                             
className='dev-action-button'
                                                             
icon={<DeleteIcon/>}
-                                                            
isDisabled={fullName === projectImage}
+                                                            
isDisabled={fullName === projectImage || !isDev}
                                                             onClick={e => {
                                                                 
setImageName(fullName);
                                                                 
setShowDeleteConfirmation(true);
@@ -260,9 +262,9 @@ export function ImagesPanel() {
                                             </FlexItem>
                                             <FlexItem>
                                                 <Tooltip content="Set project 
image" position={"bottom"}>
-                                                    <Button variant={"plain"}
+                                                    <Button variant={"link"}
                                                             
className='dev-action-button'
-                                                            
isDisabled={fullName === projectImage}
+                                                            
isDisabled={fullName === projectImage || !isDev}
                                                             onClick={e => {
                                                                 
setImageName(fullName);
                                                                 
setCommitMessage(commitMessage === '' ? new Date().toLocaleString() : 
commitMessage);
diff --git 
a/karavan-app/src/main/webui/src/project/container/ContainerButtons.tsx 
b/karavan-app/src/main/webui/src/project/container/ContainerButtons.tsx
index 50f05d39..23bede07 100644
--- a/karavan-app/src/main/webui/src/project/container/ContainerButtons.tsx
+++ b/karavan-app/src/main/webui/src/project/container/ContainerButtons.tsx
@@ -50,7 +50,7 @@ export function ContainerButtons (props: Props) {
     const isLoading = status === 'wip';
 
     function act() {
-        KaravanApi.manageContainer(project.projectId, 'project', 
project.projectId, actionType, pullImage,res => {
+        KaravanApi.manageContainer(project.projectId, 'project', 
project.projectId, actionType, pullImage ? 'always' : 'never',res => {
             const response = res?.response;
             if (response?.status === 500) {
                 EventBus.sendAlert('Error', response.data !== undefined && 
response.data.length > 0 ? response.data : response.statusText, 'warning')
diff --git 
a/karavan-app/src/main/webui/src/project/container/DeploymentPanel.tsx 
b/karavan-app/src/main/webui/src/project/container/DeploymentPanel.tsx
index 53367bd0..6e4b0aa8 100644
--- a/karavan-app/src/main/webui/src/project/container/DeploymentPanel.tsx
+++ b/karavan-app/src/main/webui/src/project/container/DeploymentPanel.tsx
@@ -27,10 +27,11 @@ import {
 import '../../designer/karavan.css';
 import UpIcon from "@patternfly/react-icons/dist/esm/icons/running-icon";
 import DownIcon from 
"@patternfly/react-icons/dist/esm/icons/error-circle-o-icon";
-import {useAppConfigStore, useProjectStore, useStatusesStore} from 
"../../api/ProjectStore";
+import {useProjectStore, useStatusesStore} from "../../api/ProjectStore";
 import {shallow} from "zustand/shallow";
 import DeleteIcon from 
"@patternfly/react-icons/dist/esm/icons/times-circle-icon";
 import RolloutIcon from 
"@patternfly/react-icons/dist/esm/icons/process-automation-icon";
+import DeployIcon from "@patternfly/react-icons/dist/esm/icons/upload-icon";
 import {KaravanApi} from "../../api/KaravanApi";
 import {EventBus} from "../../designer/utils/EventBus";
 
@@ -44,6 +45,7 @@ export function DeploymentPanel (props: Props) {
     const [ deployments] =
         useStatusesStore((s) => [s.deployments], shallow);
     const [showDeleteConfirmation, setShowDeleteConfirmation] = 
useState<boolean>(false);
+    const [showDeployConfirmation, setShowDeployConfirmation] = 
useState<boolean>(false);
     const [showRolloutConfirmation, setShowRolloutConfirmation] = 
useState<boolean>(false);
 
     function deleteDeployment() {
@@ -58,13 +60,22 @@ export function DeploymentPanel (props: Props) {
 
     function rolloutDeployment () {
         KaravanApi.rolloutDeployment(project.projectId, props.env, res => {
-            console.log(res)
             if (res.status === 200) {
                 EventBus.sendAlert("Rolled out", "Rolled out: " + 
project.projectId, 'info');
             }
         });
     }
 
+    function startDeployment(){
+        KaravanApi.startDeployment(project.projectId, props.env, res => {
+            if (res.status === 200) {
+                EventBus.sendAlert("Started", "Deployment started for " + 
project.projectId, 'info');
+            } else {
+                EventBus.sendAlert("Error", res.data, 'danger');
+            }
+        });
+    }
+
     function getDeleteConfirmation() {
         return (<Modal
             className="modal-delete"
@@ -104,13 +115,35 @@ export function DeploymentPanel (props: Props) {
                 <Button key="cancel" variant="link"
                         onClick={e => 
setShowRolloutConfirmation(false)}>Cancel</Button>
             ]}
-            onEscapePress={e => setShowDeleteConfirmation(false)}>
+            onEscapePress={e => setShowRolloutConfirmation(false)}>
             <div>{"Rollout deployment " + project.projectId + "?"}</div>
         </Modal>)
     }
 
+    function getDeployConfirmation() {
+            return (<Modal
+                className="modal-delete"
+                title="Confirmation"
+                isOpen={showDeployConfirmation}
+                onClose={() => setShowDeployConfirmation(false)}
+                actions={[
+                    <Button key="confirm" variant="primary" onClick={e => {
+                        if (project.projectId) {
+                            startDeployment();
+                            setShowDeployConfirmation(false);
+                        }
+                    }}>Deploy
+                    </Button>,
+                    <Button key="cancel" variant="link"
+                            onClick={e => 
setShowDeployConfirmation(false)}>Cancel</Button>
+                ]}
+                onEscapePress={e => setShowDeleteConfirmation(false)}>
+                <div>{"Deploy " + project.projectId + "?"}</div>
+            </Modal>)
+        }
+
     function rolloutButton() {
-        return (<Tooltip content="Rollout deployment" position={"left"}>
+        return (
             <Button size="sm" variant="secondary"
                     className="project-button dev-action-button"
                     icon={<RolloutIcon/>}
@@ -118,8 +151,20 @@ export function DeploymentPanel (props: Props) {
                         setShowRolloutConfirmation(true);
                     }}>
                 {"Rollout"}
+            </Button>)
+    }
+
+    function deployButton() {
+        return (
+            <Button size="sm" variant="primary"
+                    className="project-button dev-action-button"
+                    icon={<DeployIcon/>}
+                    onClick={e => {
+                        setShowDeployConfirmation(true);
+                    }}>
+                {"Deploy"}
             </Button>
-        </Tooltip>)
+        )
     }
 
     const deploymentStatus = deployments.find(d => d.projectId === 
project?.projectId);
@@ -128,7 +173,7 @@ export function DeploymentPanel (props: Props) {
         && deploymentStatus?.replicas === deploymentStatus?.readyReplicas)
     return (
         <Flex justifyContent={{default: "justifyContentSpaceBetween"}} 
alignItems={{default: "alignItemsCenter"}}>
-            <FlexItem>
+            <FlexItem flex={{default: 'flex_2'}}>
                 {deploymentStatus && <LabelGroup numLabels={3}>
                     <Tooltip content={"Ready Replicas / Replicas"} 
position={"left"}>
                         <Label icon={ok ? <UpIcon/> : <DownIcon/>}
@@ -149,9 +194,11 @@ export function DeploymentPanel (props: Props) {
                 </LabelGroup>}
                 {deploymentStatus === undefined && <Label icon={<DownIcon/>} 
color={"grey"}>No deployments</Label>}
             </FlexItem>
-            <FlexItem>{props.env === "dev" && rolloutButton()}</FlexItem>
+            <FlexItem>{rolloutButton()}</FlexItem>
+            <FlexItem>{deployButton()}</FlexItem>
             {showDeleteConfirmation && getDeleteConfirmation()}
             {showRolloutConfirmation && getRolloutConfirmation()}
+            {showDeployConfirmation && getDeployConfirmation()}
         </Flex>
     )
 }
diff --git a/karavan-app/src/main/webui/src/project/files/CreateFileModal.tsx 
b/karavan-app/src/main/webui/src/project/files/CreateFileModal.tsx
index 20d76296..39625adc 100644
--- a/karavan-app/src/main/webui/src/project/files/CreateFileModal.tsx
+++ b/karavan-app/src/main/webui/src/project/files/CreateFileModal.tsx
@@ -84,7 +84,9 @@ export function CreateFileModal() {
 
     function onKeyDown(event: React.KeyboardEvent<HTMLDivElement>): void {
         if (event.key === 'Enter') {
-            handleSubmit(onSubmit)()
+            event.preventDefault();
+            event.stopPropagation();
+            handleSubmit(onSubmit)();
         }
     }
 

Reply via email to