diff --git a/backend/capellacollab/feedback/routes.py b/backend/capellacollab/feedback/routes.py index c1299f00cc..7a3d5561cd 100644 --- a/backend/capellacollab/feedback/routes.py +++ b/backend/capellacollab/feedback/routes.py @@ -9,12 +9,9 @@ import fastapi from sqlalchemy import orm -from capellacollab.config import config from capellacollab.core import database from capellacollab.core import logging as log from capellacollab.core.authentication import injectables as auth_injectables -from capellacollab.settings.configuration import core as config_core -from capellacollab.settings.configuration import models as config_models from capellacollab.users import injectables as user_injectables from capellacollab.users import models as users_models @@ -23,19 +20,6 @@ router = fastapi.APIRouter() -@router.get( - "/configurations/feedback", - response_model=config_models.FeedbackConfiguration, -) -def get_feedback_configuration( - db: orm.Session = fastapi.Depends(database.get_db), -): - feedback = config_core.get_global_configuration(db).feedback - if not (config.smtp and config.smtp.enabled): - util.disable_feedback(feedback) - return feedback - - @router.post( "/feedback", status_code=204, diff --git a/backend/capellacollab/metadata/routes.py b/backend/capellacollab/metadata/routes.py deleted file mode 100644 index d079708618..0000000000 --- a/backend/capellacollab/metadata/routes.py +++ /dev/null @@ -1,45 +0,0 @@ -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -import fastapi -from sqlalchemy import orm - -import capellacollab -from capellacollab.config import config -from capellacollab.core import database -from capellacollab.core import pydantic as core_pydantic -from capellacollab.settings.configuration import core as config_core - - -class Metadata(core_pydantic.BaseModel): - version: str - privacy_policy_url: str | None - imprint_url: str | None - provider: str | None - authentication_provider: str | None - environment: str | None - - host: str | None - port: str | None - protocol: str | None - - -router = fastapi.APIRouter() - - -@router.get( - "/metadata", - response_model=Metadata, -) -def get_metadata(db: orm.Session = fastapi.Depends(database.get_db)): - cfg = config_core.get_global_configuration(db) - - return Metadata.model_validate( - cfg.metadata.model_dump() - | { - "version": capellacollab.__version__, - "host": config.general.host, - "port": str(config.general.port), - "protocol": config.general.scheme, - } - ) diff --git a/backend/capellacollab/navbar/routes.py b/backend/capellacollab/navbar/routes.py deleted file mode 100644 index 267ba4b5a9..0000000000 --- a/backend/capellacollab/navbar/routes.py +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors -# SPDX-License-Identifier: Apache-2.0 - -import fastapi -from sqlalchemy import orm - -from capellacollab.core import database -from capellacollab.settings.configuration import core as config_core -from capellacollab.settings.configuration import models as config_models - -router = fastapi.APIRouter() - - -@router.get( - "/navbar", - response_model=config_models.NavbarConfiguration, -) -def get_navbar(db: orm.Session = fastapi.Depends(database.get_db)): - cfg = config_core.get_global_configuration(db) - - return config_models.NavbarConfiguration.model_validate( - cfg.navbar.model_dump() - ) diff --git a/backend/capellacollab/routes.py b/backend/capellacollab/routes.py index 5c3d6fdce3..cec52f9b5f 100644 --- a/backend/capellacollab/routes.py +++ b/backend/capellacollab/routes.py @@ -11,8 +11,6 @@ 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 from capellacollab.notices import routes as notices_routes from capellacollab.projects import routes as projects_routes from capellacollab.sessions import routes as sessions_routes @@ -30,8 +28,6 @@ responses=auth_responses.api_exceptions(include_authentication=True), tags=["Health"], ) -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, diff --git a/backend/capellacollab/settings/configuration/routes.py b/backend/capellacollab/settings/configuration/routes.py index 7690fc19a2..5ce16c0687 100644 --- a/backend/capellacollab/settings/configuration/routes.py +++ b/backend/capellacollab/settings/configuration/routes.py @@ -9,6 +9,9 @@ from capellacollab.core import database from capellacollab.core.authentication import injectables as auth_injectables from capellacollab.feedback import util as feedback_util +from capellacollab.settings.configuration.unifiedconfig import ( + routes as unified_config_routes, +) from capellacollab.users import crud as users_crud from capellacollab.users import models as users_models @@ -25,6 +28,9 @@ tags=["Configuration"], ) +router.include_router(unified_config_routes.router, tags=["Unified Config"]) + + schema_router = fastapi.APIRouter(dependencies=[], tags=["Configuration"]) diff --git a/backend/capellacollab/settings/configuration/unifiedconfig/__init__.py b/backend/capellacollab/settings/configuration/unifiedconfig/__init__.py new file mode 100644 index 0000000000..04412280d8 --- /dev/null +++ b/backend/capellacollab/settings/configuration/unifiedconfig/__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/settings/configuration/unifiedconfig/models.py b/backend/capellacollab/settings/configuration/unifiedconfig/models.py new file mode 100644 index 0000000000..526eb179ac --- /dev/null +++ b/backend/capellacollab/settings/configuration/unifiedconfig/models.py @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors +# SPDX-License-Identifier: Apache-2.0 + +from capellacollab.core import pydantic as core_pydantic +from capellacollab.settings.configuration import models as config_models + + +class Metadata(core_pydantic.BaseModel): + version: str + privacy_policy_url: str | None + imprint_url: str | None + provider: str | None + authentication_provider: str | None + environment: str | None + + host: str | None + port: str | None + protocol: str | None + + +class UnifiedConfig(core_pydantic.BaseModel): + metadata: Metadata + feedback: config_models.FeedbackConfiguration + navbar: config_models.NavbarConfiguration + beta: config_models.BetaConfiguration diff --git a/backend/capellacollab/settings/configuration/unifiedconfig/routes.py b/backend/capellacollab/settings/configuration/unifiedconfig/routes.py new file mode 100644 index 0000000000..bce10d0b97 --- /dev/null +++ b/backend/capellacollab/settings/configuration/unifiedconfig/routes.py @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors +# SPDX-License-Identifier: Apache-2.0 + +import fastapi +from sqlalchemy import orm + +from capellacollab.core import database +from capellacollab.settings.configuration import core as config_core +from capellacollab.settings.configuration.unifiedconfig import models, util + +router = fastapi.APIRouter() + + +@router.get( + "/unified", +) +def get_unified_config( + db: orm.Session = fastapi.Depends(database.get_db), +) -> models.UnifiedConfig: + cfg = config_core.get_global_configuration(db) + + return models.UnifiedConfig( + metadata=util.get_metadata(cfg), + feedback=util.get_feedback(cfg), + beta=util.get_beta(cfg), + navbar=util.get_navbar(cfg), + ) diff --git a/backend/capellacollab/settings/configuration/unifiedconfig/util.py b/backend/capellacollab/settings/configuration/unifiedconfig/util.py new file mode 100644 index 0000000000..0d41003251 --- /dev/null +++ b/backend/capellacollab/settings/configuration/unifiedconfig/util.py @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors +# SPDX-License-Identifier: Apache-2.0 + +import capellacollab +from capellacollab.config import config +from capellacollab.settings.configuration import models as config_models +from capellacollab.settings.configuration.unifiedconfig import models + + +def get_metadata( + global_config: config_models.GlobalConfiguration, +) -> models.Metadata: + return models.Metadata.model_validate( + global_config.metadata.model_dump() + | { + "version": capellacollab.__version__, + "host": config.general.host, + "port": str(config.general.port), + "protocol": config.general.scheme, + } + ) + + +def get_feedback( + global_config: config_models.GlobalConfiguration, +) -> config_models.FeedbackConfiguration: + feedback = global_config.feedback + if not (config.smtp and config.smtp.enabled): + feedback.enabled = False + feedback.after_session = False + feedback.on_footer = False + feedback.on_session_card = False + feedback.interval.enabled = False + + return feedback + + +def get_navbar( + global_config: config_models.GlobalConfiguration, +) -> config_models.NavbarConfiguration: + return global_config.navbar + + +def get_beta( + global_config: config_models.GlobalConfiguration, +) -> config_models.BetaConfiguration: + return global_config.beta diff --git a/backend/capellacollab/users/routes.py b/backend/capellacollab/users/routes.py index 1ce274724f..6684372a0c 100644 --- a/backend/capellacollab/users/routes.py +++ b/backend/capellacollab/users/routes.py @@ -16,7 +16,6 @@ from capellacollab.projects.users import crud as projects_users_crud from capellacollab.sessions import routes as session_routes from capellacollab.settings.configuration import core as config_core -from capellacollab.settings.configuration import models as config_models from capellacollab.users import injectables as users_injectables from capellacollab.users import models as users_models from capellacollab.users.tokens import routes as tokens_routes @@ -41,18 +40,6 @@ def get_current_user( return user -@router.get( - "/beta", - response_model=config_models.BetaConfiguration, -) -def get_beta_config(db: orm.Session = fastapi.Depends(database.get_db)): - cfg = config_core.get_global_configuration(db) - - return config_models.BetaConfiguration.model_validate( - cfg.beta.model_dump() - ) - - @router.get( "/{user_id}", response_model=models.User, diff --git a/backend/tests/settings/test_global_configuration.py b/backend/tests/settings/test_global_configuration.py index baa199d66f..3bcd1a53ec 100644 --- a/backend/tests/settings/test_global_configuration.py +++ b/backend/tests/settings/test_global_configuration.py @@ -128,9 +128,9 @@ def test_metadata_is_updated( assert response.status_code == 200 - response = client.get("/api/v1/metadata") + response = client.get("/api/v1/configurations/unified") assert response.status_code == 200 - assert response.json()["environment"] == "test" + assert response.json()["metadata"]["environment"] == "test" @pytest.mark.usefixtures("admin") @@ -154,9 +154,9 @@ def test_navbar_is_updated( assert response.status_code == 200 - response = client.get("/api/v1/navbar") + response = client.get("/api/v1/configurations/unified") assert response.status_code == 200 - assert response.json()["external_links"][0] == { + assert response.json()["navbar"]["external_links"][0] == { "name": "Example", "href": "https://example.com", "role": "user", diff --git a/backend/tests/test_feedback.py b/backend/tests/test_feedback.py index a89b55be83..018c90870a 100644 --- a/backend/tests/test_feedback.py +++ b/backend/tests/test_feedback.py @@ -210,9 +210,9 @@ def test_feedback_is_updated( assert response.status_code == 200 - response = client.get("/api/v1/configurations/feedback") + response = client.get("/api/v1/configurations/unified") assert response.status_code == 200 - assert response.json() == { + assert response.json()["feedback"] == { "enabled": True, "after_session": True, "on_footer": True, @@ -262,9 +262,9 @@ def test_activate_feedback_without_recipients( @pytest.mark.usefixtures("user", "smtp_config_not_set", "feedback_enabled") def test_feedback_is_disabled_without_smtp(client: testclient.TestClient): - response = client.get("/api/v1/configurations/feedback") + response = client.get("/api/v1/configurations/unified") assert response.status_code == 200 - assert response.json()["enabled"] is False + assert response.json()["feedback"]["enabled"] is False def test_feedback_metric(db: orm.Session): diff --git a/frontend/src/app/general/metadata/metadata.service.ts b/frontend/src/app/general/metadata/metadata.service.ts index 191f3455fe..ffaca4e76a 100644 --- a/frontend/src/app/general/metadata/metadata.service.ts +++ b/frontend/src/app/general/metadata/metadata.service.ts @@ -5,11 +5,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { BehaviorSubject, Observable, tap } from 'rxjs'; -import { - Metadata, - MetadataService as OpenAPIMetadataService, -} from 'src/app/openapi'; +import { UnifiedConfigWrapperService } from '../../services/unified-config-wrapper/unified-config-wrapper.service'; @Injectable({ providedIn: 'root', @@ -18,19 +14,15 @@ export class MetadataService { constructor( private httpClient: HttpClient, public dialog: MatDialog, - private metadataService: OpenAPIMetadataService, + private unifiedConfigWrapperService: UnifiedConfigWrapperService, ) { this.loadVersion(); - this.loadBackendMetadata().subscribe(); } public version: Version | undefined; public oldVersion: string | undefined; - private _backendMetadata = new BehaviorSubject( - undefined, - ); - readonly backendMetadata = this._backendMetadata.asObservable(); + readonly backendMetadata = this.unifiedConfigWrapperService.metadata$; loadVersion(): void { if (!this.version) { @@ -42,12 +34,6 @@ export class MetadataService { } } - loadBackendMetadata(): Observable { - return this.metadataService - .getMetadata() - .pipe(tap((metadata: Metadata) => this._backendMetadata.next(metadata))); - } - get changedVersion(): boolean { const currentVersion = localStorage.getItem('version'); diff --git a/frontend/src/app/general/nav-bar/nav-bar.service.ts b/frontend/src/app/general/nav-bar/nav-bar.service.ts index a78e16a0c8..98e12a6eb2 100644 --- a/frontend/src/app/general/nav-bar/nav-bar.service.ts +++ b/frontend/src/app/general/nav-bar/nav-bar.service.ts @@ -4,34 +4,20 @@ */ import { Injectable } from '@angular/core'; import { MatSidenav } from '@angular/material/sidenav'; -import { BehaviorSubject, map, Observable, tap } from 'rxjs'; -import { - BuiltInLinkItem, - NavbarConfigurationOutput, - NavbarService as OpenAPINavbarService, - Role, -} from 'src/app/openapi'; +import { map } from 'rxjs'; +import { BuiltInLinkItem, Role } from 'src/app/openapi'; import { environment } from 'src/environments/environment'; +import { UnifiedConfigWrapperService } from '../../services/unified-config-wrapper/unified-config-wrapper.service'; @Injectable({ providedIn: 'root', }) export class NavBarService { - constructor(private navbarService: OpenAPINavbarService) { - this.loadNavbarConfig().subscribe(); - } - - loadNavbarConfig(): Observable { - return this.navbarService - .getNavbar() - .pipe(tap((navConf) => this._navbarConfig.next(navConf))); - } - - private _navbarConfig = new BehaviorSubject< - NavbarConfigurationOutput | undefined - >(undefined); + constructor( + private unifiedConfigWrapperService: UnifiedConfigWrapperService, + ) {} - readonly navbarItems$ = this._navbarConfig.pipe( + readonly navbarItems$ = this.unifiedConfigWrapperService.navbar$.pipe( map( (navbarConfig): NavBarItem[] => navbarConfig?.external_links.map((link) => ({ diff --git a/frontend/src/app/openapi/.openapi-generator/FILES b/frontend/src/app/openapi/.openapi-generator/FILES index 048a44bf5c..30e1058fce 100644 --- a/frontend/src/app/openapi/.openapi-generator/FILES +++ b/frontend/src/app/openapi/.openapi-generator/FILES @@ -6,8 +6,6 @@ api/events.service.ts api/feedback.service.ts api/health.service.ts api/integrations-pure-variants.service.ts -api/metadata.service.ts -api/navbar.service.ts api/notices.service.ts api/projects-events.service.ts api/projects-models-backups.service.ts @@ -26,6 +24,7 @@ api/settings-modelsources-git.service.ts api/settings-modelsources-t4-c-instances.service.ts api/settings-modelsources-t4-c-license-servers.service.ts api/tools.service.ts +api/unified-config.service.ts api/users-sessions.service.ts api/users-token.service.ts api/users-workspaces.service.ts @@ -214,6 +213,7 @@ model/tool-version-with-tool.ts model/tool-version.ts model/tool.ts model/toolmodel-status.ts +model/unified-config.ts model/user-metadata.ts model/user-token-with-password.ts model/user-token.ts diff --git a/frontend/src/app/openapi/api/api.ts b/frontend/src/app/openapi/api/api.ts index b6ce03b8da..e85606dcda 100644 --- a/frontend/src/app/openapi/api/api.ts +++ b/frontend/src/app/openapi/api/api.ts @@ -21,10 +21,6 @@ export * from './health.service'; import { HealthService } from './health.service'; export * from './integrations-pure-variants.service'; import { IntegrationsPureVariantsService } from './integrations-pure-variants.service'; -export * from './metadata.service'; -import { MetadataService } from './metadata.service'; -export * from './navbar.service'; -import { NavbarService } from './navbar.service'; export * from './notices.service'; import { NoticesService } from './notices.service'; export * from './projects.service'; @@ -61,6 +57,8 @@ export * from './settings-modelsources-t4-c-license-servers.service'; import { SettingsModelsourcesT4CLicenseServersService } from './settings-modelsources-t4-c-license-servers.service'; export * from './tools.service'; import { ToolsService } from './tools.service'; +export * from './unified-config.service'; +import { UnifiedConfigService } from './unified-config.service'; export * from './users.service'; import { UsersService } from './users.service'; export * from './users-sessions.service'; @@ -69,4 +67,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, FeedbackService, HealthService, IntegrationsPureVariantsService, MetadataService, NavbarService, NoticesService, ProjectsService, ProjectsEventsService, ProjectsModelsService, ProjectsModelsBackupsService, ProjectsModelsDiagramsService, ProjectsModelsGitService, ProjectsModelsModelComplexityBadgeService, ProjectsModelsProvisioningService, ProjectsModelsREADMEService, ProjectsModelsRestrictionsService, ProjectsModelsT4CService, ProjectsToolsService, SessionsService, SettingsModelsourcesGitService, SettingsModelsourcesT4CInstancesService, SettingsModelsourcesT4CLicenseServersService, ToolsService, UsersService, UsersSessionsService, UsersTokenService, UsersWorkspacesService]; +export const APIS = [AuthenticationService, ConfigurationService, EventsService, FeedbackService, HealthService, IntegrationsPureVariantsService, NoticesService, ProjectsService, ProjectsEventsService, ProjectsModelsService, ProjectsModelsBackupsService, ProjectsModelsDiagramsService, ProjectsModelsGitService, ProjectsModelsModelComplexityBadgeService, ProjectsModelsProvisioningService, ProjectsModelsREADMEService, ProjectsModelsRestrictionsService, ProjectsModelsT4CService, ProjectsToolsService, SessionsService, SettingsModelsourcesGitService, SettingsModelsourcesT4CInstancesService, SettingsModelsourcesT4CLicenseServersService, ToolsService, UnifiedConfigService, UsersService, UsersSessionsService, UsersTokenService, UsersWorkspacesService]; diff --git a/frontend/src/app/openapi/api/feedback.service.ts b/frontend/src/app/openapi/api/feedback.service.ts index b86b031e3b..bc17aa9fe8 100644 --- a/frontend/src/app/openapi/api/feedback.service.ts +++ b/frontend/src/app/openapi/api/feedback.service.ts @@ -21,8 +21,6 @@ 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 @@ -96,66 +94,6 @@ export class FeedbackService { return httpParams; } - /** - * Get Feedback Configuration - * @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 getFeedbackConfiguration(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getFeedbackConfiguration(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getFeedbackConfiguration(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getFeedbackConfiguration(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/configurations/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 diff --git a/frontend/src/app/openapi/api/navbar.service.ts b/frontend/src/app/openapi/api/navbar.service.ts deleted file mode 100644 index ec60ae1904..0000000000 --- a/frontend/src/app/openapi/api/navbar.service.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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 { NavbarConfigurationOutput } from '../model/navbar-configuration-output'; - -// @ts-ignore -import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; -import { Configuration } from '../configuration'; - - - -@Injectable({ - providedIn: 'root' -}) -export class NavbarService { - - 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 Navbar - * @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 getNavbar(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getNavbar(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getNavbar(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getNavbar(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/navbar`; - 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 - } - ); - } - -} diff --git a/frontend/src/app/openapi/api/metadata.service.ts b/frontend/src/app/openapi/api/unified-config.service.ts similarity index 83% rename from frontend/src/app/openapi/api/metadata.service.ts rename to frontend/src/app/openapi/api/unified-config.service.ts index cddbd1e271..0ad02bc400 100644 --- a/frontend/src/app/openapi/api/metadata.service.ts +++ b/frontend/src/app/openapi/api/unified-config.service.ts @@ -19,7 +19,7 @@ import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; // @ts-ignore -import { Metadata } from '../model/metadata'; +import { UnifiedConfig } from '../model/unified-config'; // @ts-ignore import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; @@ -30,7 +30,7 @@ import { Configuration } from '../configurat @Injectable({ providedIn: 'root' }) -export class MetadataService { +export class UnifiedConfigService { protected basePath = 'http://localhost'; public defaultHeaders = new HttpHeaders(); @@ -93,14 +93,14 @@ export class MetadataService { } /** - * Get Metadata + * Get Unified Config * @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 getMetadata(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getMetadata(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getMetadata(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getMetadata(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + public getUnifiedConfig(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public getUnifiedConfig(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUnifiedConfig(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUnifiedConfig(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; @@ -138,8 +138,8 @@ export class MetadataService { } } - let localVarPath = `/api/v1/metadata`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + let localVarPath = `/api/v1/unified-configuration`; + return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, diff --git a/frontend/src/app/openapi/api/users.service.ts b/frontend/src/app/openapi/api/users.service.ts index 45b107b2af..9495cfdf00 100644 --- a/frontend/src/app/openapi/api/users.service.ts +++ b/frontend/src/app/openapi/api/users.service.ts @@ -18,8 +18,6 @@ import { HttpClient, HttpHeaders, HttpParams, import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; -// @ts-ignore -import { BetaConfigurationOutput } from '../model/beta-configuration-output'; // @ts-ignore import { HTTPValidationError } from '../model/http-validation-error'; // @ts-ignore @@ -560,73 +558,6 @@ export class UsersService { ); } - /** - * Get Beta Config - * @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 getBetaConfig(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; - public getBetaConfig(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getBetaConfig(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; - public getBetaConfig(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { - - let localVarHeaders = this.defaultHeaders; - - 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; - } - - - 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/users/beta`; - 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 - } - ); - } - /** * Get Common Projects * @param userId diff --git a/frontend/src/app/openapi/model/guacamole-connection-method-input.ts b/frontend/src/app/openapi/model/guacamole-connection-method-input.ts index aa784f6a10..2149f07d7c 100644 --- a/frontend/src/app/openapi/model/guacamole-connection-method-input.ts +++ b/frontend/src/app/openapi/model/guacamole-connection-method-input.ts @@ -16,7 +16,7 @@ import { RDPPortsInput } from './rdp-ports-input'; export interface GuacamoleConnectionMethodInput { id?: string; - type?: string; + type?: GuacamoleConnectionMethodInput.TypeEnum; name?: string; description?: string; ports?: RDPPortsInput; @@ -26,4 +26,11 @@ export interface GuacamoleConnectionMethodInput { environment?: { [key: string]: EnvironmentValue; }; sharing?: ToolSessionSharingConfigurationInput; } +export namespace GuacamoleConnectionMethodInput { + export type TypeEnum = 'guacamole'; + export const TypeEnum = { + Guacamole: 'guacamole' as TypeEnum + }; +} + diff --git a/frontend/src/app/openapi/model/guacamole-connection-method-output.ts b/frontend/src/app/openapi/model/guacamole-connection-method-output.ts index 893b1a3bf5..77faae7408 100644 --- a/frontend/src/app/openapi/model/guacamole-connection-method-output.ts +++ b/frontend/src/app/openapi/model/guacamole-connection-method-output.ts @@ -16,7 +16,7 @@ import { EnvironmentValue1 } from './environment-value1'; export interface GuacamoleConnectionMethodOutput { id: string; - type: string; + type: GuacamoleConnectionMethodOutput.TypeEnum; name: string; description: string; ports: RDPPortsOutput; @@ -26,4 +26,11 @@ export interface GuacamoleConnectionMethodOutput { environment: { [key: string]: EnvironmentValue1; }; sharing: ToolSessionSharingConfigurationOutput; } +export namespace GuacamoleConnectionMethodOutput { + export type TypeEnum = 'guacamole'; + export const TypeEnum = { + Guacamole: 'guacamole' as TypeEnum + }; +} + diff --git a/frontend/src/app/openapi/model/http-connection-method-input.ts b/frontend/src/app/openapi/model/http-connection-method-input.ts index d2f8ea9f79..3288c623b7 100644 --- a/frontend/src/app/openapi/model/http-connection-method-input.ts +++ b/frontend/src/app/openapi/model/http-connection-method-input.ts @@ -16,7 +16,7 @@ import { HTTPPortsInput } from './http-ports-input'; export interface HTTPConnectionMethodInput { id?: string; - type?: string; + type?: HTTPConnectionMethodInput.TypeEnum; name?: string; description?: string; ports?: HTTPPortsInput; @@ -31,4 +31,11 @@ export interface HTTPConnectionMethodInput { */ cookies?: { [key: string]: string; }; } +export namespace HTTPConnectionMethodInput { + export type TypeEnum = 'http'; + export const TypeEnum = { + Http: 'http' as TypeEnum + }; +} + diff --git a/frontend/src/app/openapi/model/http-connection-method-output.ts b/frontend/src/app/openapi/model/http-connection-method-output.ts index 075bdd218d..2264c081a0 100644 --- a/frontend/src/app/openapi/model/http-connection-method-output.ts +++ b/frontend/src/app/openapi/model/http-connection-method-output.ts @@ -16,7 +16,7 @@ import { EnvironmentValue1 } from './environment-value1'; export interface HTTPConnectionMethodOutput { id: string; - type: string; + type: HTTPConnectionMethodOutput.TypeEnum; name: string; description: string; ports: HTTPPortsOutput; @@ -31,4 +31,11 @@ export interface HTTPConnectionMethodOutput { */ cookies: { [key: string]: string; }; } +export namespace HTTPConnectionMethodOutput { + export type TypeEnum = 'http'; + export const TypeEnum = { + Http: 'http' as TypeEnum + }; +} + diff --git a/frontend/src/app/openapi/model/models.ts b/frontend/src/app/openapi/model/models.ts index adbdbd36d1..99857ce308 100644 --- a/frontend/src/app/openapi/model/models.ts +++ b/frontend/src/app/openapi/model/models.ts @@ -189,6 +189,7 @@ export * from './tool-version-configuration-input'; export * from './tool-version-configuration-output'; export * from './tool-version-with-tool'; export * from './toolmodel-status'; +export * from './unified-config'; export * from './user'; export * from './user-metadata'; export * from './user-token'; diff --git a/frontend/src/app/openapi/model/tool-session-connection-input-methods-inner.ts b/frontend/src/app/openapi/model/tool-session-connection-input-methods-inner.ts index 24f6f199cb..2cd98e1f51 100644 --- a/frontend/src/app/openapi/model/tool-session-connection-input-methods-inner.ts +++ b/frontend/src/app/openapi/model/tool-session-connection-input-methods-inner.ts @@ -18,7 +18,7 @@ import { HTTPPortsInput } from './http-ports-input'; export interface ToolSessionConnectionInputMethodsInner { id?: string; - type?: string; + type?: ToolSessionConnectionInputMethodsInner.TypeEnum; name?: string; description?: string; ports?: HTTPPortsInput; @@ -33,4 +33,12 @@ export interface ToolSessionConnectionInputMethodsInner { */ cookies?: { [key: string]: string; }; } +export namespace ToolSessionConnectionInputMethodsInner { + export type TypeEnum = 'guacamole' | 'http'; + export const TypeEnum = { + Guacamole: 'guacamole' as TypeEnum, + Http: 'http' as TypeEnum + }; +} + diff --git a/frontend/src/app/openapi/model/tool-session-connection-output-methods-inner.ts b/frontend/src/app/openapi/model/tool-session-connection-output-methods-inner.ts index e31d5889b7..aee12f9fa7 100644 --- a/frontend/src/app/openapi/model/tool-session-connection-output-methods-inner.ts +++ b/frontend/src/app/openapi/model/tool-session-connection-output-methods-inner.ts @@ -18,7 +18,7 @@ import { EnvironmentValue1 } from './environment-value1'; export interface ToolSessionConnectionOutputMethodsInner { id: string; - type: string; + type: ToolSessionConnectionOutputMethodsInner.TypeEnum; name: string; description: string; ports: HTTPPortsOutput; @@ -33,4 +33,12 @@ export interface ToolSessionConnectionOutputMethodsInner { */ cookies: { [key: string]: string; }; } +export namespace ToolSessionConnectionOutputMethodsInner { + export type TypeEnum = 'guacamole' | 'http'; + export const TypeEnum = { + Guacamole: 'guacamole' as TypeEnum, + Http: 'http' as TypeEnum + }; +} + diff --git a/frontend/src/app/openapi/model/unified-config.ts b/frontend/src/app/openapi/model/unified-config.ts new file mode 100644 index 0000000000..615afbb1a9 --- /dev/null +++ b/frontend/src/app/openapi/model/unified-config.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. + */ + +import { NavbarConfigurationOutput } from './navbar-configuration-output'; +import { BetaConfigurationOutput } from './beta-configuration-output'; +import { Metadata } from './metadata'; +import { FeedbackConfigurationOutput } from './feedback-configuration-output'; + + +export interface UnifiedConfig { + metadata: Metadata; + feedback: FeedbackConfigurationOutput; + navbar: NavbarConfigurationOutput; + beta: BetaConfigurationOutput; +} + diff --git a/frontend/src/app/projects/models/diagrams/model-diagram-dialog/model-diagram-code-block/model-diagram-code-block.component.ts b/frontend/src/app/projects/models/diagrams/model-diagram-dialog/model-diagram-code-block/model-diagram-code-block.component.ts index 6e16ae09ff..63ecc2590b 100644 --- a/frontend/src/app/projects/models/diagrams/model-diagram-dialog/model-diagram-code-block/model-diagram-code-block.component.ts +++ b/frontend/src/app/projects/models/diagrams/model-diagram-dialog/model-diagram-code-block/model-diagram-code-block.component.ts @@ -7,7 +7,6 @@ import { AfterViewInit, Component, Input, - OnInit, Pipe, PipeTransform, forwardRef, @@ -21,12 +20,12 @@ import { import { MatIcon } from '@angular/material/icon'; import { MatTooltip } from '@angular/material/tooltip'; import hljs from 'highlight.js'; -import { MetadataService } from 'src/app/general/metadata/metadata.service'; import { ToastService } from 'src/app/helpers/toast/toast.service'; -import { Metadata, Project, ToolModel } from 'src/app/openapi'; +import { Project, ToolModel } from 'src/app/openapi'; import { getPrimaryGitModel } from 'src/app/projects/models/service/model.service'; import { OwnUserWrapperService } from 'src/app/services/user/user.service'; import { TokenService } from 'src/app/users/basic-auth-service/basic-auth-token.service'; +import { UnifiedConfigWrapperService } from '../../../../../services/unified-config-wrapper/unified-config-wrapper.service'; @Component({ selector: 'app-model-diagram-code-block', @@ -45,24 +44,16 @@ import { TokenService } from 'src/app/users/basic-auth-service/basic-auth-token. forwardRef(() => HighlightPipeTransform), ], }) -export class ModelDiagramCodeBlockComponent implements OnInit, AfterViewInit { +export class ModelDiagramCodeBlockComponent implements AfterViewInit { passwordValue?: string; - metadata?: Metadata; - constructor( - private metadataService: MetadataService, + private unifiedConfigService: UnifiedConfigWrapperService, private userService: OwnUserWrapperService, private tokenService: TokenService, private toastService: ToastService, ) {} - ngOnInit(): void { - this.metadataService.backendMetadata.subscribe((metadata) => { - this.metadata = metadata; - }); - } - @Input({ required: true }) model!: ToolModel; @@ -80,7 +71,7 @@ export class ModelDiagramCodeBlockComponent implements OnInit, AfterViewInit { } get codeBlockContent(): string { - const basePath = `${this.metadata?.protocol}://${this.metadata?.host}:${this.metadata?.port}`; + const basePath = `${this.unifiedConfigService.metadata?.protocol}://${this.unifiedConfigService.metadata?.host}:${this.unifiedConfigService.metadata?.port}`; let capellaMBSEFlags = '"path": "",'; diff --git a/frontend/src/app/services/unified-config-wrapper/unified-config-wrapper.service.ts b/frontend/src/app/services/unified-config-wrapper/unified-config-wrapper.service.ts new file mode 100644 index 0000000000..6d7d3a1459 --- /dev/null +++ b/frontend/src/app/services/unified-config-wrapper/unified-config-wrapper.service.ts @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors + * SPDX-License-Identifier: Apache-2.0 + */ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, map, Observable, tap } from 'rxjs'; +import { + UnifiedConfig, + UnifiedConfigService as OpenAPIUnifiedConfigService, +} from '../../openapi'; + +@Injectable({ + providedIn: 'root', +}) +export class UnifiedConfigWrapperService { + constructor(private unifiedConfigService: OpenAPIUnifiedConfigService) { + this.loadUnifiedConfig().subscribe(); + } + + loadUnifiedConfig(): Observable { + return this.unifiedConfigService + .getUnifiedConfig() + .pipe(tap((unified) => this._unifiedConfig.next(unified))); + } + + private _unifiedConfig = new BehaviorSubject( + undefined, + ); + + readonly unifiedConfig$ = this._unifiedConfig.asObservable(); + + readonly metadata$ = this.unifiedConfig$.pipe( + map((unifiedConfig) => unifiedConfig?.metadata), + ); + get metadata() { + return this._unifiedConfig.value?.metadata; + } + readonly feedback$ = this.unifiedConfig$.pipe( + map((unifiedConfig) => unifiedConfig?.feedback), + ); + get feedback() { + return this._unifiedConfig.value?.feedback; + } + readonly navbar$ = this.unifiedConfig$.pipe( + map((unifiedConfig) => unifiedConfig?.navbar), + ); + get navbar() { + return this._unifiedConfig.value?.navbar; + } + readonly beta$ = this.unifiedConfig$.pipe( + map((unifiedConfig) => unifiedConfig?.beta), + ); + get beta() { + return this._unifiedConfig.value?.beta; + } +} diff --git a/frontend/src/app/sessions/feedback/feedback.service.ts b/frontend/src/app/sessions/feedback/feedback.service.ts index 532764fb41..3a963da5a1 100644 --- a/frontend/src/app/sessions/feedback/feedback.service.ts +++ b/frontend/src/app/sessions/feedback/feedback.service.ts @@ -4,13 +4,9 @@ */ import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { BehaviorSubject, Observable, tap } from 'rxjs'; import { AuthenticationWrapperService } from 'src/app/services/auth/auth.service'; -import { - FeedbackConfigurationOutput, - FeedbackService as OpenAPIFeedbackService, - Session, -} from '../../openapi'; +import { Session } from '../../openapi'; +import { UnifiedConfigWrapperService } from '../../services/unified-config-wrapper/unified-config-wrapper.service'; import { FeedbackDialogComponent } from './feedback-dialog/feedback-dialog.component'; @Injectable({ @@ -18,24 +14,16 @@ import { FeedbackDialogComponent } from './feedback-dialog/feedback-dialog.compo }) export class FeedbackWrapperService { constructor( - private feedbackService: OpenAPIFeedbackService, public dialog: MatDialog, private authService: AuthenticationWrapperService, + public unifiedConfigWrapperService: UnifiedConfigWrapperService, ) { - this.loadFeedbackConfig().subscribe(() => this.triggerFeedbackPrompt()); + this.unifiedConfigWrapperService.feedback$.subscribe(() => { + this.triggerFeedbackPrompt(); + }); } - private _feedbackConfig = new BehaviorSubject< - FeedbackConfigurationOutput | undefined - >(undefined); - - public readonly feedbackConfig$ = this._feedbackConfig.asObservable(); - - loadFeedbackConfig(): Observable { - return this.feedbackService - .getFeedbackConfiguration() - .pipe(tap((feedbackConf) => this._feedbackConfig.next(feedbackConf))); - } + public readonly feedbackConfig$ = this.unifiedConfigWrapperService.feedback$; triggerFeedbackPrompt(): void { if (this.shouldShowIntervalPrompt() && this.authService.isLoggedIn()) { @@ -52,7 +40,8 @@ export class FeedbackWrapperService { } public shouldShowIntervalPrompt() { - if (!this._feedbackConfig.value?.interval?.enabled) return false; + if (!this.unifiedConfigWrapperService.feedback?.interval?.enabled) + return false; const lastPrompt = localStorage.getItem('feedbackPrompt'); if (!lastPrompt) { return true; @@ -60,13 +49,10 @@ export class FeedbackWrapperService { const lastPromptDate = new Date(parseInt(lastPrompt)); const hoursInterval = - this._feedbackConfig.value.interval.hours_between_prompt; + this.unifiedConfigWrapperService.feedback.interval.hours_between_prompt; const diff = new Date().getTime() - lastPromptDate.getTime(); const hours = diff / (1000 * 60 * 60); - if (hours >= hoursInterval) { - return true; - } - return false; + return hours >= hoursInterval; } public saveFeedbackPromptDate() { @@ -74,7 +60,6 @@ export class FeedbackWrapperService { } public shouldShowPostSessionPrompt() { - if (this._feedbackConfig.value?.after_session) return true; - return false; + return !!this.unifiedConfigWrapperService.feedback?.after_session; } } diff --git a/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts b/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts index 5a27402d6d..9047bdaad1 100644 --- a/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts +++ b/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts @@ -5,13 +5,11 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { MatButton } from '@angular/material/button'; import { MatIcon } from '@angular/material/icon'; -import { MetadataService } from 'src/app/general/metadata/metadata.service'; -import { NavBarService } from 'src/app/general/nav-bar/nav-bar.service'; import { EditorComponent } from 'src/app/helpers/editor/editor.component'; import { ToastService } from 'src/app/helpers/toast/toast.service'; import { ConfigurationSettingsService } from 'src/app/settings/core/configuration-settings/configuration-settings.service'; import { EditorComponent as EditorComponent_1 } from '../../../helpers/editor/editor.component'; -import { FeedbackWrapperService } from '../../../sessions/feedback/feedback.service'; +import { UnifiedConfigWrapperService } from '../../../services/unified-config-wrapper/unified-config-wrapper.service'; @Component({ selector: 'app-configuration-settings', @@ -24,9 +22,7 @@ export class ConfigurationSettingsComponent implements OnInit { constructor( private configurationSettingsService: ConfigurationSettingsService, private toastService: ToastService, - private metadataService: MetadataService, - private navbarService: NavBarService, - private feedbackService: FeedbackWrapperService, + private unifiedConfigService: UnifiedConfigWrapperService, ) {} ngOnInit(): void { @@ -52,9 +48,7 @@ export class ConfigurationSettingsComponent implements OnInit { 'The global configuration has been successfully updated. The metadata will be reloaded.', ); this.fetchConfiguration(); - this.metadataService.loadBackendMetadata().subscribe(); - this.navbarService.loadNavbarConfig().subscribe(); - this.feedbackService.loadFeedbackConfig().subscribe(); + this.unifiedConfigService.loadUnifiedConfig().subscribe(); }, }); } diff --git a/frontend/src/app/users/users-profile/users-profile.component.html b/frontend/src/app/users/users-profile/users-profile.component.html index 3b1a24042f..555cdf1c04 100644 --- a/frontend/src/app/users/users-profile/users-profile.component.html +++ b/frontend/src/app/users/users-profile/users-profile.component.html @@ -27,11 +27,11 @@

Profile of {{ user?.name }}

@if (ownUserService.user?.role === "administrator") { } - @if ((betaConfig$ | async)?.enabled) { + @if ((unifiedConfigWrapperService.beta$ | async)?.enabled) { @if ( ownUserService.user?.role === "administrator" || (ownUserService.user?.id === (userWrapperService.user$ | async)?.id && - (betaConfig$ | async)?.allow_self_enrollment) + (unifiedConfigWrapperService.beta$ | async)?.allow_self_enrollment) ) { } diff --git a/frontend/src/app/users/users-profile/users-profile.component.ts b/frontend/src/app/users/users-profile/users-profile.component.ts index 50fe378abf..12ba1a6869 100644 --- a/frontend/src/app/users/users-profile/users-profile.component.ts +++ b/frontend/src/app/users/users-profile/users-profile.component.ts @@ -5,10 +5,9 @@ import { AsyncPipe, DatePipe } from '@angular/common'; import { Component } from '@angular/core'; import { UntilDestroy } from '@ngneat/until-destroy'; -import { BehaviorSubject } from 'rxjs'; import { OwnUserWrapperService } from 'src/app/services/user/user.service'; import { UserWrapperService } from 'src/app/users/user-wrapper/user-wrapper.service'; -import { BetaConfigurationOutput, UsersService } from '../../openapi'; +import { UnifiedConfigWrapperService } from '../../services/unified-config-wrapper/unified-config-wrapper.service'; import { BetaTestingComponent } from './beta-testing/beta-testing.component'; import { CommonProjectsComponent } from './common-projects/common-projects.component'; import { UserInformationComponent } from './user-information/user-information.component'; @@ -31,18 +30,6 @@ export class UsersProfileComponent { constructor( public ownUserService: OwnUserWrapperService, public userWrapperService: UserWrapperService, - private usersService: UsersService, - ) { - this.getBetaConfig(); - } - - readonly betaConfig$ = new BehaviorSubject< - BetaConfigurationOutput | undefined - >(undefined); - - getBetaConfig() { - return this.usersService.getBetaConfig().subscribe((res) => { - this.betaConfig$.next(res); - }); - } + public unifiedConfigWrapperService: UnifiedConfigWrapperService, + ) {} }