Skip to content

Commit

Permalink
Added scraping volume filtering [#959]
Browse files Browse the repository at this point in the history
  • Loading branch information
mcpierce authored and BRUCELLA2 committed Oct 18, 2021
1 parent 786dcc5 commit 17fe0b0
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 163 deletions.
2 changes: 1 addition & 1 deletion comixed-webui/src/app/app.translate.ts
Expand Up @@ -24,7 +24,7 @@ export function HttpLoaderFactory(http: HttpClient): MultiTranslateHttpLoader {
{ prefix: './assets/i18n/', suffix: '/admin.json' },
{ prefix: './assets/i18n/', suffix: '/app.json' },
{ prefix: './assets/i18n/', suffix: '/collections.json' },
{ prefix: './assets/i18n/', suffix: '/comic-book.json' },
{ prefix: './assets/i18n/', suffix: '/comic-books.json' },
{ prefix: './assets/i18n/', suffix: '/comic-files.json' },
{ prefix: './assets/i18n/', suffix: '/comic-pages.json' },
{ prefix: './assets/i18n/', suffix: '/core.json' },
Expand Down
@@ -1,4 +1,4 @@
<mat-card>
<mat-card class="cx-width-100">
<mat-card-title>{{ page?.filename }}</mat-card-title>
<mat-card-content>
<div class="cx-detail-card cx-padding-2 cx-margin-2">
Expand Down
@@ -1,107 +1,128 @@
<div class="cx-horizontal-container">
<div class="cx-grow-1">
<mat-toolbar class="cx-primary-light-background">
<mat-paginator
class="cx-primary-light-background cx-height-100"
*ngIf="!!comic"
[pageSizeOptions]="[5, 10, 20]"
showFirstLastButtons
></mat-paginator>
<mat-toolbar class="cx-primary-light-background">
<mat-paginator
class="cx-primary-light-background cx-height-100"
*ngIf="!!comic"
[pageSizeOptions]="[5, 10, 20]"
showFirstLastButtons
></mat-paginator>

<div class="cx-spacer"></div>
<button
id="cancel-scraping-button"
class="cx-toolbar-button"
mat-icon-button
color="warn"
[matTooltip]="'comic-book.tooltip.cancel-scraping' | translate"
(click)="onCancelScraping()"
>
<mat-icon>cancel</mat-icon>
</button>
</mat-toolbar>
<div class="cx-vertical-container">
<div *ngIf="!!comic" class="cx-grow-1">
<mat-table
aria-label="Comic files available for import"
[dataSource]="dataSource"
matSort
matSortActive="sortOrder"
matSortDirection="desc"
matSortDisableClear="false"
>
<ng-container matColumnDef="sortOrder">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.matchability" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
<span
[matTooltip]="
'comic-book.tooltip.match-' + element.sortOrder | translate
"
>
<mat-icon *ngIf="element.sortOrder === 2">thumb_up</mat-icon>
<mat-icon *ngIf="element.sortOrder === 1">
thumbs_up_down
</mat-icon>
<mat-icon *ngIf="element.sortOrder === 0">thumb_down</mat-icon>
</span>
</mat-cell>
</ng-container>
<div class="cx-spacer"></div>
<mat-form-field appearance="fill" class="cx-width-100">
<input
#filterInput
id="filter-input"
matInput
[placeholder]="'comic-book.placeholder.scraping-filter' | translate"
(keyup)="dataSource.filter = filterInput.value"
/>
<mat-icon matPrefix>search</mat-icon>
</mat-form-field>
<button
id="cancel-scraping-button"
class="cx-toolbar-button"
mat-icon-button
color="warn"
[matTooltip]="'comic-book.tooltip.cancel-scraping' | translate"
(click)="onCancelScraping()"
>
<mat-icon>cancel</mat-icon>
</button>
</mat-toolbar>

<ng-container matColumnDef="publisher">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.publisher" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.publisher }}
</mat-cell>
</ng-container>
<div class="cx-detail-card-container">
<div fxFlex.gt-sm="75%" fxFlex.sm="100%">
<mat-table
aria-label="Comic files available for import"
[dataSource]="dataSource"
matSort
matSortActive="sortOrder"
matSortDirection="desc"
matSortDisableClear="false"
>
<ng-container matColumnDef="sortOrder">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.matchability" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
<span
[matTooltip]="
'comic-book.tooltip.match-' + element.sortOrder | translate
"
>
<mat-icon *ngIf="element.sortOrder === 2">thumb_up</mat-icon>
<mat-icon *ngIf="element.sortOrder === 1">thumbs_up_down</mat-icon>
<mat-icon *ngIf="element.sortOrder === 0">thumb_down</mat-icon>
</span>
</mat-cell>
</ng-container>

<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.series-name" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.name }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="publisher">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.publisher" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.publisher }}
</mat-cell>
</ng-container>

<ng-container matColumnDef="startYear">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.start-year" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.startYear }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.series-name" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.name }}
</mat-cell>
</ng-container>

<ng-container matColumnDef="issueCount">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.issue-count" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.issueCount }}
</mat-cell>
</ng-container>
<ng-container matColumnDef="startYear">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.start-year" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.startYear }}
</mat-cell>
</ng-container>

<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row
*matRowDef="let row; columns: displayedColumns"
[class.cx-selected-row]="row.item.id === selectedVolume?.id"
(click)="onVolumeSelected(row.item)"
></mat-row>
</mat-table>
</div>
</div>
<ng-container matColumnDef="issueCount">
<mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "scraping.label.issue-count" | translate }}
</mat-header-cell>
<mat-cell *matCellDef="let element">
{{ element.item.issueCount }}
</mat-cell>
</ng-container>

<ng-container matColumnDef="action">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let element">
<button
id="accept-button"
mat-icon-button
color="primary"
[matTooltip]="'scraping.tooltip.select-scraping-issue' | translate"
(click)="onDecision(true)"
>
<mat-icon>check_box</mat-icon>
</button>
</mat-cell>
</ng-container>

<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row
*matRowDef="let row; columns: displayedColumns"
[class.cx-selected-row]="row.item.id === selectedVolume?.id"
(click)="onVolumeSelected(row.item)"
></mat-row>
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">
{{ "comic-book.text.no-matching-volumes" | translate }}
</td>
</tr>
</mat-table>
</div>
<div>
<div fxFlex.gt-xs="25%" fxFlex.sm="100%">
<div *ngIf="!!issue" id="cx-scraping-issue-detail-content">
<cx-scraping-issue-detail
[issue]="issue"
[pageSize]="pageSize"
(decision)="onDecision($event)"
></cx-scraping-issue-detail>
<cx-scraping-issue-detail [issue]="issue"></cx-scraping-issue-detail>
</div>
</div>
</div>
Expand Up @@ -33,3 +33,9 @@
max-width: $cx-column-medium;
resize: none;
}

.mat-column-action {
width: $cx-column-small;
max-width: $cx-column-small;
resize: none;
}
Expand Up @@ -56,6 +56,7 @@ import { ConfirmationService } from '@app/core/services/confirmation.service';
import { SortableListItem } from '@app/core/models/ui/sortable-list-item';
import { MatTooltipModule } from '@angular/material/tooltip';
import { ScrapingIssueDetailComponent } from '@app/comic-books/components/scraping-issue-detail/scraping-issue-detail.component';
import { MatInputModule } from '@angular/material/input';

describe('ComicScrapingComponent', () => {
const SCRAPING_ISSUE = SCRAPING_ISSUE_1;
Expand Down Expand Up @@ -90,7 +91,8 @@ describe('ComicScrapingComponent', () => {
MatIconModule,
MatFormFieldModule,
MatPaginatorModule,
MatTooltipModule
MatTooltipModule,
MatInputModule
],
providers: [provideMockStore({ initialState }), ConfirmationService]
}).compileComponents();
Expand Down Expand Up @@ -307,4 +309,38 @@ describe('ComicScrapingComponent', () => {
expect(store.dispatch).toHaveBeenCalledWith(resetScraping());
});
});

describe('filtering', () => {
const VOLUME = {
item: SCRAPING_VOLUME,
sortOrder: 1
} as SortableListItem<ScrapingVolume>;

it('can handle null values', () => {
expect(
component.dataSource.filterPredicate(
{ item: { ...SCRAPING_VOLUME, name: null }, sortOrder: 1 },
VOLUME.item.name
)
).toBeFalse();
});

it('can filter by name', () => {
expect(
component.dataSource.filterPredicate(VOLUME, VOLUME.item.name)
).toBeTrue();
});

it('can filter by publisher', () => {
expect(
component.dataSource.filterPredicate(VOLUME, VOLUME.item.publisher)
).toBeTrue();
});

it('can filter by starting year', () => {
expect(
component.dataSource.filterPredicate(VOLUME, VOLUME.item.startYear)
).toBeTrue();
});
});
});
Expand Up @@ -91,7 +91,8 @@ export class ComicScrapingComponent
'publisher',
'name',
'startYear',
'issueCount'
'issueCount',
'action'
];

constructor(
Expand Down Expand Up @@ -143,7 +144,9 @@ export class ComicScrapingComponent
}

ngAfterViewInit(): void {
this.logger.trace('Setting up pagination');
this.dataSource.paginator = this.paginator;
this.logger.trace('Setting up sorting');
this.dataSource.sort = this.sort;
this.dataSource.sortingDataAccessor = (element, property) => {
switch (property) {
Expand All @@ -153,6 +156,14 @@ export class ComicScrapingComponent
return element.item[property];
}
};
this.logger.trace('Setting up filtering');
this.dataSource.filterPredicate = (data, filter) => {
return (
this.matchesFilter(data.item.name, filter) ||
this.matchesFilter(data.item.publisher, filter) ||
this.matchesFilter(data.item.startYear, filter)
);
};
}

onVolumeSelected(volume: ScrapingVolume): void {
Expand Down Expand Up @@ -211,4 +222,12 @@ export class ComicScrapingComponent
this.logger.trace('Canceling scraping');
this.store.dispatch(resetScraping());
}

private matchesFilter(value: string, filter: string): boolean {
console.log('Looking for', filter, ' in', value);
return (
(value || '').toLocaleLowerCase().indexOf(filter.toLocaleLowerCase()) !==
-1
);
}
}
Expand Up @@ -7,32 +7,6 @@
}}
</mat-card-subtitle>
<mat-card-content>
<div class="cx-width-100">
<cx-comic-page [imageUrl]="issue.coverUrl"></cx-comic-page>
</div>
<cx-comic-page [imageUrl]="issue.coverUrl"></cx-comic-page>
</mat-card-content>
<mat-card-actions>
<div class="cx-width-100 cx-align-content-center">
<button
id="cx-select-scraping-issue-button"
mat-icon-button
class="cx-action-button"
color="primary"
[matTooltip]="'scraping.tooltip.select-scraping-issue' | translate"
(click)="onSelect()"
>
<mat-icon>thumb_up_alt</mat-icon>
</button>
<button
id="cx-cancel-scraping-issue-button"
mat-icon-button
class="cx-action-button"
color="primary"
[matTooltip]="'scraping.tooltip.reject-scraping-issue' | translate"
(click)="onReject()"
>
<mat-icon>thumb_down_alt</mat-icon>
</button>
</div>
</mat-card-actions>
</mat-card>

0 comments on commit 17fe0b0

Please sign in to comment.