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 42e2ac895a3431b0ef894d51efdfaf7eaaea4553 Author: Marat Gubaidullin <[email protected]> AuthorDate: Mon Aug 24 15:33:09 2026 -0400 Karavan Webapp UI Models --- .../src/main/webui/src/models/AccessModels.ts | 89 +++++++ .../src/main/webui/src/models/ComplexityModels.ts | 68 +++++ .../src/main/webui/src/models/LandscapeModels.ts | 45 ++++ .../src/main/webui/src/models/ProjectModels.ts | 296 +++++++++++++++++++++ .../src/main/webui/src/models/SearchModels.ts | 20 ++ .../src/main/webui/src/models/ServiceModels.ts | 70 +++++ .../src/main/webui/src/models/SystemModels.ts | 33 +++ 7 files changed, 621 insertions(+) diff --git a/karavan-app/src/main/webui/src/models/AccessModels.ts b/karavan-app/src/main/webui/src/models/AccessModels.ts new file mode 100644 index 00000000..a2f9c2c8 --- /dev/null +++ b/karavan-app/src/main/webui/src/models/AccessModels.ts @@ -0,0 +1,89 @@ +/* + * 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. + */ +export class AccessUser { + username: string = ''; + firstName: string = ''; + lastName: string = '' + email: string = ''; + status: string = 'ACTIVE'; + passNeedUpdate: boolean = true; + roles: string[] = []; + + public constructor(init?: Partial<AccessUser>) { + Object.assign(this, init); + } +} + +/** + * Represents the external agent metadata stored in the platform cache. + */ +export interface AccessToken { + hashedToken: string; + ownerName: string; + clientName: string; + allowedProjectIds: string[]; + createdAt: string; // ISO-8601 string, e.g., "2026-06-12T15:46:14Z" + expiresAt: string; // ISO-8601 string +} + +/** + * Payload sent to the backend to generate a new agent token. + */ +export interface GenerateTokenRequest { + clientName: string; + allowedProjectIds?: string[]; // Optional: if omitted, backend defaults to ["*"] + expiresInDays?: number; // Optional: if omitted, backend defaults to 30 +} + +/** + * The response returned exactly once upon successful token creation. + */ +export interface GenerateTokenResponse { + rawToken: string; // The plaintext token starting with "tal_". Must be shown to the user immediately. + metadata: AccessToken; // The cache record data to append to the UI tables. +} + +export class AccessRole { + name: string = ''; + description: string = ''; + + + public constructor(init?: Partial<AccessRole>) { + Object.assign(this, init); + } +} + +export interface SessionInfo { + username: string; + createdAt: number; + expiredAt: number; +} + +export class AccessPassword { + currentPassword: string = '' + password: string = '' + password2: string = '' + + + public constructor(init?: Partial<AccessPassword>) { + Object.assign(this, init); + } +} + +export const PLATFORM_ADMIN = 'platform-admin' +export const PLATFORM_USER = 'platform-user' +export const PLATFORM_DEVELOPER = 'platform-developer' diff --git a/karavan-app/src/main/webui/src/models/ComplexityModels.ts b/karavan-app/src/main/webui/src/models/ComplexityModels.ts new file mode 100644 index 00000000..09daf275 --- /dev/null +++ b/karavan-app/src/main/webui/src/models/ComplexityModels.ts @@ -0,0 +1,68 @@ +/* + * 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. + */ +export enum ComplexityRouteType { + ROUTE = "ROUTE", + ROUTE_TEMPlATE = "ROUTE_TEMPlATE", + TEMPLATED_ROUTE = "TEMPLATED_ROUTE", +} + +export class ComplexityRoute { + routeId: string = '' + nodePrefixId: string = '' + fileName: string = '' + consumers: any = []; + producers: any[] = []; + routeTemplateRef: string; + type: ComplexityRouteType; + parameters: any +} + +export class ComplexityFile { + fileName: string = ''; + error: string = ''; + type: string = ''; + chars: number = 0; + routes: number = 0; + beans: number = 0; + rests: number = 0; + processors: any = {}; + componentsInt: any = {}; + componentsExt: any = {}; + kamelets: any = {}; + generated: boolean = false; + + public constructor(init?: Partial<ComplexityFile>) { + Object.assign(this, init); + } +} + +export class ComplexityProject { + projectId: string = ''; + lastUpdateDate: number = 0; + files: ComplexityFile[] = [] + routes: ComplexityRoute[] = [] + dependencies: string[] = [] + rests: number = 0; + exposesOpenApi: boolean = false; + mcp: boolean = false; + agents: boolean = false; + type: string; + + public constructor(init?: Partial<ComplexityProject>) { + Object.assign(this, init); + } +} diff --git a/karavan-app/src/main/webui/src/models/LandscapeModels.ts b/karavan-app/src/main/webui/src/models/LandscapeModels.ts new file mode 100644 index 00000000..5dd83104 --- /dev/null +++ b/karavan-app/src/main/webui/src/models/LandscapeModels.ts @@ -0,0 +1,45 @@ +/* + * 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. + */ +export class TopologyNodePosition { + id: string = ''; + x: number = 0; + y: number = 0; + collapsed?: boolean; +} + +export class LandscapeTopology { + nodes: TopologyNodePosition[] = []; + graph: any; +} + +export interface ILandscapeTag { + name: string; +} + +export interface ILandscapeApplication { + id: string; + name: string; + description: string; + tags: ILandscapeTag[]; +} + +export interface ILandscapeTemplate { + projectId: string; + fileName: string; + xKey: string; + serverId: string; +} diff --git a/karavan-app/src/main/webui/src/models/ProjectModels.ts b/karavan-app/src/main/webui/src/models/ProjectModels.ts new file mode 100644 index 00000000..bd907006 --- /dev/null +++ b/karavan-app/src/main/webui/src/models/ProjectModels.ts @@ -0,0 +1,296 @@ +/* + * 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 {LANDSCAPE_FILE_NAME_JSON, LANDSCAPE_FILE_NAME_YAML} from "@core/contants"; + +export type FileOperation = + | "create" + | "select" + | "delete" + | "none" + | "copy" + | "upload" + | "rename" + | "diff"; + +export type ProjectOperation = "create" | "select" | "delete" | "none" | "copy" + +export type DesignerTab = "routes" | "rest" | "beans" | "kamelet"; + +export const DOCKER_COMPOSE = "docker-compose.yaml"; +export const KUBERNETES_YAML = "kubernetes.yaml"; +export const APPLICATION_PROPERTIES = 'application.properties'; +export const BUILD_SH = 'build.sh'; +export const BUILD_DOCKER_COMPOSE = 'builder.' + DOCKER_COMPOSE; +export const DASHBOARD_LAYOUT_JSON = 'dashboard-layout.json'; +export const LANDSCAPE_LAYOUT_JSON = 'landscape-layout.json'; +export const BUILD_IN_FILES = [ + APPLICATION_PROPERTIES, + DOCKER_COMPOSE, + KUBERNETES_YAML, + LANDSCAPE_FILE_NAME_JSON, + LANDSCAPE_FILE_NAME_YAML, + BUILD_SH, + DASHBOARD_LAYOUT_JSON, + BUILD_DOCKER_COMPOSE, +]; + +export class AppConfig { + title: string = ''; + version: string = ''; + infrastructure: 'kubernetes' | 'docker' | 'local' = 'local'; + environment: string = ''; + environments: string[] = []; + status: any[] = []; + configFilenames: any[] = []; + advanced: any = {} + platformSecretName: string = ''; + platformConfigName: string = ''; +} + +export enum ProjectType { + integration = 'integration', + templates = 'templates', + kamelets = 'kamelets', + configuration = 'configuration', + documentation = 'documentation', + services = 'services', +} + +export const BUILD_IN_PROJECTS: string[] = [ + ProjectType.kamelets.toString(), + ProjectType.templates.toString(), + ProjectType.configuration.toString(), + ProjectType.services.toString(), + ProjectType.documentation.toString(), +]; + +export const RESERVED_WORDS: string[] = [...BUILD_IN_PROJECTS, 'karavan']; + +export interface ProjectCommited { + projectId: string; + lastCommit: string; + lastCommitTimestamp: number; +} + +export class Project { + projectId: string = ''; + name: string = ''; + lastUpdate: number = 0; + type: string = ProjectType.integration; + + public constructor(projectId: string, name: string, lastCommit: string, type: string); + public constructor(init?: Partial<Project>); + public constructor(...args: any[]) { + if (args.length === 1) { + Object.assign(this, args[0]); + return; + } else { + this.projectId = args[0]; + this.name = args[1]; + this.lastUpdate = args[2]; + this.type = args[3]; + return; + } + } +} + +export class DeploymentStatus { + projectId: string = ''; + env: string = ''; + namespace: string = ''; + cluster: string = ''; + image: string = ''; + replicas: number = 0; + readyReplicas: number = 0; + unavailableReplicas: number = 0; + type: 'devmode' | 'packaged' | 'internal' | 'build' | 'unknown' = 'unknown'; +} + +export class ServiceStatus { + name: string = ''; + env: string = ''; + namespace: string = ''; + cluster: string = ''; + port: string = ''; + targetPort: string = ''; + clusterIP: string = ''; + type: string = ''; +} + +export class ContainerPort { + privatePort?: number; + publicPort?: number; + type: string = ''; +} + +export type ContainerType = 'devmode' | 'packaged' | 'internal' | 'build' | 'unknown'; + +export class ContainerStatus { + containerName: string = ''; + containerId: string = ''; + state: string = ''; + stateMessage: string = ''; + phase: string = ''; + deployment: string = ''; + projectId: string = ''; + env: string = ''; + type: ContainerType = 'unknown'; + memoryInfo: string = ''; + cpuInfo: string = ''; + created: string = ''; + finished: string = ''; + image: string = ''; + commit: string = ''; + podId: string = ''; + ports: ContainerPort [] = []; + commands: string [] = []; + inTransit: boolean = false; + labels: any + + public constructor(init?: Partial<ContainerStatus>) { + Object.assign(this, init); + } +} + +export class PodEvent { + id: string = ''; + containerName: string = ''; + reason: string = '' + note: string = ''; + type: string = ''; + count: number = 0; + lastTimestamp: string = ''; + + public constructor(init?: Partial<PodEvent>) { + Object.assign(this, init); + } +} + +export class CamelStatus { + projectId: string = ''; + containerName: string = ''; + statuses: CamelStatusValue[] = []; + env: string = ''; +} + +export type CamelStatusName = 'context' | 'route' | 'processor' | 'consumer' | 'platform_http'; + +export class CamelStatusValue { + name: string = ''; + status: string = ''; +} + +export class ProjectFile { + name: string = ''; + projectId: string = ''; + code: string = ''; + lastUpdate: number; + + constructor(name: string, projectId: string, code: string, lastUpdate: number) { + this.name = name; + this.projectId = projectId; + this.code = code; + this.lastUpdate = lastUpdate; + } +} + +export interface ProjectFileCommited { + name: string; + projectId: string; + code: string; + commitTime: number; + syncDate: number; +} + + +export class ProjectFileType { + name: string = ''; + title: string = ''; + extension: string = ''; + + constructor(name: string, title: string, extension: string) { + this.name = name; + this.title = title; + this.extension = extension; + } +} + +export class ContainerImage { + id: string = ''; + tag: string = ''; + size: number = 0; + created: number = 0; +} + +export const ProjectFileTypes: ProjectFileType[] = [ + new ProjectFileType("INTEGRATION", "Integration", "camel.yaml"), + new ProjectFileType("KAMELET", "Kamelet", "kamelet.yaml"), + new ProjectFileType("JAVA", "Java", "java"), + new ProjectFileType("GROOVY", "Groovy", "groovy"), + new ProjectFileType("PROPERTIES", "Properties", "properties"), + new ProjectFileType("JSON", "JSON", "json"), + new ProjectFileType("OPENAPI", "OpenAPI", "json"), + new ProjectFileType("ASYNCAPI", "AsyncAPI", "yaml"), + new ProjectFileType("ASYNCAPI", "AsyncAPI", "json"), + new ProjectFileType("YAML", "YAML", "yaml"), + new ProjectFileType("DOCKER", "Docker Compose", "yaml"), + new ProjectFileType("SH", "Script", "sh"), + new ProjectFileType("MARKDOWN", "Markdown", "md"), + new ProjectFileType("SVG", "Svg", "svg"), + new ProjectFileType("OTHER", "Other", "*"), +]; + +function getProjectFileType(file: ProjectFile) { + return getProjectFileTypeByName(file.name); +} + +export function getProjectFileTypeByName(fileName: string): ProjectFileType[] { + if (fileName === DOCKER_COMPOSE) return ProjectFileTypes.filter(p => p.name === "DOCKER") + if (fileName.endsWith(".camel.yaml")) return ProjectFileTypes.filter(p => p.name === "INTEGRATION") + if (fileName.endsWith(".kamelet.yaml")) return ProjectFileTypes.filter(p => p.name === "KAMELET") + if (fileName === "openapi.json") return ProjectFileTypes.filter(p => p.name === "OPENAPI") + if (fileName === "asyncapi.json") return ProjectFileTypes.filter(p => p.name === "ASYNCAPI") + if (fileName === "landscape-asyncapi.json") return ProjectFileTypes.filter(p => p.name === "ASYNCAPI") + if (fileName === "asyncapi.yaml") return ProjectFileTypes.filter(p => p.name === "ASYNCAPI") + if (fileName.endsWith(".json")) return ProjectFileTypes.filter(p => p.name === "JSON") + if (fileName.endsWith(".yaml")) return ProjectFileTypes.filter(p => p.name === "YAML") + if (fileName.endsWith(".yml")) return ProjectFileTypes.filter(p => p.name === "YAML") + if (fileName.endsWith(".groovy")) return ProjectFileTypes.filter(p => p.name === "GROOVY") + if (fileName.endsWith(".java")) return ProjectFileTypes.filter(p => p.name === "JAVA") + if (fileName.endsWith(".md")) return ProjectFileTypes.filter(p => p.name === "MARKDOWN") + if (fileName.endsWith(".svg")) return ProjectFileTypes.filter(p => p.name === "SVG") + const extension = fileName.substring(fileName.lastIndexOf('.') + 1); + return ProjectFileTypes.filter(p => p.extension === extension); +} + +export function getProjectFileTypeName(file: ProjectFile) { + const types = getProjectFileType(file); + return types.length > 0 ? types.map(p => p.name)[0] : "OTHER"; +} + +export function getProjectFileTypeTitle(file: ProjectFile) { + const types = getProjectFileType(file); + return types.length > 0 ? types.map(p => p.title)[0] : "Other"; +} + +export function getProjectFileTypeByNameTitle(fileName: string) { + const types = getProjectFileTypeByName(fileName); + return types.length > 0 ? types.map(p => p.title)[0] : "Other"; +} + diff --git a/karavan-app/src/main/webui/src/models/SearchModels.ts b/karavan-app/src/main/webui/src/models/SearchModels.ts new file mode 100644 index 00000000..e7e64e31 --- /dev/null +++ b/karavan-app/src/main/webui/src/models/SearchModels.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ +export class SearchResult { + projectId: string = ''; + files: string[] = []; +} diff --git a/karavan-app/src/main/webui/src/models/ServiceModels.ts b/karavan-app/src/main/webui/src/models/ServiceModels.ts new file mode 100644 index 00000000..6578e17e --- /dev/null +++ b/karavan-app/src/main/webui/src/models/ServiceModels.ts @@ -0,0 +1,70 @@ +/* + * 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 * as yaml from 'js-yaml'; + +export class Healthcheck { + interval: string = ''; + retries: number = 0; + timeout: string = ''; + test: string [] = []; + + public constructor(init?: Partial<Healthcheck>) { + Object.assign(this, init); + } +} + +export class DockerComposeService { + container_name: string = ''; + image: string = ''; + restart: string = ''; + ports: string [] = []; + depends_on: string [] =[]; + environment: any = {}; + healthcheck?: Healthcheck; + + public constructor(init?: Partial<DockerComposeService>) { + Object.assign(this, init); + } +} + +export class DockerCompose { + version: string = ''; + services: DockerComposeService[] = []; + + public constructor(init?: Partial<DockerCompose>) { + Object.assign(this, init); + } +} + +export class ServicesYaml { + + static yamlToServices(code: string): DockerCompose { + const obj = yaml.load(code); + const fromYaml = JSON.parse(JSON.stringify(obj)); + const result: DockerCompose = new DockerCompose({version: fromYaml.version}); + Object.keys(fromYaml.services).forEach(key => { + const o = fromYaml.services[key]; + const service = new DockerComposeService(o); + if (!service.container_name) { + service.container_name = key; + } + result.services.push(service); + }) + return result; + } +} diff --git a/karavan-app/src/main/webui/src/models/SystemModels.ts b/karavan-app/src/main/webui/src/models/SystemModels.ts new file mode 100644 index 00000000..119b4233 --- /dev/null +++ b/karavan-app/src/main/webui/src/models/SystemModels.ts @@ -0,0 +1,33 @@ +/* + * 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. + */ +export class KubernetesSecret { + name: string = ''; + data: any = {} + + public constructor(init?: Partial<KubernetesSecret>) { + Object.assign(this, init); + } +} + +export class KubernetesConfigMap { + name: string = ''; + data: any = {} + + public constructor(init?: Partial<KubernetesSecret>) { + Object.assign(this, init); + } +} \ No newline at end of file
