Skip to content

Commit

Permalink
refactor: show/change experiment default template
Browse files Browse the repository at this point in the history
  • Loading branch information
infacc committed Aug 1, 2023
1 parent f6b830c commit 8349b5f
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 67 deletions.
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import { ExperimentWorkspaceDetailComponent } from './components/experiment-work
import { PluginFilterNodeComponent } from './components-small/plugin-filter-node/plugin-filter-node.component';
import { PluginFilterEditorComponent } from './components-small/plugin-filter-editor/plugin-filter-editor.component';
import { TabGroupListComponent } from './components/tab-group-list/tab-group-list.component';
import { ChooseTemplateComponent } from './dialogs/choose-template/choose-template.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -131,6 +132,7 @@ import { TabGroupListComponent } from './components/tab-group-list/tab-group-lis
PluginFilterNodeComponent,
PluginFilterEditorComponent,
TabGroupListComponent,
ChooseTemplateComponent,
],
imports: [
BrowserModule,
Expand Down
38 changes: 18 additions & 20 deletions src/app/components/experiment/experiment.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,24 @@ <h1 class="t-page-headline">Experiment</h1>
<mat-icon>cancel</mat-icon>
</button>
</mat-card-title>
<mat-card-content>
<mat-form-field>
<mat-label>Default Template</mat-label>
<mat-select (selectionChange)="changeDefaultTemplate($event.value)" [value]="uiTemplateId">
<mat-paginator [pageSize]="itemCount" [length]="uiTemplateCollectionSize" [pageIndex]="uiTemplatePageIndex"
(page)="getTemplatePage($event.pageIndex)" aria-label="Select page">
</mat-paginator>
<mat-divider></mat-divider>
<mat-option [value]="null">
-- none --
</mat-option>
<mat-option *ngIf="uiTemplateId && !uiTemplates.has(uiTemplateId)" [value]="uiTemplateId">
{{uiTemplateName}}
</mat-option>
<mat-divider></mat-divider>
<mat-option *ngFor="let template of uiTemplates | keyvalue:originalOrder" [value]="template.key">
{{template.value}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-card-content class="experiment-settings">
<div class="default-template-selection t-subheading">
<span>
Default Template:
</span>
<a [routerLink]="['/experiments', experimentId, 'workspace']" [queryParams]="{ template: uiTemplate?.self?.resourceKey?.uiTemplateId ?? 'all-plugins' }">
{{uiTemplate?.name ?? 'All Plugins'}}
</a>
<!-- <mat-form-field>
<mat-label>Default Template</mat-label>
</mat-form-field> -->
<button mat-icon-button (click)="showSelectDefaultTemplateDialog()">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="updateExperimentDefaultTemplate(null)">
<mat-icon>cancel</mat-icon>
</button>
</div>
<qhana-markdown class="description" [markdown]="experimentDescription"
(markdownChanges)="updateDescription($event)" [editable]="true">
</qhana-markdown>
Expand Down
12 changes: 12 additions & 0 deletions src/app/components/experiment/experiment.component.sass
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,15 @@
display: inline-flex
align-items: center
gap: 0.5em

.experiment-settings
display: flex
flex-direction: column
gap: 1rem

.default-template-selection
display: flex
flex-direction: row
justify-content: flex-start
align-items: center
gap: 1rem
68 changes: 21 additions & 47 deletions src/app/components/experiment/experiment.component.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { KeyValue } from '@angular/common';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { BehaviorSubject, Subscription } from 'rxjs';
import { debounceTime, filter, map } from 'rxjs/operators';
import { ExportExperimentDialog } from 'src/app/dialogs/export-experiment/export-experiment.component';
import { PageApiObject } from 'src/app/services/api-data-types';
import { ChooseTemplateComponent } from 'src/app/dialogs/choose-template/choose-template.component';
import { CurrentExperimentService } from 'src/app/services/current-experiment.service';
import { ExperimentApiObject, QhanaBackendService } from 'src/app/services/qhana-backend.service';
import { PluginRegistryBaseService } from 'src/app/services/registry.service';
import { TemplatesService } from 'src/app/services/templates.service';
import { TemplateApiObject, TemplatesService } from 'src/app/services/templates.service';

@Component({
selector: 'qhana-experiment',
Expand Down Expand Up @@ -38,15 +36,9 @@ export class ExperimentComponent implements OnInit, OnDestroy {
experimentDescription: string = ""; // only updated on initial experiment load
currentExperimentDescription: string = "";

readonly itemCount: number = 10;
uiTemplatePageIndex: number = 0;
uiTemplate: TemplateApiObject | null = null;

uiTemplates: Map<string, string> = new Map<string, string>();
uiTemplateId: string | null = null;
uiTemplateName: string | null = null;
uiTemplateCollectionSize: number = 0;

constructor(private route: ActivatedRoute, private router: Router, private experimentService: CurrentExperimentService, private backend: QhanaBackendService, private registry: PluginRegistryBaseService, private templates: TemplatesService, public dialog: MatDialog) { }
constructor(private route: ActivatedRoute, private router: Router, private experimentService: CurrentExperimentService, private backend: QhanaBackendService, private templates: TemplatesService, public dialog: MatDialog) { }

ngOnInit(): void {
this.routeSubscription = this.route.params.pipe(map(params => params.experimentId)).subscribe(experimentId => {
Expand All @@ -60,16 +52,14 @@ export class ExperimentComponent implements OnInit, OnDestroy {
this.lastSavedDescription = experiment?.description ?? "";
this.experimentDescription = experiment?.description ?? "";
this.currentExperimentDescription = experiment?.description ?? "";
this.uiTemplateId = experiment?.templateId?.toString() ?? null;
});
this.uiTemplateIdSubscription = this.experimentService.experimentTemplateId.subscribe(templateId => {
this.uiTemplateId = templateId?.toString() ?? null;
this.getTemplatePage();
if (this.uiTemplateId == null) {
if (templateId == null) {
this.uiTemplate = null;
return;
}
this.templates.getTemplate(this.uiTemplateId).then(template => {
this.uiTemplateName = template?.data.name ?? null;
this.templates.getTemplate(templateId.toString()).then(templateResponse => {
this.uiTemplate = templateResponse?.data ?? null;
});
});
this.autoSaveTitleSubscription = this.titleUpdates.pipe(
Expand Down Expand Up @@ -180,39 +170,23 @@ export class ExperimentComponent implements OnInit, OnDestroy {
});
}

async changeDefaultTemplate(templateId: string | null) {
showSelectDefaultTemplateDialog() {
const dialogRef = this.dialog.open(ChooseTemplateComponent, {
minWidth: "20rem", maxWidth: "40rem", width: "60%",
});
dialogRef.afterClosed().subscribe(templateId => {
if (templateId != null) {
this.updateExperimentDefaultTemplate(templateId);
}
});
}

async updateExperimentDefaultTemplate(templateId: string | null) {
if (this.experimentId == null) {
this.uiTemplatePageIndex = 0;
this.uiTemplateId = null;
this.uiTemplateName = null;
console.warn("Experiment ID is null!");
return;
}
this.uiTemplateName = this.uiTemplates.get(templateId ?? "") ?? null;
await this.templates.setExperimentDefaultTemplate(this.experimentId, templateId);
this.experimentService.reloadExperiment();
}

async getTemplatePage(pageIndex: number = 0) {
const uiTemplates = new Map<string, string>();
const params = new URLSearchParams();
params.set("sort", "name");
params.set("item-count", this.itemCount.toString());
params.set("cursor", (pageIndex + 1).toString());
await this.registry.getByRel<PageApiObject>([["ui-template", "collection"]], params).then(result => {
this.uiTemplateCollectionSize = result?.data.collectionSize ?? 0;
result?.data.items.forEach(item => {
const templateId = item.resourceKey?.uiTemplateId;
const name = item.name;
if (templateId != null && name != null) {
uiTemplates.set(templateId, name);
}
});
});
this.uiTemplates = uiTemplates;
this.uiTemplatePageIndex = pageIndex;
}

originalOrder = (a: KeyValue<string, string>, b: KeyValue<string, string>): number => {
return 0;
}
}
15 changes: 15 additions & 0 deletions src/app/dialogs/choose-template/choose-template.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<h1 mat-dialog-title>Choose Template</h1>
<div mat-dialog-content>
<div>
<qhana-growing-list [rels]="['ui-template', 'collection']" [newItemRels]="['ui-template']"
[highlighted]="highlightedTemplateSet" [highlightByKey]="'uiTemplateId'" (clickItem)="selectTemplate($event)">
</qhana-growing-list>
</div>
</div>
<div class="dialog-actions" mat-dialog-actions>
<button mat-button (click)="onCancel()">Cancel</button>
<button mat-button [mat-dialog-close]="templateId"
[disabled]="templateId == null">
Choose
</button>
</div>
Empty file.
23 changes: 23 additions & 0 deletions src/app/dialogs/choose-template/choose-template.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ChooseTemplateComponent } from './choose-template.component';

describe('ChooseTemplateDialog', () => {
let component: ChooseTemplateComponent;
let fixture: ComponentFixture<ChooseTemplateComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChooseTemplateComponent ]
})
.compileComponents();

fixture = TestBed.createComponent(ChooseTemplateComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
40 changes: 40 additions & 0 deletions src/app/dialogs/choose-template/choose-template.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Component, OnInit } from '@angular/core';
import { TemplateApiObject } from 'src/app/services/qhana-backend.service';
import { MatDialogRef } from '@angular/material/dialog';
import { ApiLink } from 'src/app/services/api-data-types';
import { PluginRegistryBaseService } from 'src/app/services/registry.service';

@Component({
selector: 'qhana-choose-template',
templateUrl: './choose-template.component.html',
styleUrls: ['./choose-template.component.sass']
})
export class ChooseTemplateComponent implements OnInit {
highlightedTemplateSet: Set<string> = new Set();
templateId: string | null = null;

constructor(public dialogRef: MatDialogRef<ChooseTemplateComponent>) { }

ngOnInit(): void {
}

async selectTemplate(templateLink: ApiLink) {
const templateId = templateLink.resourceKey?.uiTemplateId ?? null;
if (templateId == null) {
return;
}
if (this.highlightedTemplateSet.has(templateId)) {
// double click deselects template
this.highlightedTemplateSet.clear();
this.templateId = null;
return;
}
this.highlightedTemplateSet.clear();
this.highlightedTemplateSet = new Set([templateId]);
this.templateId = templateId;
}

onCancel(): void {
this.dialogRef.close();
}
}

0 comments on commit 8349b5f

Please sign in to comment.