Restructure

This commit is contained in:
Geomitron
2023-11-27 18:53:09 -06:00
parent 558d76f582
commit 49c3f38f99
758 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
<td>
<div #checkbox class="ui checkbox" (click)="$event.stopPropagation()">
<input type="checkbox" />
</div>
</td>
<td>
<span id="chartCount" *ngIf="result.chartCount > 1">{{ result.chartCount }}</span
>{{ result.name }}
</td>
<td>{{ result.artist }}</td>
<td>{{ result.album || 'Various' }}</td>
<td>{{ result.genre || 'Various' }}</td>

View File

@@ -0,0 +1,10 @@
.ui.checkbox {
display: block;
}
#chartCount {
background-color: lightgray;
border-radius: 3px;
padding: 1px 4px 2px 4px;
margin-right: 3px;
}

View File

@@ -0,0 +1,40 @@
import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core'
import { SongResult } from '../../../../../electron/shared/interfaces/search.interface'
import { SelectionService } from '../../../../core/services/selection.service'
@Component({
selector: 'tr[app-result-table-row]',
templateUrl: './result-table-row.component.html',
styleUrls: ['./result-table-row.component.scss'],
})
export class ResultTableRowComponent implements AfterViewInit {
@Input() result: SongResult
@ViewChild('checkbox', { static: true }) checkbox: ElementRef
constructor(private selectionService: SelectionService) { }
get songID() {
return this.result.id
}
ngAfterViewInit() {
this.selectionService.onSelectionChanged(this.songID, isChecked => {
if (isChecked) {
$(this.checkbox.nativeElement).checkbox('check')
} else {
$(this.checkbox.nativeElement).checkbox('uncheck')
}
})
$(this.checkbox.nativeElement).checkbox({
onChecked: () => {
this.selectionService.selectSong(this.songID)
},
onUnchecked: () => {
this.selectionService.deselectSong(this.songID)
},
})
}
}

View File

@@ -0,0 +1,30 @@
<table
id="resultTable"
class="ui stackable selectable single sortable fixed line striped compact small table"
[class.inverted]="settingsService.theme === 'Dark'">
<!-- TODO: maybe have some of these tags customizable? E.g. small/large/compact/padded -->
<!-- TODO: learn semantic themes in order to change the $mobileBreakpoint global variable (better search table adjustment) -->
<thead>
<!-- NOTE: it would be nice to make this header sticky, but Fomantic-UI doesn't currently support that -->
<tr>
<th class="collapsing" id="checkboxColumn">
<div class="ui checkbox" id="checkbox" #checkboxColumn appCheckbox (checked)="checkAll($event)">
<input type="checkbox" />
</div>
</th>
<th class="four wide" [class.sorted]="sortColumn === 'name'" [ngClass]="sortDirection" (click)="onColClicked('name')">Name</th>
<th class="four wide" [class.sorted]="sortColumn === 'artist'" [ngClass]="sortDirection" (click)="onColClicked('artist')">Artist</th>
<th class="four wide" [class.sorted]="sortColumn === 'album'" [ngClass]="sortDirection" (click)="onColClicked('album')">Album</th>
<th class="four wide" [class.sorted]="sortColumn === 'genre'" [ngClass]="sortDirection" (click)="onColClicked('genre')">Genre</th>
</tr>
</thead>
<tbody>
<tr
app-result-table-row
#tableRow
*ngFor="let result of results"
(click)="onRowClicked(result)"
[class.active]="activeRowID === result.id"
[result]="result"></tr>
</tbody>
</table>

View File

@@ -0,0 +1,25 @@
:host {
display: contents;
}
.ui.checkbox {
display: block;
}
#checkboxColumn {
width: 34.64px;
}
#resultTable {
border-radius: 0px;
thead>tr:first-child>th:first-child,
thead>tr:first-child>th:last-child {
border-radius: 0px;
}
th {
position: sticky;
top: 0;
z-index:1;
}
}

View File

@@ -0,0 +1,85 @@
import { Component, EventEmitter, OnInit, Output, QueryList, ViewChild, ViewChildren } from '@angular/core'
import Comparators from 'comparators'
import { SettingsService } from 'src/app/core/services/settings.service'
import { SongResult } from '../../../../electron/shared/interfaces/search.interface'
import { CheckboxDirective } from '../../../core/directives/checkbox.directive'
import { SearchService } from '../../../core/services/search.service'
import { SelectionService } from '../../../core/services/selection.service'
import { ResultTableRowComponent } from './result-table-row/result-table-row.component'
@Component({
selector: 'app-result-table',
templateUrl: './result-table.component.html',
styleUrls: ['./result-table.component.scss'],
})
export class ResultTableComponent implements OnInit {
@Output() rowClicked = new EventEmitter<SongResult>()
@ViewChild(CheckboxDirective, { static: true }) checkboxColumn: CheckboxDirective
@ViewChildren('tableRow') tableRows: QueryList<ResultTableRowComponent>
results: SongResult[] = []
activeRowID: number = null
sortDirection: 'ascending' | 'descending' = 'descending'
sortColumn: 'name' | 'artist' | 'album' | 'genre' | null = null
constructor(
private searchService: SearchService,
private selectionService: SelectionService,
public settingsService: SettingsService
) { }
ngOnInit() {
this.selectionService.onSelectAllChanged(selected => {
this.checkboxColumn.check(selected)
})
this.searchService.onSearchChanged(results => {
this.activeRowID = null
this.results = results
this.updateSort()
})
this.searchService.onNewSearch(() => {
this.sortColumn = null
})
}
onRowClicked(result: SongResult) {
this.activeRowID = result.id
this.rowClicked.emit(result)
}
onColClicked(column: 'name' | 'artist' | 'album' | 'genre') {
if (this.results.length == 0) { return }
if (this.sortColumn != column) {
this.sortColumn = column
this.sortDirection = 'descending'
} else if (this.sortDirection == 'descending') {
this.sortDirection = 'ascending'
} else {
this.sortDirection = 'descending'
}
this.updateSort()
}
private updateSort() {
if (this.sortColumn != null) {
this.results.sort(Comparators.comparing(this.sortColumn, { reversed: this.sortDirection == 'ascending' }))
}
}
/**
* Called when the user checks the `checkboxColumn`.
*/
checkAll(isChecked: boolean) {
if (isChecked) {
this.selectionService.selectAll()
} else {
this.selectionService.deselectAll()
}
}
}