Refine the suggestions dropdown ui a bit

This commit is contained in:
shamoon 2025-04-21 10:51:17 -07:00
parent f9ffc97970
commit 168ad3f9a2
No known key found for this signature in database
3 changed files with 61 additions and 23 deletions

View File

@ -1,6 +1,5 @@
<div ngbDropdown [popperOptions]="popperOptions"> <div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-primary" (click)="clickSuggest()" [disabled]="loading">
<button type="button" class="btn btn-sm btn-outline-primary" (click)="getSuggestions.emit(this)" [disabled]="loading" ngbDropdownToggle>
@if (loading) { @if (loading) {
<div class="spinner-border spinner-border-sm" role="status"></div> <div class="spinner-border spinner-border-sm" role="status"></div>
} @else { } @else {
@ -11,27 +10,33 @@
<span class="badge bg-primary ms-2">{{ totalSuggestions }}</span> <span class="badge bg-primary ms-2">{{ totalSuggestions }}</span>
} }
</button> </button>
<div class="btn-group" ngbDropdown #dropdown="ngbDropdown" [popperOptions]="popperOptions">
<div ngbDropdownMenu aria-labelledby="suggestionsDropdown" class="shadow suggestions-dropdown"> <button type="button" class="btn btn-sm btn-outline-primary" ngbDropdownToggle [disabled]="loading || !suggestions" aria-expanded="false" aria-controls="suggestionsDropdown" aria-label="Suggestions dropdown">
<div class="list-group list-group-flush"> <span class="visually-hidden" i18n>Show suggestions</span>
@if (suggestions?.suggested_tags.length > 0) { </button>
<div class="list-group-item text-uppercase text-muted small">Tags</div>
@for (tag of suggestions.suggested_tags; track tag) { <div ngbDropdownMenu aria-labelledby="suggestionsDropdown" class="shadow suggestions-dropdown">
<a class="list-group-item list-group-item-action bg-light small" (click)="addTag.emit(tag)" i18n>{{ tag }}</a> <div class="list-group list-group-flush small">
@if (suggestions?.suggested_tags.length > 0) {
<small class="list-group-item text-uppercase text-muted small">Tags</small>
@for (tag of suggestions.suggested_tags; track tag) {
<button type="button" class="list-group-item list-group-item-action bg-light" (click)="addTag.emit(tag)" i18n>{{ tag }}</button>
}
} }
} @if (suggestions?.suggested_document_types.length > 0) {
@if (suggestions?.suggested_document_types.length > 0) { <div class="list-group-item text-uppercase text-muted small">Document Types</div>
<div class="list-group-item text-uppercase text-muted small">Document Types</div> @for (type of suggestions.suggested_document_types; track type) {
@for (type of suggestions.suggested_document_types; track type) { <button type="button" class="list-group-item list-group-item-action bg-light" (click)="addDocumentType.emit(type)" i18n>{{ type }}</button>
<a class="list-group-item list-group-item-action bg-light small" (click)="addDocumentType.emit(type)" i18n>{{ type }}</a> }
} }
} @if (suggestions?.suggested_correspondents.length > 0) {
@if (suggestions?.suggested_correspondents.length > 0) { <div class="list-group-item text-uppercase text-muted small">Correspondents</div>
<div class="list-group-item text-uppercase text-muted small">Correspondents</div> @for (correspondent of suggestions.suggested_correspondents; track correspondent) {
@for (correspondent of suggestions.suggested_correspondents; track correspondent) { <button type="button" class="list-group-item list-group-item-action bg-light" (click)="addCorrespondent.emit(correspondent)" i18n>{{ correspondent }}</button>
<a class="list-group-item list-group-item-action bg-light small" (click)="addCorrespondent.emit(correspondent)" i18n>{{ correspondent }}</a> }
} }
} </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -29,4 +29,21 @@ describe('SuggestionsDropdownComponent', () => {
} }
expect(component.totalSuggestions).toBe(4) expect(component.totalSuggestions).toBe(4)
}) })
it('should emit getSuggestions when clickSuggest is called and suggestions are null', () => {
jest.spyOn(component.getSuggestions, 'emit')
component.suggestions = null
component.clickSuggest()
expect(component.getSuggestions.emit).toHaveBeenCalled()
})
it('should toggle dropdown when clickSuggest is called and suggestions are not null', () => {
component.suggestions = {
suggested_correspondents: [],
suggested_tags: [],
suggested_document_types: [],
}
component.clickSuggest()
expect(component.dropdown.open).toBeTruthy()
})
}) })

View File

@ -1,5 +1,11 @@
import { Component, EventEmitter, Input, Output } from '@angular/core' import {
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap' Component,
EventEmitter,
Input,
Output,
ViewChild,
} from '@angular/core'
import { NgbDropdown, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons' import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import { DocumentSuggestions } from 'src/app/data/document-suggestions' import { DocumentSuggestions } from 'src/app/data/document-suggestions'
import { pngxPopperOptions } from 'src/app/utils/popper-options' import { pngxPopperOptions } from 'src/app/utils/popper-options'
@ -13,6 +19,8 @@ import { pngxPopperOptions } from 'src/app/utils/popper-options'
export class SuggestionsDropdownComponent { export class SuggestionsDropdownComponent {
public popperOptions = pngxPopperOptions public popperOptions = pngxPopperOptions
@ViewChild('dropdown') dropdown: NgbDropdown
@Input() @Input()
suggestions: DocumentSuggestions = null suggestions: DocumentSuggestions = null
@ -35,6 +43,14 @@ export class SuggestionsDropdownComponent {
@Output() @Output()
addCorrespondent: EventEmitter<string> = new EventEmitter() addCorrespondent: EventEmitter<string> = new EventEmitter()
public clickSuggest(): void {
if (!this.suggestions) {
this.getSuggestions.emit(this)
} else {
this.dropdown.toggle()
}
}
get totalSuggestions(): number { get totalSuggestions(): number {
return ( return (
this.suggestions?.suggested_correspondents?.length + this.suggestions?.suggested_correspondents?.length +