diff --git a/static/package-lock.json b/static/package-lock.json index be6f92f..080b1cb 100644 --- a/static/package-lock.json +++ b/static/package-lock.json @@ -644,11 +644,6 @@ } } }, - "@swimlane/ngx-datatable": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-13.0.1.tgz", - "integrity": "sha512-jjMEzQhXcdD+jfKNp+7U61lWx9ZzSGDn9QbpY6pJOJwz+E2CKeek6OouT5Qcc4MY4oFL9g/SZoPjLf90cbNIRw==" - }, "@types/jasmine": { "version": "2.5.38", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.38.tgz", diff --git a/static/package.json b/static/package.json index 2b19f03..9eacace 100644 --- a/static/package.json +++ b/static/package.json @@ -29,7 +29,6 @@ "@angular/platform-browser-dynamic": "^6.0.7", "@angular/router": "^6.0.7", "@swimlane/ngx-charts": "^8.1.0", - "@swimlane/ngx-datatable": "^13.0.1", "bootstrap": "^3.3.7", "d3": "^4.11.0", "file-saver": "^1.3.8", diff --git a/static/src/app/app.component.ts b/static/src/app/app.component.ts index 8149986..5e2b202 100644 --- a/static/src/app/app.component.ts +++ b/static/src/app/app.component.ts @@ -42,6 +42,8 @@ export class AppComponent implements OnInit { sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/twotone-edit-24px.svg')); this.iconRegistry.addSvgIcon('delete', sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/twotone-delete-24px.svg')); + this.iconRegistry.addSvgIcon('stats-detail', + sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/round-assessment-24px.svg')); router.events.subscribe(event => { if (event instanceof NavigationStart) { diff --git a/static/src/app/statistic/campaign/highscore/highscore.component.css b/static/src/app/statistic/campaign/highscore/highscore.component.css index da5284b..ddd70e2 100644 --- a/static/src/app/statistic/campaign/highscore/highscore.component.css +++ b/static/src/app/statistic/campaign/highscore/highscore.component.css @@ -11,71 +11,53 @@ h2 { margin: 20px 0 0 10%; } -ngx-datatable { - width: 345px; - margin: 3% 5% 0 5%; - height: 310px; +.highscore-table-container { + width: 320px; + max-height: 394px; + margin: 100px 0 0 8%; float: left; - border: solid #dfdfdf 1px; - border-radius: 10px 10px 2px 2px; -} - -:host /deep/ .datatable-header { - width: 350px !important; - background: #222222; - font-weight: 700; - border-radius: 10px 10px 0 0; - color: white; -} - -:host /deep/ span.datatable-header-cell-label, :host /deep/ div.datatable-body-cell-label { - padding-left: 8px; -} - -:host /deep/ .ngx-datatable .datatable-header { - /*vertical center alignment*/ - display: table-cell; - vertical-align: middle; -} - -:host /deep/ .ngx-datatable .datatable-body .datatable-body-row > div { - /*vertical alignment*/ - position: relative; - top: 10px; -} - -:host /deep/ .datatable-body { overflow-x: hidden; + overflow-y: auto; + border: solid #dfdfdf 1px; + box-shadow: 3px 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12); } -:host /deep/ .datatable-body-row { - color: #222222; - border-bottom: 1px solid grey; +.highscore-table { + width: 100%; } -:host /deep/ .datatable-body-row:hover { - background-color: #f7f7f7; +table.mat-table img { + filter: invert(60%); + margin-left: -15px; } -:host /deep/ .ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell { - margin: auto; +:host /deep/ table.mat-table > thead { + position: absolute; + width: 320px; + display: inherit; + margin-left: -1px; + margin-top: -57px; + border: 1px solid #dadada; +} + +.mat-column-kill, .mat-column-friendlyFire, .mat-column-revive, .mat-column-flagTouch, +.mat-column-vehicleLight, .mat-column-vehicleHeavy, .mat-column-vehicleAir, .mat-column-death, .mat-column-respawn { + width: 67px; + text-indent: 14px; } /* Table Scrollbar BEGIN */ -:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar { +.highscore-table-container::-webkit-scrollbar { width: 12px; } -:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); - border-radius: 10px; +.highscore-table-container::-webkit-scrollbar-track { + border-left: 1px solid #f1f1f1; } -:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-thumb { - border-radius: 10px; - background: #4b4b4b; - -webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.5); +.highscore-table-container::-webkit-scrollbar-thumb { + background: rgb(234, 234, 234); } /* Table Scrollbar END */ diff --git a/static/src/app/statistic/campaign/highscore/highscore.component.html b/static/src/app/statistic/campaign/highscore/highscore.component.html index 111068f..5829dd6 100644 --- a/static/src/app/statistic/campaign/highscore/highscore.component.html +++ b/static/src/app/statistic/campaign/highscore/highscore.component.html @@ -3,6 +3,7 @@
- - - - - - {{value}} - - - +
+ - - - - - {{attributeMap.head}} - - - - - - {{value}} - - - - + + + + + + + + + + + + + + + + + +
#{{element.num}}Name + {{element.name}} + + {{attributeMap.head}} + {{element[attributeMap.prop]}}
+
-
diff --git a/static/src/app/statistic/campaign/highscore/highscore.component.ts b/static/src/app/statistic/campaign/highscore/highscore.component.ts index 1954314..55f866e 100644 --- a/static/src/app/statistic/campaign/highscore/highscore.component.ts +++ b/static/src/app/statistic/campaign/highscore/highscore.component.ts @@ -30,21 +30,6 @@ export class StatisticHighScoreComponent implements OnInit { playerAttributeDisplayNames = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length); - cellHeight = 40; - - numberColWidth = 60; - - nameColWidth = 210; - - valueColWidth = 55; - - emptyMessage = {emptyMessage: 'Keine Einträge'}; - - customClasses = { - sortAscending: 'glyphicon glyphicon-triangle-top', - sortDescending: 'glyphicon glyphicon-triangle-bottom', - }; - readonly fraction = Fraction; constructor(private route: ActivatedRoute, @@ -97,7 +82,6 @@ export class StatisticHighScoreComponent implements OnInit { private filterPlayerAttribute(attribute) { const query = this.searchTerm.value.toLowerCase().split('&'); - return this.playersStored[attribute].filter(player => { for (let i = 0; i < query.length; i++) { if (query[i].trim() !== '' && player.name.toLowerCase().includes(query[i].trim())) { @@ -107,5 +91,4 @@ export class StatisticHighScoreComponent implements OnInit { return false; }); } - } diff --git a/static/src/app/statistic/stats.module.ts b/static/src/app/statistic/stats.module.ts index f3a40fc..f882acd 100644 --- a/static/src/app/statistic/stats.module.ts +++ b/static/src/app/statistic/stats.module.ts @@ -5,15 +5,15 @@ import {statsRouterModule, statsRoutingComponents} from './stats.routing'; import {WarService} from '../services/logs/war.service'; import {NgxChartsModule} from '@swimlane/ngx-charts'; import {CampaignService} from '../services/logs/campaign.service'; -import {NgxDatatableModule} from '@swimlane/ngx-datatable'; import {PlayerService} from '../services/logs/player.service'; import {LogsService} from '../services/logs/logs.service'; -import {MatButtonModule, MatButtonToggleModule, MatExpansionModule} from '@angular/material'; +import {MatButtonModule, MatButtonToggleModule, MatExpansionModule, MatTableModule, MatSortModule} from '@angular/material'; + @NgModule({ declarations: statsRoutingComponents, - imports: [CommonModule, SharedModule, statsRouterModule, NgxChartsModule, NgxDatatableModule, - MatButtonModule, MatExpansionModule, MatButtonToggleModule], + imports: [CommonModule, SharedModule, statsRouterModule, NgxChartsModule, MatButtonModule, MatExpansionModule, + MatButtonToggleModule, MatTableModule, MatSortModule], providers: [WarService, CampaignService, PlayerService, LogsService] }) export class StatsModule { diff --git a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.css b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.css index 98f5a74..8b96911 100644 --- a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.css +++ b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.css @@ -1,32 +1,30 @@ .chart-select-group { display: flex; - width: 945px; + width: fit-content; margin: auto; } -.chart-select-group > mat-button-toggle { - background: #4b4b4b; - color: #f5f5f5; - border: 1px solid #000; +:host /deep/ mat-button-toggle { + color: #666666; + background: #e7e7e7; } -.chart-select-group > mat-button-toggle:hover { +:host /deep/ mat-button-toggle:hover { background: #afafaf; - color: #f5f5f5; } -mat-button-toggle.mat-button-toggle-checked { - background: #222222 !important; +:host /deep/ mat-button-toggle.mat-button-toggle-checked { + background: #ffffff; } :host /deep/ label.mat-button-toggle-label { - margin: 2px 0 !important; + margin: 2px 0; } :host /deep/ div.mat-button-toggle-label-content { - line-height: 25px !important; - margin-bottom: 0 !important; - font-weight: normal !important; + line-height: 25px; + margin-bottom: 0; + font-weight: normal; } .chart-container { diff --git a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html index 94f8719..9806126 100644 --- a/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html +++ b/static/src/app/statistic/war/fraction-stats/fraction-stats.component.html @@ -1,4 +1,4 @@ -
+
div { - /*vertical alignment*/ - position: relative; - top: 10px; -} - -:host /deep/ .datatable-body-row { - color: #222222; - border-bottom: 1px solid grey; -} - -:host /deep/ .datatable-body-row:hover { - background-color: #f7f7f7; -} - -:host /deep/ .ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell { - margin: auto; -} - -/* Table Scrollbar BEGIN */ -:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar { - width: 12px; -} - -:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); - border-radius: 10px; -} - -:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-thumb { - border-radius: 10px; - background: #4b4b4b; - -webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.5); -} - -/* Table Scrollbar END */ - .in-table-btn { position: absolute; margin-top: -5px; } + +/* MATERIAL TABLE */ +table.mat-table { + margin: auto; +} + +table.mat-table img { + filter: invert(60%); +} + +:host /deep/ table.mat-table > thead { + position: absolute; + display: inherit; +} + +:host /deep/ table.mat-table > tbody { + margin-top: 60px; + display: block; +} + +.mat-column-name { + width: 200px; +} +.mat-column-fraction { + width: 90px; +} + +.mat-column-kill, .mat-column-friendlyFire, .mat-column-revive, .mat-column-flagTouch, +.mat-column-vehicleLight, .mat-column-vehicleHeavy, .mat-column-vehicleAir, .mat-column-death, .mat-column-respawn { + width: 67px; + text-indent: 9px; +} + +th.mat-column-interact { + padding-left: 36px; + background: white; + position: relative; + z-index: 100; +} + +/* TABLE SCROLLBAR */ +div::-webkit-scrollbar-thumb { + border-top: solid white 56px; +} + +/* MAT ICON BUTTON */ + +:host/deep/.mat-table .mat-icon { + color: #666666; +} diff --git a/static/src/app/statistic/war/scoreboard/scoreboard.component.html b/static/src/app/statistic/war/scoreboard/scoreboard.component.html index e2559ea..dd30393 100644 --- a/static/src/app/statistic/war/scoreboard/scoreboard.component.html +++ b/static/src/app/statistic/war/scoreboard/scoreboard.component.html @@ -1,47 +1,47 @@ -
- - - - - {{value}} - - - - - - {{value === 'BLUFOR' ? fraction.BLUFOR : fraction.OPFOR}} - - +
-
- - - - - {{column.head}} - - - - -
- - - - Gesamt - - - - + + + + + + + + + + + + + + + + + + + + + + + + +
{{tableHead[0].head}} + {{element.name}} + {{tableHead[1].head}} {{element.fraction}} + {{column.head}} + {{element[column.prop]}}  + +
diff --git a/static/src/app/statistic/war/scoreboard/scoreboard.component.ts b/static/src/app/statistic/war/scoreboard/scoreboard.component.ts index aa05ffd..8c99e6a 100644 --- a/static/src/app/statistic/war/scoreboard/scoreboard.component.ts +++ b/static/src/app/statistic/war/scoreboard/scoreboard.component.ts @@ -3,6 +3,8 @@ import {War} from '../../../models/model-interfaces'; import {Fraction} from '../../../utils/fraction.enum'; import {PlayerUtils} from '../../../utils/player-utils'; import {saveAs} from 'file-saver/FileSaver'; +import {MatSort, Sort} from '@angular/material'; +import {SortUtils} from '../../../utils/sort-utils'; @Component({ selector: 'cc-scoreboard', @@ -29,6 +31,12 @@ export class ScoreboardComponent implements OnChanges { rows = []; + sortedRows = []; + + currentSort = new MatSort(); + + displayedColumns = this.tableHead.map(head => head.prop); + reorderable = false; customClasses = { @@ -37,6 +45,7 @@ export class ScoreboardComponent implements OnChanges { }; constructor(private elRef: ElementRef) { + this.displayedColumns.push('interact'); } selectPlayerDetail(view: number, player) { @@ -49,9 +58,11 @@ export class ScoreboardComponent implements OnChanges { ngOnChanges(changes: SimpleChanges) { if (changes.war) { this.rows = changes.war.currentValue.players; - this.elRef.nativeElement - .querySelector('.datatable-body') - .scrollTo(0, 0); + this.currentSort.active = 'kill'; + this.sortScoreboardData(this.currentSort); +// this.elRef.nativeElement +// .querySelector('.datatable-body') +// .scrollTo(0, 0); } if (changes.fractionFilterSelected) { this.filterPlayersByFraction(this.fractionFilterSelected); @@ -66,6 +77,24 @@ export class ScoreboardComponent implements OnChanges { } else { this.rows = this.war.players; } + this.sortScoreboardData(this.currentSort); + } + + sortScoreboardData(sort: MatSort) { + if (sort) { + this.currentSort = sort; + } + const data = this.rows.slice(); + if (!sort.active || sort.direction === '') { + this.sortedRows = data; + return; + } + + this.sortedRows = data.sort((a, b) => { + const isAsc = sort.direction === 'desc'; + const sortProperty = sort.active; + return SortUtils.compare(a[sortProperty], b[sortProperty], isAsc); + }); } exportCSV() { @@ -96,5 +125,4 @@ export class ScoreboardComponent implements OnChanges { const blob = new Blob([csvOut], {type: 'text/plain'}); saveAs(blob, this.war.title.toLowerCase().replace(' ', '_').concat('.csv')); } - } diff --git a/static/src/app/statistic/war/war-header/war-header.component.css b/static/src/app/statistic/war/war-header/war-header.component.css index 9f7a896..8508278 100644 --- a/static/src/app/statistic/war/war-header/war-header.component.css +++ b/static/src/app/statistic/war/war-header/war-header.component.css @@ -19,12 +19,19 @@ span.tab-control { padding: 4px 16px; } -.war-header { - border-bottom: thin solid lightgrey; +.nav-tabs > li.active > a { + background: #ffffff; + border-bottom: none; } -.nav-tabs > li.active > a { - background: #222222; +.nav-tabs > li.active { + position: relative; + top: 1px; + z-index: 10; +} + +.nav-tabs > li img { + filter: invert(50%); } .nav-tabs { @@ -35,12 +42,12 @@ span.tab-control { } .nav-tabs > li > a { - background: #4b4b4b; + background: #e7e7e7; + border: 1px solid #dadada; } .nav-tabs > li:not(.active) > a:hover { background: #afafaf; - color: #f5f5f5; } .nav-tabs > li:last-child { @@ -49,7 +56,7 @@ span.tab-control { .nav-link { cursor: pointer !important; - color: #FFF !important; + color: #666666 !important; } .nav-tabs > li.deactivated > a.nav-link { diff --git a/static/src/app/utils/sort-utils.ts b/static/src/app/utils/sort-utils.ts new file mode 100644 index 0000000..6592a54 --- /dev/null +++ b/static/src/app/utils/sort-utils.ts @@ -0,0 +1,6 @@ +export class SortUtils { + + public static compare(a, b, isAsc) { + return (a < b ? -1 : 1) * (isAsc ? 1 : -1); + } +} diff --git a/static/src/assets/icon/round-assessment-24px.svg b/static/src/assets/icon/round-assessment-24px.svg new file mode 100644 index 0000000..24880bd --- /dev/null +++ b/static/src/assets/icon/round-assessment-24px.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +