mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Enhancement: filterable list count sorting and opacification (#8386)
This commit is contained in:
parent
548a7f05d8
commit
9614528033
@ -2300,7 +2300,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">846</context>
|
||||
<context context-type="linenumber">847</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7266264608936522311" datatype="html">
|
||||
@ -2577,19 +2577,19 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">870</context>
|
||||
<context context-type="linenumber">871</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1169</context>
|
||||
<context context-type="linenumber">1170</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1207</context>
|
||||
<context context-type="linenumber">1208</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1248</context>
|
||||
<context context-type="linenumber">1249</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||
@ -3172,7 +3172,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">823</context>
|
||||
<context context-type="linenumber">824</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||
@ -4901,7 +4901,7 @@
|
||||
<source>Create</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">58</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/share-links-dropdown/share-links-dropdown.component.html</context>
|
||||
@ -4928,21 +4928,21 @@
|
||||
<source>Apply</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
|
||||
<context context-type="linenumber">56</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7780041345210191160" datatype="html">
|
||||
<source>Click again to exclude items.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.html</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7593728289020204896" datatype="html">
|
||||
<source>Not assigned</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
|
||||
<context context-type="linenumber">351</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">Filter drop down element to filter for documents with no correspondent/type/tag assigned</note>
|
||||
</trans-unit>
|
||||
@ -4950,7 +4950,7 @@
|
||||
<source>Open <x id="PH" equiv-text="this.title"/> filter</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
|
||||
<context context-type="linenumber">463</context>
|
||||
<context context-type="linenumber">486</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7005745151564974365" datatype="html">
|
||||
@ -6209,7 +6209,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1225</context>
|
||||
<context context-type="linenumber">1226</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/guards/dirty-saved-view.guard.ts</context>
|
||||
@ -6573,36 +6573,36 @@
|
||||
<source>Document saved successfully.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">737</context>
|
||||
<context context-type="linenumber">738</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">751</context>
|
||||
<context context-type="linenumber">752</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="448882439049417053" datatype="html">
|
||||
<source>Error saving document</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">755</context>
|
||||
<context context-type="linenumber">756</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">796</context>
|
||||
<context context-type="linenumber">797</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8410796510716511826" datatype="html">
|
||||
<source>Do you really want to move the document "<x id="PH" equiv-text="this.document.title"/>" to the trash?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">824</context>
|
||||
<context context-type="linenumber">825</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="282586936710748252" datatype="html">
|
||||
<source>Documents can be restored prior to permanent deletion.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">825</context>
|
||||
<context context-type="linenumber">826</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||
@ -6613,7 +6613,7 @@
|
||||
<source>Move to trash</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">827</context>
|
||||
<context context-type="linenumber">828</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||
@ -6624,7 +6624,7 @@
|
||||
<source>Reprocess confirm</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">866</context>
|
||||
<context context-type="linenumber">867</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||
@ -6635,70 +6635,70 @@
|
||||
<source>This operation will permanently recreate the archive file for this document.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">867</context>
|
||||
<context context-type="linenumber">868</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="302054111564709516" datatype="html">
|
||||
<source>The archive file will be re-generated with the current settings.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">868</context>
|
||||
<context context-type="linenumber">869</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1192507664585066165" datatype="html">
|
||||
<source>Reprocess operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">878</context>
|
||||
<context context-type="linenumber">879</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4409560272830824468" datatype="html">
|
||||
<source>Error executing operation</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">889</context>
|
||||
<context context-type="linenumber">890</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4458954481601077369" datatype="html">
|
||||
<source>Page Fit</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">962</context>
|
||||
<context context-type="linenumber">963</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1217563727923422413" datatype="html">
|
||||
<source>Split confirm</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1167</context>
|
||||
<context context-type="linenumber">1168</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2805304563009985503" datatype="html">
|
||||
<source>This operation will split the selected document(s) into new documents.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1168</context>
|
||||
<context context-type="linenumber">1169</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4158171846914923744" datatype="html">
|
||||
<source>Split operation will begin in the background.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1184</context>
|
||||
<context context-type="linenumber">1185</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3235014591864339926" datatype="html">
|
||||
<source>Error executing split operation</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1193</context>
|
||||
<context context-type="linenumber">1194</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6555329262222566158" datatype="html">
|
||||
<source>Rotate confirm</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1205</context>
|
||||
<context context-type="linenumber">1206</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
|
||||
@ -6709,49 +6709,49 @@
|
||||
<source>This operation will permanently rotate the original version of the current document.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1206</context>
|
||||
<context context-type="linenumber">1207</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4069543875319587651" datatype="html">
|
||||
<source>Rotation will begin in the background. Close and re-open the document after the operation has completed to see the changes.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1222</context>
|
||||
<context context-type="linenumber">1223</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2962674215361798818" datatype="html">
|
||||
<source>Error executing rotate operation</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1234</context>
|
||||
<context context-type="linenumber">1235</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3539261415918606512" datatype="html">
|
||||
<source>Delete pages confirm</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1246</context>
|
||||
<context context-type="linenumber">1247</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5854352498125813866" datatype="html">
|
||||
<source>This operation will permanently delete the selected pages from the original document.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1247</context>
|
||||
<context context-type="linenumber">1248</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8617528702531167646" datatype="html">
|
||||
<source>Delete pages operation will begin in the background. Close and re-open or reload this document after the operation has completed to see the changes.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1262</context>
|
||||
<context context-type="linenumber">1263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1249139200486584973" datatype="html">
|
||||
<source>Error executing delete pages operation</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
|
||||
<context context-type="linenumber">1271</context>
|
||||
<context context-type="linenumber">1272</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4958946940233632319" datatype="html">
|
||||
|
@ -38,7 +38,15 @@
|
||||
@for (item of selectionModel.items | filter: filterText:'name'; track item; let i = $index) {
|
||||
@if (allowSelectNone || item.id) {
|
||||
<pngx-toggleable-dropdown-button
|
||||
[item]="item" [hideCount]="hideCount(item)" [state]="selectionModel.get(item.id)" [count]="getUpdatedDocumentCount(item.id)" (toggled)="selectionModel.toggle(item.id)" (exclude)="excludeClicked(item.id)" (click)="setButtonItemIndex(i - 1)" [disabled]="disabled">
|
||||
[item]="item"
|
||||
[hideCount]="hideCount(item)"
|
||||
[opacifyCount]="!editing"
|
||||
[state]="selectionModel.get(item.id)"
|
||||
[count]="getUpdatedDocumentCount(item.id)"
|
||||
(toggled)="selectionModel.toggle(item.id)"
|
||||
(exclude)="excludeClicked(item.id)"
|
||||
(click)="setButtonItemIndex(i - 1)"
|
||||
[disabled]="disabled">
|
||||
</pngx-toggleable-dropdown-button>
|
||||
}
|
||||
}
|
||||
|
@ -509,6 +509,37 @@ describe('FilterableDropdownComponent & FilterableDropdownSelectionModel', () =>
|
||||
])
|
||||
})
|
||||
|
||||
it('selection model should sort items by state and document counts, if set', () => {
|
||||
component.items = items.concat([{ id: 4, name: 'Item D' }])
|
||||
component.selectionModel = selectionModel
|
||||
component.documentCounts = [
|
||||
{ id: 1, document_count: 0 }, // Tag1
|
||||
{ id: 2, document_count: 1 }, // Tag2
|
||||
{ id: 4, document_count: 2 },
|
||||
]
|
||||
component.selectionModel.apply()
|
||||
expect(selectionModel.items).toEqual([
|
||||
nullItem,
|
||||
{ id: 4, name: 'Item D' },
|
||||
items[1], // Tag2
|
||||
items[0], // Tag1
|
||||
])
|
||||
|
||||
selectionModel.toggle(items[1].id)
|
||||
component.documentCounts = [
|
||||
{ id: 1, document_count: 0 },
|
||||
{ id: 2, document_count: 1 },
|
||||
{ id: 4, document_count: 0 },
|
||||
]
|
||||
selectionModel.apply()
|
||||
expect(selectionModel.items).toEqual([
|
||||
nullItem,
|
||||
items[1], // Tag2
|
||||
{ id: 4, name: 'Item D' },
|
||||
items[0], // Tag1
|
||||
])
|
||||
})
|
||||
|
||||
it('should set support create, keep open model and call createRef method', fakeAsync(() => {
|
||||
component.items = items
|
||||
component.icon = 'tag-fill'
|
||||
|
@ -43,6 +43,11 @@ export class FilterableDropdownSelectionModel {
|
||||
private _intersection: Intersection = Intersection.Include
|
||||
temporaryIntersection: Intersection = this._intersection
|
||||
|
||||
private _documentCounts: SelectionDataItem[] = []
|
||||
public set documentCounts(counts: SelectionDataItem[]) {
|
||||
this._documentCounts = counts
|
||||
}
|
||||
|
||||
private _items: MatchingModel[] = []
|
||||
get items(): MatchingModel[] {
|
||||
return this._items
|
||||
@ -69,6 +74,16 @@ export class FilterableDropdownSelectionModel {
|
||||
this.getNonTemporary(b.id) == ToggleableItemState.NotSelected
|
||||
) {
|
||||
return -1
|
||||
} else if (
|
||||
this._documentCounts.length &&
|
||||
this.getDocumentCount(a.id) > this.getDocumentCount(b.id)
|
||||
) {
|
||||
return -1
|
||||
} else if (
|
||||
this._documentCounts.length &&
|
||||
this.getDocumentCount(a.id) < this.getDocumentCount(b.id)
|
||||
) {
|
||||
return 1
|
||||
} else {
|
||||
return a.name.localeCompare(b.name)
|
||||
}
|
||||
@ -286,6 +301,10 @@ export class FilterableDropdownSelectionModel {
|
||||
)
|
||||
}
|
||||
|
||||
getDocumentCount(id: number) {
|
||||
return this._documentCounts.find((c) => c.id === id)?.document_count
|
||||
}
|
||||
|
||||
init(map: Map<number, ToggleableItemState>) {
|
||||
this.temporarySelectionStates = map
|
||||
this.apply()
|
||||
@ -431,7 +450,11 @@ export class FilterableDropdownComponent implements OnDestroy, OnInit {
|
||||
}
|
||||
|
||||
@Input()
|
||||
documentCounts: SelectionDataItem[]
|
||||
set documentCounts(counts: SelectionDataItem[]) {
|
||||
if (counts) {
|
||||
this.selectionModel.documentCounts = counts
|
||||
}
|
||||
}
|
||||
|
||||
@Input()
|
||||
shortcutKey: string
|
||||
@ -544,9 +567,7 @@ export class FilterableDropdownComponent implements OnDestroy, OnInit {
|
||||
}
|
||||
|
||||
getUpdatedDocumentCount(id: number) {
|
||||
if (this.documentCounts) {
|
||||
return this.documentCounts.find((c) => c.id === id)?.document_count
|
||||
}
|
||||
return this.selectionModel.getDocumentCount(id)
|
||||
}
|
||||
|
||||
listKeyDown(event: KeyboardEvent) {
|
||||
|
@ -1,4 +1,9 @@
|
||||
<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">
|
||||
<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"
|
||||
[class.opacity-50]="opacifyCount && !hideCount && currentCount === 0"
|
||||
role="menuitem"
|
||||
(click)="toggleItem($event)"
|
||||
[disabled]="disabled">
|
||||
<div class="selected-icon me-1">
|
||||
@if (isChecked()) {
|
||||
<i-bs width="1em" height="1em" name="check"></i-bs>
|
||||
@ -18,6 +23,6 @@
|
||||
}
|
||||
</div>
|
||||
@if (!hideCount) {
|
||||
<div class="badge bg-light text-dark rounded-pill ms-auto me-1">{{count ?? item.document_count}}</div>
|
||||
<div class="badge bg-light text-dark rounded-pill ms-auto me-1">{{currentCount}}</div>
|
||||
}
|
||||
</button>
|
||||
|
@ -29,6 +29,9 @@ export class ToggleableDropdownButtonComponent {
|
||||
@Input()
|
||||
hideCount: boolean = false
|
||||
|
||||
@Input()
|
||||
opacifyCount: boolean = true
|
||||
|
||||
@Output()
|
||||
toggled = new EventEmitter()
|
||||
|
||||
@ -39,6 +42,10 @@ export class ToggleableDropdownButtonComponent {
|
||||
return 'is_inbox_tag' in this.item
|
||||
}
|
||||
|
||||
get currentCount(): number {
|
||||
return this.count ?? this.item.document_count
|
||||
}
|
||||
|
||||
toggleItem(event: MouseEvent): void {
|
||||
if (this.state == ToggleableItemState.Selected) {
|
||||
this.exclude.emit()
|
||||
|
Loading…
x
Reference in New Issue
Block a user