mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Re-work filter editor, bulk editor & reset buttons
This commit is contained in:
		| @@ -18,8 +18,8 @@ | ||||
|       <input class="form-control form-control-sm" type="text" placeholder="Search documents" aria-label="Search" | ||||
|         [formControl]="searchField" [ngbTypeahead]="searchAutoComplete" (keyup)="searchFieldKeyup($event)" (selectItem)="itemSelected($event)" i18n-placeholder> | ||||
|       <button type="button" *ngIf="!searchFieldEmpty" class="btn btn-link btn-sm px-0 position-absolute top-0 end-0" (click)="resetSearchField()"> | ||||
|         <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-x me-1" 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 fill="currentColor" class="buttonicon-sm me-1"> | ||||
|           <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|         </svg> | ||||
|       </button> | ||||
|     </form> | ||||
| @@ -107,7 +107,7 @@ | ||||
|                   <use xlink:href="assets/bootstrap-icons.svg#file-text"/> | ||||
|                 </svg><span> {{d.title | documentTitle}}</span> | ||||
|                 <span class="close" (click)="closeDocument(d); $event.preventDefault()"> | ||||
|                   <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16"> | ||||
|                   <svg fill="currentColor" class="toolbaricon"> | ||||
|                     <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|                   </svg> | ||||
|                 </span> | ||||
|   | ||||
| @@ -7,9 +7,9 @@ | ||||
|     <div class="list-group list-group-flush"> | ||||
|         <button *ngFor="let rd of relativeDates" class="list-group-item small list-goup list-group-item-action d-flex p-2" role="menuitem" (click)="setRelativeDate(rd.date)"> | ||||
|           <div class="selected-icon me-1"> | ||||
|             <svg *ngIf="relativeDate === rd.date" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> | ||||
|               <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 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.267.267 0 0 1 .02-.022z"/> | ||||
|             </svg> | ||||
|             <svg *ngIf="relativeDate === rd.date" fill="currentColor" class="buttonicon-sm"> | ||||
|               <use xlink:href="assets/bootstrap-icons.svg#check"/> | ||||
|           </svg> | ||||
|           </div> | ||||
|           {{rd.name}} | ||||
|         </button> | ||||
| @@ -18,8 +18,8 @@ | ||||
|           <div class="mb-2 d-flex flex-row w-100 justify-content-between small"> | ||||
|             <div i18n>After</div> | ||||
|             <a *ngIf="dateAfter" class="btn btn-link p-0 m-0" (click)="clearAfter()"> | ||||
|               <svg width="0.8em" height="0.8em" 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 fill="currentColor" class="buttonicon-sm"> | ||||
|                 <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|               </svg> | ||||
|               <small i18n>Clear</small> | ||||
|             </a> | ||||
| @@ -29,8 +29,8 @@ | ||||
|             <input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)" | ||||
|                     maxlength="10" [(ngModel)]="dateAfter" ngbDatepicker #dateAfterPicker="ngbDatepicker"> | ||||
|             <button class="btn btn-outline-secondary" (click)="dateAfterPicker.toggle()" type="button"> | ||||
|               <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16"> | ||||
|                 <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/> | ||||
|               <svg fill="currentColor" class="buttonicon-sm"> | ||||
|                 <use xlink:href="assets/bootstrap-icons.svg#calendar"/> | ||||
|               </svg> | ||||
|             </button> | ||||
|           </div> | ||||
| @@ -41,8 +41,8 @@ | ||||
|           <div class="mb-2 d-flex flex-row w-100 justify-content-between small"> | ||||
|             <div i18n>Before</div> | ||||
|             <a *ngIf="dateBefore" class="btn btn-link p-0 m-0" (click)="clearBefore()"> | ||||
|               <svg width="0.8em" height="0.8em" 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 fill="currentColor" class="buttonicon-sm"> | ||||
|                 <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|               </svg> | ||||
|               <small i18n>Clear</small> | ||||
|             </a> | ||||
| @@ -52,8 +52,8 @@ | ||||
|             <input class="form-control" [placeholder]="datePlaceHolder" (dateSelect)="onChangeDebounce()" (change)="onChangeDebounce()" (keypress)="onKeyPress($event)" | ||||
|                     maxlength="10" [(ngModel)]="dateBefore" ngbDatepicker #dateBeforePicker="ngbDatepicker"> | ||||
|             <button class="btn btn-outline-secondary" (click)="dateBeforePicker.toggle()" type="button"> | ||||
|               <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16"> | ||||
|                 <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/> | ||||
|               <svg fill="currentColor" class="buttonicon-sm"> | ||||
|                 <use xlink:href="assets/bootstrap-icons.svg#calendar"/> | ||||
|               </svg> | ||||
|             </button> | ||||
|           </div> | ||||
|   | ||||
| @@ -1,18 +1,18 @@ | ||||
| <button class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" (click)="toggleItem($event)" [disabled]="disabled"> | ||||
|   <div class="selected-icon me-1"> | ||||
|     <ng-container *ngIf="isChecked()"> | ||||
|       <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> | ||||
|         <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 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.267.267 0 0 1 .02-.022z"/> | ||||
|       <svg fill="currentColor" class="buttonicon-sm bi-check"> | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#check"/> | ||||
|       </svg> | ||||
|     </ng-container> | ||||
|     <ng-container *ngIf="isPartiallyChecked()"> | ||||
|       <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-dash" viewBox="0 0 16 16"> | ||||
|         <path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8z"/> | ||||
|       <svg fill="currentColor" class="buttonicon-sm bi-dash"> | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#dash"/> | ||||
|       </svg> | ||||
|     </ng-container> | ||||
|     <ng-container *ngIf="isExcluded()"> | ||||
|       <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-x" viewBox="0 0 16 16"> | ||||
|         <path 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 fill="currentColor" class="buttonicon-sm bi-x"> | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|       </svg> | ||||
|     </ng-container> | ||||
|   </div> | ||||
|   | ||||
| @@ -1,16 +1,17 @@ | ||||
| <div class="btn-group w-100" ngbDropdown role="group"> | ||||
|     <button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="isActive ? 'btn-primary' : 'btn-outline-primary'"> | ||||
|         <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor"> | ||||
|         <svg class="toolbaricon" fill="currentColor"> | ||||
|            <use xlink:href="assets/bootstrap-icons.svg#person-fill-lock" /> | ||||
|         </svg> {{title}} | ||||
|         </svg> | ||||
|         <div class="d-none d-sm-inline"> {{title}}</div> | ||||
|       <app-clearable-badge [selected]="isActive" (cleared)="reset()"></app-clearable-badge><span class="visually-hidden">selected</span> | ||||
|     </button> | ||||
|     <div class="dropdown-menu permission-filter-dropdown shadow py-0 w-2" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}"> | ||||
|         <div class="list-group list-group-flush"> | ||||
|             <button class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" (click)="setFilter(OwnerFilterType.NONE)" [disabled]="disabled"> | ||||
|                 <div class="selected-icon me-1"> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.NONE" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> | ||||
|                         <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 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.267.267 0 0 1 .02-.022z"/> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.NONE" fill="currentColor" class="buttonicon-sm"> | ||||
|                         <use xlink:href="assets/bootstrap-icons.svg#check"/> | ||||
|                     </svg> | ||||
|                 </div> | ||||
|                 <div class="me-1"> | ||||
| @@ -19,8 +20,8 @@ | ||||
|             </button> | ||||
|             <button class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" (click)="setFilter(OwnerFilterType.SELF)" [disabled]="disabled"> | ||||
|                 <div class="selected-icon me-1"> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.SELF" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> | ||||
|                         <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 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.267.267 0 0 1 .02-.022z"/> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.SELF" fill="currentColor" class="buttonicon-sm"> | ||||
|                         <use xlink:href="assets/bootstrap-icons.svg#check"/> | ||||
|                     </svg> | ||||
|                 </div> | ||||
|                 <div class="me-1"> | ||||
| @@ -29,8 +30,8 @@ | ||||
|             </button> | ||||
|             <button class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" (click)="setFilter(OwnerFilterType.NOT_SELF)" [disabled]="disabled"> | ||||
|                 <div class="selected-icon me-1"> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.NOT_SELF" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> | ||||
|                         <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 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.267.267 0 0 1 .02-.022z"/> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.NOT_SELF" fill="currentColor" class="buttonicon-sm"> | ||||
|                         <use xlink:href="assets/bootstrap-icons.svg#check"/> | ||||
|                     </svg> | ||||
|                 </div> | ||||
|                 <div class="me-1"> | ||||
| @@ -39,8 +40,8 @@ | ||||
|             </button> | ||||
|             <button class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" (click)="setFilter(OwnerFilterType.UNOWNED)" [disabled]="disabled"> | ||||
|                 <div class="selected-icon me-1"> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.UNOWNED" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> | ||||
|                         <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 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.267.267 0 0 1 .02-.022z"/> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.UNOWNED" fill="currentColor" class="buttonicon-sm"> | ||||
|                         <use xlink:href="assets/bootstrap-icons.svg#check"/> | ||||
|                     </svg> | ||||
|                 </div> | ||||
|                 <div class="me-1"> | ||||
| @@ -49,8 +50,8 @@ | ||||
|             </button> | ||||
|             <button *appIfPermissions="{ action: PermissionAction.Add, type: PermissionType.User }" class="list-group-item list-group-item-action d-flex align-items-center p-2 border-top-0 border-start-0 border-end-0 border-bottom" role="menuitem" [disabled]="disabled"> | ||||
|                 <div class="selected-icon me-1"> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.OTHERS" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16"> | ||||
|                         <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 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.267.267 0 0 1 .02-.022z"/> | ||||
|                     <svg *ngIf="selectionModel.ownerFilter === OwnerFilterType.OTHERS" fill="currentColor" class="buttonicon-sm"> | ||||
|                         <use xlink:href="assets/bootstrap-icons.svg#check"/> | ||||
|                     </svg> | ||||
|                 </div> | ||||
|                 <div class="me-1 w-100"> | ||||
| @@ -71,9 +72,9 @@ | ||||
|                 </div> | ||||
|             </button> | ||||
|             <div *ngIf="selectionModel.ownerFilter === OwnerFilterType.NONE || selectionModel.ownerFilter === OwnerFilterType.NOT_SELF" class="list-group-item list-group-item-action d-flex align-items-center p-2 ps-3 border-bottom-0 border-start-0 border-end-0"> | ||||
|                 <div class="form-check form-switch"> | ||||
|                 <div class="form-check form-switch w-100"> | ||||
|                   <input type="checkbox" class="form-check-input" id="hideUnowned" [(ngModel)]="this.selectionModel.hideUnowned" (change)="onChange()" [disabled]="disabled"> | ||||
|                   <label class="form-check-label" for="hideUnowned"><small i18n>Hide unowned</small></label> | ||||
|                   <label class="form-check-label w-100" for="hideUnowned"><small i18n>Hide unowned</small></label> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| <div class="row"> | ||||
|   <div class="col-auto mb-2 mb-xl-0" role="group" aria-label="Select"> | ||||
| <div class="d-flex flex-wrap gap-4"> | ||||
|   <div class="d-flex align-items-center" role="group" aria-label="Select"> | ||||
|     <button class="btn btn-sm btn-outline-secondary" (click)="list.selectNone()"> | ||||
|       <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor"> | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#slash-circle" /> | ||||
|       </svg> <ng-container i18n>Cancel</ng-container> | ||||
|     </button> | ||||
|   </div> | ||||
|   <div class="col-auto mb-2 mb-xl-0 ms-auto ms-md-0" role="group" aria-label="Select"> | ||||
|     <label class="me-2 mb-0" i18n>Select:</label> | ||||
|   <div class="d-flex align-items-center gap-2" role="group" aria-label="Select"> | ||||
|     <label class="me-2" i18n>Select:</label> | ||||
|     <div class="btn-group"> | ||||
|       <button class="btn btn-sm btn-outline-primary" (click)="list.selectPage()"> | ||||
|         <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor"> | ||||
| @@ -21,11 +21,9 @@ | ||||
|       </button> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="w-100 d-xl-none"></div> | ||||
|   <div class="col-auto mb-2 mb-xl-0"> | ||||
|     <div class="d-flex" *appIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }"> | ||||
|       <label class="ms-auto mt-1 mb-0 me-2" i18n>Edit:</label> | ||||
|       <app-filterable-dropdown class="me-2 me-md-3" title="Tags" icon="tag-fill" i18n-title | ||||
|     <div class="d-flex align-items-center gap-2" *appIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }"> | ||||
|       <label class="me-2" i18n>Edit:</label> | ||||
|       <app-filterable-dropdown title="Tags" icon="tag-fill" i18n-title | ||||
|         filterPlaceholder="Filter tags" i18n-filterPlaceholder | ||||
|         [items]="tags" | ||||
|         [disabled]="!userCanEditAll" | ||||
| @@ -37,7 +35,7 @@ | ||||
|         [documentCounts]="tagDocumentCounts" | ||||
|         (apply)="setTags($event)"> | ||||
|       </app-filterable-dropdown> | ||||
|       <app-filterable-dropdown class="me-2 me-md-3" title="Correspondent" icon="person-fill" i18n-title | ||||
|       <app-filterable-dropdown title="Correspondent" icon="person-fill" i18n-title | ||||
|         filterPlaceholder="Filter correspondents" i18n-filterPlaceholder | ||||
|         [items]="correspondents" | ||||
|         [disabled]="!userCanEditAll" | ||||
| @@ -48,7 +46,7 @@ | ||||
|         [documentCounts]="correspondentDocumentCounts" | ||||
|         (apply)="setCorrespondents($event)"> | ||||
|       </app-filterable-dropdown> | ||||
|       <app-filterable-dropdown class="me-2 me-md-3" title="Document type" icon="file-earmark-fill" i18n-title | ||||
|       <app-filterable-dropdown title="Document type" icon="file-earmark-fill" i18n-title | ||||
|         filterPlaceholder="Filter document types" i18n-filterPlaceholder | ||||
|         [items]="documentTypes" | ||||
|         [disabled]="!userCanEditAll" | ||||
| @@ -59,7 +57,7 @@ | ||||
|         [documentCounts]="documentTypeDocumentCounts" | ||||
|         (apply)="setDocumentTypes($event)"> | ||||
|       </app-filterable-dropdown> | ||||
|       <app-filterable-dropdown class="me-2 me-md-3" title="Storage path" icon="folder-fill" i18n-title | ||||
|       <app-filterable-dropdown title="Storage path" icon="folder-fill" i18n-title | ||||
|         filterPlaceholder="Filter storage paths" i18n-filterPlaceholder | ||||
|         [items]="storagePaths" | ||||
|         [disabled]="!userCanEditAll" | ||||
| @@ -70,18 +68,17 @@ | ||||
|         [documentCounts]="storagePathDocumentCounts" | ||||
|         (apply)="setStoragePaths($event)"> | ||||
|       </app-filterable-dropdown> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="col-auto ms-auto mb-2 mb-xl-0 d-flex"> | ||||
|     <div class="btn-toolbar me-2"> | ||||
|   <div class="d-flex align-items-center gap-2 ms-auto"> | ||||
|     <div class="btn-toolbar"> | ||||
|  | ||||
|       <button type="button" class="btn btn-sm btn-outline-primary me-2" (click)="setPermissions()" [disabled]="!userOwnsAll || !userCanEditAll"> | ||||
|         <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor"> | ||||
|           <use xlink:href="assets/bootstrap-icons.svg#person-fill-lock" /> | ||||
|         </svg> <ng-container i18n>Permissions</ng-container> | ||||
|         </svg><div class="d-none d-sm-inline"> <ng-container i18n>Permissions</ng-container></div> | ||||
|       </button> | ||||
|  | ||||
|       <div ngbDropdown class="me-2 d-flex"> | ||||
|       <div ngbDropdown> | ||||
|         <button class="btn btn-sm btn-outline-primary" id="dropdownSelect" ngbDropdownToggle> | ||||
|           <svg class="toolbaricon" fill="currentColor"> | ||||
|             <use xlink:href="assets/bootstrap-icons.svg#three-dots" /> | ||||
| @@ -94,7 +91,7 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="btn-group btn-group-sm me-2"> | ||||
|     <div class="btn-group btn-group-sm"> | ||||
|       <button class="btn btn-sm btn-outline-primary" [disabled]="awaitingDownload" (click)="downloadSelected()"> | ||||
|         <svg *ngIf="!awaitingDownload" class="toolbaricon" fill="currentColor"> | ||||
|           <use xlink:href="assets/bootstrap-icons.svg#arrow-down" /> | ||||
| @@ -134,7 +131,7 @@ | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <div class="btn-group btn-group-sm me-2"> | ||||
|     <div class="btn-group btn-group-sm"> | ||||
|       <button type="button" class="btn btn-sm btn-outline-danger" (click)="applyDelete()" *appIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.Document }" [disabled]="!userOwnsAll"> | ||||
|         <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor"> | ||||
|           <use xlink:href="assets/bootstrap-icons.svg#trash" /> | ||||
|   | ||||
| @@ -81,15 +81,15 @@ | ||||
|  | ||||
| </app-page-header> | ||||
|  | ||||
| <div class="row sticky-top pt-3 pt-sm-4 pb-2 pb-lg-4 bg-body"> | ||||
| <div class="row sticky-top pt-3 pt-sm-4 pb-3 pb-lg-4 bg-body"> | ||||
|   <app-filter-editor [hidden]="isBulkEditing" [(filterRules)]="list.filterRules" [unmodifiedFilterRules]="unmodifiedFilterRules" [selectionData]="list.selectionData" #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> | ||||
|   <div class="d-flex flex-wrap gap-3 justify-content-between align-items-center mb-3"> | ||||
|     <div class="d-flex align-items-center"> | ||||
|       <ng-container *ngIf="list.isReloading"> | ||||
|         <div class="spinner-border spinner-border-sm me-2" role="status"></div> | ||||
|         <ng-container i18n>Loading...</ng-container> | ||||
| @@ -98,9 +98,14 @@ | ||||
|       <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> | ||||
|       <button *ngIf="!list.isReloading && isFiltered" class="btn btn-link py-0" (click)="resetFilters()"> | ||||
|         <svg fill="currentColor" class="buttonicon-sm"> | ||||
|           <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|         </svg><small i18n>Reset filters</small> | ||||
|       </button> | ||||
|     </div> | ||||
|     <ngb-pagination *ngIf="list.collectionSize" [pageSize]="list.currentPageSize" [collectionSize]="list.collectionSize" [(page)]="list.currentPage" [maxSize]="5" | ||||
|     [rotate]="true" aria-label="Default pagination"></ngb-pagination> | ||||
|     [rotate]="true" aria-label="Default pagination" size="sm"></ngb-pagination> | ||||
|   </div> | ||||
| </ng-template> | ||||
|  | ||||
|   | ||||
| @@ -300,4 +300,8 @@ export class DocumentListComponent | ||||
|   get notesEnabled(): boolean { | ||||
|     return this.settingsService.get(SETTINGS_KEYS.NOTES_ENABLED) | ||||
|   } | ||||
|  | ||||
|   resetFilters() { | ||||
|     this.filterEditor.resetSelected() | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <div class="row flex-wrap" tourAnchor="tour.documents-filter-editor"> | ||||
|    <div class="col mb-2 mb-xxl-0"> | ||||
|    <div class="col mb-3 mb-xxl-0"> | ||||
|      <div class="form-inline d-flex align-items-center"> | ||||
|          <div class="input-group input-group-sm flex-fill w-auto flex-nowrap"> | ||||
|            <div ngbDropdown> | ||||
| @@ -12,8 +12,8 @@ | ||||
|             <option *ngFor="let m of textFilterModifiers" ngbDropdownItem [value]="m.id">{{m.label}}</option> | ||||
|           </select> | ||||
|           <button *ngIf="_textFilter" class="btn btn-link btn-sm px-0 position-absolute top-0 end-0 z-10" (click)="resetTextField()"> | ||||
|             <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-x me-1" 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 fill="currentColor" class="buttonicon-sm me-1"> | ||||
|               <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|             </svg> | ||||
|           </button> | ||||
|           <input #textFilterInput class="form-control form-control-sm" type="text" [disabled]="textFilterModifierIsNull" [(ngModel)]="textFilter" (keyup)="textFilterKeyup($event)" [readonly]="textFilterTarget === 'fulltext-morelike'"> | ||||
| @@ -22,8 +22,8 @@ | ||||
|   </div> | ||||
|   <div class="w-100 d-xxl-none"></div> | ||||
|     <div class="col col-xl-auto"> | ||||
|       <div class="d-flex flex-wrap"> | ||||
|         <div class="d-flex flex-wrap mb-2 mb-xxl-0"> | ||||
|       <div class="d-flex flex-wrap gap-3"> | ||||
|         <div class="d-flex flex-wrap gap-2"> | ||||
|           <app-filterable-dropdown class="flex-fill" title="Tags" icon="tag-fill" i18n-title | ||||
|             filterPlaceholder="Filter tags" i18n-filterPlaceholder | ||||
|             [items]="tags" | ||||
| @@ -49,7 +49,7 @@ | ||||
|             (opened)="onDocumentTypeDropdownOpen()" | ||||
|             [documentCounts]="documentTypeDocumentCounts" | ||||
|             [allowSelectNone]="true"></app-filterable-dropdown> | ||||
|           <app-filterable-dropdown class="me-2 flex-fill" title="Storage path" icon="folder-fill" i18n-title | ||||
|           <app-filterable-dropdown class="flex-fill" title="Storage path" icon="folder-fill" i18n-title | ||||
|             filterPlaceholder="Filter storage paths" i18n-filterPlaceholder | ||||
|             [items]="storagePaths" | ||||
|             [(selectionModel)]="storagePathSelectionModel" | ||||
| @@ -58,14 +58,14 @@ | ||||
|             [documentCounts]="storagePathDocumentCounts" | ||||
|             [allowSelectNone]="true"></app-filterable-dropdown> | ||||
|         </div> | ||||
|         <div class="d-flex flex-wrap mb-2 mb-xxl-0"> | ||||
|           <app-date-dropdown class="mb-2 mb-xl-0" | ||||
|         <div class="d-flex flex-wrap gap-2"> | ||||
|           <app-date-dropdown | ||||
|             title="Created" i18n-title | ||||
|             (datesSet)="updateRules()" | ||||
|             [(dateBefore)]="dateCreatedBefore" | ||||
|             [(dateAfter)]="dateCreatedAfter" | ||||
|             [(relativeDate)]="dateCreatedRelativeDate"></app-date-dropdown> | ||||
|           <app-date-dropdown class="mb-2 mb-xl-0 me-2" | ||||
|           <app-date-dropdown | ||||
|             title="Added" i18n-title | ||||
|             (datesSet)="updateRules()" | ||||
|             [(dateBefore)]="dateAddedBefore" | ||||
| @@ -73,19 +73,18 @@ | ||||
|             [(relativeDate)]="dateAddedRelativeDate"></app-date-dropdown> | ||||
|         </div> | ||||
|         <div class="d-flex flex-wrap"> | ||||
|           <app-permissions-filter-dropdown class="mb-2 mb-xl-0" | ||||
|           <app-permissions-filter-dropdown | ||||
|             title="Permissions" i18n-title | ||||
|             (ownerFilterSet)="updateRules()" | ||||
|             [(selectionModel)]="permissionsSelectionModel"></app-permissions-filter-dropdown> | ||||
|         </div> | ||||
|         <div class="d-flex flex-wrap d-none d-sm-inline-block"> | ||||
|           <button class="btn btn-outline-secondary btn-sm" [disabled]="!rulesModified" (click)="resetSelected()"> | ||||
|             <svg class="toolbaricon ms-n1" fill="currentColor"> | ||||
|               <use xlink:href="assets/bootstrap-icons.svg#x"></use> | ||||
|             </svg><ng-container i18n>Reset filters</ng-container> | ||||
|           </button> | ||||
|         </div> | ||||
|      </div> | ||||
|    </div> | ||||
|    <div class="w-100 d-xxl-none"></div> | ||||
|    <div class="col col-xl-auto ps-xxl-0"> | ||||
|      <button class="btn btn-link btn-sm px-0" [disabled]="!rulesModified" (click)="resetSelected()"> | ||||
|        <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-x me-1 ms-n1" 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><ng-container i18n>Reset filters</ng-container> | ||||
|      </button> | ||||
|    </div> | ||||
| </div> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <button type="button" class="btn btn-sm btn-outline-primary" (click)="openCreateDialog()" *appIfPermissions="{ action: PermissionAction.Add, type: permissionType }" i18n>Create</button> | ||||
| </app-page-header> | ||||
|  | ||||
| <div class="row"> | ||||
| <div class="row mb-3"> | ||||
|   <div class="col-md mb-2 mb-xl-0"> | ||||
|     <div class="form-inline d-flex align-items-center"> | ||||
|       <label class="text-muted me-2 mb-0" i18n>Filter by:</label> | ||||
| @@ -10,7 +10,7 @@ | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <ngb-pagination class="col-auto" [pageSize]="25" [collectionSize]="collectionSize" [(page)]="page" [maxSize]="5" (pageChange)="reloadData()" aria-label="Default pagination"></ngb-pagination> | ||||
|   <ngb-pagination class="col-auto" [pageSize]="25" [collectionSize]="collectionSize" [(page)]="page" [maxSize]="5" (pageChange)="reloadData()" size="sm" aria-label="Pagination"></ngb-pagination> | ||||
| </div> | ||||
|  | ||||
| <table class="table table-striped align-middle border shadow-sm"> | ||||
| @@ -72,5 +72,5 @@ | ||||
|  | ||||
| <div class="d-flex"> | ||||
|   <div i18n *ngIf="collectionSize > 0">{collectionSize, plural, =1 {One {{typeName}}} other {{{collectionSize || 0}} total {{typeNamePlural}}}}</div> | ||||
|   <ngb-pagination *ngIf="collectionSize > 20" class="ms-auto" [pageSize]="25" [collectionSize]="collectionSize" [(page)]="page" [maxSize]="5" (pageChange)="reloadData()" aria-label="Default pagination"></ngb-pagination> | ||||
|   <ngb-pagination *ngIf="collectionSize > 20" class="ms-auto" [pageSize]="25" [collectionSize]="collectionSize" [(page)]="page" [maxSize]="5" (pageChange)="reloadData()" size="sm" aria-label="Pagination"></ngb-pagination> | ||||
| </div> | ||||
|   | ||||
| @@ -125,8 +125,8 @@ | ||||
|           </div> | ||||
|           <div class="col-2"> | ||||
|             <button class="btn btn-link btn-sm pt-2 ps-0" [disabled]="!this.settingsForm.get('themeColor').value" (click)="clearThemeColor()"> | ||||
|               <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-x me-1" 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 fill="currentColor" class="buttonicon-sm me-1"> | ||||
|                 <use xlink:href="assets/bootstrap-icons.svg#x"/> | ||||
|               </svg><ng-container i18n>Reset</ng-container> | ||||
|             </button> | ||||
|           </div> | ||||
|   | ||||
| @@ -304,6 +304,10 @@ textarea, | ||||
|   cursor: not-allowed; | ||||
| } | ||||
|  | ||||
| ul.pagination { | ||||
|   margin-bottom: 0; | ||||
| } | ||||
|  | ||||
| .page-link { | ||||
|   color: var(--bs-secondary); | ||||
|   background-color: var(--bs-body-bg); | ||||
| @@ -317,7 +321,6 @@ textarea, | ||||
|  | ||||
| .page-item.active .page-link { | ||||
|   background-color: var(--bs-primary); | ||||
|   border-color: var(--bs-primary) !important; | ||||
|   color: var(--bs-light); | ||||
| } | ||||
|  | ||||
| @@ -425,6 +428,11 @@ textarea, | ||||
|   height: 1.2em; | ||||
| } | ||||
|  | ||||
| .buttonicon-sm { | ||||
|   width: 1em; | ||||
|   height: 1em; | ||||
| } | ||||
|  | ||||
| .sidebaricon { | ||||
|   width: 16px; | ||||
|   height: 16px; | ||||
|   | ||||
| @@ -75,6 +75,10 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt | ||||
|     color: var(--bs-body-color) !important; | ||||
|   } | ||||
|  | ||||
|   .btn { | ||||
|     --bs-btn-disabled-opacity: 0.35; | ||||
|   } | ||||
|  | ||||
|   .btn-primary { | ||||
|     &:hover, &:focus, &.active, &:active { | ||||
|       color: var(--bs-body-color) !important; | ||||
|   | ||||
| @@ -209,7 +209,7 @@ class DelayedQuery: | ||||
|                     criterias.append(query.Not(query.Term("type_id", document_type_id))) | ||||
|             elif k == "correspondent__isnull": | ||||
|                 criterias.append( | ||||
|                     query.Term("has_correspondent", self.evalBoolean(v)), | ||||
|                     query.Term("has_correspondent", self.evalBoolean(v) is False), | ||||
|                 ) | ||||
|             elif k == "is_tagged": | ||||
|                 criterias.append(query.Term("has_tag", self.evalBoolean(v))) | ||||
|   | ||||
| @@ -1084,15 +1084,15 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): | ||||
|         ) | ||||
|  | ||||
|         self.assertCountEqual( | ||||
|             search_query("&storage_path__isnull"), | ||||
|             search_query("&storage_path__isnull=true"), | ||||
|             [d1.id, d2.id, d3.id, d4.id, d5.id], | ||||
|         ) | ||||
|         self.assertCountEqual( | ||||
|             search_query("&correspondent__isnull"), | ||||
|             search_query("&correspondent__isnull=true"), | ||||
|             [d2.id, d3.id, d4.id, d5.id, d7.id], | ||||
|         ) | ||||
|         self.assertCountEqual( | ||||
|             search_query("&document_type__isnull"), | ||||
|             search_query("&document_type__isnull=true"), | ||||
|             [d1.id, d3.id, d4.id, d5.id, d7.id], | ||||
|         ) | ||||
|         self.assertCountEqual( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 shamoon
					shamoon