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 4c72df72d92704c8ecc5a5d06a3ec2de301de0d3
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Wed Jul 3 16:39:25 2024 -0400

    Ui Refactor
---
 karavan-app/src/main/webui/src/api/ProjectStore.ts |  6 ++
 .../src/main/webui/src/projects/ProjectsPage.tsx   | 51 ++++-------------
 .../main/webui/src/projects/ProjectsToolbar.tsx    | 64 ++++++++++++++++++++++
 .../webui/src/util/ModalDeleteConfirmation.tsx     | 35 ------------
 4 files changed, 82 insertions(+), 74 deletions(-)

diff --git a/karavan-app/src/main/webui/src/api/ProjectStore.ts 
b/karavan-app/src/main/webui/src/api/ProjectStore.ts
index 4cfed44c..07875a26 100644
--- a/karavan-app/src/main/webui/src/api/ProjectStore.ts
+++ b/karavan-app/src/main/webui/src/api/ProjectStore.ts
@@ -93,6 +93,8 @@ interface ProjectsState {
     projects: Project[];
     setProjects: (projects: Project[]) => void;
     upsertProject: (project: Project) => void;
+    filter: string;
+    setFilter: (filter: string) => void;
 }
 
 export const useProjectsStore = createWithEqualityFn<ProjectsState>((set) => ({
@@ -108,6 +110,10 @@ export const useProjectsStore = 
createWithEqualityFn<ProjectsState>((set) => ({
                 ? [...state.projects, project]
                 : [...state.projects.filter(f => f.projectId !== 
project.projectId), project]
         }));
+    },
+    filter: '',
+    setFilter: (filter: string) => {
+        set({filter: filter});
     }
 }), shallow)
 
diff --git a/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx 
b/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx
index a2028459..b9c23549 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx
@@ -15,23 +15,17 @@
  * limitations under the License.
  */
 
-import React, {useEffect, useState} from 'react';
+import React, {useEffect} from 'react';
 import {
-    Toolbar,
-    ToolbarContent,
-    ToolbarItem,
-    TextInput,
     PageSection,
     TextContent,
     Text,
-    Button,
     Bullseye,
     EmptyState,
     EmptyStateVariant,
     EmptyStateIcon, EmptyStateHeader
 } from '@patternfly/react-core';
 import './ProjectsPage.css';
-import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
 import {
     Tbody,
     Td,
@@ -51,46 +45,25 @@ import {MainToolbar} from "../designer/MainToolbar";
 import {Project, ProjectType} from "../api/ProjectModels";
 import {shallow} from "zustand/shallow";
 import {KaravanApi} from "../api/KaravanApi";
-import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon";
-import {ProjectService} from "../api/ProjectService";
+import {ProjectsToolbar} from "./ProjectsToolbar";
 
-export function ProjectsPage () {
+interface Props {
+    tools?: React.ReactNode
+}
 
-    const [projects, setProjects] = useProjectsStore((s) => [s.projects, 
s.setProjects], shallow)
-    const [operation, setProject] = useProjectStore((s) => [s.operation, 
s.setProject], shallow)
-    const [filter, setFilter] = useState<string>('');
+export function ProjectsPage (props: Props) {
+
+    const [projects, setProjects, filter, setFilter]
+        = useProjectsStore((s) => [s.projects, s.setProjects, s.filter, 
s.setFilter], shallow)
+    const [operation] = useProjectStore((s) => [s.operation], shallow)
 
     useEffect(() => {
         KaravanApi.getProjects((projects: Project[]) => {
             setProjects(projects);
+            setFilter('');
         });
     }, []);
 
-    function getTools() {
-        return <Toolbar id="toolbar-group-types">
-            <ToolbarContent>
-                <ToolbarItem>
-                    <Button icon={<RefreshIcon/>}
-                            variant={"link"}
-                            onClick={e => ProjectService.refreshProjects()}
-                    />
-                </ToolbarItem>
-                <ToolbarItem>
-                    <TextInput className="text-field" type="search" 
id="search" name="search"
-                               autoComplete="off" placeholder="Search by name"
-                               value={filter}
-                               onChange={(_, e) => setFilter(e)}/>
-                </ToolbarItem>
-                <ToolbarItem>
-                    <Button className="dev-action-button"
-                            icon={<PlusIcon/>}
-                            onClick={e =>
-                                setProject(new Project(), 'create')}
-                    >Create</Button>
-                </ToolbarItem>
-            </ToolbarContent>
-        </Toolbar>
-    }
 
     function title() {
         return <TextContent>
@@ -143,7 +116,7 @@ export function ProjectsPage () {
     return (
         <PageSection className="projects-page" padding={{default: 
'noPadding'}}>
             <PageSection className="tools-section" padding={{default: 
'noPadding'}}>
-                <MainToolbar title={title()} tools={getTools()}/>
+                <MainToolbar title={title()} tools={props.tools ? props.tools 
: <ProjectsToolbar/>}/>
             </PageSection>
             <PageSection isFilled className="project-section">
                 {getProjectsTable()}
diff --git a/karavan-app/src/main/webui/src/projects/ProjectsToolbar.tsx 
b/karavan-app/src/main/webui/src/projects/ProjectsToolbar.tsx
new file mode 100644
index 00000000..530fa348
--- /dev/null
+++ b/karavan-app/src/main/webui/src/projects/ProjectsToolbar.tsx
@@ -0,0 +1,64 @@
+/*
+ * 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,
+    ToolbarContent,
+    ToolbarItem,
+    TextInput,
+    Button,
+} from '@patternfly/react-core';
+import './ProjectsPage.css';
+import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon';
+import {useProjectsStore, useProjectStore} from "../api/ProjectStore";
+import {Project} from "../api/ProjectModels";
+import {shallow} from "zustand/shallow";
+import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon";
+import {ProjectService} from "../api/ProjectService";
+
+export function ProjectsToolbar () {
+
+    const [filter, setFilter] = useProjectsStore((s) => [s.filter, 
s.setFilter], shallow)
+    const [setProject] = useProjectStore((s) => [s.setProject], shallow)
+
+    return (
+        <Toolbar id="toolbar-group-types">
+            <ToolbarContent>
+                <ToolbarItem>
+                    <Button icon={<RefreshIcon/>}
+                            variant={"link"}
+                            onClick={e => ProjectService.refreshProjects()}
+                    />
+                </ToolbarItem>
+                <ToolbarItem>
+                    <TextInput className="text-field" type="search" 
id="search" name="search"
+                               autoComplete="off" placeholder="Search by name"
+                               value={filter}
+                               onChange={(_, e) => setFilter(e)}/>
+                </ToolbarItem>
+                <ToolbarItem>
+                    <Button className="dev-action-button"
+                            icon={<PlusIcon/>}
+                            onClick={e =>
+                                setProject(new Project(), 'create')}
+                    >Create</Button>
+                </ToolbarItem>
+            </ToolbarContent>
+        </Toolbar>
+    )
+}
\ No newline at end of file
diff --git a/karavan-app/src/main/webui/src/util/ModalDeleteConfirmation.tsx 
b/karavan-app/src/main/webui/src/util/ModalDeleteConfirmation.tsx
deleted file mode 100644
index ec4d0079..00000000
--- a/karavan-app/src/main/webui/src/util/ModalDeleteConfirmation.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import React from 'react';
-import {
-    Button,
-    Modal,
-    ModalVariant
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-
-interface Props {
-    content: string | React.JSX.Element
-    isOpen: boolean
-    onClose: () => void
-    onConfirm: () => void
-    title?: string
-}
-
-export function ModalDeleteConfirmation(props: Props) {
-
-    const {title, isOpen, onClose, onConfirm, content} = props;
-    return (
-            <Modal
-                title={title ? title : 'Confirmation'}
-                variant={ModalVariant.small}
-                isOpen={isOpen}
-                onClose={() => onClose()}
-                actions={[
-                    <Button key="confirm" variant="danger" onClick={e => 
onConfirm()}>Confirm</Button>,
-                    <Button key="cancel" variant="link"
-                            onClick={e => onClose()}>Cancel</Button>
-                ]}
-                onEscapePress={e => onClose()}>
-                {content}
-            </Modal>
-    )
-}
\ No newline at end of file

Reply via email to