added group logic
This commit is contained in:
parent
86f2d02a26
commit
6d6f4c6c37
@ -0,0 +1,19 @@
|
||||
<div class="list-container mt-5">
|
||||
<div>
|
||||
<div *ngFor="let candidate of candidates" class="group-list-item d-flex justify-content-between mb-2 p-3">
|
||||
<div class="subject-data">
|
||||
<div>
|
||||
Name: {{ candidate.fullName }}
|
||||
</div>
|
||||
<div>
|
||||
Login: {{ candidate.userName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="group-buttons d-flex align-items-center">
|
||||
<button (click)="onAccept(candidate.id)" class="btn btn-primary">Accept</button>
|
||||
<button (click)="onDecline(candidate.id)" class="btn btn-primary">Decline</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,5 @@
|
||||
.list-container {
|
||||
.group-list-item {
|
||||
border: 1px solid black;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GroupCandidatesComponent } from './group-candidates.component';
|
||||
|
||||
describe('GroupCandidatesComponent', () => {
|
||||
let component: GroupCandidatesComponent;
|
||||
let fixture: ComponentFixture<GroupCandidatesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ GroupCandidatesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(GroupCandidatesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,27 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { User } from 'src/app/user/interfaces/user.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-group-candidates',
|
||||
templateUrl: './group-candidates.component.html',
|
||||
styleUrls: ['./group-candidates.component.scss']
|
||||
})
|
||||
export class GroupCandidatesComponent implements OnInit {
|
||||
|
||||
@Input() candidates: User[];
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
}
|
||||
|
||||
onAccept(id: string): void {
|
||||
|
||||
}
|
||||
|
||||
onDecline(id: string): void {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1 +1,19 @@
|
||||
<p>group-edit works!</p>
|
||||
<div *ngIf="group$ | async as group">
|
||||
<div>
|
||||
<button *ngIf="group.admin.id === userId" (click)="onDelete(group.id)" class="btn btn-primary">Delete group</button>
|
||||
<button *ngIf="group.admin.id !== userId" (click)="onLeaveGroup(group.id)" class="btn btn-primary">Leave group</button>
|
||||
</div>
|
||||
<div class="group-main-data">
|
||||
<div>
|
||||
Name: {{ group.name }}
|
||||
</div>
|
||||
<div>
|
||||
Year: {{ group.year }}
|
||||
</div>
|
||||
<div>
|
||||
Admin: {{ group.admin.fullName }} ({{group.admin.userName}})
|
||||
</div>
|
||||
</div>
|
||||
<app-group-users [groupUsers]="group.users"></app-group-users>
|
||||
<app-group-candidates [candidates]="group.userCandidates"></app-group-candidates>
|
||||
</div>
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { ActivatedRouteSnapshot, Router } from '@angular/router';
|
||||
import { GroupService } from './../../services/group.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Group } from '../../interfaces/group.interface';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-group-edit',
|
||||
@ -7,9 +11,30 @@ import { Component, OnInit } from '@angular/core';
|
||||
})
|
||||
export class GroupEditComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
group$: Observable<Group>;
|
||||
userId: string;
|
||||
groupId: number;
|
||||
|
||||
constructor(private groupService: GroupService,
|
||||
private activatedRouteSnapshot: ActivatedRouteSnapshot,
|
||||
private router: Router) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.userId = localStorage.getItem('userId');
|
||||
this.groupId = this.activatedRouteSnapshot.params['groupId'];
|
||||
this.group$ = this.groupService.getGroup(this.groupId);
|
||||
}
|
||||
|
||||
onDelete(): void {
|
||||
this.groupService.delete(this.groupId).subscribe(() => {
|
||||
this.router.navigateByUrl('/groups');
|
||||
});
|
||||
}
|
||||
|
||||
onLeaveGroup(): void {
|
||||
this.groupService.leaveGroup(this.groupId).subscribe(() => {
|
||||
this.router.navigateByUrl('/groups');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,15 +4,17 @@
|
||||
<mat-tab-group>
|
||||
<mat-tab label="My groups">
|
||||
<app-group-list
|
||||
[groups]="userGroups"
|
||||
[groups]="userGroups$ | async"
|
||||
(show)="onShow($event)">
|
||||
</app-group-list>
|
||||
</mat-tab>
|
||||
<mat-tab label="All groups">
|
||||
<app-group-list
|
||||
[groups]="allGroups"
|
||||
[groups]="allGroups$ | async"
|
||||
(joinRequest)="onJoinRequest($event)"
|
||||
(show)="onShow($event)">
|
||||
</app-group-list>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
<app-group-users></app-group-users>
|
||||
<app-group-candidates></app-group-candidates>
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { GroupCandidateService } from './../../services/group-candidate.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { GroupService } from './../../services/group.service';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Group } from '../../interfaces/group.interface';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-group-main',
|
||||
@ -9,24 +12,30 @@ import { Group } from '../../interfaces/group.interface';
|
||||
})
|
||||
export class GroupMainComponent implements OnInit {
|
||||
|
||||
userGroups: Group[];
|
||||
allGroups: Group[];
|
||||
userGroups$: Observable<Group[]>;
|
||||
allGroups$: Observable<Group[]>;
|
||||
|
||||
constructor(private groupService: GroupService) { }
|
||||
constructor(private groupService: GroupService,
|
||||
private groupCandidateService: GroupCandidateService,
|
||||
private router: Router) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.userGroups$ = this.groupService.getCurrentUserGroups();
|
||||
this.allGroups$ = this.groupService.getAllGroups();
|
||||
}
|
||||
|
||||
onAddNew(): void {
|
||||
|
||||
this.router.navigateByUrl('/groups/add-new');
|
||||
}
|
||||
|
||||
onShow(groupId: number) {
|
||||
|
||||
this.router.navigateByUrl(`/groups/edit/${groupId}`);
|
||||
}
|
||||
|
||||
onJoinRequest(groupId: number) {
|
||||
|
||||
this.groupCandidateService.joinRequest(groupId).subscribe(() => {
|
||||
alert('request sent');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
<div class="list-container mt-5">
|
||||
<div>
|
||||
<div *ngFor="let user of groupUsers" class="group-list-item d-flex justify-content-between mb-2 p-3">
|
||||
<div class="subject-data">
|
||||
<div>
|
||||
Login: {{ user.userName }}
|
||||
</div>
|
||||
<div>
|
||||
Fullname: {{ user.fullName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="group-buttons d-flex align-items-center">
|
||||
<button (click)="onDeleteUser(user.id)" class="btn btn-primary">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
.list-container {
|
||||
.group-list-item {
|
||||
border: 1px solid black;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GroupUsersComponent } from './group-users.component';
|
||||
|
||||
describe('GroupUsersComponent', () => {
|
||||
let component: GroupUsersComponent;
|
||||
let fixture: ComponentFixture<GroupUsersComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ GroupUsersComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(GroupUsersComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,24 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { User } from 'src/app/user/interfaces/user.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-group-users',
|
||||
templateUrl: './group-users.component.html',
|
||||
styleUrls: ['./group-users.component.scss']
|
||||
})
|
||||
export class GroupUsersComponent implements OnInit {
|
||||
|
||||
@Input() groupUsers: User[];
|
||||
@Output() deleteUser = new EventEmitter<string>();
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
}
|
||||
|
||||
onDeleteUser(id: string): void {
|
||||
this.deleteUser.emit(id);
|
||||
}
|
||||
|
||||
}
|
15
src/app/group/components/new-group/new-group.component.html
Normal file
15
src/app/group/components/new-group/new-group.component.html
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="group-form-container d-flex justify-content-center">
|
||||
<form [formGroup]="groupForm" class="group-form d-flex flex-column mt-5">
|
||||
<mat-form-field>
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput formControlName="name" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<mat-label>Year</mat-label>
|
||||
<input matInput formControlName="year" type="number" />
|
||||
</mat-form-field>
|
||||
<div class="mt-4">
|
||||
<button (click)="onAddGroup()" class="btn btn-primary">Add</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
.group-form-container {
|
||||
.group-form {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NewGroupComponent } from './new-group.component';
|
||||
|
||||
describe('NewGroupComponent', () => {
|
||||
let component: NewGroupComponent;
|
||||
let fixture: ComponentFixture<NewGroupComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NewGroupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NewGroupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
37
src/app/group/components/new-group/new-group.component.ts
Normal file
37
src/app/group/components/new-group/new-group.component.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { GroupService } from './../../services/group.service';
|
||||
import { GroupSaveModel } from './../../interfaces/group-save-model.interface';
|
||||
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-new-group',
|
||||
templateUrl: './new-group.component.html',
|
||||
styleUrls: ['./new-group.component.scss']
|
||||
})
|
||||
export class NewGroupComponent implements OnInit {
|
||||
|
||||
groupForm: FormGroup;
|
||||
|
||||
constructor(private groupService: GroupService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.groupForm = this.createGroupForm();
|
||||
}
|
||||
|
||||
createGroupForm(): FormGroup {
|
||||
return new FormGroup({
|
||||
name: new FormControl('', Validators.required),
|
||||
year: new FormControl(0, Validators.required)
|
||||
});
|
||||
}
|
||||
|
||||
onAddGroup(): void {
|
||||
const group: GroupSaveModel = {
|
||||
name: this.groupForm.controls.name.value,
|
||||
year: this.groupForm.controls.year.value,
|
||||
adminId: localStorage.getItem('userId')
|
||||
}
|
||||
this.groupService.add(this.groupForm.value);
|
||||
}
|
||||
|
||||
}
|
@ -4,14 +4,31 @@ import { GroupMainComponent } from './components/group-main/group-main.component
|
||||
import { GroupListComponent } from './components/group-list/group-list.component';
|
||||
import { GroupEditComponent } from './components/group-edit/group-edit.component';
|
||||
import {MatTabsModule} from '@angular/material/tabs';
|
||||
import { GroupCandidatesComponent } from './components/group-candidates/group-candidates.component';
|
||||
import { GroupUsersComponent } from './components/group-users/group-users.component';
|
||||
import { NewGroupComponent } from './components/new-group/new-group.component';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { SubjectRoutingModule } from '../subject/subject-routing.module';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [GroupMainComponent, GroupListComponent, GroupEditComponent],
|
||||
declarations: [GroupMainComponent, GroupListComponent, GroupEditComponent, GroupCandidatesComponent, GroupUsersComponent, NewGroupComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatTabsModule,
|
||||
MatTableModule,
|
||||
MatInputModule,
|
||||
MatFormFieldModule,
|
||||
SubjectRoutingModule,
|
||||
ReactiveFormsModule,
|
||||
MatCheckboxModule,
|
||||
MatButtonModule,
|
||||
]
|
||||
})
|
||||
export class GroupModule { }
|
||||
|
4
src/app/group/interfaces/group-base.interface.ts
Normal file
4
src/app/group/interfaces/group-base.interface.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface GroupBase {
|
||||
name: string;
|
||||
year: number;
|
||||
}
|
5
src/app/group/interfaces/group-save-model.interface.ts
Normal file
5
src/app/group/interfaces/group-save-model.interface.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { GroupBase } from "./group-base.interface";
|
||||
|
||||
export interface GroupSaveModel extends GroupBase {
|
||||
adminId: string;
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
import { User } from "src/app/user/interfaces/user.interface";
|
||||
import { GroupBase } from "./group-base.interface";
|
||||
|
||||
export interface Group {
|
||||
id: number;
|
||||
name: string;
|
||||
year: number;
|
||||
export interface Group extends GroupBase {
|
||||
id?: number;
|
||||
admin: User;
|
||||
users: User[];
|
||||
userCandidates: User[];
|
||||
users?: User[];
|
||||
userCandidates?: User[];
|
||||
isUserInGroup?: boolean;
|
||||
}
|
||||
|
4
src/app/group/interfaces/join-request.interface.ts
Normal file
4
src/app/group/interfaces/join-request.interface.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface JoinRequest {
|
||||
groupId: number;
|
||||
userId: string;
|
||||
}
|
16
src/app/group/services/group-candidate.service.spec.ts
Normal file
16
src/app/group/services/group-candidate.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GroupCandidateService } from './group-candidate.service';
|
||||
|
||||
describe('GroupCandidateService', () => {
|
||||
let service: GroupCandidateService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(GroupCandidateService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
30
src/app/group/services/group-candidate.service.ts
Normal file
30
src/app/group/services/group-candidate.service.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { JoinRequest } from './../interfaces/join-request.interface';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { User } from 'src/app/user/interfaces/user.interface';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class GroupCandidateService {
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
getList(groupId: number): Observable<User[]> {
|
||||
return this.http.get<User[]>(`${environment.host}${environment.apiEndpoints.groupCandidates.getList}/${groupId}`);
|
||||
}
|
||||
|
||||
joinRequest(groupId: number): Observable<void> {
|
||||
const joinRequest: JoinRequest = {
|
||||
groupId,
|
||||
userId: localStorage.getItem('userId')
|
||||
}
|
||||
return this.http.post<void>(environment.host + environment.apiEndpoints.groupCandidates.joinRequest, joinRequest);
|
||||
}
|
||||
|
||||
delete(): Observable<void> {
|
||||
return this.http.delete<void>(`${environment.host}${environment.apiEndpoints.groupCandidates.delete}/${localStorage.getItem('userId')}`);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { Group } from '../interfaces/group.interface';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { GroupSaveModel } from '../interfaces/group-save-model.interface';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -11,7 +12,7 @@ export class GroupService {
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
add(group: Group): Observable<void> {
|
||||
add(group: GroupSaveModel): Observable<void> {
|
||||
return this.http.post<void>(environment.host + environment.apiEndpoints.groups, group);
|
||||
}
|
||||
|
||||
@ -19,4 +20,20 @@ export class GroupService {
|
||||
return this.http.get<Group[]>(environment.host + environment.apiEndpoints.groups.getAll);
|
||||
}
|
||||
|
||||
getGroup(groupId: number): Observable<Group> {
|
||||
return this.http.get<Group>(`${environment.host}${environment.apiEndpoints.groups.getById}/${groupId}`);
|
||||
}
|
||||
|
||||
getCurrentUserGroups(): Observable<Group[]> {
|
||||
return this.http.get<Group[]>(`${environment.host}${environment.apiEndpoints.groups.getCurrentUserGroups}/${localStorage.getItem('userId')}`);
|
||||
}
|
||||
|
||||
leaveGroup(groupId: number): Observable<void> {
|
||||
return this.http.get<void>(`${environment.host}${environment.apiEndpoints.groups.getCurrentUserGroups}/${groupId}/${localStorage.getItem('userId')}`);
|
||||
}
|
||||
|
||||
delete(groupId: number): Observable<void> {
|
||||
return this.http.delete<void>(`${environment.host}${environment.apiEndpoints.groups.delete}/${groupId}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,9 +15,15 @@ export const environment = {
|
||||
},
|
||||
groups: {
|
||||
getAll: 'api/groups/all',
|
||||
getUserGroups: 'api/groups/user-groups',
|
||||
getById: 'api/groups/get-by-id',
|
||||
getCurrentUserGroups: 'api/groups/current-user-groups',
|
||||
create: 'api/groups/create',
|
||||
delete: 'api/groups/delete'
|
||||
},
|
||||
groupCandidates: {
|
||||
getList: 'api/group-candidates/list',
|
||||
joinRequest: 'api/group-candidates/join-request',
|
||||
delete: 'api/group-candidates/delete'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user