Skip to content

Commit

Permalink
feat: Redesign Model Card
Browse files Browse the repository at this point in the history
Re-order the buttons on the model card, moving some infrequently used ones to an overflow menu.
Modify the "Create Persistent Session" button to prompt for the connection method and then
immediately create the session.

Closes #1353
  • Loading branch information
zusorio committed Jan 13, 2025
1 parent 30b7593 commit 09f0edd
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,59 +122,37 @@ <h2 class="text-xl font-medium">Models</h2>
}
</div>
<div class="m-2.5">
@if (userService.user?.role === "administrator") {
<a
mat-mini-fab
color="primary"
matTooltip="Model restrictions"
class="!m-1.5"
[routerLink]="['model', model.slug, 'restrictions']"
>
<mat-icon>key</mat-icon>
</a>
}
@if (projectUserService.verifyRole("manager")) {
<a
mat-mini-fab
color="primary"
matTooltip="Configure model"
class="!m-1.5"
[routerLink]="['model', model.slug, 'metadata']"
>
<mat-icon>settings</mat-icon>
</a>
@if (
!project?.is_archived &&
project?.type !== "training" &&
model.t4c_models &&
projectUserService.verifyPermission("write")
) {
<button
mat-mini-fab
color="primary"
matTooltip="Move model to different project"
matTooltip="Request persistent session"
class="!m-1.5"
(click)="openMoveToProjectDialog(model)"
(click)="openPersistentSessionDialog(model)"
>
<mat-icon>drive_file_move</mat-icon>
<mat-icon>screen_share</mat-icon>
</button>
<a
mat-mini-fab
color="primary"
matTooltip="Configure model sources"
class="!m-1.5"
[routerLink]="['model', model.slug, 'modelsources']"
>
<mat-icon>link</mat-icon>
</a>
@if (!project?.is_archived && project?.type !== "training") {
<a
}

@if (model.git_models) {
@if (model.tool.name === "Capella") {
<button
mat-mini-fab
color="primary"
matTooltip="Start synchronization"
matTooltip="Show diagrams of model"
class="!m-1.5"
(click)="openPipelineDialog(model)"
[disabled]="!getPrimaryGitModelURL(model)"
(click)="openDiagramsDialog(model)"
>
<mat-icon>sync</mat-icon>
</a>
<mat-icon>image_search</mat-icon>
</button>
}
}

@if (model.git_models) {
<a
mat-mini-fab
color="primary"
Expand All @@ -187,36 +165,62 @@ <h2 class="text-xl font-medium">Models</h2>
>
<mat-icon>open_in_new</mat-icon>
</a>
@if (model.tool.name === "Capella") {
<button
mat-mini-fab
color="primary"
matTooltip="Show diagrams of model"
class="!m-1.5"
[disabled]="!getPrimaryGitModelURL(model)"
(click)="openDiagramsDialog(model)"
>
<mat-icon>image_search</mat-icon>
</button>
}
}

@if (
projectUserService.verifyRole("manager") &&
!project?.is_archived &&
project?.type !== "training" &&
model.t4c_models &&
projectUserService.verifyPermission("write")
project?.type !== "training"
) {
<a
mat-mini-fab
color="primary"
matTooltip="Request persistent session"
class="!m-1.5"
routerLink="/sessions"
matTooltip="Start synchronization"
(click)="openPipelineDialog(model)"
>
<mat-icon>screen_share</mat-icon>
<mat-icon>sync</mat-icon>
</a>
}

<button
mat-mini-fab
color="primary"
matTooltip="More Options"
class="!m-1.5"
[matMenuTriggerFor]="menu"
>
<mat-icon>more_horiz</mat-icon>
</button>
<mat-menu #menu="matMenu">
@if (userService.user?.role === "administrator") {
<a
mat-menu-item
[routerLink]="['model', model.slug, 'restrictions']"
>
<mat-icon>key</mat-icon>
<span>Model restrictions</span>
</a>
}

@if (projectUserService.verifyRole("manager")) {
<a mat-menu-item [routerLink]="['model', model.slug, 'metadata']">
<mat-icon>settings</mat-icon>
<span>Configure model</span>
</a>
<button mat-menu-item (click)="openMoveToProjectDialog(model)">
<mat-icon>drive_file_move</mat-icon>
Move model to different project
</button>
<a
mat-menu-item
[routerLink]="['model', model.slug, 'modelsources']"
>
<mat-icon>link</mat-icon>
<span>Configure model sources</span>
</a>
}
</mat-menu>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import {
} from '@angular/material/button';
import { MatDialog } from '@angular/material/dialog';
import { MatIcon } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatTooltip } from '@angular/material/tooltip';
import { RouterLink } from '@angular/router';
import { Router, RouterLink } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { first, filter } from 'rxjs';
Expand All @@ -28,6 +29,7 @@ import { ReorderModelsDialogComponent } from 'src/app/projects/project-detail/mo
import { ProjectUserService } from 'src/app/projects/project-detail/project-users/service/project-user.service';
import { OwnUserWrapperService } from 'src/app/services/user/user.service';
import { SessionService } from 'src/app/sessions/service/session.service';
import { CreatePersistentSessionDialogComponent } from '../../../sessions/user-sessions-wrapper/create-sessions/create-persistent-session/create-persistent-session-dialog/create-persistent-session-dialog.component';
import { TriggerPipelineComponent } from '../../models/backup-settings/trigger-pipeline/trigger-pipeline.component';
import { ProjectWrapperService } from '../../service/project.service';
import { ModelComplexityBadgeComponent } from './model-complexity-badge/model-complexity-badge.component';
Expand All @@ -47,6 +49,7 @@ import { ModelComplexityBadgeComponent } from './model-complexity-badge/model-co
MatMiniFabAnchor,
MatMiniFabButton,
AsyncPipe,
MatMenuModule,
],
})
export class ModelOverviewComponent implements OnInit {
Expand All @@ -59,6 +62,7 @@ export class ModelOverviewComponent implements OnInit {
public projectUserService: ProjectUserService,
public userService: OwnUserWrapperService,
public projectService: ProjectWrapperService,
private router: Router,
private dialog: MatDialog,
) {}

Expand Down Expand Up @@ -124,6 +128,20 @@ export class ModelOverviewComponent implements OnInit {
});
}

openPersistentSessionDialog(model: ToolModel): void {
const dialogRef = this.dialog.open(CreatePersistentSessionDialogComponent, {
data: {
toolVersion: model.version,
tool: model.tool,
},
});
dialogRef.afterClosed().subscribe((success) => {
if (success) {
this.router.navigate(['/']);
}
});
}

openReorderModelsDialog(models: ToolModel[]): void {
if (this.project) {
this.dialog.open(ReorderModelsDialogComponent, {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!--
~ SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
~ SPDX-License-Identifier: Apache-2.0
-->

<div class="dialog space-y-2">
<h2 class="text-xl font-medium">Start a Persistent Workspace Session</h2>

<p>
Start a persistent workspace session using {{ this.data.tool.name }} ({{
this.data.toolVersion.name
}}).<br />
All changes you make to models will be saved.
</p>

@if (this.data.tool.config.connection.methods.length > 1) {
<div>
<span class="text-sm">Connection method:</span> <br />
<mat-radio-group
class="flex gap-2"
[(ngModel)]="selectedConnectionMethod"
>
@for (
connectionMethod of this.data.tool.config.connection.methods;
track connectionMethod.id
) {
<mat-radio-button [value]="connectionMethod">{{
connectionMethod.name
}}</mat-radio-button>
}
</mat-radio-group>
</div>

@if (this.selectedConnectionMethod.description) {
<div class="border p-2 text-sm shadow">
{{ this.selectedConnectionMethod.description }}
</div>
}
}

<div class="flex justify-between">
<button mat-stroked-button mat-dialog-close type="button">Cancel</button>
<button
mat-flat-button
color="primary"
type="button"
[disabled]="requestInProgress"
(click)="requestPersistentSession()"
>
{{ requestInProgress ? "Requesting..." : "Request session" }}
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { Component, Inject } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButton } from '@angular/material/button';
import {
MAT_DIALOG_DATA,
MatDialogClose,
MatDialogRef,
} from '@angular/material/dialog';
import { MatRadioButton, MatRadioGroup } from '@angular/material/radio';
import { SessionType, Tool, ToolVersion } from '../../../../../openapi';
import { ConnectionMethod } from '../../../../../settings/core/tools-settings/tool.service';
import { SessionService } from '../../../../service/session.service';
import { UserSessionService } from '../../../../service/user-session.service';

export interface CreatePersistentSessionDialogData {
tool: Tool;
toolVersion: ToolVersion;
}

@Component({
selector: 'app-create-persistent-session-dialog',
imports: [
MatRadioButton,
MatRadioGroup,
ReactiveFormsModule,
FormsModule,
MatButton,
MatDialogClose,
],
templateUrl: './create-persistent-session-dialog.component.html',
})
export class CreatePersistentSessionDialogComponent {
selectedConnectionMethod: ConnectionMethod;
requestInProgress = false;

constructor(
private sessionService: SessionService,
private userSessionService: UserSessionService,
public dialogRef: MatDialogRef<
CreatePersistentSessionDialogComponent,
boolean
>,
@Inject(MAT_DIALOG_DATA) public data: CreatePersistentSessionDialogData,
) {
this.selectedConnectionMethod = data.tool.config.connection.methods[0];
}

requestPersistentSession() {
this.requestInProgress = true;

this.sessionService
.createSession({
tool_id: this.data.tool.id,
version_id: this.data.toolVersion.id,
connection_method_id: this.selectedConnectionMethod.id!,
session_type: SessionType.Persistent,
})
.subscribe({
next: () => {
this.userSessionService.loadSessions();
this.requestInProgress = false;
this.dialogRef.close(true);
},
error: () => {
this.requestInProgress = false;
},
});
}
}
Loading

0 comments on commit 09f0edd

Please sign in to comment.