(front) Albums: exlude some results and reload

Create a new service for albums to split big ElsService
This commit is contained in:
2020-12-20 23:46:43 +01:00
parent 7e6cc36750
commit 93272d5894
6 changed files with 158 additions and 33 deletions

View File

@@ -5,15 +5,27 @@
<th>Album</th> <th>Album</th>
<th>Track Count</th> <th>Track Count</th>
<th>Album Artist</th> <th>Album Artist</th>
<th>Avg. Bit Rate</th> <th colspan="2">Bit Rate (avg / min)</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor="let album of albums"> <tr *ngFor="let album of albums">
<td>{{album.Album}}</td> <td>
{{album.Album}}
<button class="glyphicon glyphicon-zoom-out" (click)="exlude('Album', album)"></button>
</td>
<td>{{album['Track Count']}}</td> <td>{{album['Track Count']}}</td>
<td>{{album['Album Artist'] ? album['Album Artist'] : album.Artist }}</td> <td>
{{album['Album Artist'] ? album['Album Artist'] : album.Artist }}
<button *ngIf="album['Album Artist']; else removeArtist"
class="glyphicon glyphicon-zoom-out"
(click)="exlude('Album Artist', album)"></button>
<ng-template #removeArtist>
<button class="glyphicon glyphicon-zoom-out" (click)="exlude('Artist', album)"></button>
</ng-template>
</td>
<td>{{album['Avg Bit Rate']}}</td> <td>{{album['Avg Bit Rate']}}</td>
<td>{{album['Min Bit Rate']}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ElsAlbumService } from '../els-album.service';
import { ElsService } from "../els.service";
import { Album } from '../model/album'; import { Album } from '../model/album';
@Component({ @Component({
@@ -11,11 +11,47 @@ import { Album } from '../model/album';
export class AlbumsComponent implements OnInit { export class AlbumsComponent implements OnInit {
albums: Album[] = []; albums: Album[] = [];
filterQuery = ElsAlbumService.GET_ALBUMS_DEFAULT_QUERY;
constructor(private elsService: ElsService) { } constructor(private elsService : ElsAlbumService) { }
ngOnInit(): void { ngOnInit(): void {
this.elsService.getAlbums(20).subscribe(data => { this.albums = data; console.log(data);}); this.loadData();
} }
exlude(field: string, value: string): void {
// TODO Move this method to a service
if (value[field] instanceof Array) {
value[field] = value[field][0]
}
if (this.filterQuery['query']) {
this.filterQuery['query']['bool']['must_not'].push({
'match_phrase': {
[field]: value[field]
}
})
} else {
this.filterQuery['query'] = {
'bool': {
'must': [],
'filter': [ { 'match_all': {} } ],
'should': [],
'must_not': [
{
'match_phrase': {
[field]: value[field]
}
}
]
}
}
}
this.loadData()
}
loadData(): void {
// console.log(JSON.stringify(this.filterQuery))
this.elsService.getAlbums(this.filterQuery).subscribe(data => this.albums = data);
}
} }

View File

@@ -11,6 +11,7 @@ import { SongTableComponent } from './song-table/song-table.component';
import { TopPlayedComponent } from './top-played/top-played.component'; import { TopPlayedComponent } from './top-played/top-played.component';
import { ElsService } from './els.service'; import { ElsService } from './els.service';
import { ElsAlbumService } from './els-album.service';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
@@ -43,7 +44,8 @@ import { AlbumsComponent } from './albums/albums.component';
RoundPipe RoundPipe
], ],
providers: [ providers: [
ElsService ElsService,
ElsAlbumService
], ],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })

View File

@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ElsAlbumService } from './els-album.service';
describe('ElsAlbumService', () => {
let service: ElsAlbumService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ElsAlbumService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -0,0 +1,78 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http'
import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Album } from './model/album';
import { ElsService } from './els.service';
@Injectable()
export class ElsAlbumService extends ElsService {
public static readonly GET_ALBUMS_DEFAULT_QUERY = {
'sort': [ {
'Avg Bit Rate': {
'order': 'asc'
}
} ],
'size': ElsService.DEFAULT_SIZE
}
constructor(protected http: HttpClient) {
super(http);
}
getAlbums(query: any): Observable<Album[]> {
console.info('getAlbums');
console.info(query);
return this.http
.post(this.elsUrl + ElsService.ALBUM_INDEX_NAME + ElsService.ACTION_SEARCH,
JSON.stringify(query), {headers: this.headers})
.pipe(
map(res => this.responseToAlbums(res)),
catchError(error => this.handleError(error, 'getAlbums'))
);
}
getAlbumsFiltered(size: number): Observable<Album[]> {
// http://localhost:9200/itunes-albums/_search
console.info('getAlbums');
return this.http
.post(this.elsUrl + ElsService.ALBUM_INDEX_NAME + ElsService.ACTION_SEARCH,
JSON.stringify({
'sort': [ {
'Avg Bit Rate': {
'order': 'asc'
}
} ],
'size': size,
'query': {
'bool': {
'must': [],
'filter': [
{
'match_all': {}
}
],
'should': [],
'must_not': [
{
'match_phrase': {
'Artist': 'François Pérusse'
}
},
{
'match_phrase': {
'Album Artist': 'Comédiens'
}
}
]
}
}
}), {headers: this.headers})
.pipe(
map(res => this.responseToAlbums(res)),
catchError(error => this.handleError(error, 'getAlbums'))
);
}
}

View File

@@ -16,13 +16,13 @@ export class ElsService {
public static readonly ARTIST_INDEX_NAME = '/itunes-artists'; public static readonly ARTIST_INDEX_NAME = '/itunes-artists';
public static readonly ALBUM_INDEX_NAME = '/itunes-albums'; public static readonly ALBUM_INDEX_NAME = '/itunes-albums';
private static readonly ACTION_SEARCH = '/_search'; protected static readonly ACTION_SEARCH = '/_search';
private static readonly ACTION_COUNT = '/_count'; protected static readonly ACTION_COUNT = '/_count';
private elsUrl = 'http://localhost:9200'; protected elsUrl = 'http://localhost:9200';
private headers = new HttpHeaders({'Content-Type': 'application/json'}); protected headers = new HttpHeaders({'Content-Type': 'application/json'});
constructor(private http: HttpClient) { } constructor(protected http: HttpClient) { }
getTime(): Promise<number> { getTime(): Promise<number> {
return this.http return this.http
@@ -244,25 +244,6 @@ export class ElsService {
); );
} }
getAlbums(size: number): Observable<Album[]> {
// http://localhost:9200/itunes-albums/_search
console.info('getAlbums');
return this.http
.post(this.elsUrl + ElsService.ALBUM_INDEX_NAME + ElsService.ACTION_SEARCH,
JSON.stringify({
'sort': [ {
'Avg Bit Rate': {
'order': 'asc'
}
} ],
'size': size
}), {headers: this.headers})
.pipe(
map(res => this.responseToAlbums(res)),
catchError(error => this.handleError(error, 'getAlbums'))
);
}
getArtist(artistName: string): Observable<Artist> { getArtist(artistName: string): Observable<Artist> {
return this.http return this.http
.post(this.elsUrl + ElsService.ARTIST_INDEX_NAME + ElsService.ACTION_SEARCH, .post(this.elsUrl + ElsService.ARTIST_INDEX_NAME + ElsService.ACTION_SEARCH,
@@ -437,7 +418,7 @@ export class ElsService {
* *
* @param res Response to process * @param res Response to process
*/ */
private responseToAlbums(res: any): Album[] { protected responseToAlbums(res: any): Album[] {
const result: Array<Album> = []; const result: Array<Album> = [];
res.hits.hits.forEach((hit) => { res.hits.hits.forEach((hit) => {
result.push(hit._source); result.push(hit._source);
@@ -481,7 +462,7 @@ export class ElsService {
return result; return result;
} }
private handleError(error: any, origin: string): Promise<any> { protected handleError(error: any, origin: string): Promise<any> {
console.error('An error occurred!'); console.error('An error occurred!');
console.error('Origin function: ', origin); console.error('Origin function: ', origin);
console.error('An error occurred!', error); // for demo purposes only console.error('An error occurred!', error); // for demo purposes only