mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
205 lines
11 KiB
HTML
205 lines
11 KiB
HTML
<app-page-header [title]="getTitle()">
|
|
<div class="btn-group btn-group-toggle" ngbRadioGroup [(ngModel)]="displayMode"
|
|
(ngModelChange)="saveDisplayMode()">
|
|
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
|
<input ngbButton type="radio" class="btn btn-sm" value="details">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#list-ul" />
|
|
</svg>
|
|
</label>
|
|
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
|
<input ngbButton type="radio" class="btn btn-sm" value="smallCards">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#grid" />
|
|
</svg>
|
|
</label>
|
|
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
|
<input ngbButton type="radio" class="btn btn-sm" value="largeCards">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#hdd-stack" />
|
|
</svg>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="btn-group btn-group-toggle ml-2" ngbRadioGroup [(ngModel)]="list.sortDirection">
|
|
<div ngbDropdown class="btn-group">
|
|
<button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle>Sort by</button>
|
|
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
|
|
<button *ngFor="let f of getSortFields()" ngbDropdownItem (click)="list.sortField = f.field"
|
|
[class.active]="list.sortField == f.field">{{f.name}}</button>
|
|
</div>
|
|
</div>
|
|
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
|
<input ngbButton type="radio" class="btn btn-sm" value="asc">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-down" />
|
|
</svg>
|
|
</label>
|
|
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
|
<input ngbButton type="radio" class="btn btn-sm" value="des">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-up-alt" />
|
|
</svg>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="btn-group ml-2">
|
|
|
|
<button type="button" class="btn btn-sm" [ngClass]="isFiltered ? 'btn-primary' : 'btn-outline-primary'" (click)="showFilter=!showFilter">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#funnel" />
|
|
</svg>
|
|
{{ showFilter ? 'Hide' : 'Show' }} Filter Editor
|
|
</button>
|
|
|
|
<div class="btn-group" ngbDropdown role="group">
|
|
<button class="btn btn-sm btn-outline-primary dropdown-toggle-split" ngbDropdownToggle></button>
|
|
<div class="dropdown-menu" ngbDropdownMenu>
|
|
<ng-container *ngIf="!list.savedViewId">
|
|
<button ngbDropdownItem *ngFor="let config of savedViewConfigService.getConfigs()" (click)="loadViewConfig(config)">{{config.title}}</button>
|
|
<div class="dropdown-divider" *ngIf="savedViewConfigService.getConfigs().length > 0"></div>
|
|
</ng-container>
|
|
|
|
<button ngbDropdownItem (click)="saveViewConfig()" *ngIf="list.savedViewId">Save "{{list.savedViewTitle}}"</button>
|
|
<button ngbDropdownItem (click)="saveViewConfigAs()">Save as...</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</app-page-header>
|
|
|
|
<div class="row pb-1 mb-3 align-items-right">
|
|
<div class="btn-toolbar col-auto">
|
|
<span class="text-muted mt-1 mr-2">Quick Filters:</span>
|
|
<div class="btn-group ml-2" ngbDropdown role="group">
|
|
<button class="btn btn-outline-primary btn-sm" id="dropdownTags" ngbDropdownToggle>Tags</button>
|
|
<div class="dropdown-menu quick-filter" ngbDropdownMenu aria-labelledby="dropdownTags">
|
|
<div class="list-group list-group-flush">
|
|
<input class="list-group-item form-control" type="text" [(ngModel)]="filterTagsText" placeholder="Filter tags">
|
|
<ng-container *ngIf="(tags | filter: filterTagsText).length > 0">
|
|
<button class="list-group-item list-group-item-action d-flex align-items-center" role="menuitem" *ngFor="let tag of tags | filter: filterTagsText; let i = index" (click)="toggleFilterByTag(tag.id)">
|
|
<div class="selected-icon mr-1">
|
|
<svg *ngIf="currentViewIncludesTag(tag.id)" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-check" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
<path fill-rule="evenodd" d="M10.97 4.97a.75.75 0 0 1 1.071 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.236.236 0 0 1 .02-.022z"/>
|
|
</svg>
|
|
</div>
|
|
<div class="mr-1">{{tag.name}}</div>
|
|
<div class="badge bg-primary text-light rounded-pill ml-auto">{{tag.document_count}}</div>
|
|
</button>
|
|
</ng-container>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="btn-group ml-2" ngbDropdown role="group">
|
|
<button class="btn btn-outline-primary btn-sm" id="dropdownCorrespondents" ngbDropdownToggle>Correspondents</button>
|
|
<div class="dropdown-menu quick-filter" ngbDropdownMenu aria-labelledby="dropdownCorrespondents">
|
|
<div class="list-group list-group-flush">
|
|
<input class="list-group-item form-control" type="text" [(ngModel)]="filterCorrespondentsText" placeholder="Filter correspondents">
|
|
<ng-container *ngIf="(correspondents | filter: filterCorrespondentsText).length > 0">
|
|
<button class="list-group-item list-group-item-action d-flex align-items-center" role="menuitem" *ngFor="let correspondent of correspondents | filter: filterCorrespondentsText; let i = index" (click)="toggleFilterByCorrespondent(correspondent.id)">
|
|
<div class="selected-icon mr-1">
|
|
<svg *ngIf="currentViewIncludesCorrespondent(correspondent.id)" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-check" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
<path fill-rule="evenodd" d="M10.97 4.97a.75.75 0 0 1 1.071 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.236.236 0 0 1 .02-.022z"/>
|
|
</svg>
|
|
</div>
|
|
<div class="mr-1">{{correspondent.name}}</div>
|
|
<div class="badge bg-primary text-light rounded-pill ml-auto">{{correspondent.document_count}}</div>
|
|
</button>
|
|
</ng-container>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="btn-group ml-2" ngbDropdown role="group">
|
|
<button class="btn btn-outline-primary btn-sm" id="dropdownDocumentTypes" ngbDropdownToggle>Document Types</button>
|
|
<div class="dropdown-menu quick-filter" ngbDropdownMenu aria-labelledby="dropdownDocumentTypes">
|
|
<div class="list-group list-group-flush">
|
|
<input class="list-group-item form-control" type="text" [(ngModel)]="filterDocumentTypesText" placeholder="Filter document types">
|
|
<ng-container *ngIf="(documentTypes | filter: filterDocumentTypesText).length > 0">
|
|
<button class="list-group-item list-group-item-action d-flex align-items-center" role="menuitem" *ngFor="let documentType of documentTypes | filter: filterDocumentTypesText; let i = index" (click)="toggleFilterByDocumentType(documentType.id)">
|
|
<div class="selected-icon mr-1">
|
|
<svg *ngIf="currentViewIncludesDocumentType(documentType.id)" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-check" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
<path fill-rule="evenodd" d="M10.97 4.97a.75.75 0 0 1 1.071 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.236.236 0 0 1 .02-.022z"/>
|
|
</svg>
|
|
</div>
|
|
<div class="mr-1">{{documentType.name}}</div>
|
|
<div class="badge bg-primary text-light rounded-pill ml-auto">{{documentType.document_count}}</div>
|
|
</button>
|
|
</ng-container>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="btn-link border-0 bg-transparent ml-3 text-muted" *ngIf="currentViewIncludesQuickFilter()" (click)="filterEditor.clearClicked()">
|
|
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-x" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
<path fill-rule="evenodd" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
|
|
</svg>
|
|
Clear
|
|
</button>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card w-100 mb-3" [hidden]="!showFilter">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Filter Editor</h5>
|
|
<app-filter-editor [(filterRules)]="filterRules" (apply)="applyFilterRules()" (clear)="clearFilterRules()"></app-filter-editor>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<p>{{list.collectionSize || 0}} document(s) <span *ngIf="isFiltered">(filtered)</span></p>
|
|
<ngb-pagination [pageSize]="list.currentPageSize" [collectionSize]="list.collectionSize" [(page)]="list.currentPage" [maxSize]="5"
|
|
[rotate]="true" (pageChange)="list.reload()" aria-label="Default pagination"></ngb-pagination>
|
|
</div>
|
|
|
|
<div *ngIf="displayMode == 'largeCards'">
|
|
<app-document-card-large *ngFor="let d of list.documents" [document]="d" [details]="d.content" (clickTag)="filterByTag($event)" (clickCorrespondent)="filterByCorrespondent($event)">
|
|
</app-document-card-large>
|
|
</div>
|
|
|
|
<table class="table table-sm border shadow" *ngIf="displayMode == 'details'">
|
|
<thead>
|
|
<th class="d-none d-lg-table-cell">ASN</th>
|
|
<th class="d-none d-md-table-cell">Correspondent</th>
|
|
<th>Title</th>
|
|
<th class="d-none d-xl-table-cell">Document type</th>
|
|
<th>Created</th>
|
|
<th class="d-none d-xl-table-cell">Added</th>
|
|
</thead>
|
|
<tbody>
|
|
<tr *ngFor="let d of list.documents">
|
|
<td class="d-none d-lg-table-cell">
|
|
{{d.archive_serial_number}}
|
|
</td>
|
|
<td class="d-none d-md-table-cell">
|
|
<ng-container *ngIf="d.correspondent">
|
|
<a [routerLink]="" (click)="filterByCorrespondent(d.correspondent)" title="Filter by correspondent">{{(d.correspondent$ | async)?.name}}</a>
|
|
</ng-container>
|
|
</td>
|
|
<td>
|
|
<a routerLink="/documents/{{d.id}}" title="Edit document" style="overflow-wrap: anywhere;">{{d.title}}</a>
|
|
<app-tag [tag]="t" *ngFor="let t of d.tags$ | async" class="ml-1" clickable="true" linkTitle="Filter by tag" (click)="filterByTag(t.id)"></app-tag>
|
|
</td>
|
|
<td class="d-none d-xl-table-cell">
|
|
<ng-container *ngIf="d.document_type">
|
|
<a [routerLink]="" (click)="filterByDocumentType(d.document_type)" title="Filter by document type">{{(d.document_type$ | async)?.name}}</a>
|
|
</ng-container>
|
|
</td>
|
|
<td>
|
|
{{d.created | date}}
|
|
</td>
|
|
<td class="d-none d-xl-table-cell">
|
|
{{d.added | date}}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
<div class=" m-n2 row" *ngIf="displayMode == 'smallCards'">
|
|
<app-document-card-small [document]="d" *ngFor="let d of list.documents" (clickTag)="filterByTag($event)" (clickCorrespondent)="filterByCorrespondent($event)"></app-document-card-small>
|
|
</div>
|