File

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

Description

This component is an example for the manage members view All users are displayed in a paginated list. The list can be filtered. The members are hardcoded If the backend offers an interface to get all users the mockUsers list schould be replaced

Implements

OnInit

Metadata

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

Index

Properties
Methods

Constructor

constructor(dialog: MatDialog, projectStore: ProjectStoreService, route: ActivatedRoute)
Parameters :
Name Type Optional
dialog MatDialog No
projectStore ProjectStoreService No
route ActivatedRoute No

Methods

applyFilter
applyFilter(filterValue: string)

On every key pressed in the filter-field this method is triggered and reduces the shown users in the list (table)

Parameters :
Name Type Optional
filterValue string No
Returns : void
onAddClick
onAddClick()

This method adds a user to the project members list without processing a task in the back-end

Returns : void
onDeleteClick
onDeleteClick()

This method deletes a user to the project members list without processing a task in the back-end

Returns : void

Properties

addableUsers
Type : Array<userMock>
Default value : [ {id: '7', displayName: 'AddedUser1', email: 'AddedUser1.de'}, {id: '8', displayName: 'AddedUser2', email: 'AddedUser2.de'}, {id: '9', displayName: 'AddedUser3', email: 'AddedUser3.de'} ]
columnsToDisplay
Type : []
Default value : ['Name', 'Role', 'email']
dataSource
Type : MatTableDataSource<any>
mockUsers
Type : Array<userMock>
Default value : [ {id: '1', displayName: 'User1', email: 'User1.de'}, {id: '2', displayName: 'User2', email: 'User2.de'}, {id: '3', displayName: 'User3', email: 'User3.de'}, {id: '4', displayName: 'User4', email: 'User4.de'}, {id: '5', displayName: 'User5', email: 'User5.de'}, {id: '6', displayName: 'User6', email: 'User6.de'} ]
paginator
Type : MatPaginator
Decorators :
@ViewChild(MatPaginator)
paginatorModule
Type : MatPaginatorModule
Decorators :
@ViewChild(MatPaginatorModule)
Public project
Type : GetFullProjectQuery
Public project$
Type : Observable<GetFullProjectQuery>
Public projectId
Type : string
sort
Type : MatSort
Decorators :
@ViewChild(MatSort)
validationFilter
Default value : new FormControl('')
import {Component, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {ProjectStoreService} from '@app/data/project/project-store.service';
import {GetFullProjectQuery} from 'src/generated/graphql';
import {Observable} from 'rxjs';
import {FormControl} from '@angular/forms';
import {MatTableDataSource} from '@angular/material/table';
import {MatSort, MatSortable} from '@angular/material/sort';
import {MatPaginator, MatPaginatorModule} from '@angular/material/paginator';
import {AddProjectMemberDialogComponent} from '@app/dialogs/add-project-member-dialog/add-project-member-dialog.component';
import {MatDialog} from '@angular/material/dialog';
import {RemoveProjectMemberComponentComponent} from '@app/dialogs/remove-project-member-component/remove-project-member-component.component';

/**
 * This component is an example for the manage members view
 * All users are displayed in a paginated list. The list can be filtered.
 * The members are hardcoded
 * If the backend offers an interface to get all users the mockUsers list schould be replaced
 */
@Component({
  selector: 'app-project-members',
  templateUrl: './project-members.component.html',
  styleUrls: ['./project-members.component.scss']
})
export class ProjectMembersComponent implements OnInit {
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatPaginatorModule) paginatorModule: MatPaginatorModule;
  @ViewChild(MatSort) sort: MatSort;
  public projectId: string;
  public project$: Observable<GetFullProjectQuery>;
  public project: GetFullProjectQuery;
  validationFilter = new FormControl('');

  columnsToDisplay = ['Name', 'Role', 'email'];
  dataSource: MatTableDataSource<any>;

  //users
  mockUsers: Array<userMock> = [
    {id: '1', displayName: 'User1', email: 'User1.de'},
    {id: '2', displayName: 'User2', email: 'User2.de'},
    {id: '3', displayName: 'User3', email: 'User3.de'},
    {id: '4', displayName: 'User4', email: 'User4.de'},
    {id: '5', displayName: 'User5', email: 'User5.de'},
    {id: '6', displayName: 'User6', email: 'User6.de'}
  ];

  // list of users who can be added to the project
  //hardcoded
  addableUsers: Array<userMock> = [
    {id: '7', displayName: 'AddedUser1', email: 'AddedUser1.de'},
    {id: '8', displayName: 'AddedUser2', email: 'AddedUser2.de'},
    {id: '9', displayName: 'AddedUser3', email: 'AddedUser3.de'}
  ];

  constructor(private dialog: MatDialog, private projectStore: ProjectStoreService, private route: ActivatedRoute) {}

  ngOnInit(): void {
    this.projectId = this.route.snapshot.paramMap.get('id');
    this.project$ = this.projectStore.getFullProject(this.projectId);
    this.project$.subscribe((project) => {
      this.project = project;
      // MOCK DATA for table
      // FIXME Api change
      // project.node.users.nodes.forEach(u => this.mockUsers.push(u));
      this.dataSource = new MatTableDataSource<any>(this.mockUsers);

      // sort data in table
      this.sort.sort({id: 'Name', start: 'asc'} as MatSortable);
      this.dataSource.sort = this.sort;

      //paginator
      this.dataSource.paginator = this.paginator;
    });
  }

  /**
   * This method adds a user to the project members list without processing a task in the back-end
   */
  onAddClick(): void {
    const addMemberDialogRef = this.dialog.open(AddProjectMemberDialogComponent, {
      data: {addableMembers: this.addableUsers, projectId: this.projectId}
    });
    addMemberDialogRef.afterClosed().subscribe((data) => {
      if (data) {
        for (const user of data.usersToAdd) {
          this.addableUsers.forEach((addableUser) => {
            if (addableUser.id == user) {
              this.mockUsers.push(addableUser);
            }
          });
        }
        this.dataSource = new MatTableDataSource<any>(this.mockUsers);
      }
    });
  }

  /**
   * This method deletes a user to the project members list without processing a task in the back-end
   */
  onDeleteClick(): void {
    const deleteMemberDialogRef = this.dialog.open(RemoveProjectMemberComponentComponent, {
      data: {mockMembers: this.mockUsers, projectId: this.projectId}
    });
    deleteMemberDialogRef.afterClosed().subscribe((data) => {
      if (data) {
        for (const user of data.usersToDelete) {
          for (let i = 0; i < this.mockUsers.length; i++) {
            if (this.mockUsers[i].id === user) {
              this.mockUsers.splice(i, 1);
            }
          }
        }
        this.dataSource = new MatTableDataSource<any>(this.mockUsers);
      }
    });
  }

  /**
   * On every key pressed in the filter-field this method is triggered and reduces the shown users in the list (table)
   */
  applyFilter(filterValue: string): void {
    filterValue = filterValue.trim(); // Remove whitespace
    filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
    this.dataSource.filter = filterValue;
  }
}

// defines the structure of a user
export interface userMock {
  id: string;
  displayName?: string;
  username?: string;
  email?: string;
}
<div style="display: flex; flex-direction: column" class="margin-left-top p-3">
  <div *ngIf="!!project">
    <app-project-header [projectId]="projectId" [projectName]="project.node.name"></app-project-header>
  </div>

  <div>
    <div matSort matSortActive="Name">
      <button class="button-add" mat-fab color="primary" (click)="this.onAddClick()">
        <mat-icon>add</mat-icon>
      </button>

      <button class="button-remove" mat-fab color="warn" (click)="this.onDeleteClick()">
        <mat-icon>remove</mat-icon>
      </button>

      <div class="component-title">
        <mat-form-field appearance="outline">
          <mat-label>Filter</mat-label>
          <input [formControl]="this.validationFilter" matInput (keyup)="applyFilter($event.target.value)" />
        </mat-form-field>
      </div>

      <div class="table-container mat-elevation-z8">
        <!-- Table of Members -->
        <table *ngIf="(project$ | async)?.node as project" mat-table style="width: 100%; min-width: 50%" [dataSource]="this.dataSource">
          <!-- Name Column -->
          <ng-container matColumnDef="Name">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
            <td mat-cell style="text-align: left" *matCellDef="let element">{{ element.displayName }}</td>
          </ng-container>

          <!-- Role Column -->
          <ng-container matColumnDef="Role">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Role</th>
            <td mat-cell style="text-align: left" *matCellDef="let element">Administrator</td>
          </ng-container>

          <!-- Mail Column -->
          <ng-container matColumnDef="email">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Email</th>
            <td mat-cell style="text-align: left" *matCellDef="let element">{{ element.email }}</td>
          </ng-container>

          <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
          <tr mat-row *matRowDef="let rowData; columns: columnsToDisplay"></tr>
        </table>
      </div>

      <!-- TODO fix paginator -->
      <mat-paginator [length]="mockUsers.length" [pageSize]="3" [pageSizeOptions]="[3, 5, 10]"> </mat-paginator>
    </div>

    <!-- Table of Members New -->
  </div>
</div>

./project-members.component.scss

.project-title-row {
  width: 100%;
  margin-bottom: 12px;
  align-items: center;
  height: 85px;
}
.box {
  float: left;
  //display: inline-block;
  vertical-align: top;
  width: 85px;
  height: auto;
  margin-right: 5px;
}
.content {
  //display: inline-block;
  float: left;
}
.title,
.sub-title {
  margin: 0;
  padding: 3px 10px 3px 0;
}
.title {
  font-size: 17px;
  font-weight: bold;
}
.sub-title {
  font-weight: bold;
  color: #3f3f3f;
}

img {
  width: 100%;
}

.pagefill {
  width: 100%;
  height: 300px;
}
.margin-left-top {
  margin-top: 3px;
  margin-left: 3px;
}
.text-left {
  text-align: left;
}
.mat-row:hover {
  box-shadow: inset 0 0 43px -17px rgba(201, 195, 201, 1);
  cursor: pointer;
}
.button-add {
  margin: 10px 5px 10px 10px;
  float: left;
}

.button-remove {
  margin: 10px 15px 10px 5px;
  float: left;
}

.table-container {
  max-height: 500px;
  overflow: auto;
}
.center-horizontal {
  width: 100%;
  text-align: center;
  margin-top: 15px;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""