File

src/app/project-list-component/project-list.component.ts

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

OnInit

Metadata

selector app-project-list
styleUrls ./project-list.component.scss
templateUrl ./project-list.component.html

Index

Properties
Methods

Constructor

constructor(projectStore: ProjectStoreService, dialog: MatDialog, notify: UserNotifyService)
Parameters :
Name Type Optional
projectStore ProjectStoreService No
dialog MatDialog No
notify UserNotifyService No

Methods

Private changeColour
changeColour()
Returns : void
Public nothing
nothing(e: Event)
Parameters :
Name Type Optional
e Event No
Returns : void
Public openCreateProjectDialog
openCreateProjectDialog()
Returns : void
Public reloadProjects
reloadProjects()
Returns : void

Properties

lastQueriedProjectName
Type : string
loading
Type : boolean
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>

./project-list.component.scss

@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
Component
Html element with directive

results matching ""

    No results matching ""