diff --git a/backend/capellacollab/config/models.py b/backend/capellacollab/config/models.py
index cc89b851e..9315d3917 100644
--- a/backend/capellacollab/config/models.py
+++ b/backend/capellacollab/config/models.py
@@ -330,6 +330,30 @@ class PrometheusConfig(BaseConfig):
)
+class SmtpConfig(BaseConfig):
+ enabled: bool = pydantic.Field(
+ default=False,
+ description="Whether to enable SMTP. Necessary for feedback.",
+ examples=[True, False],
+ )
+ host: str = pydantic.Field(
+ description="The SMTP server host.",
+ examples=["smtp.example.com:587"],
+ pattern=r"^(.*):(\d+)$",
+ )
+ user: str = pydantic.Field(
+ description="The SMTP server user.", examples=["username"]
+ )
+ password: str = pydantic.Field(
+ description="The SMTP server password.",
+ examples=["password"],
+ )
+ sender: str = pydantic.Field(
+ description="The sender email address.",
+ examples=["capella@example.com"],
+ )
+
+
class AppConfig(BaseConfig):
docker: DockerConfig = DockerConfig()
k8s: K8sConfig = K8sConfig(context="k3d-collab-cluster")
@@ -342,3 +366,4 @@ class AppConfig(BaseConfig):
logging: LoggingConfig = LoggingConfig()
requests: RequestsConfig = RequestsConfig()
pipelines: PipelineConfig = PipelineConfig()
+ smtp: t.Optional[SmtpConfig] = None
diff --git a/backend/capellacollab/feedback/__init__.py b/backend/capellacollab/feedback/__init__.py
new file mode 100644
index 000000000..04412280d
--- /dev/null
+++ b/backend/capellacollab/feedback/__init__.py
@@ -0,0 +1,2 @@
+# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+# SPDX-License-Identifier: Apache-2.0
diff --git a/backend/capellacollab/feedback/exceptions.py b/backend/capellacollab/feedback/exceptions.py
new file mode 100644
index 000000000..41d380c84
--- /dev/null
+++ b/backend/capellacollab/feedback/exceptions.py
@@ -0,0 +1,26 @@
+# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+# SPDX-License-Identifier: Apache-2.0
+
+from fastapi import status
+
+from capellacollab.core import exceptions as core_exceptions
+
+
+class SmtpNotSetupError(core_exceptions.BaseError):
+ def __init__(self):
+ super().__init__(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ title="SMTP is not set up",
+ reason="SMTP must be set up to perform this action",
+ err_code="SMTP_NOT_SETUP",
+ )
+
+
+class FeedbackNotEnabledError(core_exceptions.BaseError):
+ def __init__(self):
+ super().__init__(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ title="Feedback is not set enabled",
+ reason="Feedback must be set up to perform this action",
+ err_code="FEEDBACK_NOT_SETUP",
+ )
diff --git a/backend/capellacollab/feedback/models.py b/backend/capellacollab/feedback/models.py
new file mode 100644
index 000000000..c32e85a1a
--- /dev/null
+++ b/backend/capellacollab/feedback/models.py
@@ -0,0 +1,51 @@
+# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+# SPDX-License-Identifier: Apache-2.0
+
+import datetime
+import enum
+import typing as t
+
+import pydantic
+
+from capellacollab.core import models as core_models
+from capellacollab.core import pydantic as core_pydantic
+from capellacollab.sessions.models import SessionType
+from capellacollab.tools import models as tools_models
+
+
+class FeedbackRating(str, enum.Enum):
+ GOOD = "good"
+ OKAY = "okay"
+ BAD = "bad"
+
+
+class AnonymizedSession(core_pydantic.BaseModel):
+ id: str
+ type: SessionType
+ created_at: datetime.datetime
+
+ version: tools_models.ToolVersionWithTool
+
+ state: str = pydantic.Field(default="UNKNOWN")
+ warnings: list[core_models.Message] = pydantic.Field(default=[])
+
+ connection_method_id: str
+ connection_method: tools_models.ToolSessionConnectionMethod | None = None
+
+
+class Feedback(core_pydantic.BaseModel):
+ rating: FeedbackRating = pydantic.Field(
+ description="The rating of the feedback"
+ )
+ feedback_text: t.Optional[str] = pydantic.Field(
+ description="The feedback text"
+ )
+ share_contact: bool = pydantic.Field(
+ description="Whether the user wants to share their contact information"
+ )
+ sessions: list[AnonymizedSession] = pydantic.Field(
+ description="The sessions the feedback is for"
+ )
+ trigger: str = pydantic.Field(
+ description="What triggered the feedback form"
+ )
diff --git a/backend/capellacollab/feedback/routes.py b/backend/capellacollab/feedback/routes.py
new file mode 100644
index 000000000..117af88cb
--- /dev/null
+++ b/backend/capellacollab/feedback/routes.py
@@ -0,0 +1,47 @@
+# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+# SPDX-License-Identifier: Apache-2.0
+
+
+import typing as t
+
+import fastapi
+from sqlalchemy import orm
+
+from capellacollab.core import database
+from capellacollab.feedback.models import Feedback
+from capellacollab.feedback.util import is_feedback_allowed, send_email
+from capellacollab.settings.configuration import core as config_core
+from capellacollab.settings.configuration import (
+ models as settings_config_models,
+)
+from capellacollab.settings.configuration.models import FeedbackConfiguration
+from capellacollab.users import injectables as user_injectables
+from capellacollab.users import models as users_models
+
+router = fastapi.APIRouter()
+
+
+@router.get(
+ "/feedback",
+ response_model=FeedbackConfiguration,
+)
+def get_feedback(db: orm.Session = fastapi.Depends(database.get_db)):
+ cfg = config_core.get_config(db, "global")
+ assert isinstance(cfg, settings_config_models.GlobalConfiguration)
+
+ return FeedbackConfiguration.model_validate(cfg.feedback.model_dump())
+
+
+@router.post("/feedback")
+def submit_feedback(
+ feedback: Feedback,
+ background_tasks: fastapi.BackgroundTasks,
+ user_agent: t.Annotated[str | None, fastapi.Header()] = None,
+ user: users_models.DatabaseUser = fastapi.Depends(
+ user_injectables.get_own_user
+ ),
+ db: orm.Session = fastapi.Depends(database.get_db),
+):
+ is_feedback_allowed(db)
+ background_tasks.add_task(send_email, feedback, user, user_agent, db)
+ return {"status": "sending"}
diff --git a/backend/capellacollab/feedback/util.py b/backend/capellacollab/feedback/util.py
new file mode 100644
index 000000000..f07c37380
--- /dev/null
+++ b/backend/capellacollab/feedback/util.py
@@ -0,0 +1,117 @@
+# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+# SPDX-License-Identifier: Apache-2.0
+
+import smtplib
+import typing as t
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+from sqlalchemy import orm
+
+from capellacollab.config import config
+from capellacollab.feedback import exceptions
+from capellacollab.feedback.models import AnonymizedSession, Feedback
+from capellacollab.settings.configuration import core as config_core
+from capellacollab.settings.configuration import (
+ models as settings_config_models,
+)
+from capellacollab.settings.configuration.models import (
+ FeedbackAnonymityPolicy,
+ FeedbackConfiguration,
+)
+from capellacollab.users import models as users_models
+
+
+def format_session(session: AnonymizedSession):
+ return f"{session.version.tool.name} ({session.version.name})"
+
+
+def is_feedback_allowed(db: orm.Session):
+ if not config.smtp or not config.smtp.enabled:
+ raise exceptions.SmtpNotSetupError()
+
+ cfg = config_core.get_config(db, "global")
+ assert isinstance(cfg, settings_config_models.GlobalConfiguration)
+ feedback_config = FeedbackConfiguration.model_validate(
+ cfg.feedback.model_dump()
+ )
+ if not feedback_config.enabled:
+ raise exceptions.FeedbackNotEnabledError()
+
+
+def format_email(
+ feedback: Feedback,
+ user: t.Optional[users_models.DatabaseUser],
+ user_agent: str | None,
+):
+ message = "\n".join(
+ [
+ f"Rating: {feedback.rating.value}",
+ f"Text: {feedback.feedback_text or 'No feedback text provided'}",
+ f"User: {f'{user.name} ({user.email})' if user else 'Anonymous User'}",
+ f"User Agent: {user_agent or 'Unknown'}",
+ f"Feedback Trigger: {feedback.trigger}",
+ *[
+ session.model_dump_json(indent=2)
+ for session in feedback.sessions
+ ],
+ ]
+ )
+
+ if len(feedback.sessions) > 0:
+ return {
+ "subject": f"New Feedback {feedback.rating.value.capitalize()} for {', '.join([format_session(session) for session in feedback.sessions])}",
+ "message": message,
+ }
+ else:
+ return {
+ "subject": f"New General Feedback {feedback.rating.value.capitalize()}",
+ "message": message,
+ }
+
+
+def send_email(
+ feedback: Feedback,
+ user: users_models.DatabaseUser,
+ user_agent: str | None,
+ db: orm.Session,
+):
+ is_feedback_allowed(db)
+ assert config.smtp, "SMTP configuration is not set up"
+
+ cfg = config_core.get_config(db, "global")
+ assert isinstance(cfg, settings_config_models.GlobalConfiguration)
+ feedback_config = FeedbackConfiguration.model_validate(
+ cfg.feedback.model_dump()
+ )
+
+ match feedback_config.anonymity_policy:
+ case FeedbackAnonymityPolicy.FORCE_ANONYMOUS:
+ is_anonymous = True
+ case FeedbackAnonymityPolicy.FORCE_IDENTIFIED:
+ is_anonymous = False
+ case _:
+ is_anonymous = not feedback
+
+ email_text = format_email(
+ feedback, None if is_anonymous else user, user_agent
+ )
+
+ mailserver = smtplib.SMTP(
+ config.smtp.host.split(":")[0], int(config.smtp.host.split(":")[1])
+ )
+ mailserver.ehlo()
+ mailserver.starttls()
+ mailserver.ehlo()
+ mailserver.login(config.smtp.user, config.smtp.password)
+
+ for receiver in feedback_config.receivers:
+ msg = MIMEMultipart()
+ msg["From"] = config.smtp.sender
+ msg["To"] = receiver
+ msg["Subject"] = email_text["subject"]
+ msg.attach(MIMEText(email_text["message"], "plain"))
+
+ mailserver.sendmail(config.smtp.sender, receiver, msg.as_string())
+
+ mailserver.quit()
diff --git a/backend/capellacollab/routes.py b/backend/capellacollab/routes.py
index 656e7894f..5c3d6fdce 100644
--- a/backend/capellacollab/routes.py
+++ b/backend/capellacollab/routes.py
@@ -9,6 +9,7 @@
from capellacollab.core import responses as auth_responses
from capellacollab.core.authentication import routes as authentication_routes
from capellacollab.events import routes as events_router
+from capellacollab.feedback import routes as feedback_routes
from capellacollab.health import routes as health_routes
from capellacollab.metadata import routes as core_metadata
from capellacollab.navbar import routes as navbar_routes
@@ -31,6 +32,7 @@
)
router.include_router(core_metadata.router, tags=["Metadata"])
router.include_router(navbar_routes.router, tags=["Navbar"])
+router.include_router(feedback_routes.router, tags=["Feedback"])
router.include_router(
sessions_routes.router,
prefix="/sessions",
diff --git a/backend/capellacollab/settings/configuration/models.py b/backend/capellacollab/settings/configuration/models.py
index 36fc6038c..6156231c8 100644
--- a/backend/capellacollab/settings/configuration/models.py
+++ b/backend/capellacollab/settings/configuration/models.py
@@ -89,6 +89,70 @@ class NavbarConfiguration(core_pydantic.BaseModelStrict):
)
+class FeedbackAnonymityPolicy(str, enum.Enum):
+ FORCE_ANONYMOUS = "force_anonymous"
+ FORCE_IDENTIFIED = "force_identified"
+ ASK_USER = "ask_user"
+
+
+class FeedbackIntervalConfiguration(core_pydantic.BaseModelStrict):
+ enabled: bool = pydantic.Field(
+ default=True,
+ description="Whether the feedback interval is enabled.",
+ )
+ hours_between_prompt: int = pydantic.Field(
+ default=168,
+ description="The interval in hours between feedback requests.",
+ ge=0,
+ )
+
+
+class FeedbackProbabilityConfiguration(core_pydantic.BaseModelStrict):
+ enabled: bool = pydantic.Field(
+ default=True,
+ description="Whether the feedback probability is enabled.",
+ )
+ percentage: int = pydantic.Field(
+ default=100,
+ description="The percentage of users that will be asked for feedback.",
+ ge=0,
+ le=100,
+ )
+
+
+class FeedbackConfiguration(core_pydantic.BaseModelStrict):
+ enabled: bool = pydantic.Field(
+ default=False,
+ description="Enable or disable the feedback system. If enabled, SMTP configuration is required.",
+ )
+ after_session: FeedbackProbabilityConfiguration = pydantic.Field(
+ default_factory=FeedbackProbabilityConfiguration,
+ description="If a feedback form is shown after terminating a session.",
+ )
+ on_footer: bool = pydantic.Field(
+ default=True,
+ description="Should a general feedback button be shown.",
+ )
+ on_session_card: bool = pydantic.Field(
+ default=True,
+ description="Should a feedback button be shown on the session cards.",
+ )
+ interval: FeedbackIntervalConfiguration = pydantic.Field(
+ default_factory=FeedbackIntervalConfiguration,
+ description="Request feedback at regular intervals.",
+ )
+ receivers: list[pydantic.EmailStr] = pydantic.Field(
+ default=[],
+ description="Email addresses to send feedback to.",
+ examples=[[], ["test@example.com"]],
+ )
+ anonymity_policy: FeedbackAnonymityPolicy = pydantic.Field(
+ default=FeedbackAnonymityPolicy.ASK_USER,
+ description="If feedback should be anonymous or identified.",
+ examples=["force_anonymous", "force_identified", "ask_user"],
+ )
+
+
class ConfigurationBase(core_pydantic.BaseModelStrict, abc.ABC):
"""
Base class for configuration models. Can be used to define new configurations
@@ -111,6 +175,10 @@ class GlobalConfiguration(ConfigurationBase):
default_factory=NavbarConfiguration
)
+ feedback: FeedbackConfiguration = pydantic.Field(
+ default_factory=FeedbackConfiguration
+ )
+
# All subclasses of ConfigurationBase are automatically registered using this dict.
NAME_TO_MODEL_TYPE_MAPPING: dict[str, t.Type[ConfigurationBase]] = {
diff --git a/backend/pyproject.toml b/backend/pyproject.toml
index 1db0a3145..c5b0f5845 100644
--- a/backend/pyproject.toml
+++ b/backend/pyproject.toml
@@ -26,6 +26,7 @@ dependencies = [
"alembic==1.13.2",
"appdirs",
"cachetools",
+ "email-validator",
"fastapi>=0.112.4",
"kubernetes",
"psycopg2-binary>2.9.7",
diff --git a/backend/tests/sessions/test_session_feedback.py b/backend/tests/sessions/test_session_feedback.py
new file mode 100644
index 000000000..eb07918dd
--- /dev/null
+++ b/backend/tests/sessions/test_session_feedback.py
@@ -0,0 +1,155 @@
+# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+# SPDX-License-Identifier: Apache-2.0
+
+from unittest import mock
+
+import pytest
+from fastapi import testclient
+from sqlalchemy import orm
+
+import capellacollab.feedback.util
+from capellacollab.config import models as config_models
+from capellacollab.settings.configuration import crud as configuration_crud
+
+
+@pytest.fixture(name="smtp_config_set")
+def mock_smtp_config_set(monkeypatch: pytest.MonkeyPatch):
+ mocked_config = config_models.AppConfig(
+ smtp=config_models.SmtpConfig(
+ enabled=True,
+ host="smtp.example.com:587",
+ user="smtp_user",
+ password="smtp_password",
+ sender="capella@example.com",
+ )
+ )
+ monkeypatch.setattr(capellacollab.feedback.util, "config", mocked_config)
+
+
+@pytest.fixture(name="smtp_config_not_set")
+def mock_smtp_config_not_set(monkeypatch: pytest.MonkeyPatch):
+ mocked_config = config_models.AppConfig(smtp=None)
+ monkeypatch.setattr(capellacollab.feedback.util, "config", mocked_config)
+
+
+@pytest.fixture(name="feedback_enabled")
+def mock_feedback_enabled(db: orm.Session):
+ configuration_crud.create_configuration(
+ db, "global", {"feedback": {"enabled": True}}
+ )
+
+
+@pytest.fixture(name="feedback_disabled")
+def mock_feedback_disabled(db: orm.Session):
+ configuration_crud.create_configuration(
+ db, "global", {"feedback": {"enabled": False}}
+ )
+
+
+@pytest.mark.usefixtures("user")
+@pytest.mark.usefixtures("smtp_config_set")
+@pytest.mark.usefixtures("feedback_enabled")
+def test_send_feedback(
+ client: testclient.TestClient,
+):
+ with mock.patch(
+ "capellacollab.feedback.routes.send_email"
+ ) as send_email_mock:
+ response = client.post(
+ "/api/v1/feedback",
+ json={
+ "rating": "good",
+ "share_contact": False,
+ "sessions": [],
+ "feedback_text": None,
+ "trigger": "test",
+ },
+ )
+
+ assert response.status_code == 200
+ assert response.json() == {"status": "sending"}
+
+ send_email_mock.assert_called_once()
+
+
+@pytest.mark.usefixtures("user")
+@pytest.mark.usefixtures("smtp_config_set")
+@pytest.mark.usefixtures("feedback_enabled")
+def test_send_feedback_with_contact(
+ client: testclient.TestClient,
+):
+ with mock.patch(
+ "capellacollab.feedback.routes.send_email"
+ ) as send_email_mock:
+ response = client.post(
+ "/api/v1/feedback",
+ json={
+ "rating": "good",
+ "share_contact": True,
+ "sessions": [],
+ "feedback_text": None,
+ "trigger": "test",
+ },
+ )
+
+ assert response.status_code == 200
+ assert response.json() == {"status": "sending"}
+
+ send_email_mock.assert_called_once()
+
+
+@pytest.mark.usefixtures("user")
+@pytest.mark.usefixtures("smtp_config_set")
+@pytest.mark.usefixtures("feedback_disabled")
+def test_send_feedback_fail_disabled(
+ client: testclient.TestClient,
+):
+ response = client.post(
+ "/api/v1/feedback",
+ json={
+ "rating": "good",
+ "share_contact": False,
+ "sessions": [],
+ "feedback_text": None,
+ "trigger": "test",
+ },
+ )
+ assert response.status_code == 500
+
+
+@pytest.mark.usefixtures("user")
+@pytest.mark.usefixtures("smtp_config_not_set")
+@pytest.mark.usefixtures("feedback_enabled")
+def test_send_feedback_fail_missing_smtp(
+ client: testclient.TestClient,
+):
+ response = client.post(
+ "/api/v1/feedback",
+ json={
+ "rating": "good",
+ "share_contact": False,
+ "sessions": [],
+ "feedback_text": None,
+ "trigger": "test",
+ },
+ )
+ assert response.status_code == 500
+
+
+@pytest.mark.usefixtures("user")
+@pytest.mark.usefixtures("smtp_config_not_set")
+@pytest.mark.usefixtures("feedback_disabled")
+def test_send_feedback_fail_disabled_and_missing_smtp(
+ client: testclient.TestClient,
+):
+ response = client.post(
+ "/api/v1/feedback",
+ json={
+ "rating": "good",
+ "share_contact": False,
+ "sessions": [],
+ "feedback_text": None,
+ "trigger": "test",
+ },
+ )
+ assert response.status_code == 500
diff --git a/backend/tests/settings/test_global_configuration.py b/backend/tests/settings/test_global_configuration.py
index 03437295d..5868bc268 100644
--- a/backend/tests/settings/test_global_configuration.py
+++ b/backend/tests/settings/test_global_configuration.py
@@ -193,3 +193,51 @@ def get_mock_own_user():
"href": "https://example.com",
"role": "user",
}
+
+
+def test_feedback_is_updated(
+ client: testclient.TestClient,
+ db: orm.Session,
+ executor_name: str,
+):
+ admin = users_crud.create_user(
+ db, executor_name, executor_name, None, users_models.Role.ADMIN
+ )
+
+ def get_mock_own_user():
+ return admin
+
+ app.dependency_overrides[users_injectables.get_own_user] = (
+ get_mock_own_user
+ )
+
+ response = client.put(
+ "/api/v1/settings/configurations/global",
+ json={
+ "feedback": {
+ "enabled": True,
+ "after_session": {"enabled": True, "percentage": 100},
+ "on_footer": True,
+ "on_session_card": True,
+ "interval": {"enabled": True, "hours_between_prompt": 24},
+ "receivers": ["test@example.com"],
+ "anonymity_policy": "ask_user",
+ }
+ },
+ )
+
+ assert response.status_code == 200
+
+ del app.dependency_overrides[users_injectables.get_own_user]
+
+ response = client.get("/api/v1/feedback")
+ assert response.status_code == 200
+ assert response.json() == {
+ "enabled": True,
+ "after_session": {"enabled": True, "percentage": 100},
+ "on_footer": True,
+ "on_session_card": True,
+ "interval": {"enabled": True, "hours_between_prompt": 24},
+ "receivers": ["test@example.com"],
+ "anonymity_policy": "ask_user",
+ }
diff --git a/docs/docs/admin/configure-for-your-org.md b/docs/docs/admin/configure-for-your-org.md
index 165898bc8..1b90ceeeb 100644
--- a/docs/docs/admin/configure-for-your-org.md
+++ b/docs/docs/admin/configure-for-your-org.md
@@ -6,15 +6,17 @@
# Configure for your Organization
When running the Collaboration Manager in production, you may want to provide
-information about the team responsible for it, as well as an imprint and
-privacy policy.
+information about the team responsible for it.
You can set this information from the configuration page in the admin
interface. Navigate to _Settings_, then _Configuration_, then edit the file to
your liking.
-Here, you can also edit the links in the navigation bar if you are not using
-the default monitoring services.
+## About your Organization
+
+You can set URLs to your organization's privacy policy and imprint. These are
+shown in the footer. The provider field should be used for the name of the team
+responsible for the Collaboration Manager.
```yaml
metadata:
@@ -23,6 +25,15 @@ metadata:
provider: Systems Engineering Toolchain team
authentication_provider: OAuth2
environment: '-'
+```
+
+## Navigation Bar
+
+You can edit the links in the navigation bar. This can be useful if you want to
+link to external resources or if you are not using the default monitoring
+setup.
+
+```yaml
navbar:
external_links:
- name: Grafana
@@ -51,3 +62,52 @@ The `role` field and can be one of `user` or `administrator`. While this will
hide the link from users without the appropriate role, it is not a security
feature, and you should make sure that the linked service enforces the
necessary access controls.
+
+## Feedback
+
+!!! info "Configure SMTP server for feedback"
+
+ For feedback to be sent, you need to configure an SMTP server in the
+ `values.yaml` of the Helm chart. Have a look at the `alerting.email`
+ configuration.
+
+Capella Collaboration Manager can prompt users for feedback. This can be useful
+for learning about any potential issues users may be facing.
+
+There are several different types of feedback prompt:
+
+- After a session: Prompt the user for feedback after they have manually
+ terminated a session. You can reduce the percentage of users that are
+ prompted by changing the `percentage` field.
+- On the session card: Show a feedback button on the session card.
+- In the footer: Show a feedback button in the footer.
+- Interval: Prompt the user for feedback after a certain number of hours have
+ passed since the last prompt.
+
+```yaml
+feedback:
+ enabled: true
+ after_session:
+ enabled: true
+ percentage: 25
+ on_footer: true
+ on_session_card: true
+ interval:
+ enabled: true
+ hours_between_prompt: 168
+ receivers:
+ - test1@example.com
+ - test2@example.com
+ anonymity_policy: ask_user
+```
+
+Prompts that are associated with a session automatically include anonymized
+metadata about the session.
+
+By default, users can choose to share their contact information when providing
+feedback. This can be disabled or made mandatory by changing the
+`anonymity_policy` field from `ask_user` to `force_anonymous` or
+`force_identified`, respectively.
+
+Feedback will be sent by email to the address specified in the `receiver`
+field.
diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts
index 2888a4f2d..05d9d3320 100644
--- a/frontend/src/app/app.component.ts
+++ b/frontend/src/app/app.component.ts
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { NgIf, NgClass, AsyncPipe } from '@angular/common';
-import { AfterViewInit, Component, ViewChild } from '@angular/core';
+import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import {
MatSidenav,
MatDrawerContainer,
@@ -18,6 +18,7 @@ import { HeaderComponent } from './general/header/header.component';
import { NavBarMenuComponent } from './general/nav-bar-menu/nav-bar-menu.component';
import { NoticeComponent } from './general/notice/notice.component';
import { PageLayoutService } from './page-layout/page-layout.service';
+import { FeedbackService } from './sessions/feedback/feedback.service';
import { FullscreenService } from './sessions/service/fullscreen.service';
@Component({
@@ -39,17 +40,27 @@ import { FullscreenService } from './sessions/service/fullscreen.service';
AsyncPipe,
],
})
-export class AppComponent implements AfterViewInit {
+export class AppComponent implements OnInit, AfterViewInit {
constructor(
public pageLayoutService: PageLayoutService,
public fullscreenService: FullscreenService,
private navBarService: NavBarService,
+ private feedbackService: FeedbackService,
) {
slugify.extend({ '.': '-' });
}
@ViewChild('sidenav') private sidenav?: MatSidenav;
+ async ngOnInit() {
+ this.feedbackService.loadFeedbackConfig().subscribe(() => {
+ if (this.feedbackService.shouldShowIntervalPrompt()) {
+ this.feedbackService.showDialog([], 'On interval');
+ this.feedbackService.saveFeedbackPromptDate();
+ }
+ });
+ }
+
ngAfterViewInit(): void {
this.navBarService.sidenav = this.sidenav;
}
diff --git a/frontend/src/app/general/footer/footer.component.html b/frontend/src/app/general/footer/footer.component.html
index 346efbc00..16d9f8bcc 100644
--- a/frontend/src/app/general/footer/footer.component.html
+++ b/frontend/src/app/general/footer/footer.component.html
@@ -42,6 +42,12 @@
>Contribute on GitHub
open_in_new
+
+ @if (feedbackService.showOnFooter$ | async) {
+
+ }
diff --git a/frontend/src/app/general/footer/footer.component.ts b/frontend/src/app/general/footer/footer.component.ts
index 0bebcb8f0..c3af01c38 100644
--- a/frontend/src/app/general/footer/footer.component.ts
+++ b/frontend/src/app/general/footer/footer.component.ts
@@ -8,6 +8,7 @@ import { MatDialog } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MetadataService } from 'src/app/general/metadata/metadata.service';
import { VersionComponent } from 'src/app/general/metadata/version/version.component';
+import { FeedbackService } from '../../sessions/feedback/feedback.service';
@Component({
selector: 'app-footer',
@@ -19,5 +20,6 @@ export class FooterComponent {
constructor(
public dialog: MatDialog,
public metadataService: MetadataService,
+ public feedbackService: FeedbackService,
) {}
}
diff --git a/frontend/src/app/openapi/.openapi-generator/FILES b/frontend/src/app/openapi/.openapi-generator/FILES
index bf02952da..a6d2b463d 100644
--- a/frontend/src/app/openapi/.openapi-generator/FILES
+++ b/frontend/src/app/openapi/.openapi-generator/FILES
@@ -3,6 +3,7 @@ api/api.ts
api/authentication.service.ts
api/configuration.service.ts
api/events.service.ts
+api/feedback.service.ts
api/health.service.ts
api/integrations-pure-variants.service.ts
api/metadata.service.ts
@@ -28,6 +29,7 @@ api/users.service.ts
configuration.ts
encoder.ts
index.ts
+model/anonymized-session.ts
model/authorization-response.ts
model/backup-pipeline-run.ts
model/backup.ts
@@ -52,6 +54,15 @@ model/diagram-metadata.ts
model/environment-value.ts
model/environment-value1.ts
model/event-type.ts
+model/feedback-anonymity-policy.ts
+model/feedback-configuration-input.ts
+model/feedback-configuration-output.ts
+model/feedback-interval-configuration-input.ts
+model/feedback-interval-configuration-output.ts
+model/feedback-probability-configuration-input.ts
+model/feedback-probability-configuration-output.ts
+model/feedback-rating.ts
+model/feedback.ts
model/file-tree.ts
model/file-type.ts
model/get-revision-model.ts
@@ -130,7 +141,8 @@ model/role.ts
model/session-connection-information.ts
model/session-monitoring-input.ts
model/session-monitoring-output.ts
-model/session-ports.ts
+model/session-ports-input.ts
+model/session-ports-output.ts
model/session-provisioning-request.ts
model/session-sharing.ts
model/session-tool-configuration-input.ts
@@ -148,6 +160,7 @@ model/t4-c-repository.ts
model/token-request.ts
model/tool-backup-configuration-input.ts
model/tool-backup-configuration-output.ts
+model/tool-input.ts
model/tool-integrations-input.ts
model/tool-integrations-output.ts
model/tool-model-provisioning-input.ts
@@ -155,11 +168,13 @@ model/tool-model-provisioning-output.ts
model/tool-model-restrictions.ts
model/tool-model.ts
model/tool-nature.ts
+model/tool-output.ts
model/tool-session-configuration-input.ts
model/tool-session-configuration-output.ts
model/tool-session-connection-input-methods-inner.ts
model/tool-session-connection-input.ts
-model/tool-session-connection-method.ts
+model/tool-session-connection-method-input.ts
+model/tool-session-connection-method-output.ts
model/tool-session-connection-output-methods-inner.ts
model/tool-session-connection-output.ts
model/tool-session-environment-input.ts
@@ -169,9 +184,9 @@ model/tool-session-sharing-configuration-input.ts
model/tool-session-sharing-configuration-output.ts
model/tool-version-configuration-input.ts
model/tool-version-configuration-output.ts
-model/tool-version-with-tool.ts
+model/tool-version-with-tool-input.ts
+model/tool-version-with-tool-output.ts
model/tool-version.ts
-model/tool.ts
model/toolmodel-status.ts
model/user-metadata.ts
model/user-token-with-password.ts
diff --git a/frontend/src/app/openapi/api/api.ts b/frontend/src/app/openapi/api/api.ts
index f498c004f..0b15f2169 100644
--- a/frontend/src/app/openapi/api/api.ts
+++ b/frontend/src/app/openapi/api/api.ts
@@ -15,6 +15,8 @@ export * from './configuration.service';
import { ConfigurationService } from './configuration.service';
export * from './events.service';
import { EventsService } from './events.service';
+export * from './feedback.service';
+import { FeedbackService } from './feedback.service';
export * from './health.service';
import { HealthService } from './health.service';
export * from './integrations-pure-variants.service';
@@ -59,4 +61,4 @@ export * from './users-token.service';
import { UsersTokenService } from './users-token.service';
export * from './users-workspaces.service';
import { UsersWorkspacesService } from './users-workspaces.service';
-export const APIS = [AuthenticationService, ConfigurationService, EventsService, HealthService, IntegrationsPureVariantsService, MetadataService, NavbarService, NoticesService, ProjectsService, ProjectsEventsService, ProjectsModelsService, ProjectsModelsBackupsService, ProjectsModelsDiagramsService, ProjectsModelsGitService, ProjectsModelsModelComplexityBadgeService, ProjectsModelsRestrictionsService, ProjectsModelsT4CService, SessionsService, SettingsModelsourcesGitService, SettingsModelsourcesT4CService, ToolsService, UsersService, UsersSessionsService, UsersTokenService, UsersWorkspacesService];
+export const APIS = [AuthenticationService, ConfigurationService, EventsService, FeedbackService, HealthService, IntegrationsPureVariantsService, MetadataService, NavbarService, NoticesService, ProjectsService, ProjectsEventsService, ProjectsModelsService, ProjectsModelsBackupsService, ProjectsModelsDiagramsService, ProjectsModelsGitService, ProjectsModelsModelComplexityBadgeService, ProjectsModelsRestrictionsService, ProjectsModelsT4CService, SessionsService, SettingsModelsourcesGitService, SettingsModelsourcesT4CService, ToolsService, UsersService, UsersSessionsService, UsersTokenService, UsersWorkspacesService];
diff --git a/frontend/src/app/openapi/api/feedback.service.ts b/frontend/src/app/openapi/api/feedback.service.ts
new file mode 100644
index 000000000..74c1952cc
--- /dev/null
+++ b/frontend/src/app/openapi/api/feedback.service.ts
@@ -0,0 +1,244 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+/* tslint:disable:no-unused-variable member-ordering */
+
+import { Inject, Injectable, Optional } from '@angular/core';
+import { HttpClient, HttpHeaders, HttpParams,
+ HttpResponse, HttpEvent, HttpParameterCodec, HttpContext
+ } from '@angular/common/http';
+import { CustomHttpParameterCodec } from '../encoder';
+import { Observable } from 'rxjs';
+
+// @ts-ignore
+import { Feedback } from '../model/feedback';
+// @ts-ignore
+import { FeedbackConfigurationOutput } from '../model/feedback-configuration-output';
+// @ts-ignore
+import { HTTPValidationError } from '../model/http-validation-error';
+
+// @ts-ignore
+import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
+import { Configuration } from '../configuration';
+
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class FeedbackService {
+
+ protected basePath = 'http://localhost';
+ public defaultHeaders = new HttpHeaders();
+ public configuration = new Configuration();
+ public encoder: HttpParameterCodec;
+
+ constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) {
+ if (configuration) {
+ this.configuration = configuration;
+ }
+ if (typeof this.configuration.basePath !== 'string') {
+ const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined;
+ if (firstBasePath != undefined) {
+ basePath = firstBasePath;
+ }
+
+ if (typeof basePath !== 'string') {
+ basePath = this.basePath;
+ }
+ this.configuration.basePath = basePath;
+ }
+ this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
+ }
+
+
+ // @ts-ignore
+ private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
+ if (typeof value === "object" && value instanceof Date === false) {
+ httpParams = this.addToHttpParamsRecursive(httpParams, value);
+ } else {
+ httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
+ }
+ return httpParams;
+ }
+
+ private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
+ if (value == null) {
+ return httpParams;
+ }
+
+ if (typeof value === "object") {
+ if (Array.isArray(value)) {
+ (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
+ } else if (value instanceof Date) {
+ if (key != null) {
+ httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10));
+ } else {
+ throw Error("key may not be null if value is Date");
+ }
+ } else {
+ Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
+ httpParams, value[k], key != null ? `${key}.${k}` : k));
+ }
+ } else if (key != null) {
+ httpParams = httpParams.append(key, value);
+ } else {
+ throw Error("key may not be null if value is not object or array");
+ }
+ return httpParams;
+ }
+
+ /**
+ * Get Feedback
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public getFeedback(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public getFeedback(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getFeedback(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getFeedback(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+
+ let localVarHeaders = this.defaultHeaders;
+
+ let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+ if (localVarHttpHeaderAcceptSelected === undefined) {
+ // to determine the Accept header
+ const httpHeaderAccepts: string[] = [
+ 'application/json'
+ ];
+ localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+ }
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ let localVarHttpContext: HttpContext | undefined = options && options.context;
+ if (localVarHttpContext === undefined) {
+ localVarHttpContext = new HttpContext();
+ }
+
+ let localVarTransferCache: boolean | undefined = options && options.transferCache;
+ if (localVarTransferCache === undefined) {
+ localVarTransferCache = true;
+ }
+
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/api/v1/feedback`;
+ return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ responseType: responseType_,
+ withCredentials: this.configuration.withCredentials,
+ headers: localVarHeaders,
+ observe: observe,
+ transferCache: localVarTransferCache,
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+ /**
+ * Submit Feedback
+ * @param feedback
+ * @param userAgent
+ * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
+ * @param reportProgress flag to report request and response progress.
+ */
+ public submitFeedback(feedback: Feedback, userAgent?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public submitFeedback(feedback: Feedback, userAgent?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public submitFeedback(feedback: Feedback, userAgent?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public submitFeedback(feedback: Feedback, userAgent?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
+ if (feedback === null || feedback === undefined) {
+ throw new Error('Required parameter feedback was null or undefined when calling submitFeedback.');
+ }
+
+ let localVarHeaders = this.defaultHeaders;
+ if (userAgent !== undefined && userAgent !== null) {
+ localVarHeaders = localVarHeaders.set('user-agent', String(userAgent));
+ }
+
+ let localVarCredential: string | undefined;
+ // authentication (PersonalAccessToken) required
+ localVarCredential = this.configuration.lookupCredential('PersonalAccessToken');
+ if (localVarCredential) {
+ localVarHeaders = localVarHeaders.set('Authorization', 'Basic ' + localVarCredential);
+ }
+
+ let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
+ if (localVarHttpHeaderAcceptSelected === undefined) {
+ // to determine the Accept header
+ const httpHeaderAccepts: string[] = [
+ 'application/json'
+ ];
+ localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
+ }
+ if (localVarHttpHeaderAcceptSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
+ }
+
+ let localVarHttpContext: HttpContext | undefined = options && options.context;
+ if (localVarHttpContext === undefined) {
+ localVarHttpContext = new HttpContext();
+ }
+
+ let localVarTransferCache: boolean | undefined = options && options.transferCache;
+ if (localVarTransferCache === undefined) {
+ localVarTransferCache = true;
+ }
+
+
+ // to determine the Content-Type header
+ const consumes: string[] = [
+ 'application/json'
+ ];
+ const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
+ if (httpContentTypeSelected !== undefined) {
+ localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
+ }
+
+ let responseType_: 'text' | 'json' | 'blob' = 'json';
+ if (localVarHttpHeaderAcceptSelected) {
+ if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
+ responseType_ = 'text';
+ } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
+ responseType_ = 'json';
+ } else {
+ responseType_ = 'blob';
+ }
+ }
+
+ let localVarPath = `/api/v1/feedback`;
+ return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`,
+ {
+ context: localVarHttpContext,
+ body: feedback,
+ responseType: responseType_,
+ withCredentials: this.configuration.withCredentials,
+ headers: localVarHeaders,
+ observe: observe,
+ transferCache: localVarTransferCache,
+ reportProgress: reportProgress
+ }
+ );
+ }
+
+}
diff --git a/frontend/src/app/openapi/api/tools.service.ts b/frontend/src/app/openapi/api/tools.service.ts
index 40711b7bd..b1be2acad 100644
--- a/frontend/src/app/openapi/api/tools.service.ts
+++ b/frontend/src/app/openapi/api/tools.service.ts
@@ -33,13 +33,13 @@ import { CreateToolVersionOutput } from '../model/create-tool-version-output';
// @ts-ignore
import { HTTPValidationError } from '../model/http-validation-error';
// @ts-ignore
-import { Tool } from '../model/tool';
-// @ts-ignore
import { ToolNature } from '../model/tool-nature';
// @ts-ignore
+import { ToolOutput } from '../model/tool-output';
+// @ts-ignore
import { ToolVersion } from '../model/tool-version';
// @ts-ignore
-import { ToolVersionWithTool } from '../model/tool-version-with-tool';
+import { ToolVersionWithToolOutput } from '../model/tool-version-with-tool-output';
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
@@ -119,9 +119,9 @@ export class ToolsService {
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
- public createTool(createToolInput: CreateToolInput, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
- public createTool(createToolInput: CreateToolInput, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
- public createTool(createToolInput: CreateToolInput, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public createTool(createToolInput: CreateToolInput, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public createTool(createToolInput: CreateToolInput, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public createTool(createToolInput: CreateToolInput, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
public createTool(createToolInput: CreateToolInput, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
if (createToolInput === null || createToolInput === undefined) {
throw new Error('Required parameter createToolInput was null or undefined when calling createTool.');
@@ -180,7 +180,7 @@ export class ToolsService {
}
let localVarPath = `/api/v1/tools`;
- return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`,
+ return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`,
{
context: localVarHttpContext,
body: createToolInput,
@@ -800,9 +800,9 @@ export class ToolsService {
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
- public getToolById(toolId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
- public getToolById(toolId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
- public getToolById(toolId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getToolById(toolId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public getToolById(toolId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getToolById(toolId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
public getToolById(toolId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
if (toolId === null || toolId === undefined) {
throw new Error('Required parameter toolId was null or undefined when calling getToolById.');
@@ -852,7 +852,7 @@ export class ToolsService {
}
let localVarPath = `/api/v1/tools/${this.configuration.encodeParam({name: "toolId", value: toolId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: undefined})}`;
- return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`,
+ return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`,
{
context: localVarHttpContext,
responseType: responseType_,
@@ -1162,9 +1162,9 @@ export class ToolsService {
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
- public getTools(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
- public getTools(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
- public getTools(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getTools(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getTools(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getTools(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
public getTools(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
let localVarHeaders = this.defaultHeaders;
@@ -1211,7 +1211,7 @@ export class ToolsService {
}
let localVarPath = `/api/v1/tools`;
- return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`,
+ return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`,
{
context: localVarHttpContext,
responseType: responseType_,
@@ -1229,9 +1229,9 @@ export class ToolsService {
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
- public getVersionsForAllTools(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
- public getVersionsForAllTools(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
- public getVersionsForAllTools(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getVersionsForAllTools(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public getVersionsForAllTools(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
+ public getVersionsForAllTools(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>;
public getVersionsForAllTools(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
let localVarHeaders = this.defaultHeaders;
@@ -1278,7 +1278,7 @@ export class ToolsService {
}
let localVarPath = `/api/v1/tools/*/versions`;
- return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`,
+ return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`,
{
context: localVarHttpContext,
responseType: responseType_,
@@ -1298,9 +1298,9 @@ export class ToolsService {
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
- public updateTool(toolId: number, createToolInput: CreateToolInput, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
- public updateTool(toolId: number, createToolInput: CreateToolInput, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
- public updateTool(toolId: number, createToolInput: CreateToolInput, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateTool(toolId: number, createToolInput: CreateToolInput, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable;
+ public updateTool(toolId: number, createToolInput: CreateToolInput, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
+ public updateTool(toolId: number, createToolInput: CreateToolInput, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>;
public updateTool(toolId: number, createToolInput: CreateToolInput, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable {
if (toolId === null || toolId === undefined) {
throw new Error('Required parameter toolId was null or undefined when calling updateTool.');
@@ -1362,7 +1362,7 @@ export class ToolsService {
}
let localVarPath = `/api/v1/tools/${this.configuration.encodeParam({name: "toolId", value: toolId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: undefined})}`;
- return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`,
+ return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`,
{
context: localVarHttpContext,
body: createToolInput,
diff --git a/frontend/src/app/openapi/model/anonymized-session.ts b/frontend/src/app/openapi/model/anonymized-session.ts
new file mode 100644
index 000000000..f3b5c04e5
--- /dev/null
+++ b/frontend/src/app/openapi/model/anonymized-session.ts
@@ -0,0 +1,31 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+import { SessionType } from './session-type';
+import { Message } from './message';
+import { ToolSessionConnectionMethodInput } from './tool-session-connection-method-input';
+import { ToolVersionWithToolInput } from './tool-version-with-tool-input';
+
+
+export interface AnonymizedSession {
+ id: string;
+ type: SessionType;
+ created_at: string;
+ version: ToolVersionWithToolInput;
+ state?: string;
+ warnings?: Array;
+ connection_method_id: string;
+ connection_method?: ToolSessionConnectionMethodInput | null;
+}
+export namespace AnonymizedSession {
+}
+
+
diff --git a/frontend/src/app/openapi/model/feedback-anonymity-policy.ts b/frontend/src/app/openapi/model/feedback-anonymity-policy.ts
new file mode 100644
index 000000000..0a50781fa
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-anonymity-policy.ts
@@ -0,0 +1,21 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+
+
+export type FeedbackAnonymityPolicy = 'force_anonymous' | 'force_identified' | 'ask_user';
+
+export const FeedbackAnonymityPolicy = {
+ ForceAnonymous: 'force_anonymous' as FeedbackAnonymityPolicy,
+ ForceIdentified: 'force_identified' as FeedbackAnonymityPolicy,
+ AskUser: 'ask_user' as FeedbackAnonymityPolicy
+};
+
diff --git a/frontend/src/app/openapi/model/feedback-configuration-input.ts b/frontend/src/app/openapi/model/feedback-configuration-input.ts
new file mode 100644
index 000000000..c89a2ec4a
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-configuration-input.ts
@@ -0,0 +1,50 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+import { FeedbackAnonymityPolicy } from './feedback-anonymity-policy';
+import { FeedbackProbabilityConfigurationInput } from './feedback-probability-configuration-input';
+import { FeedbackIntervalConfigurationInput } from './feedback-interval-configuration-input';
+
+
+export interface FeedbackConfigurationInput {
+ /**
+ * Enable or disable the feedback system. If enabled, SMTP configuration is required.
+ */
+ enabled?: boolean;
+ /**
+ * If a feedback form is shown after terminating a session.
+ */
+ after_session?: FeedbackProbabilityConfigurationInput;
+ /**
+ * Should a general feedback button be shown.
+ */
+ on_footer?: boolean;
+ /**
+ * Should a feedback button be shown on the session cards.
+ */
+ on_session_card?: boolean;
+ /**
+ * Request feedback at regular intervals.
+ */
+ interval?: FeedbackIntervalConfigurationInput;
+ /**
+ * Email addresses to send feedback to.
+ */
+ receivers?: Array;
+ /**
+ * If feedback should be anonymous or identified.
+ */
+ anonymity_policy?: FeedbackAnonymityPolicy;
+}
+export namespace FeedbackConfigurationInput {
+}
+
+
diff --git a/frontend/src/app/openapi/model/feedback-configuration-output.ts b/frontend/src/app/openapi/model/feedback-configuration-output.ts
new file mode 100644
index 000000000..ceff380a1
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-configuration-output.ts
@@ -0,0 +1,50 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+import { FeedbackAnonymityPolicy } from './feedback-anonymity-policy';
+import { FeedbackIntervalConfigurationOutput } from './feedback-interval-configuration-output';
+import { FeedbackProbabilityConfigurationOutput } from './feedback-probability-configuration-output';
+
+
+export interface FeedbackConfigurationOutput {
+ /**
+ * Enable or disable the feedback system. If enabled, SMTP configuration is required.
+ */
+ enabled: boolean;
+ /**
+ * If a feedback form is shown after terminating a session.
+ */
+ after_session: FeedbackProbabilityConfigurationOutput;
+ /**
+ * Should a general feedback button be shown.
+ */
+ on_footer: boolean;
+ /**
+ * Should a feedback button be shown on the session cards.
+ */
+ on_session_card: boolean;
+ /**
+ * Request feedback at regular intervals.
+ */
+ interval: FeedbackIntervalConfigurationOutput;
+ /**
+ * Email addresses to send feedback to.
+ */
+ receivers: Array;
+ /**
+ * If feedback should be anonymous or identified.
+ */
+ anonymity_policy: FeedbackAnonymityPolicy;
+}
+export namespace FeedbackConfigurationOutput {
+}
+
+
diff --git a/frontend/src/app/openapi/model/feedback-interval-configuration-input.ts b/frontend/src/app/openapi/model/feedback-interval-configuration-input.ts
new file mode 100644
index 000000000..9e543140e
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-interval-configuration-input.ts
@@ -0,0 +1,24 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+
+
+export interface FeedbackIntervalConfigurationInput {
+ /**
+ * Whether the feedback interval is enabled.
+ */
+ enabled?: boolean;
+ /**
+ * The interval in hours between feedback requests.
+ */
+ hours_between_prompt?: number;
+}
+
diff --git a/frontend/src/app/openapi/model/feedback-interval-configuration-output.ts b/frontend/src/app/openapi/model/feedback-interval-configuration-output.ts
new file mode 100644
index 000000000..f3a53f26c
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-interval-configuration-output.ts
@@ -0,0 +1,24 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+
+
+export interface FeedbackIntervalConfigurationOutput {
+ /**
+ * Whether the feedback interval is enabled.
+ */
+ enabled: boolean;
+ /**
+ * The interval in hours between feedback requests.
+ */
+ hours_between_prompt: number;
+}
+
diff --git a/frontend/src/app/openapi/model/feedback-probability-configuration-input.ts b/frontend/src/app/openapi/model/feedback-probability-configuration-input.ts
new file mode 100644
index 000000000..0f6c69520
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-probability-configuration-input.ts
@@ -0,0 +1,24 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+
+
+export interface FeedbackProbabilityConfigurationInput {
+ /**
+ * Whether the feedback probability is enabled.
+ */
+ enabled?: boolean;
+ /**
+ * The percentage of users that will be asked for feedback.
+ */
+ percentage?: number;
+}
+
diff --git a/frontend/src/app/openapi/model/feedback-probability-configuration-output.ts b/frontend/src/app/openapi/model/feedback-probability-configuration-output.ts
new file mode 100644
index 000000000..9a79c3bdb
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-probability-configuration-output.ts
@@ -0,0 +1,24 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+
+
+export interface FeedbackProbabilityConfigurationOutput {
+ /**
+ * Whether the feedback probability is enabled.
+ */
+ enabled: boolean;
+ /**
+ * The percentage of users that will be asked for feedback.
+ */
+ percentage: number;
+}
+
diff --git a/frontend/src/app/openapi/model/feedback-rating.ts b/frontend/src/app/openapi/model/feedback-rating.ts
new file mode 100644
index 000000000..16b48081d
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback-rating.ts
@@ -0,0 +1,21 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+
+
+export type FeedbackRating = 'good' | 'okay' | 'bad';
+
+export const FeedbackRating = {
+ Good: 'good' as FeedbackRating,
+ Okay: 'okay' as FeedbackRating,
+ Bad: 'bad' as FeedbackRating
+};
+
diff --git a/frontend/src/app/openapi/model/feedback.ts b/frontend/src/app/openapi/model/feedback.ts
new file mode 100644
index 000000000..236bdde48
--- /dev/null
+++ b/frontend/src/app/openapi/model/feedback.ts
@@ -0,0 +1,38 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+import { FeedbackRating } from './feedback-rating';
+import { AnonymizedSession } from './anonymized-session';
+
+
+export interface Feedback {
+ /**
+ * The rating of the feedback
+ */
+ rating: FeedbackRating;
+ feedback_text: string | null;
+ /**
+ * Whether the user wants to share their contact information
+ */
+ share_contact: boolean;
+ /**
+ * The sessions the feedback is for
+ */
+ sessions: Array;
+ /**
+ * What triggered the feedback form
+ */
+ trigger: string;
+}
+export namespace Feedback {
+}
+
+
diff --git a/frontend/src/app/openapi/model/global-configuration-input.ts b/frontend/src/app/openapi/model/global-configuration-input.ts
index 70c4954a1..6c568c595 100644
--- a/frontend/src/app/openapi/model/global-configuration-input.ts
+++ b/frontend/src/app/openapi/model/global-configuration-input.ts
@@ -11,6 +11,7 @@
import { NavbarConfigurationInput } from './navbar-configuration-input';
import { MetadataConfigurationInput } from './metadata-configuration-input';
+import { FeedbackConfigurationInput } from './feedback-configuration-input';
/**
@@ -19,5 +20,6 @@ import { MetadataConfigurationInput } from './metadata-configuration-input';
export interface GlobalConfigurationInput {
metadata?: MetadataConfigurationInput;
navbar?: NavbarConfigurationInput;
+ feedback?: FeedbackConfigurationInput;
}
diff --git a/frontend/src/app/openapi/model/global-configuration-output.ts b/frontend/src/app/openapi/model/global-configuration-output.ts
index cab85de70..c52b7fa67 100644
--- a/frontend/src/app/openapi/model/global-configuration-output.ts
+++ b/frontend/src/app/openapi/model/global-configuration-output.ts
@@ -11,6 +11,7 @@
import { NavbarConfigurationOutput } from './navbar-configuration-output';
import { MetadataConfigurationOutput } from './metadata-configuration-output';
+import { FeedbackConfigurationOutput } from './feedback-configuration-output';
/**
@@ -19,5 +20,6 @@ import { MetadataConfigurationOutput } from './metadata-configuration-output';
export interface GlobalConfigurationOutput {
metadata: MetadataConfigurationOutput;
navbar: NavbarConfigurationOutput;
+ feedback: FeedbackConfigurationOutput;
}
diff --git a/frontend/src/app/openapi/model/models.ts b/frontend/src/app/openapi/model/models.ts
index 7585cc893..b248ff37f 100644
--- a/frontend/src/app/openapi/model/models.ts
+++ b/frontend/src/app/openapi/model/models.ts
@@ -9,6 +9,7 @@
+ To generate a new version, run `make openapi` in the root directory of this repository.
*/
+export * from './anonymized-session';
export * from './authorization-response';
export * from './backup';
export * from './backup-pipeline-run';
@@ -33,6 +34,15 @@ export * from './diagram-metadata';
export * from './environment-value';
export * from './environment-value1';
export * from './event-type';
+export * from './feedback';
+export * from './feedback-anonymity-policy';
+export * from './feedback-configuration-input';
+export * from './feedback-configuration-output';
+export * from './feedback-interval-configuration-input';
+export * from './feedback-interval-configuration-output';
+export * from './feedback-probability-configuration-input';
+export * from './feedback-probability-configuration-output';
+export * from './feedback-rating';
export * from './file-tree';
export * from './file-type';
export * from './get-revision-model';
@@ -111,7 +121,8 @@ export * from './session';
export * from './session-connection-information';
export * from './session-monitoring-input';
export * from './session-monitoring-output';
-export * from './session-ports';
+export * from './session-ports-input';
+export * from './session-ports-output';
export * from './session-provisioning-request';
export * from './session-sharing';
export * from './session-tool-configuration-input';
@@ -126,9 +137,9 @@ export * from './t4-c-model';
export * from './t4-c-repository';
export * from './t4-c-repository-status';
export * from './token-request';
-export * from './tool';
export * from './tool-backup-configuration-input';
export * from './tool-backup-configuration-output';
+export * from './tool-input';
export * from './tool-integrations-input';
export * from './tool-integrations-output';
export * from './tool-model';
@@ -136,11 +147,13 @@ export * from './tool-model-provisioning-input';
export * from './tool-model-provisioning-output';
export * from './tool-model-restrictions';
export * from './tool-nature';
+export * from './tool-output';
export * from './tool-session-configuration-input';
export * from './tool-session-configuration-output';
export * from './tool-session-connection-input';
export * from './tool-session-connection-input-methods-inner';
-export * from './tool-session-connection-method';
+export * from './tool-session-connection-method-input';
+export * from './tool-session-connection-method-output';
export * from './tool-session-connection-output';
export * from './tool-session-connection-output-methods-inner';
export * from './tool-session-environment-input';
@@ -151,7 +164,8 @@ export * from './tool-session-sharing-configuration-output';
export * from './tool-version';
export * from './tool-version-configuration-input';
export * from './tool-version-configuration-output';
-export * from './tool-version-with-tool';
+export * from './tool-version-with-tool-input';
+export * from './tool-version-with-tool-output';
export * from './toolmodel-status';
export * from './user';
export * from './user-metadata';
diff --git a/frontend/src/app/openapi/model/session-ports-input.ts b/frontend/src/app/openapi/model/session-ports-input.ts
new file mode 100644
index 000000000..d81fbbb5d
--- /dev/null
+++ b/frontend/src/app/openapi/model/session-ports-input.ts
@@ -0,0 +1,20 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+
+
+export interface SessionPortsInput {
+ /**
+ * Port of the metrics endpoint in the container.
+ */
+ metrics?: number;
+}
+
diff --git a/frontend/src/app/openapi/model/session-ports.ts b/frontend/src/app/openapi/model/session-ports-output.ts
similarity index 92%
rename from frontend/src/app/openapi/model/session-ports.ts
rename to frontend/src/app/openapi/model/session-ports-output.ts
index 4d0a5ffac..073bbe127 100644
--- a/frontend/src/app/openapi/model/session-ports.ts
+++ b/frontend/src/app/openapi/model/session-ports-output.ts
@@ -11,7 +11,7 @@
-export interface SessionPorts {
+export interface SessionPortsOutput {
/**
* Port of the metrics endpoint in the container.
*/
diff --git a/frontend/src/app/openapi/model/session.ts b/frontend/src/app/openapi/model/session.ts
index 4a2a34835..661e2296e 100644
--- a/frontend/src/app/openapi/model/session.ts
+++ b/frontend/src/app/openapi/model/session.ts
@@ -11,9 +11,9 @@
import { BaseUser } from './base-user';
import { SessionType } from './session-type';
+import { ToolVersionWithToolOutput } from './tool-version-with-tool-output';
import { Message } from './message';
-import { ToolVersionWithTool } from './tool-version-with-tool';
-import { ToolSessionConnectionMethod } from './tool-session-connection-method';
+import { ToolSessionConnectionMethodOutput } from './tool-session-connection-method-output';
import { SessionSharing } from './session-sharing';
@@ -22,12 +22,12 @@ export interface Session {
type: SessionType;
created_at: string;
owner: BaseUser;
- version: ToolVersionWithTool;
+ version: ToolVersionWithToolOutput;
state: string;
warnings: Array;
last_seen: string;
connection_method_id: string;
- connection_method: ToolSessionConnectionMethod | null;
+ connection_method: ToolSessionConnectionMethodOutput | null;
shared_with: Array;
}
export namespace Session {
diff --git a/frontend/src/app/openapi/model/tool-input.ts b/frontend/src/app/openapi/model/tool-input.ts
new file mode 100644
index 000000000..978d11c30
--- /dev/null
+++ b/frontend/src/app/openapi/model/tool-input.ts
@@ -0,0 +1,25 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+import { ToolSessionConfigurationInput } from './tool-session-configuration-input';
+import { ToolIntegrationsInput } from './tool-integrations-input';
+
+
+export interface ToolInput {
+ /**
+ * Unique identifier of the resource.
+ */
+ id: number;
+ name?: string;
+ integrations?: ToolIntegrationsInput;
+ config?: ToolSessionConfigurationInput;
+}
+
diff --git a/frontend/src/app/openapi/model/tool-model.ts b/frontend/src/app/openapi/model/tool-model.ts
index d20807d6a..d61619a15 100644
--- a/frontend/src/app/openapi/model/tool-model.ts
+++ b/frontend/src/app/openapi/model/tool-model.ts
@@ -10,10 +10,10 @@
*/
import { GitModel } from './git-model';
+import { ToolOutput } from './tool-output';
import { T4CModel } from './t4-c-model';
import { ToolVersion } from './tool-version';
import { ToolModelRestrictions } from './tool-model-restrictions';
-import { Tool } from './tool';
import { ToolNature } from './tool-nature';
@@ -23,7 +23,7 @@ export interface ToolModel {
name: string;
description: string;
display_order: number | null;
- tool: Tool;
+ tool: ToolOutput;
version: ToolVersion | null;
nature: ToolNature | null;
git_models: Array | null;
diff --git a/frontend/src/app/openapi/model/tool.ts b/frontend/src/app/openapi/model/tool-output.ts
similarity index 95%
rename from frontend/src/app/openapi/model/tool.ts
rename to frontend/src/app/openapi/model/tool-output.ts
index 0d1c3ee13..6588b4a47 100644
--- a/frontend/src/app/openapi/model/tool.ts
+++ b/frontend/src/app/openapi/model/tool-output.ts
@@ -13,7 +13,7 @@ import { ToolSessionConfigurationOutput } from './tool-session-configuration-out
import { ToolIntegrationsOutput } from './tool-integrations-output';
-export interface Tool {
+export interface ToolOutput {
/**
* Unique identifier of the resource.
*/
diff --git a/frontend/src/app/openapi/model/tool-session-connection-method-input.ts b/frontend/src/app/openapi/model/tool-session-connection-method-input.ts
new file mode 100644
index 000000000..976b1748c
--- /dev/null
+++ b/frontend/src/app/openapi/model/tool-session-connection-method-input.ts
@@ -0,0 +1,29 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+import { EnvironmentValue } from './environment-value';
+import { SessionPortsInput } from './session-ports-input';
+import { ToolSessionSharingConfigurationInput } from './tool-session-sharing-configuration-input';
+
+
+export interface ToolSessionConnectionMethodInput {
+ id?: string;
+ type: string;
+ name?: string;
+ description?: string;
+ ports: SessionPortsInput;
+ /**
+ * Connection method specific environment variables. Check the global environment field for more information.
+ */
+ environment?: { [key: string]: EnvironmentValue; };
+ sharing?: ToolSessionSharingConfigurationInput;
+}
+
diff --git a/frontend/src/app/openapi/model/tool-session-connection-method.ts b/frontend/src/app/openapi/model/tool-session-connection-method-output.ts
similarity index 85%
rename from frontend/src/app/openapi/model/tool-session-connection-method.ts
rename to frontend/src/app/openapi/model/tool-session-connection-method-output.ts
index 41ba6a5e5..88d92f90f 100644
--- a/frontend/src/app/openapi/model/tool-session-connection-method.ts
+++ b/frontend/src/app/openapi/model/tool-session-connection-method-output.ts
@@ -9,17 +9,17 @@
+ To generate a new version, run `make openapi` in the root directory of this repository.
*/
-import { SessionPorts } from './session-ports';
+import { SessionPortsOutput } from './session-ports-output';
import { ToolSessionSharingConfigurationOutput } from './tool-session-sharing-configuration-output';
import { EnvironmentValue1 } from './environment-value1';
-export interface ToolSessionConnectionMethod {
+export interface ToolSessionConnectionMethodOutput {
id: string;
type: string;
name: string;
description: string;
- ports: SessionPorts;
+ ports: SessionPortsOutput;
/**
* Connection method specific environment variables. Check the global environment field for more information.
*/
diff --git a/frontend/src/app/openapi/model/tool-version-with-tool-input.ts b/frontend/src/app/openapi/model/tool-version-with-tool-input.ts
new file mode 100644
index 000000000..d03035a84
--- /dev/null
+++ b/frontend/src/app/openapi/model/tool-version-with-tool-input.ts
@@ -0,0 +1,25 @@
+/*
+ * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Capella Collaboration
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ + To generate a new version, run `make openapi` in the root directory of this repository.
+ */
+
+import { ToolVersionConfigurationInput } from './tool-version-configuration-input';
+import { ToolInput } from './tool-input';
+
+
+export interface ToolVersionWithToolInput {
+ /**
+ * Unique identifier of the resource.
+ */
+ id: number;
+ name?: string;
+ config?: ToolVersionConfigurationInput;
+ tool: ToolInput;
+}
+
diff --git a/frontend/src/app/openapi/model/tool-version-with-tool.ts b/frontend/src/app/openapi/model/tool-version-with-tool-output.ts
similarity index 84%
rename from frontend/src/app/openapi/model/tool-version-with-tool.ts
rename to frontend/src/app/openapi/model/tool-version-with-tool-output.ts
index 399bef2bf..1dec33004 100644
--- a/frontend/src/app/openapi/model/tool-version-with-tool.ts
+++ b/frontend/src/app/openapi/model/tool-version-with-tool-output.ts
@@ -10,16 +10,16 @@
*/
import { ToolVersionConfigurationOutput } from './tool-version-configuration-output';
-import { Tool } from './tool';
+import { ToolOutput } from './tool-output';
-export interface ToolVersionWithTool {
+export interface ToolVersionWithToolOutput {
/**
* Unique identifier of the resource.
*/
id: number;
name: string;
config: ToolVersionConfigurationOutput;
- tool: Tool;
+ tool: ToolOutput;
}
diff --git a/frontend/src/app/projects/models/init-model/init-model.component.ts b/frontend/src/app/projects/models/init-model/init-model.component.ts
index 2552e9804..eb60c57ff 100644
--- a/frontend/src/app/projects/models/init-model/init-model.component.ts
+++ b/frontend/src/app/projects/models/init-model/init-model.component.ts
@@ -20,7 +20,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { combineLatest, filter, map, switchMap, tap } from 'rxjs';
import { SKIP_ERROR_HANDLING_CONTEXT } from 'src/app/general/error-handling/error-handling.interceptor';
import {
- Tool,
+ ToolOutput,
ToolModel,
ToolNature,
ToolVersion,
@@ -92,7 +92,7 @@ export class InitModelComponent implements OnInit {
}
}),
map((model: ToolModel) => model.tool),
- switchMap((tool: Tool) =>
+ switchMap((tool: ToolOutput) =>
combineLatest([
this.toolsService.getToolVersions(tool.id, undefined, undefined, {
context: SKIP_ERROR_HANDLING_CONTEXT,
diff --git a/frontend/src/app/sessions/delete-session-dialog/delete-session-dialog.component.html b/frontend/src/app/sessions/delete-session-dialog/delete-session-dialog.component.html
index e7e5e38ae..6d6768a08 100644
--- a/frontend/src/app/sessions/delete-session-dialog/delete-session-dialog.component.html
+++ b/frontend/src/app/sessions/delete-session-dialog/delete-session-dialog.component.html
@@ -21,7 +21,7 @@ Terminate Session
-
+