Skip to content

Commit

Permalink
Add edit and delete functions for template details in templates page
Browse files Browse the repository at this point in the history
  • Loading branch information
buehlefs committed Aug 7, 2024
1 parent eccfd86 commit 85746b1
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import { CreateExperimentDialog } from './dialogs/create-experiment/create-exper
import { DeleteDialog } from './dialogs/delete-dialog/delete-dialog.dialog';
import { ExportExperimentDialog } from './dialogs/export-experiment/export-experiment.dialog';
import { MarkdownHelpDialog } from './dialogs/markdown-help/markdown-help.dialog';
import { UiTemplateComponent } from "./components-small/ui-template/ui-template.component";

@NgModule({
declarations: [
Expand Down Expand Up @@ -134,6 +135,7 @@ import { MarkdownHelpDialog } from './dialogs/markdown-help/markdown-help.dialog
TabGroupListComponent,
ChooseTemplateDialog,
UiTemplatesPageComponent,
UiTemplateComponent,
],
imports: [
BrowserModule,
Expand Down
42 changes: 42 additions & 0 deletions src/app/components-small/ui-template/ui-template.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<mat-card appearance="outlined" class="card" *ngIf="templateData != null">
<mat-card-title class="t-headline header">
<div [hidden]="isEditing">
UI Template: {{templateData.name}}
</div>
<mat-form-field class="name-field" [hidden]="!isEditing">
<mat-label>UI Template Name:</mat-label>
<input matInput [(ngModel)]="currentName">
</mat-form-field>
<div class="header-buttons">
<button mat-stroked-button (click)="updateTemplate()" *ngIf="isDirty"><mat-icon>save</mat-icon>save</button>
<button mat-icon-button (click)="toggleEdit()" *ngIf="templateUpdateLink != null"><mat-icon>{{isEditing ? 'edit_off' : 'edit'}}</mat-icon></button>
<button mat-icon-button (click)="deleteTemplate()" color="warn" *ngIf="templateDeleteLink != null"><mat-icon>delete</mat-icon></button>
</div>
</mat-card-title>
<mat-card-content class="content">
<mat-chip-set class="tags" [hidden]="isEditing">
<mat-chip *ngFor="let tag of templateData.tags">{{tag}}</mat-chip>
</mat-chip-set>
<mat-form-field class="tags-field" *ngIf="isEditing">
<mat-label>Tags</mat-label>
<mat-chip-grid #chipGrid>
@for (tag of currentTags; track tag) {
<mat-chip-row
(removed)="removeTag(tag)"
>
{{tag}}
<button matChipRemove [attr.aria-label]="'remove ' + tag">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
}
<input
placeholder="New Tag"
[matChipInputFor]="chipGrid"
(matChipInputTokenEnd)="addTag($event)"
/>
</mat-chip-grid>
</mat-form-field>
<qhana-markdown [editable]="isEditing" [markdown]="templateData.description" (markdownChanges)="currentDescription = $event"></qhana-markdown>
</mat-card-content>
</mat-card>
23 changes: 23 additions & 0 deletions src/app/components-small/ui-template/ui-template.component.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.header
display: flex
align-items: center
justify-content: space-between
gap: 1rem

.header-buttons
display: flex
align-items: center
gap: 0.5rem

.content, .content:last-child
padding: 0
margin-block-start: 0.5rem

.name-field
flex-grow: 1

.tags
margin-block-end: 0.5rem

.tags-field
width: 100%
144 changes: 144 additions & 0 deletions src/app/components-small/ui-template/ui-template.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ApiLink, ChangedApiObject } from 'src/app/services/api-data-types';
import { TemplateApiObject } from 'src/app/services/templates.service';
import { PluginRegistryBaseService } from 'src/app/services/registry.service';
import { MatChipInputEvent } from '@angular/material/chips';
import { Subscription } from 'rxjs';
import { MatDialog } from '@angular/material/dialog';
import { DeleteDialog } from 'src/app/dialogs/delete-dialog/delete-dialog.dialog';

@Component({
selector: 'qhana-ui-template',
templateUrl: './ui-template.component.html',
styleUrl: './ui-template.component.sass'
})
export class UiTemplateComponent implements OnChanges, OnInit, OnDestroy {

@Input() templateLink: ApiLink | null = null;


templateData: TemplateApiObject | null = null;
templateUpdateLink: ApiLink | null = null;
templateDeleteLink: ApiLink | null = null;

isEditing: boolean = false;

currentName: string | null = null;
currentTags: string[] | null = null;
currentDescription: string | null = null;

private tagsDirty: boolean = false;
private updateSubscription: Subscription | null = null;

constructor(private registry: PluginRegistryBaseService, private dialog: MatDialog) { }

ngOnInit(): void {
this.updateSubscription = this.registry.apiObjectSubject.subscribe((apiObject) => {
if (apiObject.self.href !== this.templateLink?.href) {
return;
}
if (apiObject.self.resourceType === "ui-template") {
this.templateData = apiObject as TemplateApiObject;
if (this.isEditing) {
this.currentTags = [...(apiObject as TemplateApiObject).tags];
this.tagsDirty = false;
}
}
});
}

ngOnDestroy(): void {
this.updateSubscription?.unsubscribe();
}

ngOnChanges(changes: SimpleChanges): void {
this.loadTemplate();
}

private async loadTemplate() {
if (this.templateLink == null) {
this.templateData = null;
return;
}
const templateResponse = await this.registry.getByApiLink<TemplateApiObject>(this.templateLink);
this.templateData = templateResponse?.data ?? null;

this.templateUpdateLink = templateResponse?.links?.find(link => link.rel.some(rel => rel === "update") && link.resourceType == "ui-template") ?? null;
this.templateDeleteLink = templateResponse?.links?.find(link => link.rel.some(rel => rel === "delete") && link.resourceType == "ui-template") ?? null;
}

get isDirty() {
if (!this.isEditing) {
return false;
}
if (this.currentName !== this.templateData?.name) {
return true;
}
if (this.currentDescription !== this.templateData?.description) {
return true;
}
if (this.tagsDirty) {
return true;
}
return false;
}

toggleEdit() {
if (this.templateData == null || this.templateUpdateLink == null) {
this.isEditing = false;
} else {
this.isEditing = !this.isEditing;
}
if (this.isEditing) {
this.currentName = this.templateData?.name ?? null;
this.currentTags = [...(this.templateData?.tags ?? [])];
this.currentDescription = this.templateData?.description ?? null;
this.tagsDirty = false;
} else {
this.currentName = null;
this.currentTags = null;
this.currentDescription = null;
this.tagsDirty = false;
}
}

removeTag(tag: string) {
this.currentTags = this.currentTags?.filter(t => t !== tag) ?? null;
this.tagsDirty = true;
}

addTag(event: MatChipInputEvent) {
const tag = event.value;
this.currentTags?.push(tag);
this.tagsDirty = true;
}

async updateTemplate() {
if (!this.isDirty || this.templateUpdateLink == null) {
return;
}

this.registry.submitByApiLink(this.templateUpdateLink, {
name: this.currentName,
description: this.currentDescription,
tags: this.currentTags,
});
}

async deleteTemplate() {
if (this.templateDeleteLink == null) {
return;
}

const dialogRef = this.dialog.open(DeleteDialog, {
data: this.templateLink,
});

const doDelete = await dialogRef.afterClosed().toPromise();
if (doDelete) {
this.registry.submitByApiLink(this.templateDeleteLink);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ <h2 class="sidebar-header">Templates:</h2>
<div class="content-container">
<div class="main-content">
<!--qhana-experiment-workspace-detail></qhana-experiment-workspace-detail-->
<qhana-ui-template [templateLink]="selectedTemplate"></qhana-ui-template>
<div class="scroll-spacer"></div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
.content-container .main-content
max-width: 60rem
margin-inline: auto
padding-block-start: 2rem

.title
display: flex
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export class UiTemplatesPageComponent implements OnInit, OnDestroy {
highlightedTemplates: Set<string> = new Set();

templateId: string | null = null;

private routeParamSubscription: Subscription | null = null;
private templateCreatedSubscription: Subscription | null = null;
private templateDeletedSubscription: Subscription | null = null;


constructor(private route: ActivatedRoute, private router: Router, private registry: PluginRegistryBaseService, private templates: TemplatesService, private dialog: MatDialog) { }
Expand All @@ -32,18 +35,37 @@ export class UiTemplatesPageComponent implements OnInit, OnDestroy {
} else {
this.highlightedTemplates.clear();
}
console.log(this.highlightedTemplates, templateId)
this.templateId = templateId;
this.loadActiveTemplateFromId(templateId);
});

this.templateCreatedSubscription = this.registry.newApiObjectSubject.subscribe(created => {
if (created.new.resourceType === "ui-template") {
// new template created
if (this.templateId == null) {
this.selectTemplate(created.new);
}
}
});

this.templateDeletedSubscription = this.registry.deletedApiObjectSubject.subscribe(deleted => {
if (this.templateId == null) {
return;
}
if (deleted.deleted.resourceType === "ui-template" && deleted.deleted.resourceKey?.uiTemplateId === this.templateId) {
// current template was deleted, navigate to overview
this.selectTemplate(null);
}
});
}

ngOnDestroy(): void {
this.routeParamSubscription?.unsubscribe();
this.templateDeletedSubscription?.unsubscribe();
this.templateCreatedSubscription?.unsubscribe();
}

selectTemplate(templateLink: ApiLink | null) {
console.log(templateLink)
if (templateLink == null) {
this.router.navigate(["/templates"]);
return;
Expand Down Expand Up @@ -72,6 +94,7 @@ export class UiTemplatesPageComponent implements OnInit, OnDestroy {
this.selectedTemplate = templatePage.data.items[0];
} else {
console.warn(`Template API returned an ambiguous response for template id ${newTemplateId}`, templatePage);
this.selectTemplate(null);
}
}

Expand Down

0 comments on commit 85746b1

Please sign in to comment.