From 76b5666b6e038b7ae4a4fc64f637b6724ee2de15 Mon Sep 17 00:00:00 2001 From: drumonii Date: Wed, 25 Sep 2019 21:20:53 -0400 Subject: [PATCH] Restyle components using Nebular https://github.com/akveo/nebular/ --- README.adoc | 2 +- .../api/BuildsRestController.java | 2 +- frontend/angular.json | 5 +- frontend/package-lock.json | 50 +++++-- frontend/package.json | 6 +- .../e2e/src/builds/builds.e2e-spec.ts | 2 +- .../e2e/src/champion/champion.e2e-spec.ts | 4 +- .../e2e/src/champion/champion.po.ts | 9 +- .../e2e/src/champions/champions.po.ts | 8 +- .../troll-build/e2e/src/error/not-found.po.ts | 6 +- .../e2e/src/troll-build-app.e2e-spec.ts | 8 +- .../troll-build/e2e/src/troll-build-app.po.ts | 4 +- .../src/app/champion/champion.module.ts | 12 +- .../src/app/champion/champion.page.html | 74 +++++----- .../src/app/champion/champion.page.scss | 23 ++- .../src/app/champion/champion.page.spec.ts | 90 ++++++------ .../src/app/champion/champion.page.ts | 4 +- .../src/app/champion/champion.service.ts | 2 - .../app/champion/troll-build.component.html | 136 ++++++++---------- .../app/champion/troll-build.component.scss | 67 +++------ .../src/app/champion/troll-build.module.ts | 24 ++++ .../app/champions/champion-img.component.html | 5 + ...onent.scss => champion-img.component.scss} | 13 +- ...spec.ts => champion-img.component.spec.ts} | 22 +-- ...component.ts => champion-img.component.ts} | 8 +- .../src/app/champions/champion-img.module.ts | 21 +++ .../src/app/champions/champion.component.html | 7 - .../src/app/champions/champions.module.ts | 15 +- .../src/app/champions/champions.page.html | 66 ++++----- .../src/app/champions/champions.page.scss | 18 ++- .../src/app/champions/champions.page.spec.ts | 81 ++++------- .../directive/lazy-load-img.directive.spec.ts | 4 +- .../app/directive/lazy-load-img.directive.ts | 4 +- .../src/app/error/not-found.module.ts | 3 + .../src/app/error/not-found.page.html | 26 ++-- .../src/app/error/not-found.page.spec.ts | 4 +- .../app/layout/footer/footer.component.html | 46 +++--- .../app/layout/footer/footer.component.scss | 30 +++- .../layout/footer/footer.component.spec.ts | 17 +-- .../src/app/layout/footer/footer.module.ts | 24 ++++ .../src/app/layout/footer/versions.service.ts | 4 +- .../app/layout/header/header.component.html | 33 ++--- .../app/layout/header/header.component.scss | 19 --- .../layout/header/header.component.spec.ts | 66 ++++----- .../src/app/layout/header/header.module.ts | 19 +++ .../src/app/layout/layout.module.ts | 18 +-- .../src/app/troll-build-app-routing.module.ts | 3 +- .../src/app/troll-build-app.component.html | 16 ++- .../src/app/troll-build-app.module.ts | 9 +- frontend/projects/troll-build/src/styles.scss | 47 ------ .../troll-build/src/styles/_alert.scss | 5 + .../troll-build/src/styles/_button-group.scss | 20 +++ .../troll-build/src/styles/_buttons.scss | 34 +++++ .../troll-build/src/styles/_footer.scss | 21 +++ .../troll-build/src/styles/_forms.scss | 57 ++++++++ .../troll-build/src/styles/_grid.scss | 24 ++++ .../troll-build/src/styles/_header.scss | 37 +++++ .../troll-build/src/styles/_layout.scss | 33 +++++ .../troll-build/src/styles/_lists.scss | 8 ++ .../troll-build/src/styles/_message.scss | 25 ++++ .../troll-build/src/styles/_reset.scss | 56 ++++++++ .../troll-build/src/styles/_tags.scss | 18 +++ .../troll-build/src/styles/_theme.scss | 53 +++++++ .../projects/troll-build/src/styles/ltb.scss | 42 ++++++ 64 files changed, 1017 insertions(+), 602 deletions(-) create mode 100644 frontend/projects/troll-build/src/app/champion/troll-build.module.ts create mode 100644 frontend/projects/troll-build/src/app/champions/champion-img.component.html rename frontend/projects/troll-build/src/app/champions/{champion.component.scss => champion-img.component.scss} (63%) rename frontend/projects/troll-build/src/app/champions/{champion.component.spec.ts => champion-img.component.spec.ts} (68%) rename frontend/projects/troll-build/src/app/champions/{champion.component.ts => champion-img.component.ts} (60%) create mode 100644 frontend/projects/troll-build/src/app/champions/champion-img.module.ts delete mode 100644 frontend/projects/troll-build/src/app/champions/champion.component.html create mode 100644 frontend/projects/troll-build/src/app/layout/footer/footer.module.ts create mode 100644 frontend/projects/troll-build/src/app/layout/header/header.module.ts delete mode 100644 frontend/projects/troll-build/src/styles.scss create mode 100644 frontend/projects/troll-build/src/styles/_alert.scss create mode 100644 frontend/projects/troll-build/src/styles/_button-group.scss create mode 100644 frontend/projects/troll-build/src/styles/_buttons.scss create mode 100644 frontend/projects/troll-build/src/styles/_footer.scss create mode 100644 frontend/projects/troll-build/src/styles/_forms.scss create mode 100644 frontend/projects/troll-build/src/styles/_grid.scss create mode 100644 frontend/projects/troll-build/src/styles/_header.scss create mode 100644 frontend/projects/troll-build/src/styles/_layout.scss create mode 100644 frontend/projects/troll-build/src/styles/_lists.scss create mode 100644 frontend/projects/troll-build/src/styles/_message.scss create mode 100644 frontend/projects/troll-build/src/styles/_reset.scss create mode 100644 frontend/projects/troll-build/src/styles/_tags.scss create mode 100644 frontend/projects/troll-build/src/styles/_theme.scss create mode 100644 frontend/projects/troll-build/src/styles/ltb.scss diff --git a/README.adoc b/README.adoc index e919147a3..829226a42 100644 --- a/README.adoc +++ b/README.adoc @@ -15,7 +15,7 @@ the popular online game: http://leagueoflegends.com/[League of Legends]. * http://www.postgresql.org/[PostgreSQL] or https://github.com/h2database/h2database[H2] * https://github.com/flyway/flyway[Flyway] * https://github.com/ehcache[EhCache] -* https://github.com/jgthms/bulma[Bulma] +* https://github.com/akveo/nebular/[Nebular] * https://github.com/vmware/clarity/[Clarity] == Running the Backend locally diff --git a/backend/src/main/java/com/drumonii/loltrollbuild/api/BuildsRestController.java b/backend/src/main/java/com/drumonii/loltrollbuild/api/BuildsRestController.java index 606aa9dcb..3062fd7d4 100644 --- a/backend/src/main/java/com/drumonii/loltrollbuild/api/BuildsRestController.java +++ b/backend/src/main/java/com/drumonii/loltrollbuild/api/BuildsRestController.java @@ -29,7 +29,7 @@ */ @RestController @RequestMapping("${api.base-path}/builds") -@Disabled +// TODO: Restore @Disabled public class BuildsRestController { static final int PAGE_SIZE = 20; diff --git a/frontend/angular.json b/frontend/angular.json index 4fa2d1e86..9c6279099 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -173,8 +173,7 @@ "projects/troll-build/src/assets" ], "styles": [ - "projects/troll-build/src/styles.scss", - "./node_modules/font-awesome/css/font-awesome.css" + "projects/troll-build/src/styles/ltb.scss" ], "scripts": [], "deployUrl": "/troll-build/" @@ -243,7 +242,7 @@ "projects/troll-build/src/assets" ], "styles": [ - "projects/troll-build/src/styles.scss" + "projects/troll-build/src/styles/ltb.scss" ], "scripts": [] } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 723e0538d..7474628c2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -252,6 +252,23 @@ "tslib": "^1.9.0" } }, + "@angular/cdk": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-8.2.3.tgz", + "integrity": "sha512-ZwO5Sn720RA2YvBqud0JAHkZXjmjxM0yNzCO8RVtRE9i8Gl26Wk0j0nQeJkVm4zwv2QO8MwbKUKGTMt8evsokA==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^1.7.1" + }, + "dependencies": { + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "optional": true + } + } + }, "@angular/cli": { "version": "8.3.12", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-8.3.12.tgz", @@ -2270,6 +2287,19 @@ "resolved": "https://registry.npmjs.org/@clr/ui/-/ui-2.2.2.tgz", "integrity": "sha512-ES/GtraMH9OJFXbyu+CghshVyqpzVADJrBJ4QTI0nrOTGVxtxcGdGkRaDVjbR5Zxw741V7E0ysgv8b/X+QRFjg==" }, + "@nebular/eva-icons": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@nebular/eva-icons/-/eva-icons-4.5.0.tgz", + "integrity": "sha512-EhhmRjtkCL5uHGLL4PDePxy9gTm7OV7jZW3aSGd4ocxedI+TNwmQCqKEDoKK18rLFeIjPofIjHIAgPzk1Ra0Ag==" + }, + "@nebular/theme": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@nebular/theme/-/theme-4.5.0.tgz", + "integrity": "sha512-qhZyDdHeo8uzuGnDOZ2kH0rxbb2hYEPewI+svGaJyHHPHHjJROHJB2EpBRKs2qBoY4tQeuOjEyn1q/GI34y6Sw==", + "requires": { + "intersection-observer": "0.5.0" + } + }, "@ngtools/webpack": { "version": "8.3.12", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.3.12.tgz", @@ -3650,11 +3680,6 @@ "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", "dev": true }, - "bulma": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.7.5.tgz", - "integrity": "sha512-cX98TIn0I6sKba/DhW0FBjtaDpxTelU166pf7ICXpCCuplHWyu6C9LYZmL5PEsnePIeJaiorsTEzzNk3Tsm1hw==" - }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -5257,6 +5282,11 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "eva-icons": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eva-icons/-/eva-icons-1.1.2.tgz", + "integrity": "sha512-R5iD6nYcQS/qQOfC1ooP1hs8Xg+VKYfO95SXDzVWFUwYdxXrJYc7+ZnbE7tsl1amFjbRMm+c/vnH4NVaB2zrUQ==" + }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -5868,11 +5898,6 @@ } } }, - "font-awesome": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -6645,6 +6670,11 @@ "ipaddr.js": "^1.9.0" } }, + "intersection-observer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.5.0.tgz", + "integrity": "sha512-8Zgt4ijlyvIrQVTA7MPb2W9+KhoetrAbxlh0RmTGxpx0+ZsAXvy7IsbNnZIrqZ6TddAdWeQj49x7Ph7Ir6KRkA==" + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index 2a93badf3..af76cc015 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,6 +25,7 @@ "private": true, "dependencies": { "@angular/animations": "8.2.11", + "@angular/cdk": "^8.2.3", "@angular/common": "8.2.11", "@angular/compiler": "8.2.11", "@angular/core": "8.2.11", @@ -35,12 +36,13 @@ "@clr/angular": "^2.2.2", "@clr/icons": "^2.2.2", "@clr/ui": "^2.2.2", + "@nebular/eva-icons": "^4.5.0", + "@nebular/theme": "^4.5.0", "@ngx-loading-bar/core": "^4.2.0", "@ngx-loading-bar/http-client": "^4.2.0", "@webcomponents/custom-elements": "^1.3.0", - "bulma": "^0.7.5", "core-js": "^2.6.5", - "font-awesome": "^4.7.0", + "eva-icons": "^1.1.2", "rxjs": "^6.5.3", "tslib": "^1.10.0", "zone.js": "~0.9.1" diff --git a/frontend/projects/troll-build/e2e/src/builds/builds.e2e-spec.ts b/frontend/projects/troll-build/e2e/src/builds/builds.e2e-spec.ts index a92f2a498..4ce9fef4c 100644 --- a/frontend/projects/troll-build/e2e/src/builds/builds.e2e-spec.ts +++ b/frontend/projects/troll-build/e2e/src/builds/builds.e2e-spec.ts @@ -1,6 +1,6 @@ import { BuildsPage } from './builds.po'; -xdescribe('builds page', () => { +describe('builds page', () => { const page = new BuildsPage(); // ** saved build page is tested on champion spec diff --git a/frontend/projects/troll-build/e2e/src/champion/champion.e2e-spec.ts b/frontend/projects/troll-build/e2e/src/champion/champion.e2e-spec.ts index f3056f9e8..edb7df312 100644 --- a/frontend/projects/troll-build/e2e/src/champion/champion.e2e-spec.ts +++ b/frontend/projects/troll-build/e2e/src/champion/champion.e2e-spec.ts @@ -19,10 +19,10 @@ describe('champion page', () => { expect(await trollBuild.trinket().count()).toBe(1); }); - xit('should save the troll build', async () => { + it('should save the troll build', async () => { await page.saveTrollBuild(); - const savedBuildLink = await page.getSavedBuild(); + const savedBuildLink = await page.getSavedBuildInputLink().getText(); await page.navigateToBuild(savedBuildLink); expect(await page.getTitle()).toContain('Build'); }); diff --git a/frontend/projects/troll-build/e2e/src/champion/champion.po.ts b/frontend/projects/troll-build/e2e/src/champion/champion.po.ts index 5531d82ce..d73afd2a2 100644 --- a/frontend/projects/troll-build/e2e/src/champion/champion.po.ts +++ b/frontend/projects/troll-build/e2e/src/champion/champion.po.ts @@ -21,7 +21,7 @@ export class ChampionPage extends BaseTrollBuildPage { } private getMaps(): ElementFinder { - return element(by.css('#map-select')); + return element(by.css('[data-e2e="map-select"]')); } getDefaultSelectedMap(): ElementFinder { @@ -50,12 +50,11 @@ export class ChampionPage extends BaseTrollBuildPage { async saveTrollBuild(): Promise { await element(by.css('#save-build-btn')).click(); - const saveBuildInput = await element(by.css('#saved-build-input-link')); - await browser.wait(ExpectedConditions.presenceOf(saveBuildInput)); + await browser.wait(ExpectedConditions.presenceOf(this.getSavedBuildInputLink())); } - async getSavedBuild(): Promise { - return element(by.css('#saved-build-input-link')).getText(); + getSavedBuildInputLink(): ElementFinder { + return element(by.css('[data-e2e="saved-build-input-link"]')); } } diff --git a/frontend/projects/troll-build/e2e/src/champions/champions.po.ts b/frontend/projects/troll-build/e2e/src/champions/champions.po.ts index 16d93fdfd..e2be5a990 100644 --- a/frontend/projects/troll-build/e2e/src/champions/champions.po.ts +++ b/frontend/projects/troll-build/e2e/src/champions/champions.po.ts @@ -9,7 +9,7 @@ export class ChampionsPage extends BaseTrollBuildPage { } getChampions(): ElementArrayFinder { - return element.all(by.css('.champion')); + return element.all(by.css('ltb-champion-img')); } getFirstChampion(): ElementFinder { @@ -17,15 +17,15 @@ export class ChampionsPage extends BaseTrollBuildPage { } async championName(champion: ElementFinder): Promise { - return champion.element(by.css('.champion-name')).getText(); + return champion.element(by.css('[data-e2e="champion-name"]')).getText(); } getChampionTagFilters(): ElementArrayFinder { - return element.all(by.css('.champion-tag-btn')); + return element.all(by.css('[data-e2e="champion-tag-filter-btn"]')); } getChampionNameFilter(): ElementFinder { - return element(by.css('#champions-search-input')); + return element(by.css('[data-e2e="champions-search-input"]')); } } diff --git a/frontend/projects/troll-build/e2e/src/error/not-found.po.ts b/frontend/projects/troll-build/e2e/src/error/not-found.po.ts index 5f8ea7239..55189ce0b 100644 --- a/frontend/projects/troll-build/e2e/src/error/not-found.po.ts +++ b/frontend/projects/troll-build/e2e/src/error/not-found.po.ts @@ -9,15 +9,15 @@ export class NotFoundPage extends BaseTrollBuildPage { } getMsgHeader(): ElementFinder { - return element(by.css('#title')); + return element(by.css('[data-e2e="title"]')); } getMsgBody(): ElementFinder { - return element(by.css('#msg')); + return element(by.css('[data-e2e="msg"]')); } getReturnToHomeLink(): ElementFinder { - return element(by.css('#return-to-home')); + return element(by.css('[data-e2e="return-to-home"]')); } } diff --git a/frontend/projects/troll-build/e2e/src/troll-build-app.e2e-spec.ts b/frontend/projects/troll-build/e2e/src/troll-build-app.e2e-spec.ts index 6ef34e92b..80ff2f0fb 100644 --- a/frontend/projects/troll-build/e2e/src/troll-build-app.e2e-spec.ts +++ b/frontend/projects/troll-build/e2e/src/troll-build-app.e2e-spec.ts @@ -17,18 +17,14 @@ describe('troll-build-app', () => { }); it('should have body styles', async () => { - const body = element(by.css('body')); + const body = element(by.css('nb-layout .layout')); const bodyBgImageCss = await body.getCssValue('background-image'); expect(bodyBgImageCss).toContain('background.jpg'); const bodyBgRpeatCss = await body.getCssValue('background-repeat'); expect(bodyBgRpeatCss).toBe('no-repeat'); const bodyBgColorCss = await element(by.css('body')).getCssValue('background-color'); - if (bodyBgColorCss.indexOf('rgba') === -1) { - expect(bodyBgColorCss).toBe('rgb(0, 0, 0)'); - } else { // if IE - expect(bodyBgColorCss).toBe('rgba(0, 0, 0, 1)'); - } + expect(bodyBgColorCss).toBe('rgba(0, 0, 0, 0)'); }); it('should show the troll build header', async () => { diff --git a/frontend/projects/troll-build/e2e/src/troll-build-app.po.ts b/frontend/projects/troll-build/e2e/src/troll-build-app.po.ts index 22b95fc5a..69a391928 100644 --- a/frontend/projects/troll-build/e2e/src/troll-build-app.po.ts +++ b/frontend/projects/troll-build/e2e/src/troll-build-app.po.ts @@ -9,11 +9,11 @@ export class TrollBuildAppPage extends BaseTrollBuildPage { } async getHeaderText(): Promise { - return element(by.css('#header-title')).getText(); + return element(by.css('.header-title')).getText(); } getFooter(): ElementFinder { - return element(by.css('#footer')); + return element(by.css('footer')); } } diff --git a/frontend/projects/troll-build/src/app/champion/champion.module.ts b/frontend/projects/troll-build/src/app/champion/champion.module.ts index fe4002798..097c8f19b 100644 --- a/frontend/projects/troll-build/src/app/champion/champion.module.ts +++ b/frontend/projects/troll-build/src/app/champion/champion.module.ts @@ -2,20 +2,26 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; +import { NbAlertModule, NbButtonModule, NbSelectModule, NbSpinnerModule } from '@nebular/theme'; + import { ChampionRoutingModule } from './champion-routing.module'; +import { TrollBuildModule } from './troll-build.module'; import { ChampionPage } from './champion.page'; -import { TrollBuildComponent } from './troll-build.component'; import { ChampionService } from './champion.service'; @NgModule({ imports: [ CommonModule, FormsModule, - ChampionRoutingModule + NbAlertModule, + NbButtonModule, + NbSelectModule, + NbSpinnerModule, + ChampionRoutingModule, + TrollBuildModule ], declarations: [ ChampionPage, - TrollBuildComponent ], providers: [ ChampionService diff --git a/frontend/projects/troll-build/src/app/champion/champion.page.html b/frontend/projects/troll-build/src/app/champion/champion.page.html index b37318b83..5ed3a8b03 100644 --- a/frontend/projects/troll-build/src/app/champion/champion.page.html +++ b/frontend/projects/troll-build/src/app/champion/champion.page.html @@ -1,48 +1,48 @@ -
-
- -
-
+
+ +
+
+ +
{{champion.partype}}
- +
-
+ +

{{champion.name}}

-

{{champion.title}}

+

{{champion.title}}

    -
  • {{tag}}
  • +
  • {{tag}}
-
- -
+ + + {{gameMap.mapName}} + +
-
- -
+ + + Fetching maps... + +
+
+
+ +
+
-
-
-
-
-

An error has occurred while generating a Troll Build. Please try again later.

-
-
-
-
+ + An error has occurred while generating a Troll Build. Please try again later. +
@@ -70,5 +60,5 @@
-
+
diff --git a/frontend/projects/troll-build/src/app/champion/champion.page.scss b/frontend/projects/troll-build/src/app/champion/champion.page.scss index 86e14fa29..3fc367d51 100644 --- a/frontend/projects/troll-build/src/app/champion/champion.page.scss +++ b/frontend/projects/troll-build/src/app/champion/champion.page.scss @@ -1,6 +1,8 @@ +@import '~@nebular/theme/styles/global/breakpoints'; + #champion-img { + width: 100%; display: block; - width: 80%; border-radius: 5px 5px 0 0; } @@ -12,13 +14,11 @@ #champion-title { margin-bottom: 1em; font-size: 1.1em; + text-transform: capitalize; } #champion-tags { margin-bottom: 1rem; - .champion-tag { - margin-right: 0.5rem; - } } #champion-img-container { @@ -47,19 +47,14 @@ } #new-build-btn { - display: block; - width: 80%; - font-size: 1.1em; + width: 100%; border-top-left-radius: 0; border-top-right-radius: 0; + border-top: none; } -#save-build-btn { - background-color: #c28017; -} - -@media screen and (max-width: 768px) { - #champion-img, #new-build-btn { - width: 65%; +@include media-breakpoint-up(xs) { + #champion-tags { + margin-bottom: 1.75rem; } } diff --git a/frontend/projects/troll-build/src/app/champion/champion.page.spec.ts b/frontend/projects/troll-build/src/app/champion/champion.page.spec.ts index b40eb8460..80c042440 100644 --- a/frontend/projects/troll-build/src/app/champion/champion.page.spec.ts +++ b/frontend/projects/troll-build/src/app/champion/champion.page.spec.ts @@ -6,6 +6,8 @@ import { ActivatedRoute } from '@angular/router'; import { HttpHeaders, HttpResponse } from '@angular/common/http'; import { By } from '@angular/platform-browser'; +import { NbThemeModule } from '@nebular/theme'; + import { of } from 'rxjs'; import { ChampionPage } from './champion.page'; @@ -108,7 +110,7 @@ describe('ChampionPage', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [ChampionModule, FormsModule, HttpClientTestingModule, RouterTestingModule], + imports: [FormsModule, HttpClientTestingModule, RouterTestingModule, NbThemeModule.forRoot(), ChampionModule], providers: [ { provide: ActivatedRoute, @@ -898,7 +900,7 @@ describe('ChampionPage', () => { inject([ChampionService], (championService: ChampionService) => { fixture.detectChanges(); - const mapSelect = fixture.debugElement.query(By.css('#map-select')); + const mapSelect = fixture.debugElement.query(By.css('[data-e2e="map-select"]')); expect(mapSelect).toBeTruthy(); const championServiceSpy = spyOn(championService, 'getTrollBuild'); @@ -923,13 +925,13 @@ describe('ChampionPage', () => { } })); - xit('should reset the saved Build and generate a new Troll Build after clicking the new build button', + it('should reset the saved Build and generate a new Troll Build after clicking the new build button', inject([ChampionService], (championService: ChampionService) => { fixture.detectChanges(); const championServiceSpy = spyOn(championService, 'getTrollBuild'); - const mapSelect = fixture.debugElement.query(By.css('#map-select')); + const mapSelect = fixture.debugElement.query(By.css('[data-e2e="map-select"]')); expect(mapSelect).toBeTruthy(); const newBuild = fixture.debugElement.query(By.css('#new-build-btn')); @@ -968,7 +970,7 @@ describe('ChampionPage', () => { } })); - xit('should save a Troll Build with after clicking the save build button and then show its self link', + it('should save a Troll Build with after clicking the save build button and then show its self link', inject([ChampionService], (championService: ChampionService) => { fixture.detectChanges(); @@ -976,7 +978,7 @@ describe('ChampionPage', () => { const buildsServiceSpy = spyOn(championService, 'saveBuild'); const execCommandSpy = spyOn(document, 'execCommand'); - const mapSelect = fixture.debugElement.query(By.css('#map-select')); + const mapSelect = fixture.debugElement.query(By.css('[data-e2e="map-select"]')); expect(mapSelect).toBeTruthy(); for (let i = 0; i < maps.length; i++) { @@ -1064,7 +1066,7 @@ describe('ChampionPage', () => { const championPartype = fixture.debugElement.query(By.css('#champion-partype')); expect(championPartype.nativeElement.textContent).toBe(`${skarner.partype}`); - const championTags = fixture.debugElement.queryAll(By.css('.champion-tag')); + const championTags = fixture.debugElement.queryAll(By.css('#champion-tags .ltb-tag')); expect(championTags.map(championTag => championTag.nativeElement.textContent)).toEqual(skarner.tags); // New Build @@ -1073,48 +1075,51 @@ describe('ChampionPage', () => { expect(newBuildBtn.nativeElement.textContent).toBe('New Build'); // Maps - const mapsSelect = fixture.debugElement.query(By.css('#map-select')); + const mapsSelect = fixture.debugElement.query(By.css('[data-e2e="map-select"]')); expect(mapsSelect.nativeElement.selectedIndex) .toBe(maps.findIndex(map => map.mapId === selectedMap)); expect(mapsSelect.nativeElement.options[mapsSelect.nativeElement.selectedIndex].text) .toBe(maps.find(map => map.mapId === selectedMap).mapName); - const mapsOption = fixture.debugElement.queryAll(By.css('.map-option')); + const mapsOption = mapsSelect.queryAll(By.css('.ltb-option')); expect(mapsOption.map(mapOption => mapOption.nativeElement.textContent.trim())) .toEqual(maps.map(map => map.mapName)); // Troll Build - const trollBuildItemsHeader = fixture.debugElement.query(By.css('.troll-build-items-header')); + const trollBuildItemsRow = fixture.debugElement.query(By.css('#items-row')); + const trollBuildItemsHeader = trollBuildItemsRow.query(By.css('.troll-build-object-header')); expect(trollBuildItemsHeader.nativeElement.textContent).toBe('Items'); - const trollBuildItems = fixture.debugElement.queryAll(By.css('.troll-build-item')); + const trollBuildItems = trollBuildItemsRow.queryAll(By.css('.troll-build-objects > .troll-build-object')); expect(trollBuildItems.length).toBe(trollBuild.items.length); for (let i = 0; i < trollBuildItems.length; i++) { expect(trollBuildItems[i].attributes['data-tooltip']).toBe(trollBuild.items[i].name); - const trollBuildItemImg = trollBuildItems[i].query(By.css('.troll-build-item-img')); + const trollBuildItemImg = trollBuildItems[i].query(By.css('.troll-build-object-img')); expect(trollBuildItemImg.nativeElement.src).toContain(`/api/img/items/${trollBuild.items[i].id}`); } - const trollBuildSummonerSpellsHeader = fixture.debugElement.query(By.css('.troll-build-summoner-spells-header')); + const trollBuildSummonerSpellsRow = fixture.debugElement.query(By.css('#summoner-spells-and-trinket-row > #summoner-spells-row')); + const trollBuildSummonerSpellsHeader = trollBuildSummonerSpellsRow.query(By.css('.troll-build-object-header')); expect(trollBuildSummonerSpellsHeader.nativeElement.textContent).toBe('Summoner Spells'); - const trollBuildSummonerSpells = fixture.debugElement.queryAll(By.css('.troll-build-summoner-spell')); + const trollBuildSummonerSpells = trollBuildSummonerSpellsRow.queryAll(By.css('.troll-build-objects > .troll-build-object')); expect(trollBuildSummonerSpells.length).toBe(trollBuild.summonerSpells.length); for (let i = 0; i < trollBuildSummonerSpells.length; i++) { expect(trollBuildSummonerSpells[i].attributes['data-tooltip']).toBe(trollBuild.summonerSpells[i].name); - const trollBuildSummonerSpellsImg = trollBuildSummonerSpells[i].query(By.css('.troll-build-summoner-spells-img')); + const trollBuildSummonerSpellsImg = trollBuildSummonerSpells[i].query(By.css('.troll-build-object-img')); expect(trollBuildSummonerSpellsImg.nativeElement.src).toContain(`/api/img/summoner-spells/${trollBuild.summonerSpells[i].id}`); } - const trollBuildTrinketHeader = fixture.debugElement.query(By.css('.troll-build-trinket-header')); + const trollBuildTrinketRow = fixture.debugElement.query(By.css('#summoner-spells-and-trinket-row > #trinket-row')); + const trollBuildTrinketHeader = trollBuildTrinketRow.query(By.css('.troll-build-object-header')); expect(trollBuildTrinketHeader.nativeElement.textContent).toBe('Trinket'); - const trollBuildTrinket = fixture.debugElement.query(By.css('.troll-build-trinket')); + const trollBuildTrinket = trollBuildTrinketRow.query(By.css('.troll-build-objects > .troll-build-object')); expect(trollBuildTrinket).toBeTruthy(); expect(trollBuildTrinket.attributes['data-tooltip']).toBe(trollBuild.trinket.name); - const trollBuildTrinketImg = fixture.debugElement.query(By.css('.troll-build-trinket-img')); + const trollBuildTrinketImg = fixture.debugElement.query(By.css('.troll-build-object-img')); expect(trollBuildTrinketImg.nativeElement.src).toContain(`/api/img/items/${trollBuild.trinket.id}`); // Save Troll Build - // const saveBuildBtn = fixture.debugElement.query(By.css('#save-build-btn')); - // expect(saveBuildBtn.nativeElement.textContent).toBe('Save Build'); - // expect(newBuildBtn.nativeElement.disabled).toBeFalsy('Expected save build button to be enabled'); + const saveBuildBtn = fixture.debugElement.query(By.css('#save-build-btn')); + expect(saveBuildBtn.nativeElement.textContent).toBe('Save Build'); + expect(newBuildBtn.nativeElement.disabled).toBeFalsy('Expected save build button to be enabled'); } }); @@ -1139,31 +1144,34 @@ describe('ChampionPage', () => { const newBuildBtnLoading = fixture.debugElement.query(By.css('#new-build-btn')); expect(newBuildBtnLoading.classes['is-loading']).toBeTruthy(); - const trollBuildLoadingItemsHeader = fixture.debugElement.query(By.css('.troll-build-items-header')); + const trollBuildItemsRow = fixture.debugElement.query(By.css('#items-row')); + const trollBuildLoadingItemsHeader = trollBuildItemsRow.query(By.css('.troll-build-object-header')); expect(trollBuildLoadingItemsHeader.nativeElement.textContent).toBe('Items'); - const trollBuildLoadingItems = fixture.debugElement.queryAll(By.css('.troll-build-loading-item')); - expect(trollBuildLoadingItems.length).toBe(6); - const trollBuildLoadingItemsImgs = fixture.debugElement.queryAll(By.css('.troll-build-item-img')); - expect(trollBuildLoadingItemsImgs.length).toBe(6); + const trollBuildLoadingItems = trollBuildItemsRow.queryAll(By.css('.troll-build-objects > .troll-build-object')); + expect(trollBuildLoadingItems.length).toBe(6, 'count of items loading li'); + const trollBuildLoadingItemsImgs = trollBuildItemsRow.queryAll(By.css('.troll-build-object-img')); + expect(trollBuildLoadingItemsImgs.length).toBe(6, 'count of items loading img'); for (const trollBuildLoadingItemsImg of trollBuildLoadingItemsImgs) { expect(trollBuildLoadingItemsImg.nativeElement.src).toContain('assets/images/dummy_item.png'); } - const trollBuildLoadingSummonerSpellsHeader = fixture.debugElement.query(By.css('.troll-build-summoner-spells-header')); + const trollBuildSummonerSpellsRow = fixture.debugElement.query(By.css('#summoner-spells-and-trinket-row > #summoner-spells-row')); + const trollBuildLoadingSummonerSpellsHeader = trollBuildSummonerSpellsRow.query(By.css('.troll-build-object-header')); expect(trollBuildLoadingSummonerSpellsHeader.nativeElement.textContent).toBe('Summoner Spells'); - const trollBuildLoadingSummonerSpells = fixture.debugElement.queryAll(By.css('.troll-build-loading-summoner-spell')); - expect(trollBuildLoadingSummonerSpells.length).toBe(2); - const trollBuildLoadingSummonerSpellsImgs = fixture.debugElement.queryAll(By.css('.troll-build-summoner-spells-img')); - expect(trollBuildLoadingSummonerSpellsImgs.length).toBe(2); + const trollBuildLoadingSummonerSpells = trollBuildSummonerSpellsRow.queryAll(By.css('.troll-build-objects > .troll-build-object')); + expect(trollBuildLoadingSummonerSpells.length).toBe(2, 'count of summoner spells loading li'); + const trollBuildLoadingSummonerSpellsImgs = trollBuildSummonerSpellsRow.queryAll(By.css('.troll-build-object-img')); + expect(trollBuildLoadingSummonerSpellsImgs.length).toBe(2, 'count of summoner spells loading img'); for (const trollBuildLoadingSummonerSpellsImg of trollBuildLoadingSummonerSpellsImgs) { expect(trollBuildLoadingSummonerSpellsImg.nativeElement.src).toContain('assets/images/dummy_item.png'); } - const trollBuildLoadingTrinketHeader = fixture.debugElement.query(By.css('.troll-build-trinket-header')); + const trollBuildTrinketRow = fixture.debugElement.query(By.css('#summoner-spells-and-trinket-row > #trinket-row')); + const trollBuildLoadingTrinketHeader = trollBuildTrinketRow.query(By.css('.troll-build-object-header')); expect(trollBuildLoadingTrinketHeader.nativeElement.textContent).toBe('Trinket'); - const trollBuildLoadingTrinket = fixture.debugElement.query(By.css('.troll-build-loading-trinket')); + const trollBuildLoadingTrinket = trollBuildTrinketRow.query(By.css('.troll-build-objects > .troll-build-object')); expect(trollBuildLoadingTrinket).toBeTruthy(); - const trollBuildLoadingTrinketImg = fixture.debugElement.query(By.css('.troll-build-trinket-img')); + const trollBuildLoadingTrinketImg = trollBuildTrinketRow.query(By.css('.troll-build-object-img')); expect(trollBuildLoadingTrinketImg.nativeElement.src).toContain('assets/images/dummy_item.png'); const saveBuildBtn = fixture.debugElement.query(By.css('#save-build-btn')); @@ -1193,11 +1201,8 @@ describe('ChampionPage', () => { it('should show unable to generate Troll Build alert', () => { fixture.detectChanges(); - const alert = fixture.debugElement.query(By.css('#no-troll-build-alert')); - expect(alert).toBeTruthy(); - - const alertMsg = fixture.debugElement.query(By.css('#no-troll-build-alert-msg')); - expect(alertMsg.nativeElement.textContent) + const alert = fixture.debugElement.query(By.css('[data-e2e="no-troll-build-alert"]')); + expect(alert.nativeElement.textContent) .toBe('An error has occurred while generating a Troll Build. Please try again later.'); }); @@ -1220,12 +1225,7 @@ describe('ChampionPage', () => { it('should should game maps select with single loading option', () => { fixture.detectChanges(); - const mapSelectLoading = fixture.debugElement.query(By.css('#map-select-loading')); - expect(mapSelectLoading).toBeTruthy(); - - const mapsOption = fixture.debugElement.queryAll(By.css('.map-option-loading')); - expect(mapsOption.map(mapOption => mapOption.nativeElement.textContent.trim())) - .toEqual(jasmine.arrayContaining(['Fetching maps...'])); + expect(fixture.debugElement.query(By.css('[data-e2e="map-select-loading"]'))).toBeTruthy(); }); }); diff --git a/frontend/projects/troll-build/src/app/champion/champion.page.ts b/frontend/projects/troll-build/src/app/champion/champion.page.ts index 0a613fddc..299ef2b64 100644 --- a/frontend/projects/troll-build/src/app/champion/champion.page.ts +++ b/frontend/projects/troll-build/src/app/champion/champion.page.ts @@ -24,10 +24,10 @@ export class ChampionPage implements OnInit, OnDestroy { champion: Champion; trollBuild$: Observable; - trollBuildLoading: boolean; + trollBuildLoading = true; build: Build; - buildSaving: boolean; + buildSaving = false; private subscriptions = new Subscription(); diff --git a/frontend/projects/troll-build/src/app/champion/champion.service.ts b/frontend/projects/troll-build/src/app/champion/champion.service.ts index 631d8fcac..f62f0a982 100644 --- a/frontend/projects/troll-build/src/app/champion/champion.service.ts +++ b/frontend/projects/troll-build/src/app/champion/champion.service.ts @@ -9,8 +9,6 @@ import { Champion } from '@ltb-model/champion'; import { TrollBuild } from '@ltb-model/troll-build'; import { GameMap } from '@ltb-model/game-map'; import { Build } from '@ltb-model/build'; -import { Item } from '@ltb-model/item'; -import { SummonerSpell } from '@ltb-model/summoner-spell'; @Injectable() export class ChampionService { diff --git a/frontend/projects/troll-build/src/app/champion/troll-build.component.html b/frontend/projects/troll-build/src/app/champion/troll-build.component.html index e8454fd03..fb4419e6a 100644 --- a/frontend/projects/troll-build/src/app/champion/troll-build.component.html +++ b/frontend/projects/troll-build/src/app/champion/troll-build.component.html @@ -1,103 +1,91 @@ -
-
-

Items

-
    +
    +
    +

    Items

    +
      -
    • - +
    • +
    • -
    • - item loading +
    • + item loading
    -
    -
    -

    Summoner Spells

    -
      +
      + +
      +

      Summoner Spells

      +
        -
      • - +
      • +
      • -
      • - summoner spell loading +
      • + summoner spell loading
      -
      -

      Trinket

      -
        + +
        +

        Trinket

        +
          -
        • - +
        • +
        • -
        • - trinket loading +
        • + trinket loading
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +
      +
      + +
      +
      + +
      + +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      diff --git a/frontend/projects/troll-build/src/app/champion/troll-build.component.scss b/frontend/projects/troll-build/src/app/champion/troll-build.component.scss index a3a855f00..9ab334ec8 100644 --- a/frontend/projects/troll-build/src/app/champion/troll-build.component.scss +++ b/frontend/projects/troll-build/src/app/champion/troll-build.component.scss @@ -1,62 +1,31 @@ -.troll-build-item-img, .troll-build-summoner-spells-img, .troll-build-trinket-img { +@import '~@nebular/theme/styles/global/breakpoints'; + +.troll-build-object-img { border-radius: 5px; + margin: 0.25em; width: 75px; + height: 75px; } -.troll-build-items-header, .troll-build-summoner-spells-header, .troll-build-trinket-header { +.troll-build-objects-header { font-size: 1.3em; margin-bottom: 0.5em; } -.troll-build-objects { - list-style: none; - .troll-build-object { - display: inline-block; - margin-left: 1em; - &:first-child { - margin-left: 0; - } +#summoner-spells-and-trinket-row { + justify-content: space-between; + .ltb-column { + flex: none; } } -.with-tooltip { - position: relative; - cursor: pointer; - &:before, &:after { - transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out, transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24); - } - &:before { - content: ""; - position: absolute; - top: -6px; - left: 50%; - transform: translateX(-50%); - z-index: 99; - opacity: 0; - } - &:after { - content: attr(data-tooltip); - position: absolute; - left: 50%; - top: -6px; - transform: translateX(-50%) translateY(-100%); - background: black; - text-align: center; - color: white; - font-size: 0.9em; - min-width: 100px; - border-radius: 5px; - pointer-events: none; - padding: 4px 4px; - z-index: 99; - opacity: 0; - } - &:hover { - &:after { - opacity: 1; - } - &:before { - opacity: 1; - } +@include media-breakpoint-down(sm) { + + $img-size: 55px; + + .troll-build-object-img { + width: $img-size; + height: $img-size; } + } diff --git a/frontend/projects/troll-build/src/app/champion/troll-build.module.ts b/frontend/projects/troll-build/src/app/champion/troll-build.module.ts new file mode 100644 index 000000000..6b0cabf07 --- /dev/null +++ b/frontend/projects/troll-build/src/app/champion/troll-build.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { NbButtonModule, NbIconModule, NbInputModule, NbSpinnerModule, NbTooltipModule } from '@nebular/theme'; + +import { TrollBuildComponent } from './troll-build.component'; + +@NgModule({ + imports: [ + CommonModule, + NbButtonModule, + NbIconModule, + NbInputModule, + NbSpinnerModule, + NbTooltipModule + ], + declarations: [ + TrollBuildComponent + ], + exports: [ + TrollBuildComponent + ] +}) +export class TrollBuildModule { } diff --git a/frontend/projects/troll-build/src/app/champions/champion-img.component.html b/frontend/projects/troll-build/src/app/champions/champion-img.component.html new file mode 100644 index 000000000..5ae6c446c --- /dev/null +++ b/frontend/projects/troll-build/src/app/champions/champion-img.component.html @@ -0,0 +1,5 @@ + +

      {{champion.name}}

      + +
      diff --git a/frontend/projects/troll-build/src/app/champions/champion.component.scss b/frontend/projects/troll-build/src/app/champions/champion-img.component.scss similarity index 63% rename from frontend/projects/troll-build/src/app/champions/champion.component.scss rename to frontend/projects/troll-build/src/app/champions/champion-img.component.scss index 7ea39babb..25362b1ab 100644 --- a/frontend/projects/troll-build/src/app/champions/champion.component.scss +++ b/frontend/projects/troll-build/src/app/champions/champion-img.component.scss @@ -1,10 +1,17 @@ -.champion-column { +:host { padding: 0.5rem; - text-align: center; + &:hover { + transform: translateY(-3px); + } } .champion-name { - color: white; + margin: 0; + text-align: center; +} + +.champion-link { + text-decoration: none; } .champion-img { diff --git a/frontend/projects/troll-build/src/app/champions/champion.component.spec.ts b/frontend/projects/troll-build/src/app/champions/champion-img.component.spec.ts similarity index 68% rename from frontend/projects/troll-build/src/app/champions/champion.component.spec.ts rename to frontend/projects/troll-build/src/app/champions/champion-img.component.spec.ts index 599859e3d..8b02c8223 100644 --- a/frontend/projects/troll-build/src/app/champions/champion.component.spec.ts +++ b/frontend/projects/troll-build/src/app/champions/champion-img.component.spec.ts @@ -3,13 +3,14 @@ import { RouterTestingModule } from '@angular/router/testing'; import { RouterLinkWithHref } from '@angular/router'; import { By } from '@angular/platform-browser'; -import { ChampionComponent } from './champion.component'; +import { ChampionImgModule } from './champion-img.module'; +import { ChampionImgComponent } from './champion-img.component'; import { Champion } from '@ltb-model/champion'; import { LazyLoadImgDirective } from '@ltb-directive/lazy-load-img.directive'; -describe('ChampionComponent', () => { - let component: ChampionComponent; - let fixture: ComponentFixture; +describe('ChampionImgComponent', () => { + let component: ChampionImgComponent; + let fixture: ComponentFixture; const alistar: Champion = { id: 12, @@ -37,14 +38,13 @@ describe('ChampionComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule], - declarations: [ChampionComponent, LazyLoadImgDirective] + imports: [RouterTestingModule, ChampionImgModule] }) .compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(ChampionComponent); + fixture = TestBed.createComponent(ChampionImgComponent); component = fixture.componentInstance; component.champion = alistar; @@ -53,16 +53,16 @@ describe('ChampionComponent', () => { }); it('should show the Champion', () => { - const championLink = fixture.debugElement.query(By.css('.champion-link')); + const championLink = fixture.debugElement.query(By.css('[data-e2e="champion-link"]')); const championRouterLink = championLink.injector.get(RouterLinkWithHref); expect(championRouterLink.href).toBe(`/champions/${alistar.key}`); - const championName = fixture.debugElement.query(By.css('.champion-name')); + const championName = fixture.debugElement.query(By.css('[data-e2e="champion-name"]')); expect(championName.nativeElement.textContent).toBe(alistar.name); - const championImg = fixture.debugElement.query(By.css('.champion-img')); + const championImg = fixture.debugElement.query(By.css('[data-e2e="champion-img"]')); expect(championImg.injector.get(LazyLoadImgDirective)).toBeTruthy(); expect(championImg.nativeElement.src).toContain('assets/images/dummy_champion.png'); - expect(championImg.attributes['ng-reflect-data-src']).toBe(`/api/img/champions/${alistar.id}`); + expect(championImg.attributes['ng-reflect-img-src']).toBe(`/api/img/champions/${alistar.id}`); }); }); diff --git a/frontend/projects/troll-build/src/app/champions/champion.component.ts b/frontend/projects/troll-build/src/app/champions/champion-img.component.ts similarity index 60% rename from frontend/projects/troll-build/src/app/champions/champion.component.ts rename to frontend/projects/troll-build/src/app/champions/champion-img.component.ts index 4992dc984..ab873a011 100644 --- a/frontend/projects/troll-build/src/app/champions/champion.component.ts +++ b/frontend/projects/troll-build/src/app/champions/champion-img.component.ts @@ -3,12 +3,12 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core import { Champion } from '@ltb-model/champion'; @Component({ - selector: 'ltb-champion', - templateUrl: './champion.component.html', - styleUrls: ['./champion.component.scss'], + selector: 'ltb-champion-img', + templateUrl: './champion-img.component.html', + styleUrls: ['./champion-img.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class ChampionComponent implements OnInit { +export class ChampionImgComponent implements OnInit { @Input() champion: Champion; diff --git a/frontend/projects/troll-build/src/app/champions/champion-img.module.ts b/frontend/projects/troll-build/src/app/champions/champion-img.module.ts new file mode 100644 index 000000000..9bf46ddcd --- /dev/null +++ b/frontend/projects/troll-build/src/app/champions/champion-img.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; + +import { ChampionImgComponent } from './champion-img.component'; +import { LazyLoadImgModule } from '@ltb-directive/lazy-load-img.module'; + +@NgModule({ + imports: [ + CommonModule, + RouterModule, + LazyLoadImgModule + ], + declarations: [ + ChampionImgComponent + ], + exports: [ + ChampionImgComponent + ] +}) +export class ChampionImgModule { } diff --git a/frontend/projects/troll-build/src/app/champions/champion.component.html b/frontend/projects/troll-build/src/app/champions/champion.component.html deleted file mode 100644 index 7e972098a..000000000 --- a/frontend/projects/troll-build/src/app/champions/champion.component.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/frontend/projects/troll-build/src/app/champions/champions.module.ts b/frontend/projects/troll-build/src/app/champions/champions.module.ts index 30abf896d..34afe8334 100644 --- a/frontend/projects/troll-build/src/app/champions/champions.module.ts +++ b/frontend/projects/troll-build/src/app/champions/champions.module.ts @@ -2,27 +2,30 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; +import { NbAlertModule, NbButtonModule, NbIconModule, NbInputModule } from '@nebular/theme'; + import { ChampionsRoutingModule } from './champions-routing.module'; +import { ChampionImgModule } from './champion-img.module'; import { ChampionsNameFilterPipe } from './champions-name-filter.pipe'; import { ChampionsTagsFilterPipe } from './champions-tags-filter.pipe'; import { ChampionsPage } from './champions.page'; import { ChampionsService } from './champions.service'; -import { ChampionComponent } from './champion.component'; - -import { LazyLoadImgModule } from '@ltb-directive/lazy-load-img.module'; @NgModule({ imports: [ CommonModule, FormsModule, + NbAlertModule, + NbButtonModule, + NbIconModule, + NbInputModule, ChampionsRoutingModule, - LazyLoadImgModule + ChampionImgModule ], declarations: [ ChampionsNameFilterPipe, ChampionsTagsFilterPipe, - ChampionsPage, - ChampionComponent + ChampionsPage ], providers: [ ChampionsService diff --git a/frontend/projects/troll-build/src/app/champions/champions.page.html b/frontend/projects/troll-build/src/app/champions/champions.page.html index 412a7ff0d..c72cc9d72 100644 --- a/frontend/projects/troll-build/src/app/champions/champions.page.html +++ b/frontend/projects/troll-build/src/app/champions/champions.page.html @@ -1,43 +1,35 @@ -
      -
      - -
      -
      -

      - - - - -

      -
      -
      - -
      - - {{tag}} - -
      - -
      -
      - -
      -
      -
      + +
      +
      + + +
      +
      +
      +
      + +
      +
      - -
      -
      -

      No Champions exist in the database!

      -
      -
      -
      +
      + +
      -
      +
      + + + + + No Champions exist in the database! This may be an application issue, which if it is, the administrator is likely working to fix it. + + + diff --git a/frontend/projects/troll-build/src/app/champions/champions.page.scss b/frontend/projects/troll-build/src/app/champions/champions.page.scss index 510f95829..00ffd6b78 100644 --- a/frontend/projects/troll-build/src/app/champions/champions.page.scss +++ b/frontend/projects/troll-build/src/app/champions/champions.page.scss @@ -1,5 +1,17 @@ -.champion { - &:hover { - transform: translateY(-3px); +#champions-container { + flex-wrap: wrap; + flex-direction: row; + justify-content: center; +} + +#search-container, #filter-container { + display: flex; + justify-content: center; + margin-bottom: 1em; +} + +.ltb-input-addon { + > .ltb-input { + border-radius: 290486px; } } diff --git a/frontend/projects/troll-build/src/app/champions/champions.page.spec.ts b/frontend/projects/troll-build/src/app/champions/champions.page.spec.ts index 2e95a6728..5a557d886 100644 --- a/frontend/projects/troll-build/src/app/champions/champions.page.spec.ts +++ b/frontend/projects/troll-build/src/app/champions/champions.page.spec.ts @@ -3,11 +3,13 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { By } from '@angular/platform-browser'; +import { NbEvaIconsModule } from '@nebular/eva-icons'; + import { of } from 'rxjs'; import { ChampionsPage } from './champions.page'; import { ChampionsModule } from './champions.module'; -import { ChampionComponent } from './champion.component'; +import { ChampionImgComponent } from './champion-img.component'; import { ChampionsService } from './champions.service'; import { Champion } from '@ltb-model/champion'; import { TitleService } from '@ltb-service/title.service'; @@ -18,7 +20,7 @@ describe('ChampionsPage', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [ChampionsModule, HttpClientTestingModule, RouterTestingModule], + imports: [HttpClientTestingModule, RouterTestingModule, NbEvaIconsModule, ChampionsModule], }) .compileComponents(); })); @@ -83,71 +85,61 @@ describe('ChampionsPage', () => { const tags = ['Assassin', 'Fighter', 'Mage', 'Marksman', 'Support', 'Tank']; - beforeEach(inject([ChampionsService], (championsService: ChampionsService) => { + beforeEach(inject([ChampionsService, TitleService], (championsService: ChampionsService, title: TitleService) => { + spyOn(title, 'resetTitle'); spyOn(championsService, 'getChampions').and.returnValue(of(champions)); spyOn(championsService, 'getChampionTags').and.returnValue(of(tags)); + + fixture.detectChanges(); })); - afterEach(inject([ChampionsService], (championsService: ChampionsService) => { + afterEach(inject([ChampionsService, TitleService], (championsService: ChampionsService, title: TitleService) => { expect(championsService.getChampions).toHaveBeenCalled(); expect(championsService.getChampionTags).toHaveBeenCalled(); + expect(title.resetTitle).toHaveBeenCalled(); })); - it('should reset the title', inject([TitleService], (title: TitleService) => { - spyOn(title, 'resetTitle').and.callThrough(); - - fixture.detectChanges(); + it('should show champions and tags', () => { + const championsSearch = fixture.debugElement.query(By.css('[data-e2e="champions-search-input"]')); + expect(championsSearch.nativeElement.placeholder).toBe('Search by Champion'); - expectChampionAndTags(); + const championTags = fixture.debugElement.queryAll(By.css('.ltb-btn-group button.ltb-btn')); + expect(championTags.map(championTag => championTag.nativeElement.textContent.trim())).toEqual(tags); - expect(title.resetTitle).toHaveBeenCalledWith(); - })); + expect(fixture.debugElement.queryAll(By.directive(ChampionImgComponent)).length).toBe(champions.length); + }); it('should filter Champions with clicking a tag', () => { - fixture.detectChanges(); - - expectChampionAndTags(); - const tagToFilter = 'Mage'; const tagToFilterIndex = tags.findIndex(tag => tag === tagToFilter); - const championTags = fixture.debugElement.queryAll(By.css('.champion-tag-btn')); + const championTags = fixture.debugElement.queryAll(By.css('.ltb-btn-group button.ltb-btn')); championTags[tagToFilterIndex].triggerEventHandler('click', null); fixture.detectChanges(); expect(component.championsFilterTag).toBe(tagToFilter); - const championBoxes = fixture.debugElement.queryAll(By.css('.champion')); - expect(championBoxes.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(ChampionImgComponent)).length).toBe(1); }); it('should reset the Champions filter with re-clicking the same tag', () => { - fixture.detectChanges(); - - expectChampionAndTags(); - const tagToFilter = 'Fighter'; const tagToFilterIndex = tags.findIndex(tag => tag === tagToFilter); component.championsFilterTag = tagToFilter; - const championTags = fixture.debugElement.queryAll(By.css('.champion-tag-btn')); + const championTags = fixture.debugElement.queryAll(By.css('.ltb-btn-group button.ltb-btn')); championTags[tagToFilterIndex].triggerEventHandler('click', null); fixture.detectChanges(); expect(component.championsFilterTag).toBe(''); - const championCards = fixture.debugElement.queryAll(By.css('.champion')); - expect(championCards.length).toBe(champions.length); + expect(fixture.debugElement.queryAll(By.directive(ChampionImgComponent)).length).toBe(champions.length); }); it('should filter Champions with search input', () => { - fixture.detectChanges(); - - expectChampionAndTags(); - - const championsSearch = fixture.debugElement.query(By.css('#champions-search-input')); + const championsSearch = fixture.debugElement.query(By.css('[data-e2e="champions-search-input"]')); championsSearch.nativeElement.value = 'maokai'; const inputEvent = document.createEvent('Event'); inputEvent.initEvent('input', false, false); @@ -155,24 +147,9 @@ describe('ChampionsPage', () => { fixture.detectChanges(); - const championBoxes = fixture.debugElement.queryAll(By.css('.champion')); - expect(championBoxes.length).toBe(1); + expect(fixture.debugElement.queryAll(By.directive(ChampionImgComponent)).length).toBe(1); }); - function expectChampionAndTags() { - const championsSearch = fixture.debugElement.query(By.css('#champions-search-input')); - expect(championsSearch.nativeElement.placeholder).toBe('Search by Champion'); - - const championTags = fixture.debugElement.queryAll(By.css('.champion-tag-btn')); - expect(championTags.map(championTag => championTag.nativeElement.textContent.trim())).toEqual(tags); - - const championBoxes = fixture.debugElement.queryAll(By.css('.champion')); - expect(championBoxes.length).toBe(champions.length); - - expect(fixture.debugElement.queryAll(By.directive(ChampionComponent)).length).toBe(champions.length); - - } - }); describe('with no Champions nor Champion tags', () => { @@ -180,6 +157,8 @@ describe('ChampionsPage', () => { beforeEach(inject([ChampionsService], (championsService: ChampionsService) => { spyOn(championsService, 'getChampions').and.returnValue(of([])); spyOn(championsService, 'getChampionTags').and.returnValue(of([])); + + fixture.detectChanges(); })); afterEach(inject([ChampionsService], (championsService: ChampionsService) => { @@ -188,15 +167,9 @@ describe('ChampionsPage', () => { })); it('should show the no Champions alert', () => { - fixture.detectChanges(); - - const alert = fixture.debugElement.query(By.css('#no-champions-alert')); - expect(alert).toBeTruthy(); - - const alertMsg = fixture.debugElement.query(By.css('#no-champions-alert-msg')); - expect(alertMsg.nativeElement.textContent).toBe('No Champions exist in the database!'); + const alert = fixture.debugElement.query(By.css('[data-e2e="no-champions-alert"]')); + expect(alert.nativeElement.textContent).toContain('No Champions exist in the database!'); }); }); - }); diff --git a/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.spec.ts b/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.spec.ts index bf2021846..5b01297e1 100644 --- a/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.spec.ts +++ b/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.spec.ts @@ -5,7 +5,7 @@ import { By } from '@angular/platform-browser'; import { LazyLoadImgModule } from './lazy-load-img.module'; @Component({ - template: `` + template: `` }) class TestLazyLoadImgComponent { } @@ -43,7 +43,7 @@ describe('LazyLoadImgDirective', () => { if (supportsIntersectionObserver) { expect(IntersectionObserver.prototype.observe).toHaveBeenCalled(); } else { - expect(img.nativeElement.src).toContain('dataSrc.png'); + expect(img.nativeElement.src).toContain('imgSrc.png'); } }); diff --git a/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.ts b/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.ts index 3904253f3..d61d8ac85 100644 --- a/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.ts +++ b/frontend/projects/troll-build/src/app/directive/lazy-load-img.directive.ts @@ -5,7 +5,7 @@ import { AfterViewInit, Directive, ElementRef, Input } from '@angular/core'; }) export class LazyLoadImgDirective implements AfterViewInit { - @Input() dataSrc: string; + @Input() imgSrc: string; constructor(private elementRef: ElementRef) {} @@ -32,7 +32,7 @@ export class LazyLoadImgDirective implements AfterViewInit { } private loadImage() { - this.elementRef.nativeElement.src = this.dataSrc; + this.elementRef.nativeElement.src = this.imgSrc; } } diff --git a/frontend/projects/troll-build/src/app/error/not-found.module.ts b/frontend/projects/troll-build/src/app/error/not-found.module.ts index ae9cd1611..fd1764b22 100644 --- a/frontend/projects/troll-build/src/app/error/not-found.module.ts +++ b/frontend/projects/troll-build/src/app/error/not-found.module.ts @@ -1,12 +1,15 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { NbIconModule } from '@nebular/theme'; + import { NotFoundRoutingModule } from './not-found-routing.module'; import { NotFoundPage } from './not-found.page'; @NgModule({ imports: [ CommonModule, + NbIconModule, NotFoundRoutingModule ], declarations: [ diff --git a/frontend/projects/troll-build/src/app/error/not-found.page.html b/frontend/projects/troll-build/src/app/error/not-found.page.html index fabb5fc2a..a07776055 100644 --- a/frontend/projects/troll-build/src/app/error/not-found.page.html +++ b/frontend/projects/troll-build/src/app/error/not-found.page.html @@ -1,16 +1,12 @@ -
      -
      -
      -
      -

      Page Not Found

      -
      -
      -

      The page you requested was not found. Please double check the URL and try again.

      -
      - - Return to home - -
      -
      +
      +
      +
      Page Not Found
      -
      +
      +

      The page you requested was not found. Please double check the URL and try again.

      +
      + + Return to home + +
      +
      diff --git a/frontend/projects/troll-build/src/app/error/not-found.page.spec.ts b/frontend/projects/troll-build/src/app/error/not-found.page.spec.ts index c778f8194..76ef60fff 100644 --- a/frontend/projects/troll-build/src/app/error/not-found.page.spec.ts +++ b/frontend/projects/troll-build/src/app/error/not-found.page.spec.ts @@ -1,6 +1,8 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; +import { NbEvaIconsModule } from '@nebular/eva-icons'; + import { NotFoundPage } from './not-found.page'; import { NotFoundModule } from './not-found.module'; @@ -10,7 +12,7 @@ describe('NotFoundPage', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [NotFoundModule, RouterTestingModule] + imports: [RouterTestingModule, NbEvaIconsModule, NotFoundModule] }) .compileComponents(); })); diff --git a/frontend/projects/troll-build/src/app/layout/footer/footer.component.html b/frontend/projects/troll-build/src/app/layout/footer/footer.component.html index 778a7084a..80c458247 100644 --- a/frontend/projects/troll-build/src/app/layout/footer/footer.component.html +++ b/frontend/projects/troll-build/src/app/layout/footer/footer.component.html @@ -1,30 +1,20 @@ -