Search screen
This commit is contained in:
parent
23cef69647
commit
889def7465
@ -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"
|
||||
> <s>{{ term }}</s></span
|
||||
>. {{ 'search-screen.must-contain' | translate }}:
|
||||
<span
|
||||
(click)="$event.stopPropagation(); updateNavigation(search$.getValue().query, term)"
|
||||
*ngFor="let term of unmatched"
|
||||
> <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"
|
||||
> <s>{{ term }}</s></span
|
||||
>. {{ 'search-screen.must-contain' | translate }}:
|
||||
<span (click)="$event.stopPropagation(); updateNavigation(search$.getValue().query, term)" *ngFor="let term of unmatched"
|
||||
> <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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user