Search screen

This commit is contained in:
Adina Țeudan 2021-09-06 15:44:35 +03:00
parent 23cef69647
commit 889def7465
4 changed files with 99 additions and 125 deletions

View File

@ -11,84 +11,76 @@
<div class="red-content-inner">
<div class="content-container">
<iqser-table-header [tableColumnConfigs]="tableColumnConfigs" [tableHeaderLabel]="tableHeaderLabel"></iqser-table-header>
<iqser-empty-state
*ngIf="searchResult.length === 0"
[icon]="'iqser:search'"
[text]="'search-screen.no-data' | translate"
></iqser-empty-state>
<cdk-virtual-scroll-viewport #scrollViewport [itemSize]="itemSize" iqserHasScrollbar>
<div
*cdkVirtualFor="let item of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey"
[class.pointer]="true"
[routerLink]="item.routerLink"
class="table-item"
>
<div class="filename">
<div [matTooltip]="item.filename" class="table-item-title heading" matTooltipPosition="above">
<span
*ngIf="item.highlights.filename; else defaultFilename"
[innerHTML]="item.highlights.filename[0]"
class="highlights"
></span>
<ng-template #defaultFilename>{{ item.filename }}</ng-template>
</div>
<ng-container *ngIf="item.highlights['sections.text'] as highlights">
<div *ngIf="highlights.length > 0" class="small-label">
<span [innerHTML]="highlights[0]" class="highlights"></span>
</div>
<div *ngIf="highlights.length > 1" class="small-label">
<span [innerHTML]="highlights[1]" class="highlights"></span>
</div>
</ng-container>
<div *ngIf="item.unmatched?.length && item.unmatched as unmatched" class="small-label">
<span>
{{ 'search-screen.missing' | translate }}:<span *ngFor="let term of unmatched"
>&nbsp;<s>{{ term }}</s></span
>.&nbsp;{{ 'search-screen.must-contain' | translate }}:
<span
(click)="$event.stopPropagation(); updateNavigation(search$.getValue().query, term)"
*ngFor="let term of unmatched"
>&nbsp;<u>{{ term }}</u></span
>
</span>
</div>
</div>
<div>
<iqser-status-bar
[configs]="[
{
color: item.status,
label: fileStatusTranslations[item.status] | translate,
length: 1,
cssClass: 'all-caps-label'
}
]"
[small]="true"
></iqser-status-bar>
</div>
<div class="small-label">
{{ item.dossierName }}
</div>
<div class="small-label stats-subtitle">
<div>
<mat-icon svgIcon="red:pages"></mat-icon>
{{ item.numberOfPages }}
</div>
</div>
<div class="scrollbar-placeholder"></div>
</div>
</cdk-virtual-scroll-viewport>
<iqser-scroll-button *ngIf="searchResult.length" [itemSize]="itemSize" [scrollViewport]="scrollViewport"></iqser-scroll-button>
<iqser-table
[hasScrollButton]="true"
[itemSize]="85"
[noDataText]="'search-screen.no-data' | translate"
noDataIcon="iqser:search"
></iqser-table>
</div>
</div>
</section>
<ng-template #filenameTemplate let-item="entity">
<div class="cell filename">
<div [matTooltip]="item.filename" class="table-item-title heading" matTooltipPosition="above">
<span
*ngIf="item.highlights.filename; else defaultFilename"
[innerHTML]="item.highlights.filename[0]"
class="highlights"
></span>
<ng-template #defaultFilename>{{ item.filename }}</ng-template>
</div>
<ng-container *ngIf="item.highlights['sections.text'] as highlights">
<div *ngIf="highlights.length > 0" class="small-label">
<span [innerHTML]="highlights[0]" class="highlights"></span>
</div>
<div *ngIf="highlights.length > 1" class="small-label">
<span [innerHTML]="highlights[1]" class="highlights"></span>
</div>
</ng-container>
<div *ngIf="item.unmatched?.length && item.unmatched as unmatched" class="small-label">
<span>
{{ 'search-screen.missing' | translate }}:<span *ngFor="let term of unmatched"
>&nbsp;<s>{{ term }}</s></span
>.&nbsp;{{ 'search-screen.must-contain' | translate }}:
<span (click)="$event.stopPropagation(); updateNavigation(search$.getValue().query, term)" *ngFor="let term of unmatched"
>&nbsp;<u>{{ term }}</u></span
>
</span>
</div>
</div>
</ng-template>
<ng-template #statusTemplate let-item="entity">
<div class="cell">
<iqser-status-bar
[configs]="[
{
color: item.status,
label: fileStatusTranslations[item.status] | translate,
length: 1,
cssClass: 'all-caps-label'
}
]"
[small]="true"
></iqser-status-bar>
</div>
</ng-template>
<ng-template #dossierTemplate let-item="entity">
<div class="cell small-label">
{{ item.dossierName }}
</div>
</ng-template>
<ng-template #pagesTemplate let-item="entity">
<div class="cell small-label stats-subtitle">
<div>
<mat-icon svgIcon="red:pages"></mat-icon>
{{ item.numberOfPages }}
</div>
</div>
</ng-template>

View File

@ -1,42 +1,12 @@
@import 'libs/common-ui/src/assets/styles/mixins';
@import '../../../../../assets/styles/variables';
.content-container {
position: relative;
:host ::ng-deep iqser-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .table-item > div.cell {
.highlights {
@include line-clamp(1);
cdk-virtual-scroll-viewport {
::ng-deep.cdk-virtual-scroll-content-wrapper {
grid-template-columns: 2fr 1fr 1fr auto 11px;
.table-item {
> div {
height: 85px;
padding: 0 24px;
}
.status-container {
width: 160px;
padding-right: 13px;
}
.highlights em {
background-color: #fffcc4;
}
.highlights {
@include line-clamp(1);
}
//.stats-subtitle > div {
// width: fit-content;
//}
}
}
&.has-scrollbar:hover {
::ng-deep.cdk-virtual-scroll-content-wrapper {
grid-template-columns: 2fr 1fr 1fr auto;
}
em {
background-color: #fffcc4;
}
}
}

View File

@ -1,4 +1,4 @@
import { Component, Injector, OnDestroy } from '@angular/core';
import { Component, forwardRef, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { DefaultListingServices, keyChecker, Listable, ListingComponent, LoadingService, TableColumnConfig } from '@iqser/common-ui';
import { MatchedDocument, SearchControllerService, SearchResult } from '@redaction/red-ui-http';
import { BehaviorSubject, Observable } from 'rxjs';
@ -32,20 +32,17 @@ interface SearchInput {
@Component({
templateUrl: './search-screen.component.html',
styleUrls: ['./search-screen.component.scss'],
providers: [...DefaultListingServices]
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => SearchScreenComponent) }]
})
export class SearchScreenComponent extends ListingComponent<ListItem> implements OnDestroy {
export class SearchScreenComponent extends ListingComponent<ListItem> implements OnDestroy, OnInit {
readonly fileStatusTranslations = fileStatusTranslations;
readonly searchPositions = SearchPositions;
readonly itemSize = 85;
@ViewChild('filenameTemplate', { static: true }) filenameTemplate: TemplateRef<never>;
@ViewChild('statusTemplate', { static: true }) statusTemplate: TemplateRef<never>;
@ViewChild('dossierTemplate', { static: true }) dossierTemplate: TemplateRef<never>;
@ViewChild('pagesTemplate', { static: true }) pagesTemplate: TemplateRef<never>;
readonly tableHeaderLabel = _('search-screen.table-header');
readonly tableColumnConfigs: TableColumnConfig<ListItem>[] = [
{ label: _('search-screen.cols.document') },
{ label: _('search-screen.cols.status') },
{ label: _('search-screen.cols.dossier') },
{ label: _('search-screen.cols.pages') }
];
tableColumnConfigs: TableColumnConfig<ListItem>[];
readonly search$ = new BehaviorSubject<SearchInput>(null);
readonly searchResults$: Observable<ListItem[]> = this.search$.asObservable().pipe(
switchMap(query => this._search(query)),
@ -94,6 +91,8 @@ export class SearchScreenComponent extends ListingComponent<ListItem> implements
});
}
routerLinkFn = (entity: ListItem) => [entity.routerLink];
setInitialConfig(): void {
return;
}
@ -104,6 +103,19 @@ export class SearchScreenComponent extends ListingComponent<ListItem> implements
this._router.navigate([], { queryParams }).then();
}
ngOnInit(): void {
this._configureTableColumns();
}
private _configureTableColumns() {
this.tableColumnConfigs = [
{ label: _('search-screen.cols.document'), template: this.filenameTemplate, width: '2fr' },
{ label: _('search-screen.cols.status'), template: this.statusTemplate },
{ label: _('search-screen.cols.dossier'), template: this.dossierTemplate },
{ label: _('search-screen.cols.pages'), template: this.pagesTemplate, width: 'auto' }
];
}
private _search(searchInput: SearchInput): Observable<SearchResult> {
return this._searchControllerService.search({
dossierIds: searchInput.dossierIds,

@ -1 +1 @@
Subproject commit d8379489b9da22ce463db6bcb4b351ec24287e30
Subproject commit 08222bdaeb1e16b37c75b66a2a49b0b3b96d9de7