File
Description
This component is the landing page for the user after loggin in to the system
It shows a list of all projects the user can access
Implements
Metadata
selector |
app-project-list |
styleUrls |
./project-list.component.scss |
templateUrl |
./project-list.component.html |
Methods
Private
changeColour
|
changeColour()
|
|
|
Public
nothing
|
nothing(e: Event)
|
|
Parameters :
Name |
Type |
Optional |
e |
Event
|
No
|
|
Public
openCreateProjectDialog
|
openCreateProjectDialog()
|
|
|
Public
reloadProjects
|
reloadProjects()
|
|
|
lastQueriedProjectName
|
Type : string
|
|
pendingCreate
|
Default value : false
|
|
projectName
|
Type : string
|
Default value : ''
|
|
projects
|
Type : Pick<Project, "id" | "name">[]
|
Default value : []
|
|
import {Component, OnInit} from '@angular/core';
import {MatDialog} from '@angular/material/dialog';
import {CreateProjectDialogComponent} from 'src/app/dialogs/create-project-dialog/create-project-dialog.component';
import {Project} from 'src/generated/graphql';
import {ProjectStoreService} from '../data/project/project-store.service';
import {UserNotifyService} from '@app/user-notify/user-notify.service';
/**
* This component is the landing page for the user after loggin in to the system
* It shows a list of all projects the user can access
*/
@Component({
selector: 'app-project-list',
templateUrl: './project-list.component.html',
styleUrls: ['./project-list.component.scss']
})
export class ProjectListComponent implements OnInit {
pendingCreate = false;
projectName = '';
lastQueriedProjectName: string;
projects: Pick<Project, 'id' | 'name'>[] = [];
loading: boolean;
constructor(private projectStore: ProjectStoreService, private dialog: MatDialog, private notify: UserNotifyService) {}
ngOnInit(): void {
// get all projects from the database
this.reloadProjects();
}
public reloadProjects(): void {
if (this.lastQueriedProjectName === this.projectName && this.lastQueriedProjectName) {
return;
}
this.loading = true;
this.projectStore.getAll(this.projectName).subscribe(
(projects) => {
this.loading = false;
this.projects = projects;
this.lastQueriedProjectName = this.projectName;
},
(error) => {
this.loading = false;
this.notify.notifyError('Failed to load projects', error);
}
);
}
public openCreateProjectDialog(): void {
const createProjectDialogRef = this.dialog.open(CreateProjectDialogComponent);
createProjectDialogRef.afterClosed().subscribe((result) => {
this.changeColour();
if (result?.createdProjectId) {
this.projectName = '';
this.reloadProjects();
}
});
}
// remove the focus from the create project button after the project is created
private changeColour(): void {
const b = document.querySelector('#buttonCreateProject') as HTMLElement;
b.blur();
}
// if the shortcut icon to the graph view of a project is clicked the list view fires a event that a row was clicked
// and the user jumps to the project overview. This method prevents the default event and enable the shortcut button
// to perform its action
public nothing(e: Event): void {
e.preventDefault();
e.stopPropagation();
}
}
<div class="mat-toolbar-single-row">
<h1 class="centered-headline">My Projects</h1>
</div>
<div class="list-header">
<h2 class="list-h2">Project-List</h2>
<button mat-raised-button color="accent" id="buttonCreateProject" (click)="openCreateProjectDialog()" class="floating-button">
Create Project
</button>
<!-- <button mat-raised-button color="primary" (click)="this.createDemoProject()"-->
<!-- class="floating-button">Create Demo Project-->
<!-- </button>-->
</div>
<!-- list wrapper including search input field and list of projects -->
<div class="listWrapper">
<nz-input-group nzSearch [nzAddOnAfter]="suffixIconButton">
<input type="text" [(ngModel)]="projectName" nz-input placeholder="Search projects..." (keydown.enter)="reloadProjects()" />
</nz-input-group>
<!-- search button -->
<ng-template #suffixIconButton>
<button
nz-button
nzType="primary"
[nzLoading]="pendingCreate"
nzSearch
(click)="reloadProjects()"
[disabled]="projectName === lastQueriedProjectName"
>
<i nz-icon nzType="search"></i>
</button>
</ng-template>
<nz-alert *ngIf="!loading && projects.length == 0" nzMessage="No projects found!" nzType="info"></nz-alert>
<!-- list of projects -->
<mat-nav-list class="mat-nav-list-padding-removed">
<a *ngFor="let project of projects" mat-list-item [routerLink]="['/projects', project.id]">
<!-- name of project -->
<span matLine>{{ project.name }}</span>
<a
[routerLink]="['/projects', project.id, 'graph']"
mat-icon-button
(click)="this.nothing($event)"
title="Open project in graph view"
>
<mat-icon class="graph-icon">account_tree</mat-icon>
</a>
<mat-divider></mat-divider>
</a>
</mat-nav-list>
</div>
@import "~@angular/material/theming";
@import "variables";
@import "src/styles/spinner";
span[matLine] {
padding-left: 16px;
}
.nz-input-group {
max-width: 100%;
}
.nz-input-group {
max-width: 100%;
}
.listWrapper {
max-width: 50%;
//background-color: black;
-webkit-box-shadow: 2px 3px 18px -6px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 2px 3px 18px -6px rgba(0, 0, 0, 0.75);
box-shadow: 2px 3px 18px -6px rgba(0, 0, 0, 0.75);
margin-top: 15px;
margin-left: auto;
margin-right: auto;
}
.centered-headline {
margin: auto;
}
.mat-nav-list-padding-removed {
padding-top: 0;
}
.floating-button {
float: right;
}
.list-header {
max-width: 50%;
margin-left: auto;
margin-right: auto;
height: 36px;
margin-bottom: 5px;
}
.list-h2 {
max-width: 50%;
float: left;
margin-bottom: 0;
}
.graph-icon {
color: $icon-gray;
}
#buttonDeleteProject {
margin: 5px;
}
#buttonCreateProject {
margin: 5px;
}
Legend
Html element with directive