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 ea21116823e896e1a1bdd9bba18cbc60668866d4 Author: Marat Gubaidullin <[email protected]> AuthorDate: Fri Feb 27 16:22:37 2026 -0500 Front-end Stores for 4.18.0 --- .../main/webui/src/karavan/stores/AccessStore.ts | 16 +++ .../webui/src/karavan/stores/DeveloperStore.ts | 14 -- .../main/webui/src/karavan/stores/ProjectStore.ts | 157 ++++++++++++--------- .../main/webui/src/karavan/stores/SearchStore.ts | 18 ++- .../main/webui/src/karavan/stores/SystemStore.ts | 16 +++ 5 files changed, 140 insertions(+), 81 deletions(-) diff --git a/karavan-app/src/main/webui/src/karavan/stores/AccessStore.ts b/karavan-app/src/main/webui/src/karavan/stores/AccessStore.ts index f92b5071..38a73db9 100644 --- a/karavan-app/src/main/webui/src/karavan/stores/AccessStore.ts +++ b/karavan-app/src/main/webui/src/karavan/stores/AccessStore.ts @@ -1,3 +1,19 @@ +/* + * 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 {createWithEqualityFn} from "zustand/traditional"; import {shallow} from "zustand/shallow"; import {AccessRole, AccessUser, PLATFORM_ADMIN, PLATFORM_DEVELOPER} from "@models/AccessModels"; diff --git a/karavan-app/src/main/webui/src/karavan/stores/DeveloperStore.ts b/karavan-app/src/main/webui/src/karavan/stores/DeveloperStore.ts deleted file mode 100644 index 6d25ebb4..00000000 --- a/karavan-app/src/main/webui/src/karavan/stores/DeveloperStore.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {createWithEqualityFn} from "zustand/traditional"; -import {shallow} from "zustand/shallow"; - -interface DeveloperState { - loading: boolean; - setLoading: (loading: boolean) => void; -} - -export const useDeveloperStore = createWithEqualityFn<DeveloperState>((set) => ({ - loading: false, - setLoading: (loading: boolean) => { - set({loading: loading}) - }, -}), shallow) \ No newline at end of file diff --git a/karavan-app/src/main/webui/src/karavan/stores/ProjectStore.ts b/karavan-app/src/main/webui/src/karavan/stores/ProjectStore.ts index d1255970..6e0edfc7 100644 --- a/karavan-app/src/main/webui/src/karavan/stores/ProjectStore.ts +++ b/karavan-app/src/main/webui/src/karavan/stores/ProjectStore.ts @@ -18,19 +18,21 @@ import { AppConfig, CamelStatus, ContainerImage, - ContainerStatus, DeploymentStatus, DesignerTab, FileOperation, Project, + ProjectCommited, ProjectFile, + ProjectFileCommited, ProjectOperation, ServiceStatus } from "@models/ProjectModels"; -import {ProjectEventBus} from "@bus/ProjectEventBus"; -import {unstable_batchedUpdates} from "react-dom"; import {createWithEqualityFn} from "zustand/traditional"; import {shallow} from "zustand/shallow"; +import {KaravanApi} from "@api/KaravanApi"; +import {AxiosResponse} from "axios"; +import isEqual from "lodash/isEqual"; interface AppConfigState { loading: boolean; @@ -84,22 +86,43 @@ export const useAppConfigStore = createWithEqualityFn<AppConfigState>((set) => ( interface ProjectsState { projects: Project[]; + projectsCommited: ProjectCommited[]; setProjects: (projects: Project[]) => void; upsertProject: (project: Project) => void; + fetchProjects: () => Promise<void>; + fetchProjectsCommited: () => Promise<void>; filter: string; setFilter: (filter: string) => void; labels: any; setLabels: (labels: any) => void; } -export const useProjectsStore = createWithEqualityFn<ProjectsState>((set) => ({ +export const useProjectsStore = createWithEqualityFn<ProjectsState>((set, get) => ({ projects: [], + projectsCommited: [], labels: {}, setProjects: (ps: Project[]) => { set((state: ProjectsState) => ({ projects: ps, })); }, + fetchProjects: async (): Promise<void> => { + await new Promise<Project[]>((resolve) => { + KaravanApi.getProjects(resolve); + }).then(projects => { + set({ projects: projects }); + }) + }, + fetchProjectsCommited: async (): Promise<void> => { + const currentProjectsCommited = get().projectsCommited; + await new Promise<ProjectCommited[]>((resolve) => { + KaravanApi.getProjectsCommited(resolve); + }).then(projectsCommited => { + if (!isEqual(currentProjectsCommited, projectsCommited)) { + set({ projectsCommited: projectsCommited }); + } + }) + }, setLabels: (labels: any) => { set({labels: labels}); }, @@ -117,8 +140,8 @@ export const useProjectsStore = createWithEqualityFn<ProjectsState>((set) => ({ }), shallow) -export const ProjectMenus = ['topology', 'files', 'readme', 'build', 'containers'] as const; -export const ProjectRuntimeMenus = ['JVM', 'camel', 'log'] as const; +export const ProjectMenus = ['topology', 'source','readme', 'build', 'containers'] as const; +export const ProjectRuntimeMenus = ['pod', 'JVM', 'camel', 'log', 'tryout'] as const; export type ProjectMenu = typeof ProjectMenus[number]; export type ProjectRuntimeMenu = typeof ProjectRuntimeMenus[number]; @@ -135,6 +158,7 @@ interface ProjectState { setOperation: (o: ProjectOperation) => void; camelStatuses: CamelStatus[], setCamelStatuses: (camelStatuses: CamelStatus[]) => void; + fetchCamelStatuses: (projectId: string, env: string) => Promise<void>; camelTraces: CamelStatus[], setCamelTraces: (camelTraces: CamelStatus[]) => void; refreshTrace: boolean @@ -182,6 +206,14 @@ export const useProjectStore = createWithEqualityFn<ProjectState>((set) => ({ return {camelStatuses: camelStatuses}; }); }, + fetchCamelStatuses: async (projectId: string, env: string): Promise<void> => { + await new Promise<AxiosResponse<CamelStatus[]>>((resolve) => { + KaravanApi.getProjectCamelStatuses(projectId, env, resolve); + }).then(response=> { + const statuses = response.status === 200 ? response.data : []; + set({camelStatuses: statuses}); + }) + }, camelTraces: [], setCamelTraces: (camelTraces: CamelStatus[]) => { set((state: ProjectState) => { @@ -194,26 +226,66 @@ export const useProjectStore = createWithEqualityFn<ProjectState>((set) => ({ }, }), shallow) + +export type FilesSideBarType = 'create' | 'upload' | 'library' + interface FilesState { files: ProjectFile[]; + commitedFiles: ProjectFileCommited[]; diff: any; setFiles: (files: ProjectFile[]) => void; + fetchFiles: (projectId: string) => Promise<ProjectFile[]>; + fetchCommitedFiles: (projectId: string) => Promise<any>; upsertFile: (file: ProjectFile) => void; selectedFileNames: string[]; setSelectedFileNames: (selectedFileNames: string[]) => void; selectFile: (filename: string) => void; unselectFile: (filename: string) => void; + selector: 'files' | 'commits'; + setSelector: (selector: 'files' | 'commits') => void; + showSideBar: FilesSideBarType; + setShowSideBar: (showSideBar: FilesSideBarType) => void; + title: string; + setTitle: (title: string) => void; } -export const useFilesStore = createWithEqualityFn<FilesState>((set) => ({ +export const useFilesStore = createWithEqualityFn<FilesState>((set, get) => ({ files: [], + commitedFiles: [], diff: {}, selectedFileNames: [], + selector: 'files', + showSideBar: null, + setShowSideBar: (showSideBar: FilesSideBarType) => { + set({showSideBar: showSideBar}); + }, + title: null, + setTitle: (title: string) => { + set({ title: title }); + }, setFiles: (files: ProjectFile[]) => { set((state: FilesState) => ({ files: files })); }, + fetchFiles: async (projectId: string): Promise<any> => { + return await new Promise<ProjectFile[]>((resolve) => { + KaravanApi.getFiles(projectId, resolve); + }).then(files => { + set({ files: files }); + return files; + }) + }, + fetchCommitedFiles: async (projectId: string): Promise<any> => { + const currentCommitedFiles = get().commitedFiles; + await new Promise<ProjectFileCommited[]>((resolve) => { + KaravanApi.getCommitedFiles(projectId, resolve); + }).then(files => { + if (!isEqual(currentCommitedFiles, files)) { + set({ commitedFiles: files }); + } + }) + }, upsertFile: (file: ProjectFile) => { set((state: FilesState) => ({ files: state.files.find(f => f.name === file.name) === undefined @@ -240,6 +312,9 @@ export const useFilesStore = createWithEqualityFn<FilesState>((set) => ({ const names = [...state.selectedFileNames.filter(f => f !== filename)]; return ({selectedFileNames: names}) }); + }, + setSelector: (selector: 'files' | 'commits') => { + set({selector: selector}); } }), shallow) @@ -301,7 +376,6 @@ export const useDevModeStore = createWithEqualityFn<DevModeState>((set) => ({ interface StatusesState { deployments: DeploymentStatus[]; services: ServiceStatus[]; - containers: ContainerStatus[]; camelContexts: CamelStatus[]; routes: CamelStatus[]; setRoutes: (routes: CamelStatus[]) => void; @@ -311,14 +385,14 @@ interface StatusesState { setProcessors: (processors: CamelStatus[]) => void; setDeployments: (d: DeploymentStatus[]) => void; setServices: (s: ServiceStatus[]) => void; - setContainers: (c: ContainerStatus[]) => void; setCamelContexts: (camelContexts: CamelStatus[]) => void; + camels: CamelStatus[]; + setCamels: (c: CamelStatus[]) => void; } -export const useStatusesStore = createWithEqualityFn<StatusesState>((set) => ({ +export const useStatusesStore = createWithEqualityFn<StatusesState>((set, get) => ({ deployments: [], services: [], - containers: [], camelContexts: [], routes: [], consumers: [], @@ -333,11 +407,6 @@ export const useStatusesStore = createWithEqualityFn<StatusesState>((set) => ({ services: s, })); }, - setContainers: (c: ContainerStatus[]) => { - set((state: StatusesState) => ({ - containers: c, - })); - }, setCamelContexts: (c: CamelStatus[]) => { set((state: StatusesState) => ({ camelContexts: c, @@ -354,42 +423,15 @@ export const useStatusesStore = createWithEqualityFn<StatusesState>((set) => ({ setProcessors: (processors: CamelStatus[]) => { set({processors}) }, -}), shallow) - -interface LogState { - podName?: string, - data: string; - setData: (data: string) => void; - addData: (data: string) => void; - addDataAsync: (data: string) => void; - currentLine: number; - setCurrentLine: (currentLine: number) => void; -} - -export const useLogStore = createWithEqualityFn<LogState>((set) => ({ - podName: undefined, - data: '', - setData: (data: string) => { - set({data: data}) - }, - addData: (data: string) => { - set((state: LogState) => { - const delimiter = state.data.endsWith('\n') ? '' : '\n'; - return ({data: state.data.concat(delimiter, data)}) - }) - }, - addDataAsync: async (data: string) => { - set((state: LogState) => { - const delimiter = state.data.endsWith('\n') ? '' : '\n'; - return ({data: state.data.concat(delimiter, data)}) - }) - }, - currentLine: 0, - setCurrentLine: (currentLine: number) => { - set((state: LogState) => ({currentLine: currentLine})) + camels: [], + setCamels: (c: CamelStatus[]) => { + set((state: StatusesState) => ({ + camels: c, + })); }, }), shallow) + interface SelectedContainerState { selectedContainerName?: string; setSelectedContainerName: (selectedContainerName?: string) => void; @@ -400,20 +442,3 @@ export const useSelectedContainerStore = createWithEqualityFn<SelectedContainerS set({selectedContainerName: selectedContainerName }) }, }), shallow) - - -const sub = ProjectEventBus.onLog()?.subscribe((result: ["add" | "set", string]) => { - if (result[0] === 'add') { - unstable_batchedUpdates(() => { - useLogStore.setState((state: LogState) => { - const delimiter = state.data.endsWith('\n') ? '' : '\n'; - const newData = state.data ? state.data.concat(delimiter, result[1]) : result[1] - return ({data: newData, currentLine: state.currentLine + 1}); - }) - }) - } else if (result[0] === 'set') { - unstable_batchedUpdates(() => { - useLogStore.setState({data: result[1], currentLine: 0}); - }) - } -}); diff --git a/karavan-app/src/main/webui/src/karavan/stores/SearchStore.ts b/karavan-app/src/main/webui/src/karavan/stores/SearchStore.ts index 14a6c0da..8e533874 100644 --- a/karavan-app/src/main/webui/src/karavan/stores/SearchStore.ts +++ b/karavan-app/src/main/webui/src/karavan/stores/SearchStore.ts @@ -1,6 +1,22 @@ +/* + * 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 {createWithEqualityFn} from "zustand/traditional"; import {shallow} from "zustand/shallow"; -import {SearchResult} from "../models/SearchModels"; +import {SearchResult} from "@models/SearchModels"; interface SearchState { search: string; diff --git a/karavan-app/src/main/webui/src/karavan/stores/SystemStore.ts b/karavan-app/src/main/webui/src/karavan/stores/SystemStore.ts index bd3ea094..0b374a99 100644 --- a/karavan-app/src/main/webui/src/karavan/stores/SystemStore.ts +++ b/karavan-app/src/main/webui/src/karavan/stores/SystemStore.ts @@ -1,3 +1,19 @@ +/* + * 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 {createWithEqualityFn} from "zustand/traditional"; import {shallow} from "zustand/shallow"; import {KubernetesConfigMap, KubernetesSecret} from "@models/SystemModels";
