mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-11-10 08:21:01 +00:00
Merge branch 'dev' into feature/ocr-templates
This commit is contained in:
33 files changed
+1399
-706
No files matched your search
+18
-11
@@ -4030,14 +4030,21 @@
|
||||
<source>Sources</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.html</context>
|
||||
<context context-type="linenumber">46,47</context>
|
||||
<context context-type="linenumber">47,48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6025275430560167531" datatype="html">
|
||||
<source>+<x id="INTERPOLATION" equiv-text="{{ hiddenReferenceCount(message) }}"/> more</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.html</context>
|
||||
<context context-type="linenumber">49,50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8066608938393600549" datatype="html">
|
||||
<source>Message</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.html</context>
|
||||
<context context-type="linenumber">61,62</context>
|
||||
<context context-type="linenumber">66,67</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/email-document-dialog/email-document-dialog.component.html</context>
|
||||
@@ -4048,22 +4055,22 @@
|
||||
<source>Stop</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.html</context>
|
||||
<context context-type="linenumber">74</context>
|
||||
<context context-type="linenumber">79</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.html</context>
|
||||
<context context-type="linenumber">74</context>
|
||||
<context context-type="linenumber">79</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6490688569532630280" datatype="html">
|
||||
<source>Send</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.html</context>
|
||||
<context context-type="linenumber">78</context>
|
||||
<context context-type="linenumber">83</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.html</context>
|
||||
<context context-type="linenumber">78</context>
|
||||
<context context-type="linenumber">83</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
|
||||
@@ -4090,14 +4097,14 @@
|
||||
<source>Ask a question about this document...</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">83</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="224049052163028286" datatype="html">
|
||||
<source>Ask a question about a document...</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/chat/chat/chat.component.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">84</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8700121026680200191" datatype="html">
|
||||
@@ -6984,7 +6991,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/input/select/select.component.ts</context>
|
||||
<context context-type="linenumber">179</context>
|
||||
<context context-type="linenumber">185</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1880237574877817137" datatype="html">
|
||||
@@ -7091,7 +7098,7 @@
|
||||
<source>Private</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/input/select/select.component.ts</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
<context context-type="linenumber">73</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/tag/tag.component.html</context>
|
||||
@@ -7114,7 +7121,7 @@
|
||||
<source>No items found</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/common/input/select/select.component.ts</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
<context context-type="linenumber">114</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6541407358060244620" datatype="html">
|
||||
|
||||
@@ -42,11 +42,16 @@
|
||||
<span class="text-break">{{ message.content }}</span>
|
||||
}
|
||||
@if (message.role === 'assistant' && !message.isStreaming && message.references?.length) {
|
||||
<div class="chat-references list-group mt-3">
|
||||
<div class="list-group-item text-muted small py-1" i18n>Sources</div>
|
||||
@for (reference of message.references; track reference.id) {
|
||||
<a class="list-group-item list-group-item-action d-flex align-items-center text-primary" [routerLink]="['/documents', reference.id]" [title]="reference.title">
|
||||
<pngx-bs-icon width="0.9em" height="0.9em" name="file-text" class="me-2 flex-shrink-0"></pngx-bs-icon><span class="text-truncate">{{ reference.title }}</span>
|
||||
<div class="chat-references mt-2 pt-2 border-top">
|
||||
<div class="d-flex align-items-center text-muted mb-1">
|
||||
<span i18n>Sources</span>
|
||||
@if (hiddenReferenceCount(message) > 0 && !expandedReferences().has(message)) {
|
||||
<button type="button" class="badge rounded-pill bg-body-secondary text-body-secondary fw-normal border-0 ms-2" (click)="expandReferences(message)" i18n>+{{ hiddenReferenceCount(message) }} more</button>
|
||||
}
|
||||
</div>
|
||||
@for (reference of visibleReferences(message); track reference.id) {
|
||||
<a class="reference-link d-flex align-items-center lh-sm text-primary text-decoration-none py-1" [routerLink]="['/documents', reference.id]" [title]="reference.title">
|
||||
<pngx-bs-icon width="0.8em" height="0.8em" name="file-text" class="me-2 flex-shrink-0"></pngx-bs-icon><span class="text-truncate">{{ reference.title }}</span>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.message .flex-grow-1 {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
white-space: initial;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import { BootstrapIconComponent } from 'src/app/components/common/bootstrap-icon
|
||||
import { MarkdownPipe } from 'src/app/pipes/markdown.pipe'
|
||||
import {
|
||||
ChatMessage,
|
||||
ChatReference,
|
||||
ChatService,
|
||||
parseChatResponse,
|
||||
} from 'src/app/services/chat.service'
|
||||
@@ -40,8 +41,29 @@ export class ChatComponent implements OnInit {
|
||||
readonly input = signal('')
|
||||
readonly documentId = signal<number>(undefined)
|
||||
readonly slowResponse = signal(false)
|
||||
readonly expandedReferences = signal<Set<ChatMessage>>(new Set())
|
||||
public popperOptions = pngxPopperOptions
|
||||
|
||||
static readonly COLLAPSED_REFERENCE_COUNT = 2
|
||||
|
||||
public visibleReferences(message: ChatMessage): ChatReference[] {
|
||||
if (this.expandedReferences().has(message)) {
|
||||
return message.references
|
||||
}
|
||||
return message.references.slice(0, ChatComponent.COLLAPSED_REFERENCE_COUNT)
|
||||
}
|
||||
|
||||
public hiddenReferenceCount(message: ChatMessage): number {
|
||||
return Math.max(
|
||||
0,
|
||||
message.references.length - ChatComponent.COLLAPSED_REFERENCE_COUNT
|
||||
)
|
||||
}
|
||||
|
||||
public expandReferences(message: ChatMessage): void {
|
||||
this.expandedReferences.update((expanded) => new Set(expanded).add(message))
|
||||
}
|
||||
|
||||
private chatService: ChatService = inject(ChatService)
|
||||
private router: Router = inject(Router)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
[appendTo]="appendTo"
|
||||
[loading]="loading()"
|
||||
[typeahead]="documentsInput$"
|
||||
(mousedown)="$event.stopImmediatePropagation()"
|
||||
(mousedown)="appendTo && $event.stopImmediatePropagation()"
|
||||
(change)="onChange(selectedDocumentIDs)">
|
||||
<ng-template ng-label-tmp let-document="item">
|
||||
<div class="d-flex align-items-center">
|
||||
|
||||
@@ -97,6 +97,7 @@ describe('SelectComponent', () => {
|
||||
let createNewVal
|
||||
component.createNew.subscribe((v) => (createNewVal = v))
|
||||
expect(component.allowCreateNew).toBeTruthy()
|
||||
const closeSpy = jest.spyOn(component.ngSelectComponent, 'close')
|
||||
component.onSearch({ term: 'foo' })
|
||||
component.addItem(undefined)
|
||||
expect(createNewVal).toEqual('foo')
|
||||
@@ -105,6 +106,8 @@ describe('SelectComponent', () => {
|
||||
component.onSearch({ term: 'baz' })
|
||||
component.clickNew()
|
||||
expect(createNewVal).toEqual('baz')
|
||||
// dropdown should close when creating a new item so it isn't left open behind the modal
|
||||
expect(closeSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should search items by independent normalized terms', () => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
forwardRef,
|
||||
Input,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from '@angular/core'
|
||||
import {
|
||||
FormsModule,
|
||||
@@ -11,7 +12,7 @@ import {
|
||||
ReactiveFormsModule,
|
||||
} from '@angular/forms'
|
||||
import { RouterModule } from '@angular/router'
|
||||
import { NgSelectModule } from '@ng-select/ng-select'
|
||||
import { NgSelectComponent, NgSelectModule } from '@ng-select/ng-select'
|
||||
import { BootstrapIconComponent } from 'src/app/components/common/bootstrap-icon/bootstrap-icon.component'
|
||||
import { matchesSearchText } from 'src/app/utils/text-search'
|
||||
import { AbstractInputComponent } from '../abstract-input'
|
||||
@@ -124,6 +125,9 @@ export class SelectComponent extends AbstractInputComponent<number | string> {
|
||||
@Output()
|
||||
filterDocuments = new EventEmitter<any[]>()
|
||||
|
||||
@ViewChild(NgSelectComponent)
|
||||
ngSelectComponent: NgSelectComponent
|
||||
|
||||
public addItemRef: (name) => void
|
||||
|
||||
private _lastSearchTerm: string
|
||||
@@ -150,11 +154,13 @@ export class SelectComponent extends AbstractInputComponent<number | string> {
|
||||
if (name) this.createNew.next(name)
|
||||
else this.createNew.next(this._lastSearchTerm)
|
||||
this.clearLastSearchTerm()
|
||||
this.ngSelectComponent?.close()
|
||||
}
|
||||
|
||||
clickNew() {
|
||||
this.createNew.next(this._lastSearchTerm)
|
||||
this.clearLastSearchTerm()
|
||||
this.ngSelectComponent?.close()
|
||||
}
|
||||
|
||||
clearLastSearchTerm() {
|
||||
|
||||
Reference in new issue
Block a user