Skip to content

Commit bca4d58

Browse files
committed
Search solr suggestions
1 parent 85a031e commit bca4d58

13 files changed

Lines changed: 199 additions & 175 deletions

File tree

src/app/core/submission/vocabularies/models/vocabulary-options.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export class VocabularyOptions {
1616
/**
1717
* The type of the vocabulary (source): xml, authority, suggest
1818
*/
19-
type: string;
19+
type?: string;
2020

2121
constructor(name: string,
2222
closed: boolean = false, type: string = 'xml') {

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value-field/dso-edit-metadata-authority-field/dso-edit-metadata-authority-field.component.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ import { Item } from '@dspace/core/shared/item.model';
1515
import { MetadataValue } from '@dspace/core/shared/metadata.models';
1616
import { Vocabulary } from '@dspace/core/submission/vocabularies/models/vocabulary.model';
1717
import { VocabularyService } from '@dspace/core/submission/vocabularies/vocabulary.service';
18+
import { SearchServiceStub } from '@dspace/core/testing/search-service.stub';
1819
import { createPaginatedList } from '@dspace/core/testing/utils.test';
1920
import { VocabularyServiceStub } from '@dspace/core/testing/vocabulary-service.stub';
2021
import { createSuccessfulRemoteDataObject$ } from '@dspace/core/utilities/remote-data.utils';
2122
import { TranslateModule } from '@ngx-translate/core';
23+
import { SearchService } from 'src/app/shared/search/search.service';
2224

2325
import { RegistryService } from '../../../../admin/admin-registries/registry/registry.service';
2426
import { DynamicOneboxModel } from '../../../../shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.model';
@@ -32,6 +34,7 @@ describe('DsoEditMetadataAuthorityFieldComponent', () => {
3234
let fixture: ComponentFixture<DsoEditMetadataAuthorityFieldComponent>;
3335

3436
let vocabularyService: any;
37+
let searchService: any;
3538
let itemService: ItemDataService;
3639
let registryService: RegistryService;
3740
let notificationsService: NotificationsService;
@@ -112,6 +115,7 @@ describe('DsoEditMetadataAuthorityFieldComponent', () => {
112115
findByHref: createSuccessfulRemoteDataObject$(item),
113116
});
114117
vocabularyService = new VocabularyServiceStub();
118+
searchService = new SearchServiceStub();
115119
registryService = jasmine.createSpyObj('registryService', {
116120
queryMetadataFields: createSuccessfulRemoteDataObject$(createPaginatedList(metadataFields)),
117121
});
@@ -150,6 +154,7 @@ describe('DsoEditMetadataAuthorityFieldComponent', () => {
150154
],
151155
providers: [
152156
{ provide: VocabularyService, useValue: vocabularyService },
157+
{ provide: SearchService, useValue: searchService },
153158
{ provide: ItemDataService, useValue: itemService },
154159
{ provide: RegistryService, useValue: registryService },
155160
{ provide: NotificationsService, useValue: notificationsService },
Lines changed: 48 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,83 @@
1-
<ng-template #suggestrt let-listEntry="result" let-t="term">
2-
<ng-container
3-
[ngTemplateOutlet]="suggestrte"
4-
[ngTemplateOutletContext]="{entry: listEntry}">
5-
</ng-container>
6-
</ng-template>
7-
8-
<ng-template #suggestrte let-entry="entry">
9-
<ul class="list-unstyled mb=0">
1+
<ng-template #rt let-listEntry="result" let-t="term">
2+
<ul class="list-unstyled mb-0">
3+
@if (listEntry.display) {
104
<li
115
class="list-item text-truncate text-primary"
12-
[innerHTML]="(entry.term + ' (' + entry.weight + ')')">
6+
[innerHtml]="listEntry.display">
137
</li>
14-
</ul>
15-
</ng-template>
16-
17-
<ng-template #rt let-listEntry="result" let-t="term">
18-
<ng-container
19-
[ngTemplateOutlet]="(listEntry.hasOtherInformation()) ? hasInfo : noInfo"
20-
[ngTemplateOutletContext]="{entry: listEntry}">
21-
</ng-container>
22-
</ng-template>
23-
24-
<ng-template #hasInfo let-entry="entry">
25-
<ul class="list-unstyled mb-0">
26-
<li class="list-item text-truncate text-primary fw-bold">{{entry.value}}</li>
27-
28-
@for (item of entry.otherInformation | dsObjNgFor; track item) {
8+
} @else {
9+
<li class="list-item text-truncate text-primary fw-bold">
10+
{{listEntry.value}}
11+
</li>
12+
}
2913

30-
<li class="list-item text-truncate text-secondary" >
31-
{{ 'form.other-information.' + item.key | translate }} : {{item.value}}
32-
</li>
14+
@if (listEntry.hasOtherInformation()) {
15+
@for (item of listEntry.otherInformation | dsObjNgFor; track item.key) {
3316

34-
}
35-
</ul>
36-
</ng-template>
17+
<li class="list-item text-truncate text-secondary" >
18+
{{ 'form.other-information.' + item.key | translate }} : {{item.value}}
19+
</li>
3720

38-
<ng-template #noInfo let-entry="entry">
39-
<ul class="list-unstyled mb-0">
40-
<li class="list-item text-truncate text-primary fw-bold">{{entry.value}}</li>
21+
}}
4122
</ul>
4223
</ng-template>
4324

44-
@if (!(isHierarchicalVocabulary() | async)) {
45-
4625
<div class="position-relative right-addon">
4726

48-
@if (searching || loadingInitialValue) {
27+
@if ((vocabulary$ | async)?.hierarchical) {
4928

50-
<i class="fas fa-circle-notch fa-spin fa-2x fa-fw text-primary position-absolute mt-1 p-0" aria-hidden="true"></i>
29+
<i class="dropdown-toggle position-absolute tree-toggle" (click)="openTree($event)"
30+
aria-hidden="true"></i>
31+
<input class="form-control"
32+
[attr.aria-labelledby]="'label_' + model.id"
33+
[attr.autoComplete]="model.autoComplete"
34+
[attr.aria-label]="model.label | translate"
35+
[class.is-invalid]="showErrorMessages"
36+
[class.tree-input]="!model.readOnly"
37+
[id]="id"
38+
[name]="model.name"
39+
[placeholder]="model.placeholder"
40+
[readonly]="true"
41+
[disabled]="model.readOnly"
42+
[type]="model.inputType"
43+
[value]="currentValue?.display"
44+
(focus)="onFocus($event)"
45+
(change)="onChange($event)"
46+
(click)="openTree($event)"
47+
(keydown)="$event.preventDefault()"
48+
(keypress)="$event.preventDefault()"
49+
(keyup)="$event.preventDefault()">
5150

5251
} @else {
5352

53+
@if (loading) {
54+
<i
55+
class="fas fa-circle-notch fa-spin fa-2x fa-fw text-primary position-absolute mt-1 p-0"
56+
aria-hidden="true">
57+
</i>
58+
} @else {
5459
<i
5560
dsAuthorityConfidenceState
5661
class="far fa-circle fa-2x fa-fw position-absolute mt-1 p-0"
5762
aria-hidden="true"
5863
[authorityValue]="currentValue"
59-
(whenClickOnConfidenceNotAccepted)="whenClickOnConfidenceNotAccepted($event)"></i>
60-
64+
(whenClickOnConfidenceNotAccepted)="whenClickOnConfidenceNotAccepted($event)">
65+
</i>
6166
}
6267

63-
<input #instance="ngbTypeahead"
68+
<input #typeahead="ngbTypeahead"
6469
class="form-control"
6570
[attr.aria-labelledby]="'label_' + model.id"
6671
[attr.autoComplete]="model.autoComplete"
6772
[attr.aria-label]="model.label | translate"
6873
[class.is-invalid]="showErrorMessages"
6974
[id]="model.id"
70-
[inputFormatter]="formatter"
7175
[name]="model.name"
7276
[ngbTypeahead]="search"
7377
[placeholder]="model.placeholder"
7478
[readonly]="model.readOnly"
7579
[disabled]="model.readOnly"
76-
[resultTemplate]="isSolrSuggest ? suggestrt : rt"
80+
[resultTemplate]="rt"
7781
[type]="model.inputType"
7882
[(ngModel)]="currentValue"
7983
(blur)="onBlur($event)"
@@ -83,37 +87,8 @@
8387
(selectItem)="onSelectItem($event)">
8488

8589
@if (searchFailed) {
86-
8790
<div class="invalid-feedback">Sorry, suggestions could not be loaded.</div>
88-
8991
}
9092

93+
}
9194
</div>
92-
93-
} @else {
94-
95-
<div class="position-relative right-addon">
96-
<i class="dropdown-toggle position-absolute tree-toggle" (click)="openTree($event)"
97-
aria-hidden="true"></i>
98-
<input class="form-control"
99-
[attr.aria-labelledby]="'label_' + model.id"
100-
[attr.autoComplete]="model.autoComplete"
101-
[attr.aria-label]="model.label | translate"
102-
[class.is-invalid]="showErrorMessages"
103-
[class.tree-input]="!model.readOnly"
104-
[id]="id"
105-
[name]="model.name"
106-
[placeholder]="model.placeholder"
107-
[readonly]="true"
108-
[disabled]="model.readOnly"
109-
[type]="model.inputType"
110-
[value]="currentValue?.display"
111-
(focus)="onFocus($event)"
112-
(change)="onChange($event)"
113-
(click)="openTree($event)"
114-
(keydown)="$event.preventDefault()"
115-
(keypress)="$event.preventDefault()"
116-
(keyup)="$event.preventDefault()">
117-
</div>
118-
119-
}

src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.spec.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
mockDynamicFormLayoutService,
2929
mockDynamicFormValidationService,
3030
} from '@dspace/core/testing/dynamic-form-mock-services';
31+
import { SearchServiceStub } from '@dspace/core/testing/search-service.stub';
3132
import { createTestComponent } from '@dspace/core/testing/utils.test';
3233
import { VocabularyServiceStub } from '@dspace/core/testing/vocabulary-service.stub';
3334
import { createSuccessfulRemoteDataObject$ } from '@dspace/core/utilities/remote-data.utils';
@@ -44,6 +45,7 @@ import { TranslateModule } from '@ngx-translate/core';
4445
import { getTestScheduler } from 'jasmine-marbles';
4546
import { of } from 'rxjs';
4647
import { TestScheduler } from 'rxjs/testing';
48+
import { SearchService } from 'src/app/shared/search/search.service';
4749

4850
import { ObjNgFor } from '../../../../../utils/object-ngfor.pipe';
4951
import { AuthorityConfidenceStateDirective } from '../../../../directives/authority-confidence-state.directive';
@@ -97,6 +99,7 @@ describe('DsDynamicOneboxComponent test suite', () => {
9799
let testFixture: ComponentFixture<TestComponent>;
98100
let oneboxCompFixture: ComponentFixture<DsDynamicOneboxComponent>;
99101
let vocabularyServiceStub: any;
102+
let searchServiceStub: any;
100103
let modalService: any;
101104
let html;
102105
let modal;
@@ -137,6 +140,7 @@ describe('DsDynamicOneboxComponent test suite', () => {
137140
// waitForAsync beforeEach
138141
beforeEach(() => {
139142
vocabularyServiceStub = new VocabularyServiceStub();
143+
searchServiceStub = new SearchServiceStub();
140144

141145
modal = jasmine.createSpyObj('modal',
142146
{
@@ -164,6 +168,7 @@ describe('DsDynamicOneboxComponent test suite', () => {
164168
ChangeDetectorRef,
165169
DsDynamicOneboxComponent,
166170
{ provide: VocabularyService, useValue: vocabularyServiceStub },
171+
{ provide: SearchService, useValue: searchServiceStub },
167172
{ provide: DynamicFormLayoutService, useValue: mockDynamicFormLayoutService },
168173
{ provide: DynamicFormValidationService, useValue: mockDynamicFormValidationService },
169174
{ provide: NgbModal, useValue: modal },
@@ -259,14 +264,14 @@ describe('DsDynamicOneboxComponent test suite', () => {
259264

260265
it('should emit blur Event onBlur when popup is closed', () => {
261266
spyOn(oneboxComponent.blur, 'emit');
262-
spyOn(oneboxComponent.instance, 'isPopupOpen').and.returnValue(false);
267+
spyOn(oneboxComponent.typeahead, 'isPopupOpen').and.returnValue(false);
263268
oneboxComponent.onBlur(new Event('blur'));
264269
expect(oneboxComponent.blur.emit).toHaveBeenCalled();
265270
});
266271

267272
it('should not emit blur Event onBlur when popup is opened', () => {
268273
spyOn(oneboxComponent.blur, 'emit');
269-
spyOn(oneboxComponent.instance, 'isPopupOpen').and.returnValue(true);
274+
spyOn(oneboxComponent.typeahead, 'isPopupOpen').and.returnValue(true);
270275
const input = oneboxCompFixture.debugElement.query(By.css('input'));
271276

272277
input.nativeElement.blur();
@@ -278,7 +283,7 @@ describe('DsDynamicOneboxComponent test suite', () => {
278283
oneboxCompFixture.detectChanges();
279284
spyOn(oneboxComponent.blur, 'emit');
280285
spyOn(oneboxComponent.change, 'emit');
281-
spyOn(oneboxComponent.instance, 'isPopupOpen').and.returnValue(false);
286+
spyOn(oneboxComponent.typeahead, 'isPopupOpen').and.returnValue(false);
282287
oneboxComponent.onBlur(new Event('blur'));
283288
expect(oneboxComponent.change.emit).toHaveBeenCalled();
284289
expect(oneboxComponent.blur.emit).toHaveBeenCalled();
@@ -291,7 +296,7 @@ describe('DsDynamicOneboxComponent test suite', () => {
291296
oneboxCompFixture.detectChanges();
292297
spyOn(oneboxComponent.blur, 'emit');
293298
spyOn(oneboxComponent.change, 'emit');
294-
spyOn(oneboxComponent.instance, 'isPopupOpen').and.returnValue(false);
299+
spyOn(oneboxComponent.typeahead, 'isPopupOpen').and.returnValue(false);
295300
oneboxComponent.onBlur(new Event('blur'));
296301
expect(oneboxComponent.change.emit).not.toHaveBeenCalled();
297302
expect(oneboxComponent.blur.emit).toHaveBeenCalled();
@@ -304,7 +309,7 @@ describe('DsDynamicOneboxComponent test suite', () => {
304309
oneboxCompFixture.detectChanges();
305310
spyOn(oneboxComponent.blur, 'emit');
306311
spyOn(oneboxComponent.change, 'emit');
307-
spyOn(oneboxComponent.instance, 'isPopupOpen').and.returnValue(false);
312+
spyOn(oneboxComponent.typeahead, 'isPopupOpen').and.returnValue(false);
308313
oneboxComponent.onBlur(new Event('blur'));
309314
expect(oneboxComponent.change.emit).not.toHaveBeenCalled();
310315
expect(oneboxComponent.blur.emit).toHaveBeenCalled();

0 commit comments

Comments
 (0)