mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-09-14 21:45:37 -05:00
Cool parent revealing in detail dropdown
This commit is contained in:
@@ -26,9 +26,20 @@
|
|||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template ng-option-tmp let-item="item" let-index="index" let-search="searchTerm">
|
<ng-template ng-option-tmp let-item="item" let-index="index" let-search="searchTerm">
|
||||||
<div class="tag-wrap">
|
<div class="tag-option-row d-flex align-items-center">
|
||||||
@if (item.id && tags) {
|
@if (item.id && tags) {
|
||||||
<pngx-tag class="me-2" [tag]="getTag(item.id)" showParents="true"></pngx-tag>
|
@if (getTag(item.id)?.parent) {
|
||||||
|
<i-bs name="list-nested" class="me-1"></i-bs>
|
||||||
|
<span class="hierarchy-reveal d-flex align-items-center">
|
||||||
|
<span class="parents d-flex align-items-center">
|
||||||
|
@for (p of getParentChain(item.id); track p.id) {
|
||||||
|
<span class="badge me-1" [style.background]="p.color" [style.color]="p.text_color">{{p.name}}</span>
|
||||||
|
<i-bs name="chevron-right" width=".8em" height=".8em" class="me-1"></i-bs>
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
<pngx-tag class="current-tag d-flex" [tag]="getTag(item.id)"></pngx-tag>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@@ -20,3 +20,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dropdown hierarchy reveal for ng-select options
|
||||||
|
::ng-deep .ng-dropdown-panel .ng-option {
|
||||||
|
.tag-option-row {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hierarchy-reveal {
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 0;
|
||||||
|
transition: max-width 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .hierarchy-indicator {
|
||||||
|
// display: inline-block;
|
||||||
|
// width: .35rem;
|
||||||
|
// height: 1rem;
|
||||||
|
// border-radius: .25rem;
|
||||||
|
// background: var(--pngx-border-color, rgba(0,0,0,.2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
.parents .badge {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand reveal area when hovering or when option is keyboard-marked
|
||||||
|
::ng-deep .ng-dropdown-panel .ng-option:hover .hierarchy-reveal,
|
||||||
|
::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked .hierarchy-reveal {
|
||||||
|
max-width: 1000px; // effectively "auto" for transition
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade indicator when expanded
|
||||||
|
::ng-deep .ng-dropdown-panel .ng-option:hover .hierarchy-indicator,
|
||||||
|
::ng-deep .ng-dropdown-panel .ng-option.ng-option-marked .hierarchy-indicator {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
@@ -211,4 +211,22 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
|
|||||||
this.tags.filter((t) => this.value.includes(t.id))
|
this.tags.filter((t) => this.value.includes(t.id))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns ancestors from root → immediate parent for a tag id
|
||||||
|
*/
|
||||||
|
getParentChain(id: number): Tag[] {
|
||||||
|
const chain: Tag[] = []
|
||||||
|
let current = this.getTag(id)
|
||||||
|
const guard = new Set<number>()
|
||||||
|
while (current?.parent) {
|
||||||
|
if (guard.has(current.parent)) break
|
||||||
|
guard.add(current.parent)
|
||||||
|
const parent = this.getTag(current.parent)
|
||||||
|
if (!parent) break
|
||||||
|
chain.unshift(parent)
|
||||||
|
current = parent
|
||||||
|
}
|
||||||
|
return chain
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,6 +55,7 @@ import {
|
|||||||
checkLg,
|
checkLg,
|
||||||
chevronDoubleLeft,
|
chevronDoubleLeft,
|
||||||
chevronDoubleRight,
|
chevronDoubleRight,
|
||||||
|
chevronRight,
|
||||||
clipboard,
|
clipboard,
|
||||||
clipboardCheck,
|
clipboardCheck,
|
||||||
clipboardCheckFill,
|
clipboardCheckFill,
|
||||||
@@ -94,6 +95,7 @@ import {
|
|||||||
infoCircle,
|
infoCircle,
|
||||||
journals,
|
journals,
|
||||||
link,
|
link,
|
||||||
|
listNested,
|
||||||
listTask,
|
listTask,
|
||||||
listUl,
|
listUl,
|
||||||
microsoft,
|
microsoft,
|
||||||
@@ -264,6 +266,7 @@ const icons = {
|
|||||||
checkLg,
|
checkLg,
|
||||||
chevronDoubleLeft,
|
chevronDoubleLeft,
|
||||||
chevronDoubleRight,
|
chevronDoubleRight,
|
||||||
|
chevronRight,
|
||||||
clipboard,
|
clipboard,
|
||||||
clipboardCheck,
|
clipboardCheck,
|
||||||
clipboardCheckFill,
|
clipboardCheckFill,
|
||||||
@@ -303,6 +306,7 @@ const icons = {
|
|||||||
infoCircle,
|
infoCircle,
|
||||||
journals,
|
journals,
|
||||||
link,
|
link,
|
||||||
|
listNested,
|
||||||
listTask,
|
listTask,
|
||||||
listUl,
|
listUl,
|
||||||
microsoft,
|
microsoft,
|
||||||
|
Reference in New Issue
Block a user