Merge branch 'max_dev' of Software_Engineering_I/greenvironment-frontend into master

master
Max_ES 5 years ago committed by Gitea
commit d0483dcb1c

@ -22,8 +22,9 @@
</div>
</div>
<mat-form-field class="input">
<textarea matInput #content type="text" (input)="onTextInputChange()" [(ngModel)]="textInputValue" [disabled]="posting"
<textarea matInput #content type="text" maxlength="2048" (input)="onTextInputChange()" [(ngModel)]="textInputValue" [disabled]="posting"
mat-autosize="true" matAutosizeMaxRows="3" placeholder="post something"></textarea>
<mat-hint align="end">{{content.value.length}} / 2048</mat-hint>
</mat-form-field>
<input style="display: none" id="fileInput" type="file" accept="video/*,image/*" (change)="onFileInputChange($event)" #fileInput>
<div class="input">

@ -4,39 +4,29 @@
<mat-toolbar id="toolbar" fxShow="true" fxHide.gt-sm="true">
<mat-toolbar-row>
<div class="hover-box" matTooltip="upload new picture" *ngIf="isAdmin" (click)="openFileUploadDialog()">
<img class="profile-picture" [src]="groupProfile.picture"/>
<img class="profile-picture" [src]="groupProfile.picture" />
<mat-icon id="icon">camera_alt</mat-icon>
</div>
<div *ngIf="!isAdmin" (click)="openPfpLightbox()">
<img class="profile-picture" [src]="groupProfile.picture"/>
<img class="profile-picture" [src]="groupProfile.picture" />
</div>
<span id="username">{{groupProfile.name}}</span>
<div class="button-box">
<button mat-icon-button *ngIf="!groupProfile.joined"
class="request-button"
matTooltip="join group" matTooltipShowDelay="500"
(click)="joinGroup(groupProfile)"
[disabled]="!groupProfile.allowedToJoinGroup">
<button mat-icon-button *ngIf="!groupProfile.joined" class="request-button" matTooltip="join group"
matTooltipShowDelay="500" (click)="joinGroup(groupProfile)" [disabled]="!groupProfile.allowedToJoinGroup">
<mat-icon>group_add</mat-icon>
</button>
<button mat-icon-button *ngIf="groupProfile.joined"
class="request-button"
matTooltip="leave group" matTooltipShowDelay="500"
(click)="leaveGroup(groupProfile)">
<button mat-icon-button *ngIf="groupProfile.joined" class="request-button" matTooltip="leave group"
matTooltipShowDelay="500" (click)="leaveGroup(groupProfile)">
<mat-icon>directions_run</mat-icon>
</button>
<button mat-icon-button
class="request-button"
matTooltip="create event" matTooltipShowDelay="500"
(click)="openDialog()"
[disabled]="!isAdmin">
<button mat-icon-button class="request-button" matTooltip="create event" matTooltipShowDelay="500"
(click)="openDialog()" [disabled]="!isAdmin">
<mat-icon>event</mat-icon>
</button>
<div style="display: contents;" *ngIf="groupProfile.deletable">
<button mat-icon-button
class="request-button"
matTooltip="delete this group" matTooltipShowDelay="0"
<button mat-icon-button class="request-button" matTooltip="delete this group" matTooltipShowDelay="0"
(click)="deleteGroup()">
<mat-icon>delete</mat-icon>
</button>
@ -45,8 +35,8 @@
</mat-toolbar-row>
<mat-toolbar-row>
<div class="info-box">
<span id="handle" class="pointer"
(click)="showUserProfile(groupProfile.creator)">created by {{groupProfile.creator.username}}
<span id="handle" class="pointer" (click)="showUserProfile(groupProfile.creator)">created by
{{groupProfile.creator.username}}
@{{groupProfile.creator.handle}}</span>
</div>
</mat-toolbar-row>
@ -60,41 +50,31 @@
<mat-toolbar id="toolbar" fxShow="true" fxHide.lt-md="true">
<mat-toolbar-row>
<div class="hover-box" matTooltip="upload new picture" *ngIf="isAdmin" (click)="openFileUploadDialog()">
<img class="profile-picture" [src]="groupProfile.picture"/>
<img class="profile-picture" [src]="groupProfile.picture" />
<mat-icon id="icon">camera_alt</mat-icon>
</div>
<div *ngIf="!isAdmin" (click)="openPfpLightbox()">
<img class="profile-picture" [src]="groupProfile.picture"/>
<img class="profile-picture" [src]="groupProfile.picture" />
</div>
<span id="username">{{groupProfile.name}}</span>
<span id="handle" class="pointer"
(click)="showUserProfile(groupProfile.creator)">created by {{groupProfile.creator.username}}
<span id="handle" class="pointer" (click)="showUserProfile(groupProfile.creator)">created by
{{groupProfile.creator.username}}
@{{groupProfile.creator.handle}}</span>
<div class="button-box">
<button mat-icon-button *ngIf="!groupProfile.joined"
class="request-button"
matTooltip="join group" matTooltipShowDelay="500"
(click)="joinGroup(groupProfile)"
[disabled]="!groupProfile.allowedToJoinGroup">
<button mat-icon-button *ngIf="!groupProfile.joined" class="request-button" matTooltip="join group"
matTooltipShowDelay="500" (click)="joinGroup(groupProfile)" [disabled]="!groupProfile.allowedToJoinGroup">
<mat-icon>group_add</mat-icon>
</button>
<button mat-icon-button *ngIf="groupProfile.joined"
class="request-button"
matTooltip="leave group" matTooltipShowDelay="500"
(click)="leaveGroup(groupProfile)">
<button mat-icon-button *ngIf="groupProfile.joined" class="request-button" matTooltip="leave group"
matTooltipShowDelay="500" (click)="leaveGroup(groupProfile)">
<mat-icon>directions_run</mat-icon>
</button>
<button mat-icon-button
class="request-button"
matTooltip="create event" matTooltipShowDelay="500"
(click)="openDialog()"
[disabled]="!isAdmin">
<button mat-icon-button class="request-button" matTooltip="create event" matTooltipShowDelay="500"
(click)="openDialog()" [disabled]="!isAdmin">
<mat-icon>event</mat-icon>
</button>
<div style="display: contents;" *ngIf="groupProfile.deletable">
<button mat-icon-button
class="request-button"
matTooltip="delete this group" matTooltipShowDelay="0"
<button mat-icon-button class="request-button" matTooltip="delete this group" matTooltipShowDelay="0"
(click)="deleteGroup()">
<mat-icon>delete</mat-icon>
</button>
@ -116,24 +96,24 @@
</mat-panel-title>
</mat-expansion-panel-header>
<div class="list">
<mat-card class="card" *ngFor="let event of groupProfile.events"
[class.selected]="event === selectedEvent"
<mat-card class="card" *ngFor="let event of groupProfile.events" [class.selected]="event === selectedEvent"
tabindex="0">
<mat-card-header>
<mat-card-title>{{event.name}}</mat-card-title>
<mat-card-subtitle>{{event.date}}</mat-card-subtitle>
<div class="button-box">
<button *ngIf="!event.joined" mat-icon-button class="request-button"
matTooltip="join event" matTooltipShowDelay="500"
(click)="joinEvent(event)">
<button *ngIf="!event.joined" mat-icon-button class="request-button" matTooltip="join event"
matTooltipShowDelay="500" (click)="joinEvent(event)">
<mat-icon>event_available</mat-icon>
</button>
<button *ngIf="event.joined" mat-icon-button class="request-button"
matTooltip="leave event" matTooltipShowDelay="500"
(click)="leaveEvent(event)"
[disabled]="!event.joined">
<button *ngIf="event.joined" mat-icon-button class="request-button" matTooltip="leave event"
matTooltipShowDelay="500" (click)="leaveEvent(event)" [disabled]="!event.joined">
<mat-icon>event_busy</mat-icon>
</button>
<button *ngIf="event.deletable" mat-icon-button class="request-button" matTooltip="delete event"
matTooltipShowDelay="0" (click)="deleteEvent(event)">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-card-header>
</mat-card>
@ -145,8 +125,32 @@
Members
</mat-panel-title>
</mat-expansion-panel-header>
<div class="list">
<user-list [userList]="groupProfile.members"></user-list>
<div id="list">
<mat-card class="member-card" *ngFor="let user of groupProfile.members"
[class.selected]="user === selectedUser" tabindex="0">
<mat-card-header>
<div mat-card-avatar (click)="showUserProfile(user)">
<img class="card-picture" [src]="user.profilePicture" />
</div>
<mat-card-title class="pointer" (click)="showUserProfile(user)">{{user.username}}</mat-card-title>
<mat-card-subtitle class="pointer" (click)="showUserProfile(user)">{{user.handle}}</mat-card-subtitle>
<mat-card-subtitle *ngIf="user.isGroupAdmin" class="pointer" (click)="showUserProfile(user)">[admin]
</mat-card-subtitle>
<div id="icon-box" *ngIf="isAdmin">
<button mat-icon-button [matMenuTriggerFor]="menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button *ngIf="!user.isGroupAdmin" mat-menu-item (click)="addGroupAdmin(user)">
<span>give admin rights</span>
</button>
<button *ngIf="user.isGroupAdmin" mat-menu-item (click)="removeGroupAdmin(user)">
<span>revoke admin rights</span>
</button>
</mat-menu>
</div>
</mat-card-header>
</mat-card>
</div>
</mat-expansion-panel>
</mat-accordion>
@ -157,4 +161,3 @@
</div>
<mat-spinner *ngIf="loading" style="margin:0 auto; margin-top: 10em;" diameter="100"></mat-spinner>
</div>

@ -107,12 +107,62 @@ $mat-card-header-size: 100px !default
margin-top: 0.5em
margin-bottom: 0.5em
.profile-picture
background-image: url(https://material.angular.io/assets/img/examples/shiba1.jpg)
.profile-picture:hover
cursor: pointer
$mat-card-header-size-small: 54px !default
.profile-picture-small
height: $mat-card-header-size-small
width: $mat-card-header-size-small
border-radius: 50%
flex-shrink: 0
background-size: cover
transition-duration: 0.5s
z-index: 10
object-fit: cover
.profile-picture:hover
.member-card
box-sizing: border-box
width: 100%
margin-top: 0.5em
outline: none
user-select: none
::ng-deep .mat-card-header-text
width: 1000%
margin: auto 0 auto 24px
.mat-card-subtitle
margin: 0
word-break: break-all
.mat-card-title
margin: 0
word-break: break-all
.request-button
margin-top: 0.5em
margin-bottom: 0.5em
.pointer:hover
cursor: pointer
.icon-box
text-align: right
width: 100%
$pic-size: 40px !default
.card-picture
cursor: pointer
height: $pic-size
width: $pic-size
border-radius: 50%
flex-shrink: 0
background-size: cover
transition-duration: 0.5s
z-index: 10
object-fit: cover
.pointer
cursor: pointer

@ -1,15 +1,15 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import {Data, NavigationEnd, Router} from '@angular/router';
import {User} from 'src/app/models/user';
import {MatSort} from '@angular/material/sort';
import {RequestService} from 'src/app/services/request/request.service';
import {DatasharingService} from '../../services/datasharing.service';
import {GroupService} from 'src/app/services/group/group.service';
import {Group} from 'src/app/models/group';
import {Event} from 'src/app/models/event';
import {MatDialog, MatDialogRef} from '@angular/material/dialog';
import {DialogGroupFileUploadComponent} from './fileUpload/fileUpload.component';
import {Lightbox} from 'ngx-lightbox';
import { Component, OnInit, ViewChild } from '@angular/core';
import { Data, NavigationEnd, Router } from '@angular/router';
import { User } from 'src/app/models/user';
import { MatSort } from '@angular/material/sort';
import { RequestService } from 'src/app/services/request/request.service';
import { DatasharingService } from '../../services/datasharing.service';
import { GroupService } from 'src/app/services/group/group.service';
import { Group } from 'src/app/models/group';
import { Event } from 'src/app/models/event';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { DialogGroupFileUploadComponent } from './fileUpload/fileUpload.component';
import { Lightbox } from 'ngx-lightbox';
// DIALOG COMPONENT to create events
@Component({
@ -100,7 +100,7 @@ export class GroupComponent implements OnInit {
});
}
@ViewChild(MatSort, {static: true}) sort: MatSort;
@ViewChild(MatSort, { static: true }) sort: MatSort;
ngOnInit() {
this.loading = true;
@ -174,6 +174,10 @@ export class GroupComponent implements OnInit {
});
}
public deleteEvent(event: Event) {
this.groupService.deleteEvent(event.id).subscribe();
}
public showUserProfile(user: User) {
this.router.navigate(['profile/' + user.userID]);
}
@ -198,11 +202,19 @@ export class GroupComponent implements OnInit {
});
}
addGroupAdmin(user: User) {
this.groupService.addGroupAdmin(user.userID.toString(), this.id).subscribe();
}
removeGroupAdmin(user: User) {
this.groupService.removeGroupAdmin(user.userID.toString(), this.id).subscribe();
}
openPfpLightbox() {
this.lightbox.open([{
src: this.groupProfile.picture,
thumb: this.groupProfile.picture,
}], 0, {disableScrolling: true});
}], 0, { disableScrolling: true });
}
}

@ -1,10 +1,11 @@
import {IEvent} from './interfaces/IEvent';
import { IEvent } from './interfaces/IEvent';
export class Event {
id: string;
name: string;
date: string;
joined: boolean;
deletable: boolean;
public assignFromResponse(eventDataResponse: IEvent) {
this.id = eventDataResponse.id;
@ -12,6 +13,7 @@ export class Event {
const temp = new Date(Number(eventDataResponse.dueDate));
this.date = temp.toLocaleString('en-GB');
this.joined = eventDataResponse.joined;
this.deletable = eventDataResponse.deletable;
return this;
}

@ -1,7 +1,7 @@
import {User} from 'src/app/models/user';
import {Event} from 'src/app/models/event';
import {IGroup} from './interfaces/IGroup';
import {environment} from 'src/environments/environment';
import { User } from 'src/app/models/user';
import { Event } from 'src/app/models/event';
import { IGroup } from './interfaces/IGroup';
import { environment } from 'src/environments/environment';
export class Group {
id: number;
@ -36,6 +36,13 @@ export class Group {
user = new User();
this.admins.push(user.assignFromResponse(admin));
}
for (const admin of this.admins) {
for (const member of this.members) {
if (member.userID === admin.userID) {
member.isGroupAdmin = true;
}
}
}
}
if (groupDataResponse.events) {
for (const event of groupDataResponse.events) {

@ -7,4 +7,6 @@ export interface IEvent {
dueDate: string;
joined: boolean;
deletable: boolean;
}

@ -1,9 +1,9 @@
import {FriendRequest} from 'src/app/models/friendRequest';
import {FriendInfo} from 'src/app/models/friendinfo';
import {GroupInfo} from 'src/app/models/groupinfo';
import {Post} from 'src/app/models/post';
import {IUser} from './interfaces/IUser';
import {environment} from 'src/environments/environment';
import { FriendRequest } from 'src/app/models/friendRequest';
import { FriendInfo } from 'src/app/models/friendinfo';
import { GroupInfo } from 'src/app/models/groupinfo';
import { Post } from 'src/app/models/post';
import { IUser } from './interfaces/IUser';
import { environment } from 'src/environments/environment';
export class User {
loggedIn = false;
@ -18,6 +18,7 @@ export class User {
joinedAt: string;
friendCount: number;
groupCount: number;
isGroupAdmin: boolean;
darkmode = false;

@ -1,14 +1,14 @@
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from 'src/environments/environment';
import {User} from 'src/app/models/user';
import {Event} from 'src/app/models/event';
import {BehaviorSubject} from 'rxjs';
import {Group} from 'src/app/models/group';
import {tap} from 'rxjs/operators';
import {BaseService} from '../base.service';
import {IFileUploadResult} from '../../models/interfaces/IFileUploadResult';
import {DatasharingService} from 'src/app/services/datasharing.service';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { User } from 'src/app/models/user';
import { Event } from 'src/app/models/event';
import { BehaviorSubject } from 'rxjs';
import { Group } from 'src/app/models/group';
import { tap } from 'rxjs/operators';
import { BaseService } from '../base.service';
import { IFileUploadResult } from '../../models/interfaces/IFileUploadResult';
import { DatasharingService } from 'src/app/services/datasharing.service';
const getGroupGraphqlQuery = `query($groupId: ID!) {
getGroup(groupId:$groupId){
@ -20,7 +20,7 @@ const getGroupGraphqlQuery = `query($groupId: ID!) {
creator{id name handle}
admins{id name handle}
members{id name handle profilePicture}
events{id name dueDate joined}
events{id name dueDate joined deletable}
}
}`;
@ -40,14 +40,14 @@ export class GroupService extends BaseService {
*/
private static buildGetGroupBody(id: string): any {
return {
query: getGroupGraphqlQuery, variables: {groupId: id}
query: getGroupGraphqlQuery, variables: { groupId: id }
};
}
public getGroupData(groupId: string) {
const url = environment.graphQLUrl;
return this.http.post(url, GroupService.buildGetGroupBody(groupId), {headers: this.headers})
return this.http.post(url, GroupService.buildGetGroupBody(groupId), { headers: this.headers })
.pipe(this.retryRated())
.pipe(tap(response => {
const group_ = new Group();
@ -82,6 +82,55 @@ export class GroupService extends BaseService {
}));
}
public addGroupAdmin(userId: string, groupId: string) {
const body = {
query: `mutation($groupId: ID!, $userId: ID!) {
addGroupAdmin(groupId: $groupId, userId: $userId) {
admins{id name handle profilePicture}
}
}`, variables: {
userId,
groupId
}
};
return this.postGraphql(body, null, 0)
.pipe(tap(response => {
const admins: User[] = [];
for (const admin of response.data.addGroupAdmin) {
admins.push(admin.assignFromResponse(admin));
}
const group = this.group.getValue();
group.admins = admins;
this.group.next(group);
}));
}
public removeGroupAdmin(userId: string, groupId: string) {
const body = {
query: `mutation($groupId: ID!, $userId: ID!) {
removeGroupAdmin(groupId: $groupId, userId: $userId) {
admins{id name handle profilePicture}
}
}`, variables: {
userId,
groupId
}
};
return this.postGraphql(body, null, 0)
.pipe(tap(response => {
const admins: User[] = [];
for (const admin of response.data.addGroupAdmin) {
admins.push(admin.assignFromResponse(admin));
}
const group = this.group.getValue();
group.admins = admins;
this.group.next(group);
}));
}
public joinEvent(eventId: string) {
const body = {
query: `mutation($eventId: ID!) {
@ -97,8 +146,6 @@ export class GroupService extends BaseService {
}
public leaveEvent(eventId: string) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
const body = {
query: `mutation($eventId: ID!) {
leaveEvent(eventId: $eventId) {
@ -108,7 +155,31 @@ export class GroupService extends BaseService {
eventId: eventId
}
};
return this.postGraphql(body);
return this.postGraphql(body)
.pipe(this.retryRated());
}
public deleteEvent(eventId: string) {
const body = {
query: `mutation($eventId: ID!) {
deleteEvent(eventId: $eventId) {
joined
}
}`, variables: {
eventId
}
};
return this.postGraphql(body)
.pipe(this.retryRated())
.pipe(tap(response => {
const group = this.group.getValue();
for (let i = 0; i < group.events.length; i++) {
if (group.events[i].id === eventId) {
group.events.splice(i, 1);
}
}
this.group.next(group);
}));
}
public changeProfilePicture(file: any, id: number) {

Loading…
Cancel
Save