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

Reply via email to