forked from hazza/dspace-angular
added new submission list component for persons
This commit is contained in:
@@ -158,7 +158,7 @@ describe('ItemRelationshipsComponent', () => {
|
|||||||
deleteRelationship: observableOf(new RestResponse(true, 200, 'OK')),
|
deleteRelationship: observableOf(new RestResponse(true, 200, 'OK')),
|
||||||
getItemResolvedRelatedItemsAndRelationships: observableCombineLatest(observableOf([author1, author2]), observableOf([item, item]), observableOf(relationships)),
|
getItemResolvedRelatedItemsAndRelationships: observableCombineLatest(observableOf([author1, author2]), observableOf([item, item]), observableOf(relationships)),
|
||||||
getRelationshipsByRelatedItemIds: observableOf(relationships),
|
getRelationshipsByRelatedItemIds: observableOf(relationships),
|
||||||
getRelationshipTypeLabelsByItem: observableOf([relationshipType.leftLabel])
|
getRelationshipTypeLabelsByItem: observableOf([relationshipType.leftwardType])
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ import { OrgUnitSearchResultGridElementComponent } from './item-grid-elements/se
|
|||||||
import { ProjectSearchResultGridElementComponent } from './item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component';
|
import { ProjectSearchResultGridElementComponent } from './item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component';
|
||||||
import { PersonItemMetadataListElementComponent } from './metadata-representations/person/person-item-metadata-list-element.component';
|
import { PersonItemMetadataListElementComponent } from './metadata-representations/person/person-item-metadata-list-element.component';
|
||||||
import { OrgUnitItemMetadataListElementComponent } from './metadata-representations/org-unit/org-unit-item-metadata-list-element.component';
|
import { OrgUnitItemMetadataListElementComponent } from './metadata-representations/org-unit/org-unit-item-metadata-list-element.component';
|
||||||
|
import { PersonSearchResultListSubmissionElementComponent } from './submission/item-list-elements/person/person-search-result-list-submission-element.component';
|
||||||
|
|
||||||
const ENTRY_COMPONENTS = [
|
const ENTRY_COMPONENTS = [
|
||||||
OrgUnitComponent,
|
OrgUnitComponent,
|
||||||
@@ -38,7 +39,8 @@ const ENTRY_COMPONENTS = [
|
|||||||
ProjectSearchResultListElementComponent,
|
ProjectSearchResultListElementComponent,
|
||||||
PersonSearchResultGridElementComponent,
|
PersonSearchResultGridElementComponent,
|
||||||
OrgUnitSearchResultGridElementComponent,
|
OrgUnitSearchResultGridElementComponent,
|
||||||
ProjectSearchResultGridElementComponent
|
ProjectSearchResultGridElementComponent,
|
||||||
|
PersonSearchResultListSubmissionElementComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@@ -0,0 +1,17 @@
|
|||||||
|
<ds-item-type-badge [object]="dso"></ds-item-type-badge>
|
||||||
|
<ds-truncatable [id]="dso.id">
|
||||||
|
<select>
|
||||||
|
<option [value]="firstMetadataValue('person.name')" [innerHTML]="firstMetadataValue('person.name')"></option>
|
||||||
|
<option *ngFor="let value of allMetadataValues('title.alternative')" [value]="value" [innerHTML]="value"></option>
|
||||||
|
</select>
|
||||||
|
<span class="text-muted">
|
||||||
|
<ds-truncatable-part [id]="dso.id" [minLines]="1">
|
||||||
|
<span *ngIf="dso.allMetadata(['person.jobTitle']).length > 0"
|
||||||
|
class="item-list-job-title">
|
||||||
|
<span *ngFor="let value of allMetadataValues(['person.jobTitle']); let last=last;">
|
||||||
|
<span [innerHTML]="value"><span [innerHTML]="value"></span></span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</ds-truncatable-part>
|
||||||
|
</span>
|
||||||
|
</ds-truncatable>
|
@@ -0,0 +1,94 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { PersonSearchResultListSubmissionElementComponent } from './person-search-result-list-submission-element.component';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe';
|
||||||
|
import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
|
||||||
|
|
||||||
|
let personListElementComponent: PersonSearchResultListSubmissionElementComponent;
|
||||||
|
let fixture: ComponentFixture<PersonSearchResultListSubmissionElementComponent>;
|
||||||
|
|
||||||
|
const mockItemWithMetadata: ItemSearchResult = Object.assign(
|
||||||
|
new ItemSearchResult(),
|
||||||
|
{
|
||||||
|
indexableObject: Object.assign(new Item(), {
|
||||||
|
bitstreams: observableOf({}),
|
||||||
|
metadata: {
|
||||||
|
'dc.title': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is just another title'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'person.jobTitle': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'Developer'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const mockItemWithoutMetadata: ItemSearchResult = Object.assign(
|
||||||
|
new ItemSearchResult(),
|
||||||
|
{
|
||||||
|
indexableObject: Object.assign(new Item(), {
|
||||||
|
bitstreams: observableOf({}),
|
||||||
|
metadata: {
|
||||||
|
'dc.title': [
|
||||||
|
{
|
||||||
|
language: 'en_US',
|
||||||
|
value: 'This is just another title'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('PersonSearchResultListElementComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [PersonSearchResultListSubmissionElementComponent, TruncatePipe],
|
||||||
|
providers: [
|
||||||
|
{ provide: TruncatableService, useValue: {} }
|
||||||
|
],
|
||||||
|
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
}).overrideComponent(PersonSearchResultListSubmissionElementComponent, {
|
||||||
|
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
fixture = TestBed.createComponent(PersonSearchResultListSubmissionElementComponent);
|
||||||
|
personListElementComponent = fixture.componentInstance;
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('When the item has a job title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
personListElementComponent.object = mockItemWithMetadata;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show the job title span', () => {
|
||||||
|
const jobTitleField = fixture.debugElement.query(By.css('span.item-list-job-title'));
|
||||||
|
expect(jobTitleField).not.toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('When the item has no job title', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
personListElementComponent.object = mockItemWithoutMetadata;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not show the job title span', () => {
|
||||||
|
const jobTitleField = fixture.debugElement.query(By.css('span.item-list-job-title'));
|
||||||
|
expect(jobTitleField).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,19 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component';
|
||||||
|
import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model';
|
||||||
|
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||||
|
import { Item } from '../../../../../core/shared/item.model';
|
||||||
|
import { Context } from '../../../../../core/shared/context.model';
|
||||||
|
|
||||||
|
@listableObjectComponent('PersonSearchResult', ViewMode.ListElement, Context.Submission)
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-person-search-result-list-submission-element',
|
||||||
|
styleUrls: ['./person-search-result-list-submission-element.component.scss'],
|
||||||
|
templateUrl: './person-search-result-list-submission-element.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* The component for displaying a list element for an item search result of the type Person
|
||||||
|
*/
|
||||||
|
export class PersonSearchResultListSubmissionElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> {
|
||||||
|
}
|
@@ -60,6 +60,8 @@
|
|||||||
[searchConfig]="this.searchConfig"
|
[searchConfig]="this.searchConfig"
|
||||||
[selectable]="true"
|
[selectable]="true"
|
||||||
[selectionConfig]="{ repeatable: repeatable, listId: listId }"
|
[selectionConfig]="{ repeatable: repeatable, listId: listId }"
|
||||||
|
[linkType]="linkTypes.ExternalLink"
|
||||||
|
[context]="context"
|
||||||
(deselectObject)="deselectObject.emit($event)"
|
(deselectObject)="deselectObject.emit($event)"
|
||||||
(selectObject)="selectObject.emit($event)">
|
(selectObject)="selectObject.emit($event)">
|
||||||
</ds-search-results>
|
</ds-search-results>
|
||||||
|
@@ -18,6 +18,9 @@ import { concat, map, multicast, switchMap, take, takeWhile, tap } from 'rxjs/op
|
|||||||
import { DSpaceObject } from '../../../../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../../../../core/shared/dspace-object.model';
|
||||||
import { getSucceededRemoteData } from '../../../../../../core/shared/operators';
|
import { getSucceededRemoteData } from '../../../../../../core/shared/operators';
|
||||||
import { RouteService } from '../../../../../../core/services/route.service';
|
import { RouteService } from '../../../../../../core/services/route.service';
|
||||||
|
import { CollectionElementLinkType } from '../../../../../object-collection/collection-element-link.type';
|
||||||
|
import { Context } from '../../../../../../core/shared/context.model';
|
||||||
|
import { relationship } from '../../../../../../core/cache/builders/build-decorators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-dynamic-lookup-relation-search-tab',
|
selector: 'ds-dynamic-lookup-relation-search-tab',
|
||||||
@@ -48,6 +51,8 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
|
|||||||
id: 'submission-relation-list',
|
id: 'submission-relation-list',
|
||||||
pageSize: 5
|
pageSize: 5
|
||||||
});
|
});
|
||||||
|
linkTypes = CollectionElementLinkType;
|
||||||
|
context: Context;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private searchService: SearchService,
|
private searchService: SearchService,
|
||||||
@@ -62,6 +67,13 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
|
|||||||
this.resetRoute();
|
this.resetRoute();
|
||||||
this.routeService.setParameter('fixedFilterQuery', this.relationship.filter);
|
this.routeService.setParameter('fixedFilterQuery', this.relationship.filter);
|
||||||
this.routeService.setParameter('configuration', this.relationship.searchConfiguration);
|
this.routeService.setParameter('configuration', this.relationship.searchConfiguration);
|
||||||
|
/**
|
||||||
|
* TODO REMOVE NEXT LINE
|
||||||
|
*/
|
||||||
|
this.relationship.nameVariants = true;
|
||||||
|
if (this.relationship.nameVariants) {
|
||||||
|
this.context = Context.Submission;
|
||||||
|
}
|
||||||
|
|
||||||
this.someSelected$ = this.selection$.pipe(map((selection) => isNotEmpty(selection)));
|
this.someSelected$ = this.selection$.pipe(map((selection) => isNotEmpty(selection)));
|
||||||
this.resultsRD$ = this.searchConfigService.paginatedSearchOptions.pipe(
|
this.resultsRD$ = this.searchConfigService.paginatedSearchOptions.pipe(
|
||||||
@@ -77,8 +89,7 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
|
|||||||
() => new ReplaySubject(1),
|
() => new ReplaySubject(1),
|
||||||
subject => subject.pipe(
|
subject => subject.pipe(
|
||||||
takeWhile((rd: RemoteData<PaginatedList<SearchResult<DSpaceObject>>>) => rd.isLoading),
|
takeWhile((rd: RemoteData<PaginatedList<SearchResult<DSpaceObject>>>) => rd.isLoading),
|
||||||
concat(subject.pipe(take(1))
|
concat(subject.pipe(take(1)))
|
||||||
)
|
|
||||||
)
|
)
|
||||||
) as any
|
) as any
|
||||||
)
|
)
|
||||||
|
@@ -2,4 +2,5 @@ export interface RelationshipOptions {
|
|||||||
relationshipType: string;
|
relationshipType: string;
|
||||||
filter: string;
|
filter: string;
|
||||||
searchConfiguration: string;
|
searchConfiguration: string;
|
||||||
|
nameVariants: boolean;
|
||||||
}
|
}
|
||||||
|
@@ -52,7 +52,7 @@ export class ConcatFieldParser extends FieldParser {
|
|||||||
concatGroup.separator = this.separator;
|
concatGroup.separator = this.separator;
|
||||||
|
|
||||||
const input1ModelConfig: DynamicInputModelConfig = this.initModel(id + CONCAT_FIRST_INPUT_SUFFIX, false, false);
|
const input1ModelConfig: DynamicInputModelConfig = this.initModel(id + CONCAT_FIRST_INPUT_SUFFIX, false, false);
|
||||||
const input2ModelConfig: DynamicInputModelConfig = this.initModel(id + CONCAT_SECOND_INPUT_SUFFIX, true, false);
|
const input2ModelConfig: DynamicInputModelConfig = this.initModel(id + CONCAT_SECOND_INPUT_SUFFIX, false, false);
|
||||||
input2ModelConfig.hint = ' ';
|
input2ModelConfig.hint = ' ';
|
||||||
|
|
||||||
if (this.configData.mandatory) {
|
if (this.configData.mandatory) {
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
[hideGear]="true"
|
[hideGear]="true"
|
||||||
[selectable]="selectable"
|
[selectable]="selectable"
|
||||||
[selectionConfig]="selectionConfig"
|
[selectionConfig]="selectionConfig"
|
||||||
|
[context]="context"
|
||||||
(deselectObject)="deselectObject.emit($event)"
|
(deselectObject)="deselectObject.emit($event)"
|
||||||
(selectObject)="selectObject.emit($event)"
|
(selectObject)="selectObject.emit($event)"
|
||||||
>
|
>
|
||||||
|
@@ -10,6 +10,7 @@ import { SortOptions } from '../../../core/cache/models/sort-options.model';
|
|||||||
import { ListableObject } from '../../object-collection/shared/listable-object.model';
|
import { ListableObject } from '../../object-collection/shared/listable-object.model';
|
||||||
import { CollectionElementLinkType } from '../../object-collection/collection-element-link.type';
|
import { CollectionElementLinkType } from '../../object-collection/collection-element-link.type';
|
||||||
import { ViewMode } from '../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../core/shared/view-mode.model';
|
||||||
|
import { Context } from '../../../core/shared/context.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search-results',
|
selector: 'ds-search-results',
|
||||||
@@ -64,6 +65,8 @@ export class SearchResultsComponent {
|
|||||||
|
|
||||||
@Input() selectable = false;
|
@Input() selectable = false;
|
||||||
|
|
||||||
|
@Input() context: Context;
|
||||||
|
|
||||||
@Input() selectionConfig: {repeatable: boolean, listId: string};
|
@Input() selectionConfig: {repeatable: boolean, listId: string};
|
||||||
|
|
||||||
@Output() deselectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
|
@Output() deselectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
|
||||||
|
Reference in New Issue
Block a user