This is an automated email from the ASF dual-hosted git repository.

mgubaidullin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit 3ec0329e47a350057eb3ff180bd35c4d47559648
Author: Marat Gubaidullin <[email protected]>
AuthorDate: Mon Aug 24 17:57:01 2026 -0400

    Karavan-app UI Page Settings
---
 .../webui/src/ui/page-settings/SettingsPage.tsx    | 110 +++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/karavan-app/src/main/webui/src/ui/page-settings/SettingsPage.tsx 
b/karavan-app/src/main/webui/src/ui/page-settings/SettingsPage.tsx
new file mode 100644
index 00000000..fc12537b
--- /dev/null
+++ b/karavan-app/src/main/webui/src/ui/page-settings/SettingsPage.tsx
@@ -0,0 +1,110 @@
+import React, {useEffect, useState} from 'react';
+import {capitalize, Content, Tab, Tabs, TabTitleText,} from 
'@patternfly/react-core';
+import {RightPanel} from "@shared/ui/RightPanel";
+import {useFilesStore, useFileStore, useProjectsStore, useProjectStore} from 
"@stores/ProjectStore";
+import {shallow} from "zustand/shallow";
+import {DeveloperManager} from "@developer/DeveloperManager";
+import {ErrorBoundaryWrapper} from "@shared/ui/ErrorBoundaryWrapper";
+import {SourcesTab} from "@page-project/files/SourcesTab";
+import {useParams} from "react-router-dom";
+import {SettingsMenu, SettingsMenus, useSettingsStore} from 
"@stores/SettingsStore";
+import {ROUTES} from "@compass/navigation/Routes";
+import {ProjectFile} from "@models/ProjectModels";
+import {ProjectToolbar} from "@page-project/toolbar/ProjectToolbar";
+import {TabProps} from "@patternfly/react-core/src/components/Tabs/Tab";
+import {SourcesDrawerPanel} from "@page-project/files/SourcesDrawerPanel";
+
+export function SettingsPage() {
+
+    const [projects] = useProjectsStore((s) => [s.projects], shallow)
+    const [setProject] = useProjectStore((s) => [s.setProject], shallow);
+    const [file, operation, setFile] = useFileStore((s) => [s.file, 
s.operation, s.setFile], shallow);
+    const [fetchFiles, fetchCommitedFiles, setFiles] = useFilesStore((s) => 
[s.fetchFiles, s.fetchCommitedFiles, s.setFiles], shallow);
+    const showFilePanel = file !== undefined && operation === 'select';
+    const {setCurrentMenu, currentMenu} = useSettingsStore();
+    const [key, setKey] = useState<string>();
+
+    const {projectId, fileName} = useParams();
+
+    useEffect(() => {
+        window.history.replaceState({}, "", `${ROUTES.SETTINGS}`);
+        if (projectId && fileName) {
+            selectProject(projectId, fileName);
+        } else {
+            selectProject(SettingsMenus[0], fileName);
+            setCurrentMenu(SettingsMenus[0]);
+        }
+        return () => {
+            setCurrentMenu(SettingsMenus[0]);
+            selectProject(undefined);
+            setFiles([])
+        };
+    }, []);
+
+    function title() {
+        return (<Content component="h2">Settings</Content>)
+    }
+
+    const onNavSelect = (event: React.MouseEvent<HTMLElement, MouseEvent>, 
eventKey: TabProps['eventKey']) => {
+        setCurrentMenu(eventKey as SettingsMenu);
+        selectProject(eventKey as string, undefined);
+        setFile("none", undefined);
+    };
+
+    function selectProject(projectId: string, fileName?: string) {
+        const p = projects.find(p => p.projectId === projectId);
+        if (p) {
+            setProject(p, "select");
+            fetchFiles(p.projectId).then(value => {
+                fetchCommitedFiles(p.projectId).then(_ => {
+                    selectFile(value, fileName);
+                })
+            });
+        }
+    }
+
+    function selectFile(newFiles: ProjectFile[], fileName?: string) {
+        if (fileName) {
+            const f = newFiles?.find(file => file.name === fileName);
+            setFile('select', f);
+        } else {
+            setFile('none', undefined);
+        }
+        setKey(new Date().toLocaleString("en-US"));
+    }
+
+    function getNavigation() {
+        return (
+            <Tabs onSelect={onNavSelect} isNav activeKey={currentMenu}>
+                {SettingsMenus.map((item, i) => {
+                    return (
+                        <Tab
+                            key={item}
+                            eventKey={item}
+                            
title={<TabTitleText>{capitalize(item?.toString())}</TabTitleText>}
+                        />
+                    )
+                })}
+            </Tabs>
+        )
+    }
+
+    return (
+        <RightPanel
+            title={title()}
+            toolsStart={getNavigation()}
+            tools={currentMenu === 'configuration' && <ProjectToolbar/>}
+            drawerPanel={<SourcesDrawerPanel/>}
+            mainPanel={
+                <div key={key} className="right-panel-card">
+                    <ErrorBoundaryWrapper onError={error => 
console.error(error)}>
+                        {!showFilePanel && currentMenu === 'templates' && 
<SourcesTab/>}
+                        {!showFilePanel && currentMenu === 'kamelets' && 
<SourcesTab/>}
+                        {!showFilePanel && currentMenu === 'configuration' && 
<SourcesTab/>}
+                        {showFilePanel && <DeveloperManager/>}
+                    </ErrorBoundaryWrapper>
+                </div>
+            }
+        />
+    )
+}
\ No newline at end of file

Reply via email to