diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 758e450..c668095 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -6,6 +6,7 @@ import { AppComponent } from './app.component'; import { HomeComponent } from '../components/home/home.component'; import { ReactiveFormsModule } from '@angular/forms'; import { LayoutComponent } from '../components/layout/layout.component'; +import { PoolService } from 'src/shared/pool.service'; @NgModule({ declarations: [ @@ -18,7 +19,7 @@ import { LayoutComponent } from '../components/layout/layout.component'; AppRoutingModule, ReactiveFormsModule ], - providers: [], + providers: [PoolService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/src/components/home/home.component.ts b/src/components/home/home.component.ts index d1bb4fe..2e8af8d 100644 --- a/src/components/home/home.component.ts +++ b/src/components/home/home.component.ts @@ -1,10 +1,13 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { Champion } from 'src/models/champion'; import { Bonus } from 'src/models/bonus'; -import { Constants } from 'src/common/constants'; +import { PoolService } from 'src/shared/pool.service'; + import { DomSanitizer } from '@angular/platform-browser'; import * as _ from 'lodash'; +import { Subscription } from 'rxjs'; + @Component({ @@ -13,32 +16,46 @@ import * as _ from 'lodash'; styleUrls: ['./home.component.scss'] }) -export class HomeComponent implements OnInit { - teamSize = 0; - champions: Champion[] = [...Constants.Champions]; - roles = [...Constants.roles]; +export class HomeComponent implements OnInit, OnDestroy { formFilters; - championsPool: Champion[] = []; - rolesPool = []; - rolesCount = []; - bonuses: Bonus [] = [...Constants.bonuses]; - bonusesPool: Bonus [] = []; + bonusesPool: Bonus[] = []; + champions: Champion[] = []; noChampSelected = true; - selectedRole = ''; + roles: [] = []; + rolesCount: [] = []; + rolesPool: [] = []; + teamSize = 0; + subscription: Subscription; + constructor( private fb: FormBuilder, - private sanitizer: DomSanitizer - ) { } + private sanitizer: DomSanitizer, + private poolService: PoolService + ) { + this.subscription = this.poolService.setChampions().subscribe( data => { + if (data) { + const {champions, roles, rolesPool, bonusesPool, noChampSelected, teamSize } = data; + this.champions = champions; + this.roles = roles; + this.rolesPool = rolesPool; + this.bonusesPool = bonusesPool; + this.noChampSelected = noChampSelected; + this.teamSize = teamSize; + } + }) + } - ngOnInit() { - this.roles.forEach(role => { - this.rolesCount[role] = 0; - }); + ngOnInit(): void { this.formFilters = this.fb.group({ teamSize: [this.teamSize] }); - this.championSort(Constants.championName); + } + + ngOnDestroy(): void { + if(this.subscription) { + this.subscription.unsubscribe(); + } } /** @@ -49,55 +66,15 @@ export class HomeComponent implements OnInit { return this.sanitizer.bypassSecurityTrustStyle(`url(${'../../assets/images/' + name + '.png'})`); } + /** * Select or unselect champion * @param champion model */ - selectChampion(champion) { - const champIndex = this.champions.findIndex((champ => champ.name === champion.name)); - if (!this.champions[champIndex].isSelected) { - this.champions[champIndex].isSelected = true; - this.championsPool.push(champion); - champion.roles.forEach( role => { - this.rolesCount[role]++; - }); - this.formFilters.patchValue({ - teamSize: ++this.teamSize - }); - this.noChampSelected = false; - } else { - this.champions[champIndex].isSelected = false; - this.championsPool = _.remove(this.championsPool, champ => { - return champ.name !== champion.name; - }); - champion.roles.forEach(role => { - this.rolesCount[role]--; - }); - this.formFilters.patchValue({ - teamSize: --this.teamSize - }); - if ( this.teamSize === 0 ) { - this.noChampSelected = true; - } - } - this.getBonus(); - this.updatePool(); - this.updateSinergies(); - } - - /** - * Sort champion by param - * @param param use to sort - */ - championSort(param) { - this.champions.sort( (a, b) => { - if (a[param] > b[param]) { - return 1; - } - if (a[param] < b[param]) { - return -1; - } - return 0; + selectChampion(champion) { + this.poolService.selectChampion(champion); + this.formFilters.patchValue({ + teamSize: this.teamSize }); } @@ -106,116 +83,24 @@ export class HomeComponent implements OnInit { * @param role name of role */ selectRole(role) { - if (role !== this.selectedRole) { - this.resetComposition(); - this.selectedRole = role; - let countChampions = 0; - this.champions.map( champion => { - if (_.indexOf(champion.roles, role) !== -1) { - champion.isSelected = true; - countChampions++; - this.championsPool.push(champion); - champion.roles.forEach( rol => { - this.rolesCount[rol]++; - }); - } - return champion; - }); - this.updatePool(); - this.updateSinergies(); - this.teamSize = countChampions; - this.formFilters.patchValue({ - teamSize: this.teamSize - }); - this.getBonus(); - this.noChampSelected = false; - } else { - this.resetComposition(); - } - } - - /** - * Get champions bonuses - */ - getBonus() { - this.bonusesPool = []; - this.bonuses.forEach( bonus => { - if (bonus.role === 'ninja' ) { - if ( this.rolesCount[bonus.role] === bonus.units) { - this.bonusesPool[bonus.role] = bonus; - } - } else if (bonus.units <= this.rolesCount[bonus.role]) { - this.bonusesPool[bonus.role] = bonus; - } - + this.poolService.selectRole(role); + this.formFilters.patchValue({ + teamSize: this.teamSize }); } - /** - * Update role pool - */ - updatePool() { - this.rolesPool = []; - this.championsPool.forEach( champion => { - this.rolesPool = _.union(this.rolesPool, champion.roles); - }); - } - - /** - * Update sinergies - */ - updateSinergies() { - this.champions.map(champion => { - champion.sinergy2 = false; - return champion.sinergy = false; - }); - this.champions.map(champion => { - let countRoles = 0; - this.rolesPool.forEach( role => { - if (_.indexOf(champion.roles, role) !== -1 ) { - countRoles++; - } - }); - switch (countRoles) { - case 1: - return champion.sinergy = true; - break; - case 2: - return champion.sinergy2 = true; - break; - } - }); - - } - /** * Check role filter selected * @param role name */ checkRoleFilter(role) { - if (this.selectedRole === role) { - return true; - } else { - return false; - } + return this.poolService.checkRoleFilter(role); } /** * Reset composition */ resetComposition() { - this.rolesCount = []; - this.rolesPool = []; - this.championsPool = []; - this.noChampSelected = true; - this.selectedRole = ''; - this.teamSize = 0; - this.champions.map(champion => { - champion.sinergy = false; - champion.sinergy2 = false; - champion.isSelected = false; - return champion; - }); - this.ngOnInit(); + this.poolService.resetComposition(); } } diff --git a/src/common/constants.ts b/src/shared/constants.ts similarity index 100% rename from src/common/constants.ts rename to src/shared/constants.ts diff --git a/src/shared/pool.service.ts b/src/shared/pool.service.ts new file mode 100644 index 0000000..850783c --- /dev/null +++ b/src/shared/pool.service.ts @@ -0,0 +1,216 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; + +import { Constants } from 'src/shared/constants'; +import { Bonus } from 'src/models/bonus'; +import { Champion } from 'src/models/champion'; + +import * as _ from 'lodash'; + +@Injectable({ + providedIn: 'root', +}) +export class PoolService { + bonuses: Bonus[] = [...Constants.bonuses]; + bonusesPool: Bonus[] = []; + champions: Champion[] = [...Constants.Champions]; + championsPool: Champion[] = []; + noChampSelected = true; + roles = [...Constants.roles]; + rolesCount = []; + rolesPool = []; + selectedRole = ''; + teamSize = 0; + dataToShare = new BehaviorSubject(null); + + constructor() { } + + /** + * Set Champion pool and return data + * @returns Observable + */ + setChampions(): Observable { + this.roles.forEach(role => { + this.rolesCount[role] = 0; + }); + this.championSort(Constants.championName); + this.updateDataToShare(); + return this.dataToShare.asObservable(); + } + + updateDataToShare() { + this.dataToShare.next({ + champions: this.champions, + roles: this.roles, + rolesCount: this.rolesCount, + rolesPool: this.rolesPool, + bonusesPool: this.bonusesPool, + noChampSelected: this.noChampSelected, + teamSize: this.teamSize + }); + } + + /** + * Select or unselect champion + * @param champion model + */ + selectChampion(champion) { + const champIndex = this.champions.findIndex((champ => champ.name === champion.name)); + if (!this.champions[champIndex].isSelected) { + this.champions[champIndex].isSelected = true; + this.championsPool.push(champion); + champion.roles.forEach(role => { + this.rolesCount[role]++; + }); + this.teamSize++; + this.noChampSelected = false; + } else { + this.champions[champIndex].isSelected = false; + this.championsPool = _.remove(this.championsPool, champ => { + return champ.name !== champion.name; + }); + champion.roles.forEach(role => { + this.rolesCount[role]--; + }); + this.teamSize--; + if (this.teamSize === 0) { + this.noChampSelected = true; + } + } + this.getBonus(); + this.updatePool(); + this.updateSinergies(); + this.updateDataToShare(); + } + + + /** + * Sort champion by param + * @param param use to sort + */ + championSort(param) { + this.champions.sort((a, b) => { + if (a[param] > b[param]) { + return 1; + } + if (a[param] < b[param]) { + return -1; + } + return 0; + }); + } + + /** + * Select role pool + * @param role name of role + */ + selectRole(role): void { + if (role !== this.selectedRole) { + this.resetComposition(); + this.selectedRole = role; + let countChampions = 0; + this.champions.map(champion => { + if (_.indexOf(champion.roles, role) !== -1) { + champion.isSelected = true; + countChampions++; + this.championsPool.push(champion); + champion.roles.forEach(rol => { + this.rolesCount[rol]++; + }); + } + return champion; + }); + this.updatePool(); + this.updateSinergies(); + this.teamSize = countChampions; + this.getBonus(); + this.noChampSelected = false; + } else { + this.resetComposition(); + } + this.updateDataToShare(); + } + + /** + * Get champions bonuses + */ + getBonus() { + this.bonusesPool = []; + this.bonuses.forEach(bonus => { + if (bonus.role === 'ninja') { + if (this.rolesCount[bonus.role] === bonus.units) { + this.bonusesPool[bonus.role] = bonus; + } + } else if (bonus.units <= this.rolesCount[bonus.role]) { + this.bonusesPool[bonus.role] = bonus; + } + }); + } + + /** + * Update role pool + */ + updatePool() { + this.rolesPool = []; + this.championsPool.forEach(champion => { + this.rolesPool = _.union(this.rolesPool, champion.roles); + }); + } + + /** + * Update sinergies + */ + updateSinergies() { + this.champions.map(champion => { + champion.sinergy2 = false; + return champion.sinergy = false; + }); + this.champions.map(champion => { + let countRoles = 0; + this.rolesPool.forEach(role => { + if (_.indexOf(champion.roles, role) !== -1) { + countRoles++; + } + }); + switch (countRoles) { + case 1: + return champion.sinergy = true; + case 2: + return champion.sinergy2 = true; + } + }); + + } + + /** + * Check role filter selected + * @param role name + */ + checkRoleFilter(role) { + if (this.selectedRole === role) { + return true; + } else { + return false; + } + } + + /** + * Reset composition + */ + resetComposition() { + this.rolesCount = []; + this.rolesPool = []; + this.championsPool = []; + this.noChampSelected = true; + this.selectedRole = ''; + this.teamSize = 0; + this.champions.map(champion => { + champion.sinergy = false; + champion.sinergy2 = false; + champion.isSelected = false; + return champion; + }); + this.updateDataToShare(); + } + +} \ No newline at end of file