]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Add "clearable" badge
authorMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Sat, 29 Oct 2022 22:03:27 +0000 (15:03 -0700)
committerMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Sat, 29 Oct 2022 22:03:27 +0000 (15:03 -0700)
src-ui/src/app/app.module.ts
src-ui/src/app/components/common/clearable-badge/clearable-badge.component.html [new file with mode: 0644]
src-ui/src/app/components/common/clearable-badge/clearable-badge.component.scss [new file with mode: 0644]
src-ui/src/app/components/common/clearable-badge/clearable-badge.component.ts [new file with mode: 0644]
src-ui/src/app/components/common/date-dropdown/date-dropdown.component.html
src-ui/src/app/components/common/date-dropdown/date-dropdown.component.ts
src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.html
src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts

index 02fd8ea66a5c8d0296afc299b12cbeb358fc8b0a..c5afc6942f30d4e81c0e1e18c2df9ba5a0d3d1e0 100644 (file)
@@ -24,6 +24,7 @@ import { CorrespondentEditDialogComponent } from './components/common/edit-dialo
 import { TagEditDialogComponent } from './components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component'
 import { DocumentTypeEditDialogComponent } from './components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component'
 import { TagComponent } from './components/common/tag/tag.component'
+import { ClearableBadge } from './components/common/clearable-badge/clearable-badge.component'
 import { PageHeaderComponent } from './components/common/page-header/page-header.component'
 import { AppFrameComponent } from './components/app-frame/app-frame.component'
 import { ToastsComponent } from './components/common/toasts/toasts.component'
@@ -141,6 +142,7 @@ function initializeApp(settings: SettingsService) {
     DocumentTypeEditDialogComponent,
     StoragePathEditDialogComponent,
     TagComponent,
+    ClearableBadge,
     PageHeaderComponent,
     AppFrameComponent,
     ToastsComponent,
diff --git a/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.html b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.html
new file mode 100644 (file)
index 0000000..64727e0
--- /dev/null
@@ -0,0 +1,9 @@
+<button *ngIf="active" class="position-absolute top-0 start-100 translate-middle badge bg-secondary border border-light rounded-circle p-1" title="Clear" i18n-title (click)="onClick($event)">
+    <svg *ngIf="!isNumbered && selected" width="1em" height="1em" class="check m-0 p-0 opacity-75" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+        <use xlink:href="assets/bootstrap-icons.svg#check-lg"/>
+    </svg>
+    <div *ngIf="isNumbered" class="number">{{number}}<span class="visually-hidden">selected</span></div>
+    <svg width=".9em" height="1em" class="x m-0 p-0 opacity-75" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+        <use xlink:href="assets/bootstrap-icons.svg#x-lg"/>
+    </svg>
+</button>
diff --git a/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.scss b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.scss
new file mode 100644 (file)
index 0000000..14ca3fd
--- /dev/null
@@ -0,0 +1,25 @@
+.badge {
+    width: 20px;
+    height: 20px;
+}
+
+.x {
+    display: none;
+}
+
+.number {
+    width: 1em;
+    height: 1em;
+    display: inline-block;
+}
+
+button:hover {
+    .check,
+    .number {
+        display: none;
+    }
+
+    .x {
+        display: inline-block;
+    }
+}
diff --git a/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.ts b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.ts
new file mode 100644 (file)
index 0000000..93f63d4
--- /dev/null
@@ -0,0 +1,33 @@
+import { Component, Input, Output, EventEmitter } from '@angular/core'
+
+@Component({
+  selector: 'app-clearable-badge',
+  templateUrl: './clearable-badge.component.html',
+  styleUrls: ['./clearable-badge.component.scss'],
+})
+export class ClearableBadge {
+  constructor() {}
+
+  @Input()
+  number: number
+
+  @Input()
+  selected: boolean
+
+  @Output()
+  cleared: EventEmitter<boolean> = new EventEmitter()
+
+  get active(): boolean {
+    return this.selected || this.number > -1
+  }
+
+  get isNumbered(): boolean {
+    return this.number > -1
+  }
+
+  onClick(event: PointerEvent) {
+    this.cleared.emit(true)
+    event.stopImmediatePropagation()
+    event.preventDefault()
+  }
+}
index dc8ae868858b67b6d6382502cfb68bcb41dea873..58634b4d011f82c90a76ef51e515043b3ceec8b8 100644 (file)
@@ -1,11 +1,7 @@
   <div class="btn-group w-100" ngbDropdown role="group">
   <button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="dateBefore || dateAfter ? 'btn-primary' : 'btn-outline-primary'">
     {{title}}
-    <div *ngIf="isActive" class="position-absolute top-0 start-100 p-1 translate-middle badge bg-secondary border border-light rounded-circle">
-      <svg width="1em" height="1em" class="m-0 p-0 opacity-75" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
-        <use xlink:href="assets/bootstrap-icons.svg#check-lg"/>
-      </svg><span class="visually-hidden">selected</span>
-    </div>
+    <app-clearable-badge [selected]="isActive" (cleared)="reset()"></app-clearable-badge><span class="visually-hidden">selected</span>
   </button>
   <div class="dropdown-menu date-dropdown shadow pt-0" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
     <div class="list-group list-group-flush">
index 9eb4c477adab054b70d1bf85016fe5de99be4278..e901acfeb8d8c96cefdad1738247babc9b87c77d 100644 (file)
@@ -106,6 +106,13 @@ export class DateDropdownComponent implements OnInit, OnDestroy {
     }
   }
 
+  reset() {
+    this.dateBefore = null
+    this.dateAfter = null
+    this.relativeDate = null
+    this.onChange()
+  }
+
   setRelativeDate(rd: RelativeDate) {
     this.dateBefore = null
     this.dateAfter = null
index eef92c4eb41096c9f23d6425e671d50044596da1..9ce3c8da22535bc07c542667b7fd6709af391840 100644 (file)
@@ -5,14 +5,7 @@
     </svg>
     <div class="d-none d-sm-inline">&nbsp;{{title}}</div>
     <ng-container *ngIf="!editing && selectionModel.selectionSize() > 0">
-      <div *ngIf="multiple" class="position-absolute top-0 start-100 translate-middle badge bg-secondary border border-light text-light rounded-pill">
-        {{selectionModel.totalCount}}<span class="visually-hidden">selected</span>
-      </div>
-      <div *ngIf="!multiple" class="position-absolute top-0 start-100 p-1 translate-middle badge bg-secondary border border-light rounded-circle">
-        <svg width="1em" height="1em" class="m-0 p-0 opacity-75" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
-          <use xlink:href="assets/bootstrap-icons.svg#check-lg"/>
-        </svg><span class="visually-hidden">selected</span>
-      </div>
+      <app-clearable-badge [number]="multiple ? selectionModel.totalCount : undefined" [selected]="!multiple && selectionModel.selectionSize() > 0" (cleared)="reset()"></app-clearable-badge>
     </ng-container>
   </button>
   <div class="dropdown-menu py-0 shadow" ngbDropdownMenu attr.aria-labelledby="dropdown{{title}}">
index 9a16b4426d81abe89cf4cf7e07bdda307a4c042b..373f0aa5dc0cb1c9b2a80c4b25d015bff3000cb7 100644 (file)
@@ -384,4 +384,9 @@ export class FilterableDropdownComponent {
       this.selectionModel.exclude(itemID)
     }
   }
+
+  reset() {
+    this.selectionModel.reset()
+    this.selectionModelChange.emit(this.selectionModel)
+  }
 }