From 183574498871a9877847a410399b8157c050661b Mon Sep 17 00:00:00 2001 From: romeonicholas Date: Thu, 2 Nov 2023 15:30:34 +0100 Subject: [PATCH] Add reorder button and skeletal dialog to model overview feat: update models table and functions for display order fix: Get reorder path working fix: Bad merge fix: Hide reorder button from non-managers refactor: remove unused comments style: Clean up reorder modal feat: Add function to update a group of models, use for model reordering fix: Remove unused imports feat: order models by id when no display order has been set docs: Add missing license headers fix: Remove excess declaration and format files fix: Rename angular functions to meet linter standards fix: eslint styling fix: Move display order out of post model test: Add test to patch model display order fix: Revert unecessary angular function name changes This reverts commit e876fed1e37b7d9861a35dfa4beccf59e60b7b9a. build: Update frontend versions build(deps-dev): bump alembic from 1.12.0 to 1.12.1 in /backend Bumps [alembic](https://github.com/sqlalchemy/alembic) from 1.12.0 to 1.12.1. - [Release notes](https://github.com/sqlalchemy/alembic/releases) - [Changelog](https://github.com/sqlalchemy/alembic/blob/main/CHANGES) - [Commits](https://github.com/sqlalchemy/alembic/commits) --- updated-dependencies: - dependency-name: alembic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] docs(user): Add instructions for secondary click on macOS The usual option to press `Control` while clicking doesn't work in RDP-sessions on macOS. The `Control` can't be evaluated and mapped properly. It's passed to the Linux container, which can't handle the `Control` key. refactor: Create floating window mgr component feat: Add tiling window manager with slider build: Update frontend versions fix(session-viewer): Disable pointer event while resizing sessions This commit fixes a small bug that was introduced in #1150. When the pointer events are not disabled on the iframe, some pointer events are "stolen" by the iframe. Therefore, they can not be used by our event handlers. This led to a "jumpy" behaviour while resizing. fix: Get reorder path working fix: Undo rebase errors feat: Add tiling window manager with slider fix: Get reorder path working Revert "build: Update frontend versions" This reverts commit 800f6ce72b9fc82eca79b55ec76944a9606265a8. build: Update frontend versions build(deps-dev): bump alembic from 1.12.0 to 1.12.1 in /backend Bumps [alembic](https://github.com/sqlalchemy/alembic) from 1.12.0 to 1.12.1. - [Release notes](https://github.com/sqlalchemy/alembic/releases) - [Changelog](https://github.com/sqlalchemy/alembic/blob/main/CHANGES) - [Commits](https://github.com/sqlalchemy/alembic/commits) --- updated-dependencies: - dependency-name: alembic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] docs(user): Add instructions for secondary click on macOS The usual option to press `Control` while clicking doesn't work in RDP-sessions on macOS. The `Control` can't be evaluated and mapped properly. It's passed to the Linux container, which can't handle the `Control` key. refactor: Create floating window mgr component feat: Add tiling window manager with slider build: Update frontend versions fix(session-viewer): Disable pointer event while resizing sessions This commit fixes a small bug that was introduced in #1150. When the pointer events are not disabled on the iframe, some pointer events are "stolen" by the iframe. Therefore, they can not be used by our event handlers. This led to a "jumpy" behaviour while resizing. fix: Migrate logic for button showing to Angular 17 blocks fix: replace if statement with rxjs filtering fix: Remove unused matdialog declaration fix: Shift logic for project check to come before sending data fix: Refactor data model for reordering view fix: Rename all related instances of reorderModels to reorderModelsDialog fix: Update for loop of models to Angular 17 format fix: Separate out patchModel to reduce duplication in model updates fix: Manually format html fix: use model ids in place of names and rename patch function --- ...6_add_user_determined_display_order_to_.py | 24 ++++ .../capellacollab/projects/toolmodels/crud.py | 5 + .../projects/toolmodels/models.py | 3 + .../projects/toolmodels/routes.py | 9 +- .../toolmodels/test_toolmodel_routes.py | 18 +++ frontend/package-lock.json | 135 ++++++++++++++++++ frontend/src/app/app.module.ts | 2 + .../projects/models/service/model.service.ts | 54 +++++-- .../model-overview.component.html | 58 ++++---- .../model-overview.component.ts | 23 ++- .../reorder-models-dialog.component.html | 39 +++++ .../reorder-models-dialog.component.ts | 50 +++++++ 12 files changed, 380 insertions(+), 40 deletions(-) create mode 100644 backend/capellacollab/alembic/versions/0e2028f83156_add_user_determined_display_order_to_.py create mode 100644 frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.html create mode 100644 frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.ts diff --git a/backend/capellacollab/alembic/versions/0e2028f83156_add_user_determined_display_order_to_.py b/backend/capellacollab/alembic/versions/0e2028f83156_add_user_determined_display_order_to_.py new file mode 100644 index 0000000000..bb2f2da59a --- /dev/null +++ b/backend/capellacollab/alembic/versions/0e2028f83156_add_user_determined_display_order_to_.py @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: Copyright DB Netz AG and the capella-collab-manager contributors +# SPDX-License-Identifier: Apache-2.0 + +"""Add user-determined display order to models + +Revision ID: 0e2028f83156 +Revises: ac0e6e0f77ee +Create Date: 2023-11-12 14:47:12.295103 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = "0e2028f83156" +down_revision = "ac0e6e0f77ee" +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column( + "models", sa.Column("display_order", sa.Integer(), nullable=True) + ) diff --git a/backend/capellacollab/projects/toolmodels/crud.py b/backend/capellacollab/projects/toolmodels/crud.py index 7195222558..b2498ae248 100644 --- a/backend/capellacollab/projects/toolmodels/crud.py +++ b/backend/capellacollab/projects/toolmodels/crud.py @@ -83,6 +83,7 @@ def create_model( version: tools_models.DatabaseVersion | None = None, nature: tools_models.DatabaseNature | None = None, configuration: dict[str, str] | None = None, + display_order: int | None = None, ) -> models.DatabaseCapellaModel: restrictions = restrictions_models.DatabaseToolModelRestrictions() @@ -96,6 +97,7 @@ def create_model( nature=nature, restrictions=restrictions, configuration=configuration, + display_order=display_order, ) db.add(restrictions) db.add(model) @@ -133,6 +135,7 @@ def update_model( version: tools_models.DatabaseVersion, nature: tools_models.DatabaseNature, project: projects_model.DatabaseProject, + display_order: int | None, ) -> models.DatabaseCapellaModel: model.version = version model.nature = nature @@ -142,6 +145,8 @@ def update_model( if name: model.name = name model.slug = slugify.slugify(name) + if display_order: + model.display_order = display_order db.commit() return model diff --git a/backend/capellacollab/projects/toolmodels/models.py b/backend/capellacollab/projects/toolmodels/models.py index 7016be16f0..58c0245abe 100644 --- a/backend/capellacollab/projects/toolmodels/models.py +++ b/backend/capellacollab/projects/toolmodels/models.py @@ -54,6 +54,7 @@ class PatchCapellaModel(pydantic.BaseModel): version_id: int | None = None nature_id: int | None = None project_slug: str | None = None + display_order: int | None = None class ToolDetails(pydantic.BaseModel): @@ -72,6 +73,7 @@ class DatabaseCapellaModel(database.Base): name: orm.Mapped[str] = orm.mapped_column(index=True) slug: orm.Mapped[str] description: orm.Mapped[str] + display_order: orm.Mapped[int | None] configuration: orm.Mapped[dict[str, str] | None] @@ -116,6 +118,7 @@ class CapellaModel(pydantic.BaseModel): slug: str name: str description: str + display_order: int | None tool: tools_models.ToolBase version: tools_models.ToolVersionBase | None = None nature: tools_models.ToolNatureBase | None = None diff --git a/backend/capellacollab/projects/toolmodels/routes.py b/backend/capellacollab/projects/toolmodels/routes.py index 412b6a4fff..25a36f3f94 100644 --- a/backend/capellacollab/projects/toolmodels/routes.py +++ b/backend/capellacollab/projects/toolmodels/routes.py @@ -183,7 +183,14 @@ def patch_tool_model( new_project = model.project return crud.update_model( - db, model, body.description, body.name, version, nature, new_project + db, + model, + body.description, + body.name, + version, + nature, + new_project, + body.display_order, ) diff --git a/backend/tests/projects/toolmodels/test_toolmodel_routes.py b/backend/tests/projects/toolmodels/test_toolmodel_routes.py index b5e9fc6a55..7e8c9f28ce 100644 --- a/backend/tests/projects/toolmodels/test_toolmodel_routes.py +++ b/backend/tests/projects/toolmodels/test_toolmodel_routes.py @@ -86,3 +86,21 @@ def test_rename_toolmodel_where_name_already_exists( assert response.status_code == 409 assert "A model with a similar name already exists" in response.text mock_get_model_by_slugs.assert_called_once() + + +def test_update_toolmodel_order_successful( + capella_model: toolmodels_models.DatabaseCapellaModel, + project: projects_models.DatabaseProject, + client: testclient.TestClient, + executor_name: str, + db: orm.Session, +): + users_crud.create_user(db, executor_name, users_models.Role.ADMIN) + + response = client.patch( + f"/api/v1/projects/{project.slug}/models/{capella_model.slug}", + json={"display_order": 1}, + ) + + assert response.status_code == 200 + assert "1" in response.text diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ea2b8a0473..8f4dd38a36 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -776,6 +776,45 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.3.tgz", + "integrity": "sha512-SOngD3rKnwZWhhUV68AYlH8M3LRGvF69jnDrYKwtRy1ESqSH7tt+1vexGC290gKvqH7bNMgYv8f5BS1AASRfzw==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@angular-eslint/builder": { "version": "17.1.1", "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-17.1.1.tgz", @@ -938,6 +977,48 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { + "version": "0.1700.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1700.3.tgz", + "integrity": "sha512-HUjx7vD16paWXHKHYc2LsSn/kaYbFr2YNnlzuSr9C0kauKS1e7sRpRvtGwQzXfohzgyKi81AAU5uA2KLRGq83w==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "17.0.3", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.3.tgz", + "integrity": "sha512-SOngD3rKnwZWhhUV68AYlH8M3LRGvF69jnDrYKwtRy1ESqSH7tt+1vexGC290gKvqH7bNMgYv8f5BS1AASRfzw==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, "node_modules/@angular/cli/node_modules/@npmcli/git": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.3.tgz", @@ -1307,6 +1388,18 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/@angular/cli/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@angular/cli/node_modules/read-package-json": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-7.0.0.tgz", @@ -5381,6 +5474,45 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.0.3.tgz", + "integrity": "sha512-SOngD3rKnwZWhhUV68AYlH8M3LRGvF69jnDrYKwtRy1ESqSH7tt+1vexGC290gKvqH7bNMgYv8f5BS1AASRfzw==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "3.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@schematics/angular/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@sigstore/bundle": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.0.0.tgz", @@ -15985,6 +16117,9 @@ "version": "10.1.0", "inBundle": true, "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, "engines": { "node": "14 || >=16.14" } diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index da1ae3c9d9..ecb909b4cd 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -98,6 +98,7 @@ import { EditProjectMetadataComponent } from './projects/project-detail/edit-pro import { ModelComplexityBadgeComponent } from './projects/project-detail/model-overview/model-complexity-badge/model-complexity-badge.component'; import { ModelOverviewComponent } from './projects/project-detail/model-overview/model-overview.component'; import { MoveModelComponent } from './projects/project-detail/model-overview/move-model/move-model.component'; +import { ReorderModelsDialogComponent } from './projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component'; import { ProjectDetailsComponent } from './projects/project-detail/project-details.component'; import { ProjectMetadataComponent } from './projects/project-detail/project-metadata/project-metadata.component'; import { AddUserToProjectDialogComponent } from './projects/project-detail/project-users/add-user-to-project/add-user-to-project.component'; @@ -215,6 +216,7 @@ import { UsersProfileComponent } from './users/users-profile/users-profile.compo ProjectUserSettingsComponent, ProjectWrapperComponent, PureVariantsComponent, + ReorderModelsDialogComponent, SessionComponent, SessionIFrameComponent, SessionOverviewComponent, diff --git a/frontend/src/app/projects/models/service/model.service.ts b/frontend/src/app/projects/models/service/model.service.ts index 9095f29694..a1491769df 100644 --- a/frontend/src/app/projects/models/service/model.service.ts +++ b/frontend/src/app/projects/models/service/model.service.ts @@ -10,7 +10,7 @@ import { AsyncValidatorFn, ValidationErrors, } from '@angular/forms'; -import { BehaviorSubject, map, Observable, take, tap } from 'rxjs'; +import { BehaviorSubject, forkJoin, map, Observable, take, tap } from 'rxjs'; import slugify from 'slugify'; import { ModelRestrictions } from 'src/app/projects/models/model-restrictions/service/model-restrictions.service'; import { T4CModel } from 'src/app/projects/models/model-source/t4c/service/t4c-model.service'; @@ -92,24 +92,48 @@ export class ModelService { ); } + private applyModelPatch( + projectSlug: string, + modelSlug: string, + patchData: PatchModel, + ): Observable { + return this.http.patch( + `${this.base_url}${projectSlug}/models/${modelSlug}/`, + patchData, + ); + } + updateModel( projectSlug: string, modelSlug: string, patchModel: PatchModel, ): Observable { - return this.http - .patch( - `${this.base_url}${projectSlug}/models/${modelSlug}/`, - patchModel, - ) - .pipe( - tap({ - next: (model) => { - this.loadModels(projectSlug); - this._model.next(model); - }, - }), - ); + return this.applyModelPatch(projectSlug, modelSlug, patchModel).pipe( + tap({ + next: (model) => { + this.loadModels(projectSlug); + this._model.next(model); + }, + }), + ); + } + + updateModels( + projectSlug: string, + modelUpdates: { modelSlug: string; patchModel: PatchModel }[], + ): Observable { + const updateObservables = modelUpdates.map(({ modelSlug, patchModel }) => + this.applyModelPatch(projectSlug, modelSlug, patchModel), + ); + + return forkJoin(updateObservables).pipe( + tap({ + next: (models: Model[]) => { + this.loadModels(projectSlug); + this._model.next(models[models.length - 1]); + }, + }), + ); } deleteModel(projectSlug: string, modelSlug: string): Observable { @@ -184,6 +208,7 @@ export type Model = { t4c_models: T4CModel[]; git_models: GetGitModel[]; restrictions: ModelRestrictions; + display_order: number; }; export type PatchModel = { @@ -192,6 +217,7 @@ export type PatchModel = { nature_id?: number; version_id?: number; project_slug?: string; + display_order?: number; }; export function getPrimaryGitModel(model: Model): GetGitModel | undefined { diff --git a/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html b/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html index 3998bf63fb..d73bbea3b7 100644 --- a/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html +++ b/frontend/src/app/projects/project-detail/model-overview/model-overview.component.html @@ -6,29 +6,40 @@

Models

- - add - + @if (projectUserService.verifyRole("manager")) { + + add + + @if (models !== undefined && models.length > 1) { + + } + }
@@ -45,7 +56,6 @@

Models

>
- (this.project = project)); + + this.modelService.models$ + .pipe(untilDestroyed(this), filter(Boolean)) + .subscribe((models) => { + this.models = models.sort((a, b) => { + if (a.display_order && b.display_order) { + return a.display_order - b.display_order; + } + return b.id - a.id; + }); + }); } getPrimaryWorkingMode(model: Model): string { @@ -88,4 +101,12 @@ export class ModelOverviewComponent implements OnInit { data: { projectSlug: this.project?.slug, model: model }, }); } + + openReorderModelsDialog(models: Model[]): void { + if (this.project) { + this.dialog.open(ReorderModelsDialogComponent, { + data: { projectSlug: this.project.slug, models: models }, + }); + } + } } diff --git a/frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.html b/frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.html new file mode 100644 index 0000000000..9ebe1ba3e1 --- /dev/null +++ b/frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.html @@ -0,0 +1,39 @@ + + +
+

Reorder models

+
+ Drag and drop models in the order you would like them to appear in the + project overview, then press save. + All members of a project team will see the + updated order. +
+ +
+ @for (model of data.models; track model.id) { +
+ + reorder + + + {{ model.name }} ({{ model.tool.name }} + - {{ model.version.name }} + ) + +
+ } +
+ +
+ +
+
diff --git a/frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.ts b/frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.ts new file mode 100644 index 0000000000..ed683c36a9 --- /dev/null +++ b/frontend/src/app/projects/project-detail/model-overview/reorder-models-dialog/reorder-models-dialog.component.ts @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: Copyright DB Netz AG and the capella-collab-manager contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { ToastService } from 'src/app/helpers/toast/toast.service'; +import { + Model, + ModelService, +} from 'src/app/projects/models/service/model.service'; +import {} from 'src/app/projects/service/project.service'; +@Component({ + selector: 'app-reorder-models', + templateUrl: './reorder-models-dialog.component.html', +}) +export class ReorderModelsDialogComponent { + constructor( + public modelService: ModelService, + private dialogRef: MatDialogRef, + private toastService: ToastService, + @Inject(MAT_DIALOG_DATA) + public data: { projectSlug: string; models: Model[] }, + ) {} + + drop(event: CdkDragDrop): void { + moveItemInArray(this.data.models, event.previousIndex, event.currentIndex); + } + + async reorderModels() { + const modelsToPatch = this.data.models.map((model, index) => { + return { + modelSlug: model.slug, + patchModel: { display_order: index + 1 }, + }; + }); + + this.modelService + .updateModels(this.data.projectSlug, modelsToPatch) + .subscribe(() => { + this.toastService.showSuccess( + `Model order updated`, + `Successfully reordered models in project ${this.data.projectSlug}`, + ); + this.dialogRef.close(); + }); + } +}