Directly check permissions and no subscription (uisettings is always initialized on frontend startup) update permission directive to accept single string add explicit management permission name
216 lines
11 KiB
HTML
216 lines
11 KiB
HTML
<app-page-header [title]="getTitle()">
|
|
|
|
<div ngbDropdown class="me-2 d-flex">
|
|
<button class="btn btn-sm btn-outline-primary" id="dropdownSelect" ngbDropdownToggle>
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#text-indent-left" />
|
|
</svg>
|
|
<div class="d-none d-sm-inline"> <ng-container i18n>Select</ng-container></div>
|
|
</button>
|
|
<div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow">
|
|
<button ngbDropdownItem (click)="list.selectNone()" i18n>Select none</button>
|
|
<button ngbDropdownItem (click)="list.selectPage()" i18n>Select page</button>
|
|
<button ngbDropdownItem (click)="list.selectAll()" i18n>Select all</button>
|
|
</div>
|
|
</div>
|
|
<div class="btn-group flex-fill" role="group">
|
|
<input type="radio" class="btn-check" [(ngModel)]="displayMode" value="details" (ngModelChange)="saveDisplayMode()" id="displayModeDetails">
|
|
<label for="displayModeDetails" class="btn btn-outline-primary btn-sm">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#list-ul" />
|
|
</svg>
|
|
</label>
|
|
<input type="radio" class="btn-check" [(ngModel)]="displayMode" value="smallCards" (ngModelChange)="saveDisplayMode()" id="displayModeSmall">
|
|
<label for="displayModeSmall" class="btn btn-outline-primary btn-sm">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#grid" />
|
|
</svg>
|
|
</label>
|
|
<input type="radio" class="btn-check" [(ngModel)]="displayMode" value="largeCards" (ngModelChange)="saveDisplayMode()" id="displayModeLarge">
|
|
<label for="displayModeLarge" class="btn btn-outline-primary btn-sm">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#hdd-stack" />
|
|
</svg>
|
|
</label>
|
|
</div>
|
|
|
|
<div ngbDropdown class="btn-group ms-2 flex-fill">
|
|
<button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle i18n>Sort</button>
|
|
<div ngbDropdownMenu aria-labelledby="dropdownBasic1" class="shadow dropdown-menu-right">
|
|
<div class="w-100 d-flex pb-2 mb-1 border-bottom">
|
|
<input type="radio" class="btn-check" [value]="false" [(ngModel)]="listSortReverse" id="listSortReverseFalse">
|
|
<label class="btn btn-outline-primary btn-sm mx-2 flex-fill" for="listSortReverseFalse">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-down" />
|
|
</svg>
|
|
</label>
|
|
<input type="radio" class="btn-check" [value]="true" [(ngModel)]="listSortReverse" id="listSortReverseTrue">
|
|
<label class="btn btn-outline-primary btn-sm me-2 flex-fill" for="listSortReverseTrue">
|
|
<svg class="toolbaricon" fill="currentColor">
|
|
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-up-alt" />
|
|
</svg>
|
|
</label>
|
|
</div>
|
|
<div>
|
|
<button *ngFor="let f of getSortFields()" ngbDropdownItem (click)="setSortField(f.field)"
|
|
[class.active]="list.sortField == f.field">{{f.name}}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="btn-group ms-2 flex-fill" *ifPermissions="'documents.view_savedview'" ngbDropdown role="group">
|
|
<button class="btn btn-sm btn-outline-primary dropdown-toggle flex-fill" tourAnchor="tour.documents-views" ngbDropdownToggle>
|
|
<ng-container i18n>Views</ng-container>
|
|
<div *ngIf="savedViewIsModified" class="position-absolute top-0 start-100 p-2 translate-middle badge bg-secondary border border-light rounded-circle">
|
|
<span class="visually-hidden">selected</span>
|
|
</div>
|
|
</button>
|
|
<div class="dropdown-menu shadow dropdown-menu-right" ngbDropdownMenu>
|
|
<ng-container *ngIf="!list.activeSavedViewId">
|
|
<button ngbDropdownItem *ngFor="let view of savedViewService.allViews" (click)="loadViewConfig(view.id)">{{view.name}}</button>
|
|
<div class="dropdown-divider" *ngIf="savedViewService.allViews.length > 0"></div>
|
|
</ng-container>
|
|
|
|
<div *ifPermissions="'documents.change_savedviewfilterrule'">
|
|
<button ngbDropdownItem (click)="saveViewConfig()" *ngIf="list.activeSavedViewId" [disabled]="!savedViewIsModified" i18n>Save "{{list.activeSavedViewTitle}}"</button>
|
|
</div>
|
|
<button ngbDropdownItem (click)="saveViewConfigAs()" *ifPermissions="'documents.add_savedview'" i18n>Save as...</button>
|
|
</div>
|
|
</div>
|
|
|
|
</app-page-header>
|
|
|
|
<div class="row sticky-top pt-3 pt-sm-4 pb-2 pb-lg-4 bg-body">
|
|
<app-filter-editor [hidden]="isBulkEditing" [(filterRules)]="list.filterRules" [unmodifiedFilterRules]="unmodifiedFilterRules" #filterEditor></app-filter-editor>
|
|
<app-bulk-editor [hidden]="!isBulkEditing"></app-bulk-editor>
|
|
</div>
|
|
|
|
|
|
<ng-template #pagination>
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<p>
|
|
<ng-container *ngIf="list.isReloading">
|
|
<div class="spinner-border spinner-border-sm me-2" role="status"></div>
|
|
<ng-container i18n>Loading...</ng-container>
|
|
</ng-container>
|
|
<span i18n *ngIf="list.selected.size > 0">{list.collectionSize, plural, =1 {Selected {{list.selected.size}} of one document} other {Selected {{list.selected.size}} of {{list.collectionSize || 0}} documents}}</span>
|
|
<ng-container *ngIf="!list.isReloading">
|
|
<span i18n *ngIf="list.selected.size == 0">{list.collectionSize, plural, =1 {One document} other {{{list.collectionSize || 0}} documents}}</span> <span i18n *ngIf="isFiltered">(filtered)</span>
|
|
</ng-container>
|
|
</p>
|
|
<ngb-pagination *ngIf="list.collectionSize" [pageSize]="list.currentPageSize" [collectionSize]="list.collectionSize" [(page)]="list.currentPage" [maxSize]="5"
|
|
[rotate]="true" aria-label="Default pagination"></ngb-pagination>
|
|
</div>
|
|
</ng-template>
|
|
|
|
<div tourAnchor="tour.documents">
|
|
<ng-container *ngTemplateOutlet="pagination"></ng-container>
|
|
</div>
|
|
|
|
<ng-container *ngIf="list.error ; else documentListNoError">
|
|
<div class="alert alert-danger" role="alert"><ng-container i18n>Error while loading documents</ng-container>: {{list.error}}</div>
|
|
</ng-container>
|
|
|
|
<ng-template #documentListNoError>
|
|
<div *ngIf="displayMode == 'largeCards'">
|
|
<app-document-card-large [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" *ngFor="let d of list.documents; trackBy: trackByDocumentId" [document]="d" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickDocumentType)="clickDocumentType($event)" (clickStoragePath)="clickStoragePath($event)" (clickMoreLike)="clickMoreLike(d.id)">
|
|
</app-document-card-large>
|
|
</div>
|
|
|
|
<table class="table table-sm align-middle border shadow-sm" *ngIf="displayMode == 'details'">
|
|
<thead>
|
|
<th></th>
|
|
<th class="d-none d-lg-table-cell"
|
|
sortable="archive_serial_number"
|
|
[currentSortField]="list.sortField"
|
|
[currentSortReverse]="list.sortReverse"
|
|
(sort)="onSort($event)"
|
|
i18n>ASN</th>
|
|
<th class="d-none d-md-table-cell"
|
|
sortable="correspondent__name"
|
|
[currentSortField]="list.sortField"
|
|
[currentSortReverse]="list.sortReverse"
|
|
(sort)="onSort($event)"
|
|
i18n>Correspondent</th>
|
|
<th
|
|
sortable="title"
|
|
[currentSortField]="list.sortField"
|
|
[currentSortReverse]="list.sortReverse"
|
|
(sort)="onSort($event)"
|
|
i18n>Title</th>
|
|
<th class="d-none d-xl-table-cell"
|
|
sortable="document_type__name"
|
|
[currentSortField]="list.sortField"
|
|
[currentSortReverse]="list.sortReverse"
|
|
(sort)="onSort($event)"
|
|
i18n>Document type</th>
|
|
<th class="d-none d-xl-table-cell"
|
|
sortable="storage_path__name"
|
|
[currentSortField]="list.sortField"
|
|
[currentSortReverse]="list.sortReverse"
|
|
(sort)="onSort($event)"
|
|
i18n>Storage path</th>
|
|
<th
|
|
sortable="created"
|
|
[currentSortField]="list.sortField"
|
|
[currentSortReverse]="list.sortReverse"
|
|
(sort)="onSort($event)"
|
|
i18n>Created</th>
|
|
<th class="d-none d-xl-table-cell"
|
|
sortable="added"
|
|
[currentSortField]="list.sortField"
|
|
[currentSortReverse]="list.sortReverse"
|
|
(sort)="onSort($event)"
|
|
i18n>Added</th>
|
|
</thead>
|
|
<tbody>
|
|
<tr *ngFor="let d of list.documents; trackBy: trackByDocumentId" (click)="toggleSelected(d, $event); $event.stopPropagation();" [ngClass]="list.isSelected(d) ? 'table-row-selected' : ''">
|
|
<td>
|
|
<div class="form-check">
|
|
<input type="checkbox" class="form-check-input" id="docCheck{{d.id}}" [checked]="list.isSelected(d)" (click)="toggleSelected(d, $event); $event.stopPropagation();">
|
|
<label class="form-check-label" for="docCheck{{d.id}}"></label>
|
|
</div>
|
|
</td>
|
|
<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 (click)="clickCorrespondent(d.correspondent);$event.stopPropagation()" title="Filter by correspondent" i18n-title>{{(d.correspondent$ | async)?.name}}</a>
|
|
</ng-container>
|
|
</td>
|
|
<td>
|
|
<a (click)="openDocumentsService.openDocument(d)" title="Edit document" i18n-title style="overflow-wrap: anywhere;">{{d.title | documentTitle}}</a>
|
|
<app-tag [tag]="t" *ngFor="let t of d.tags$ | async" class="ms-1" clickable="true" linkTitle="Filter by tag" i18n-linkTitle (click)="clickTag(t.id);$event.stopPropagation()"></app-tag>
|
|
</td>
|
|
<td class="d-none d-xl-table-cell">
|
|
<ng-container *ngIf="d.document_type">
|
|
<a (click)="clickDocumentType(d.document_type);$event.stopPropagation()" title="Filter by document type" i18n-title>{{(d.document_type$ | async)?.name}}</a>
|
|
</ng-container>
|
|
</td>
|
|
<td class="d-none d-xl-table-cell">
|
|
<ng-container *ngIf="d.storage_path">
|
|
<a (click)="clickStoragePath(d.storage_path);$event.stopPropagation()" title="Filter by storage path" i18n-title>{{(d.storage_path$ | async)?.name}}</a>
|
|
</ng-container>
|
|
</td>
|
|
<td>
|
|
{{d.created_date | customDate}}
|
|
</td>
|
|
<td class="d-none d-xl-table-cell">
|
|
{{d.added | customDate}}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="row row-cols-paperless-cards" *ngIf="displayMode == 'smallCards'">
|
|
<app-document-card-small class="p-0" [selected]="list.isSelected(d)" (toggleSelected)="toggleSelected(d, $event)" [document]="d" *ngFor="let d of list.documents; trackBy: trackByDocumentId" (clickTag)="clickTag($event)" (clickCorrespondent)="clickCorrespondent($event)" (clickStoragePath)="clickStoragePath($event)" (clickDocumentType)="clickDocumentType($event)"></app-document-card-small>
|
|
</div>
|
|
<div *ngIf="list.documents?.length > 15" class="mt-3">
|
|
<ng-container *ngTemplateOutlet="pagination"></ng-container>
|
|
</div>
|
|
|
|
|
|
</ng-template>
|