Merge branch 'julius-dev' of Software_Engineering_I/greenvironment-frontend into master

master
Trivernis 5 years ago committed by Gitea
commit 8a3494f4a6

2515
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -17,8 +17,8 @@
"@angular/compiler": "~8.2.14",
"@angular/core": "^8.2.14",
"@angular/flex-layout": "^8.0.0-beta.27",
"@angular/forms": "^7.2.15",
"@angular/http": "^7.2.15",
"@angular/forms": "^7.2.16",
"@angular/http": "^7.2.16",
"@angular/material": "^8.2.3",
"@angular/platform-browser": "8.2.14",
"@angular/platform-browser-dynamic": "^8.2.14",
@ -41,10 +41,10 @@
"zone.js": "^0.8.29"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.803.21",
"@angular/cli": "^8.3.21",
"@angular-devkit/build-angular": "^0.803.23",
"@angular/cli": "^8.3.23",
"@angular/compiler-cli": "^8.2.14",
"@angular/language-service": "^7.2.15",
"@angular/language-service": "^7.2.16",
"@types/jasmine": "^2.8.16",
"@types/jasminewd2": "^2.0.8",
"@types/node": "~8.9.4",
@ -59,6 +59,6 @@
"protractor": "^5.4.2",
"ts-node": "~7.0.0",
"tslint": "^5.20.1",
"typescript": "~3.5.0"
"typescript": "<3.6.0"
}
}

@ -4,6 +4,7 @@ import { Login } from 'src/app/models/login';
import { LoginService } from 'src/app/services/login/login.service';
import {Router} from '@angular/router';
import * as sha512 from 'js-sha512';
import {IErrorResponse} from '../../models/interfaces/IErrorResponse';
@Component({
selector: 'app-login',
@ -21,22 +22,37 @@ export class LoginComponent implements OnInit {
errorMessage: string;
email = new FormControl('', [Validators.required, Validators.email]);
public getErrorMessage() {
private getErrorMessage() {
return this.errorMessage;
}
public loginError(error: any) {
private loginError(errorResponse: IErrorResponse) {
const error = errorResponse.error;
this.errorOccurred = true;
this.errorMessage = error.errors[0].message;
}
/**
* Fired when the submit button is pressed.
* A login request is performed and the user is redirected to the home page on success.
* @param pEmail
* @param pPasswordHash
*/
onClickSubmit(pEmail: string, pPasswordHash: string) {
this.errorOccurred = false;
this.errorMessage = ' ';
this.login.email = pEmail.trim().toLowerCase();
this.login.passwordHash = sha512.sha512(pPasswordHash);
this.loginService.login(this.login, error => this.loginError(error.json()));
this.loginService.login(this.login).subscribe( () => {
this.router.navigateByUrl('').catch((error) => {
this.errorMessage = error.message;
this.errorOccurred = true;
});
}, (error: IErrorResponse) => {
if (error.error) {
this.loginError(error);
}
});
}
ngOnInit() {}

@ -18,13 +18,12 @@ export class SearchComponent implements OnInit {
searchValue = ' ';
category = 'user';
user: User;
foundUsers: Array<User> = new Array();
foundGroups: Array<GroupInfo> = new Array();
foundUsers: User[] = [];
foundGroups: GroupInfo[] = [];
constructor(
private searchService: SearchService,
private requestService: RequestService,
private http: Http,
private router: Router,
private data: DatasharingService) { }
ngOnInit() {
@ -46,19 +45,16 @@ export class SearchComponent implements OnInit {
this.loading = true;
this.findUser(searchWord);
} else if (this.category === 'groupe') {
// this.findUserByHandle(searchWord);
console.log('search group');
}
}
}
findUser(name: String) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
this.http.post(environment.graphQLUrl, this.searchService.buildJsonUser(name))
findUser(name: string) {
this.searchService.search(name)
.subscribe(response => {
this.foundUsers = this.searchService.renderUsers(response.json());
this.foundGroups = this.searchService.renderGroups(response.json());
this.foundUsers = this.searchService.getUsersForResponse(response);
this.foundGroups = this.searchService.getGroupsForResponse(response);
for (const foundUser of this.foundUsers) {
foundUser.allowedToSendRequest = this.requestService.isAllowedToSendRequest(foundUser.userID, this.user);
}

@ -5,4 +5,11 @@ export class FriendRequest {
senderUserID: number;
senderHandle: string;
senderUsername: string;
constructor(id?: number, senderUserId?: number, senderHandle?: string, senderName?: string) {
this.id = id;
this.senderUserID = senderUserId;
this.senderHandle = senderHandle;
this.senderUsername = senderName;
}
}

@ -0,0 +1,12 @@
import {IUser} from './IUser';
export interface IChat {
id: number;
namespace: string;
members: IUser[];
messages: any[];
}

@ -0,0 +1,8 @@
import {IGraphqlError} from './IGraphqlError';
export interface IErrorResponse {
error: {
errors: IGraphqlError[];
data: any;
};
}

@ -0,0 +1,8 @@
export interface IGraphqlError {
message: string;
path: string[];
location: {line: number; column: number}[];
}

@ -0,0 +1,20 @@
import {IUser} from './IUser';
export interface IGroup {
id: number;
name: string;
creator: IUser;
admins: IUser[];
members: IUser[];
chat: any;
events: any;
joined: boolean;
}

@ -0,0 +1,18 @@
import {IUser} from './IUser';
export enum RequestType {
FRIENDREQUEST = 'FRIENDREQUEST',
GROUPINVITE = 'GROUPINVITE',
EVENTINVITE = 'EVENTINVITE',
}
export interface IRequest {
id: number;
sender: IUser;
receiver: IUser;
type: RequestType;
}

@ -0,0 +1,12 @@
import {IUser} from './IUser';
import {IGroup} from './IGroup';
export interface ISearchResult {
users: IUser[];
groups: IGroup[];
posts: any[];
events: any[];
}

@ -0,0 +1,3 @@
export interface ISettings {
darkmode?: boolean;
}

@ -0,0 +1,49 @@
import {IGroup} from './IGroup';
import {ISettings} from './ISettings';
import {IChat} from './IChat';
import {IRequest} from './IRequest';
export interface IUser {
id: number;
name: string;
handle: string;
email?: string;
profilePicture?: string;
settings?: string;
level: number;
points: number;
numberOfPosts: number;
postCount: number;
posts: any[];
chats: IChat[];
receivedRequests: IRequest[];
sentRequests: IRequest[];
joinedAt: string;
friendCount: number;
friends: IUser[];
groupCount: number;
groups: IGroup[];
eventCount: number;
events: any[];
}

@ -2,6 +2,7 @@ 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';
export class User {
loggedIn = false;
@ -18,12 +19,39 @@ export class User {
darkmode = false;
friends: FriendInfo[] = new Array();
groups: GroupInfo[] = new Array();
posts: Post[] = new Array();
friends: FriendInfo[] = [];
groups: GroupInfo[] = [];
posts: Post[] = [];
chatIDs: number[];
receivedRequests: FriendRequest[] = new Array();
sentRequestUserIDs: number[] = new Array(); // IDs of users that already received requests of the logged in user
receivedRequests: FriendRequest[] = [];
sentRequestUserIDs: number[] = []; // IDs of users that already received requests of the logged in user
allowedToSendRequest = true; /* if a user already received a request this should
be false to avoid multiple invitations*/
public assignFromResponse(userDataResponse: IUser) {
this.userID = userDataResponse.id;
this.username = userDataResponse.name;
this.handle = userDataResponse.handle;
this.email = userDataResponse.email;
this.points = userDataResponse.points;
this.level = userDataResponse.level;
this.profilePicture = userDataResponse.profilePicture;
this.joinedAt = userDataResponse.joinedAt;
this.friendCount = userDataResponse.friendCount;
this.groupCount = userDataResponse.groupCount;
try {
this.darkmode = !!JSON.parse(userDataResponse.settings).darkmode;
} catch (err) {
console.error(err);
}
this.friends = userDataResponse.friends
.map(friend => new FriendInfo(friend.id, friend.name, friend.level));
this.groups = userDataResponse.groups
.map(group => new GroupInfo(group.id, group.name));
this.chatIDs = userDataResponse.chats.map(chat => chat.id);
this.sentRequestUserIDs = userDataResponse.sentRequests
.map(request => request.receiver.id);
this.receivedRequests = userDataResponse.receivedRequests
.map(request => new FriendRequest(request.id, request.sender.id, request.sender.handle, request.sender.name));
}
}

@ -0,0 +1,14 @@
import {Injectable} from '@angular/core';
import {HttpHeaders} from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export abstract class BaseService {
protected headers: HttpHeaders;
protected constructor() {
this.headers = new HttpHeaders();
this.headers.set('Content-Type', 'application/json');
}
}

@ -1,105 +1,79 @@
import {Injectable} from '@angular/core';
import {Headers, Http, Request} from '@angular/http';
import {HttpClient} from '@angular/common/http';
import {Login} from '../../models/login';
import {User} from 'src/app/models/user';
import {DatasharingService} from '../datasharing.service';
import {Router} from '@angular/router';
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 {IUser} from '../../models/interfaces/IUser';
import {BaseService} from '../base.service';
import {tap} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class LoginService {
constructor(private http: Http, private data: DatasharingService, private router: Router) {
}
public login(login: Login, errorCb: any) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
interface ILoginRequestResult {
data: {
login: IUser;
};
}
return this.http.post(environment.graphQLUrl, this.buildJson(login))
.subscribe(response => {
this.loginSuccess();
this.updateUserInfo(response.json());
}, errorCb
);
const graphqlQuery = `mutation($email: String!, $pwHash: String!) {
login(email: $email, passwordHash: $pwHash) {
id,
name,
email,
handle,
points,
level,
receivedRequests{id, sender{name, handle, id}},
sentRequests{receiver{id}},
friends {
id,
name,
level
},
groups {
id,
name
},
chats{
id
},
settings
}
}`;
public loginSuccess() {
this.router.navigateByUrl('');
}
@Injectable({
providedIn: 'root'
})
export class LoginService extends BaseService {
public updateUserInfo(response: any) {
const user: User = new User();
let friendRequest: FriendRequest = new FriendRequest();
user.loggedIn = true;
user.userID = response.data.login.id;
user.username = response.data.login.name;
user.handle = response.data.login.handle;
user.email = response.data.login.email;
user.points = response.data.login.points;
user.level = response.data.login.level;
for (const friend of response.data.login.friends) {
user.friends.push(new FriendInfo(friend.id, friend.name, friend.level));
}
for (const group of response.data.login.groups) {
user.groups.push(new GroupInfo(group.id, group.name));
}
user.chatIDs = response.data.login.chats;
for (const request of response.data.login.sentRequests) {
user.sentRequestUserIDs.push(request.receiver.id);
}
for (const request of response.data.login.receivedRequests) {
friendRequest = new FriendRequest();
friendRequest.id = request.id;
friendRequest.senderUserID = request.sender.id;
friendRequest.senderUsername = request.sender.name;
friendRequest.senderHandle = request.sender.handle;
user.receivedRequests.push(friendRequest);
}
if (JSON.parse(response.data.login.settings).darkmode === 'true') {
user.darkmode = true;
}
this.data.changeUserInfo(user);
constructor(private http: HttpClient, private datasharingService: DatasharingService) {
super();
}
public buildJson(login: Login): any {
const body = {
query: `mutation($email: String!, $pwHash: String!) {
login(email: $email, passwordHash: $pwHash) {
id,
name,
email,
handle,
points,
level,
receivedRequests{id, sender{name, handle, id}},
sentRequests{receiver{id}},
friends {
id,
name,
level
},
groups {
id,
name
},
chats{
id
},
settings
}
}`
, variables: {
/**
* Builds the body for the login request
* @param login
*/
private static buildRequestBody(login: Login): any {
return {
query: graphqlQuery,
variables: {
email: login.email,
pwHash: login.passwordHash,
}
};
return body;
}
/**
* Performs a login request and returns the data of the logged in user.
* @param login
*/
public login(login: Login) {
const body = LoginService.buildRequestBody(login);
return this.http.post<ILoginRequestResult>(environment.graphQLUrl, body)
.pipe(tap(response => {
const user = new User();
user.assignFromResponse(response.data.login);
this.datasharingService.changeUserInfo(user);
}));
}
}

@ -1,71 +1,109 @@
import {Injectable} from '@angular/core';
import {Headers, Http} from '@angular/http';
import {HttpClient} from '@angular/common/http';
import {DatasharingService} from '../datasharing.service';
import {Router} from '@angular/router';
import {environment} from 'src/environments/environment';
import { User } from 'src/app/models/user';
import { GroupInfo } from 'src/app/models/groupinfo';
import {User} from 'src/app/models/user';
import {GroupInfo} from 'src/app/models/groupinfo';
import {Observable} from 'rxjs';
import {ISearchResult} from '../../models/interfaces/ISearchResult';
import {environment} from '../../../environments/environment';
import {BaseService} from '../base.service';
import {tap} from 'rxjs/operators';
interface ISearchRequestResult {
data: {
search: ISearchResult;
};
}
const graphqlQuery = `query($query: String!, $first: Int, $offset: Int) {
search(query:$query, first: $first, offset: $offset) {
users{
profilePicture,
name,
id,
handle,
points,
level,
friends {
id
}
}
groups{
id
name
creator{id name handle}
members{id name handle}
}
}
}`;
@Injectable({
providedIn: 'root'
})
export class SearchService {
export class SearchService extends BaseService {
constructor(private http: HttpClient, private data: DatasharingService, private router: Router) {
super();
}
users: Array<User>;
constructor(private http: Http, private data: DatasharingService, private router: Router) {
users: User[];
/**
* Builds the body for the request
* @param query - the search query
* @param first - the limit of elements to fetch
* @param offset - offset
*/
private static buildRequestBody(query: String, first: number = 20, offset: number = 0): any {
return {
query: graphqlQuery,
variables: {
query,
first,
offset
}
};
}
public renderUsers(pResponse: any): Array<User> {
/**
* Maps the users in the response to the user class
* @param response
*/
public getUsersForResponse(response: ISearchRequestResult): User[] {
const users = new Array<User>();
for (const user of pResponse.data.search.users) {
const pUser = new User();
pUser.profilePicture = user.profilePicture;
pUser.username = user.name;
pUser.userID = user.id;
pUser.handle = user.handle;
pUser.points = user.points;
pUser.level = user.level;
pUser.friends = user.friends;
users.push(pUser);
for (const foundUser of response.data.search.users) {
const user = new User();
user.profilePicture = foundUser.profilePicture;
user.username = foundUser.name;
user.userID = foundUser.id;
user.handle = foundUser.handle;
user.points = foundUser.points;
user.level = foundUser.level;
// @ts-ignore
user.friends = foundUser.friends;
users.push(user);
}
return users;
}
public renderGroups(pResponse: any): Array<GroupInfo> {
/**
* Maps the groups in the response to the group class
* @param response
*/
public getGroupsForResponse(response: ISearchRequestResult): Array<GroupInfo> {
const groups = new Array<GroupInfo>();
for (const group of pResponse.data.search.groups) {
for (const group of response.data.search.groups) {
groups.push(new GroupInfo(group.id, group.name));
}
return groups;
}
public buildJsonUser(name_: String): any {
const body = {
query: `query($name: String!) {
search(query:$name, first: 100, offset: 0) {
users{
profilePicture,
name,
id,
handle,
points,
level,
friends {
id
}
}
groups{
id
name
creator{id name handle}
members{id name handle}
}
}
}`
, variables: {
name: name_
}
};
return body;
/**
* Searches for users, groups, events and posts with a specified query.
* @param query
*/
public search(query: string): Observable<ISearchRequestResult> {
const body = SearchService.buildRequestBody(query);
return this.http.post<ISearchRequestResult>(environment.graphQLUrl, body, {headers: this.headers});
}
}

@ -70,7 +70,7 @@
],
"no-misused-new": true,
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-redundant-jsdoc": false,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,

Loading…
Cancel
Save