0)" class="form-row align-items-center">
@@ -12,29 +11,19 @@
-
-
-
-
-
-
-
-
-
-
-
{{value.name}}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.component.ts
index 00f8cadc73..b1d69ea2f6 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.component.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.component.ts
@@ -1,10 +1,6 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import {
- DynamicFormControlComponent,
- DynamicFormLayoutService,
- DynamicFormValidationService
-} from '@ng-dynamic-forms/core';
+import { DynamicFormControlComponent, DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core';
import { FormGroup } from '@angular/forms';
import { hasValue, isNotEmpty } from '../../../../../empty.util';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
@@ -12,11 +8,9 @@ import { DsDynamicLookupRelationModalComponent } from './dynamic-lookup-relation
import { DynamicLookupRelationModel } from './dynamic-lookup-relation.model';
import { DSpaceObject } from '../../../../../../core/shared/dspace-object.model';
import { RelationshipService } from '../../../../../../core/data/relationship.service';
-import { Item } from '../../../../../../core/shared/item.model';
import { SelectableListService } from '../../../../../object-list/selectable-list/selectable-list.service';
import { SelectableListState } from '../../../../../object-list/selectable-list/selectable-list.reducer';
import { Observable } from 'rxjs';
-import { ListableObject } from '../../../../../object-collection/shared/listable-object.model';
import { map } from 'rxjs/operators';
import { SearchResult } from '../../../../../search/search-result.model';
@@ -39,8 +33,10 @@ export class DsDynamicLookupRelationComponent extends DynamicFormControlComponen
modalRef: NgbModalRef;
modalValuesString = '';
- fieldName: string;
listId: string;
+ filter: string;
+ searchConfig: string;
+
constructor(private modalService: NgbModal,
protected layoutService: DynamicFormLayoutService,
@@ -52,8 +48,9 @@ export class DsDynamicLookupRelationComponent extends DynamicFormControlComponen
}
ngOnInit(): void {
- this.fieldName = this.model.name.substring(RELATION_TYPE_METADATA_PREFIX.length);
- this.listId = 'list-' + this.fieldName;
+ this.filter = this.model.relationship.filter;
+ this.searchConfig = this.model.relationship.searchConfiguration;
+ this.listId = 'list-' + this.model.relationship.relationshipType;
this.model.value = this.selectableListService.getSelectableList(this.listId).pipe(
map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : []),
);
@@ -69,27 +66,15 @@ export class DsDynamicLookupRelationComponent extends DynamicFormControlComponen
modalComp.repeatable = this.model.repeatable;
modalComp.relationKey = this.model.name;
modalComp.listId = this.listId;
- modalComp.fieldName = this.fieldName;
+ modalComp.filter = this.filter;
+ modalComp.fieldName = this.searchConfig;
+ modalComp.label = this.model.label;
this.modalRef.result.then((resultString = '') => {
this.modalValuesString = resultString;
});
}
- // add() {
- // if (isNotEmpty(this.model.value)) {
- // this.model.value = [...this.model.value, ...this.selectedResults];
- // } else {
- // this.model.value = this.selectedResults;
- // }
- //
- // this.modalValuesString = '';
- // this.selectedResults = [];
- // this.selectedResults.forEach((item: Item) => {
- // this.relationService.addRelationship(this.model.item, item);
- // })
- // }
-
removeSelection(object: SearchResult) {
this.selectableListService.deselectSingle(this.listId, object);
}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.model.ts
index e0e580e1f8..fd015d9a90 100644
--- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.model.ts
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.model.ts
@@ -1,6 +1,7 @@
import { DynamicFormControlLayout, serializable } from '@ng-dynamic-forms/core';
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model';
import { Item } from '../../../../../../core/shared/item.model';
+import { RelationshipOptions } from './model/relationship-options.model';
export const DYNAMIC_FORM_CONTROL_TYPE_LOOKUP_RELATION = 'LOOKUP_RELATION';
@@ -8,6 +9,7 @@ export interface DynamicLookupRelationModelConfig extends DsDynamicInputModelCon
value?: any;
repeatable: boolean;
item: Item;
+ relationship: RelationshipOptions;
}
export class DynamicLookupRelationModel extends DsDynamicInputModel {
@@ -15,6 +17,7 @@ export class DynamicLookupRelationModel extends DsDynamicInputModel {
@serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_LOOKUP_RELATION;
@serializable() value: any;
@serializable() repeatable: boolean;
+ relationship: RelationshipOptions;
item: Item;
constructor(config: DynamicLookupRelationModelConfig, layout?: DynamicFormControlLayout) {
@@ -25,6 +28,7 @@ export class DynamicLookupRelationModel extends DsDynamicInputModel {
this.disabled = true;
this.repeatable = config.repeatable;
this.item = config.item;
+ this.relationship = config.relationship;
this.valueUpdates.next(config.value);
}
}
diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/model/relationship-options.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/model/relationship-options.model.ts
new file mode 100644
index 0000000000..cd6e00e7dc
--- /dev/null
+++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup-relation/model/relationship-options.model.ts
@@ -0,0 +1,5 @@
+export interface RelationshipOptions {
+ relationshipType: string;
+ filter: string;
+ searchConfiguration: string;
+}
diff --git a/src/app/shared/form/builder/models/form-field.model.ts b/src/app/shared/form/builder/models/form-field.model.ts
index 439bf89f8f..e86bc2791a 100644
--- a/src/app/shared/form/builder/models/form-field.model.ts
+++ b/src/app/shared/form/builder/models/form-field.model.ts
@@ -2,6 +2,7 @@ import { autoserialize } from 'cerialize';
import { FormRowModel } from '../../../../core/config/models/config-submission-forms.model';
import { LanguageCode } from './form-field-language-value.model';
import { FormFieldMetadataValueObject } from './form-field-metadata-value.model';
+import { RelationshipOptions } from '../ds-dynamic-form-ui/models/lookup-relation/model/relationship-options.model';
export class FormFieldModel {
@@ -32,6 +33,9 @@ export class FormFieldModel {
@autoserialize
selectableMetadata: FormFieldMetadataValueObject[];
+ @autoserialize
+ selectableRelationships: RelationshipOptions[];
+
@autoserialize
rows: FormRowModel[];
diff --git a/src/app/shared/form/builder/parsers/lookup-relation-field-parser.ts b/src/app/shared/form/builder/parsers/lookup-relation-field-parser.ts
index 202edfec8e..ddd2449de8 100644
--- a/src/app/shared/form/builder/parsers/lookup-relation-field-parser.ts
+++ b/src/app/shared/form/builder/parsers/lookup-relation-field-parser.ts
@@ -1,20 +1,14 @@
import { FieldParser } from './field-parser';
-import {
- DynamicLookupModel,
- DynamicLookupModelConfig
-} from '../ds-dynamic-form-ui/models/lookup/dynamic-lookup.model';
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
-import {
- DynamicLookupRelationModel,
- DynamicLookupRelationModelConfig
-} from '../ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.model';
+import { DynamicLookupRelationModel, DynamicLookupRelationModelConfig } from '../ds-dynamic-form-ui/models/lookup-relation/dynamic-lookup-relation.model';
export class LookupRelationFieldParser extends FieldParser {
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any {
const lookupModelConfig: DynamicLookupRelationModelConfig = this.initModel(null, label);
lookupModelConfig.repeatable = this.configData.repeatable;
-
+ /* TODO what to do with multiple relationships? */
+ lookupModelConfig.relationship = this.configData.selectableRelationships[0];
return new DynamicLookupRelationModel(lookupModelConfig);
}
}
diff --git a/src/app/shared/object-collection/object-collection.component.html b/src/app/shared/object-collection/object-collection.component.html
index 0323251b12..af65b652bb 100644
--- a/src/app/shared/object-collection/object-collection.component.html
+++ b/src/app/shared/object-collection/object-collection.component.html
@@ -7,6 +7,8 @@
(pageChange)="onPageChange($event)"
(pageSizeChange)="onPageSizeChange($event)"
(sortDirectionChange)="onSortDirectionChange($event)"
+ (deselectObject)="deselectObject.emit($event)"
+ (selectObject)="selectObject.emit($event)"
(sortFieldChange)="onSortFieldChange($event)"
[selectable]="selectable"
[selectionConfig]="selectionConfig"
diff --git a/src/app/shared/object-collection/object-collection.component.ts b/src/app/shared/object-collection/object-collection.component.ts
index fcc3bd330e..4dde335c98 100644
--- a/src/app/shared/object-collection/object-collection.component.ts
+++ b/src/app/shared/object-collection/object-collection.component.ts
@@ -35,6 +35,8 @@ export class ObjectCollectionComponent implements OnChanges, OnInit {
@Input() hideGear = false;
@Input() selectable = false;
@Input() selectionConfig: {repeatable: boolean, listId: string};
+ @Output() deselectObject: EventEmitter = new EventEmitter();
+ @Output() selectObject: EventEmitter = new EventEmitter();
pageInfo: Observable;
private sub;
diff --git a/src/app/shared/object-collection/shared/item-search-result.model.ts b/src/app/shared/object-collection/shared/item-search-result.model.ts
index 89a9d782a6..bea0a6f24a 100644
--- a/src/app/shared/object-collection/shared/item-search-result.model.ts
+++ b/src/app/shared/object-collection/shared/item-search-result.model.ts
@@ -1,7 +1,9 @@
import { SearchResult } from '../../search/search-result.model';
import { Item } from '../../../core/shared/item.model';
import { searchResultFor } from '../../search/search-result-element-decorator';
+import { inheritEquatable } from '../../../core/utilities/equals.decorators';
@searchResultFor(Item)
+@inheritEquatable(SearchResult)
export class ItemSearchResult extends SearchResult
- {
}
diff --git a/src/app/shared/object-list/object-list.component.ts b/src/app/shared/object-list/object-list.component.ts
index a8467d92af..6070cad37d 100644
--- a/src/app/shared/object-list/object-list.component.ts
+++ b/src/app/shared/object-list/object-list.component.ts
@@ -79,8 +79,11 @@ export class ObjectListComponent {
*/
@Output() sortDirectionChange: EventEmitter = new EventEmitter();
- @Output() paginationChange: EventEmitter = new EventEmitter();
+ @Output() paginationChange: EventEmitter = new EventEmitter();
+ @Output() deselectObject: EventEmitter = new EventEmitter();
+
+ @Output() selectObject: EventEmitter = new EventEmitter();
/**
* An event fired when the sort field is changed.
* Event's payload equals to the newly selected sort field.
@@ -108,66 +111,24 @@ export class ObjectListComponent {
this.paginationChange.emit(event);
}
- // isDisabled(object: ListableObject): boolean {
- // return hasValue(this.previousSelection.find((selected) => selected === object));
- // }
-
selectCheckbox(value: boolean, object: ListableObject) {
if (value) {
this.selectionService.selectSingle(this.selectionConfig.listId, object);
+ this.selectObject.emit(object);
+
} else {
this.selectionService.deselectSingle(this.selectionConfig.listId, object);
+ this.deselectObject.emit(object);
}
}
selectRadio(value: boolean, object: ListableObject) {
if (value) {
this.selectionService.selectSingle(this.selectionConfig.listId, object, false);
+ this.selectObject.emit(object);
+ } else {
+ this.selectionService.deselectSingle(this.selectionConfig.listId, object);
+ this.deselectObject.emit(object);
}
}
-
- selectPage(page: SearchResult[]) {
- this.selectionService.select(this.selectionConfig.listId, this.objects.payload.page);
- }
-
- deselectPage(page: SearchResult[]) {
- this.selectionService.deselect(this.selectionConfig.listId, this.objects.payload.page);
-
- }
-
- deselectAll() {
- this.selectionService.deselectAll(this.selectionConfig.listId);
- }
-
- // isAllSelected() {
- // return this.allSelected;
- // }
- //
- // isSomeSelected() {
- // return isNotEmpty(this.selection);
- // }
- //
- //
- // selectAll() {
- // this.allSelected = true;
- // this.selectAllLoading = true;
- // const fullPagination = Object.assign(new PaginationComponentOptions(), {
- // query: this.searchQuery,
- // currentPage: 1,
- // pageSize: Number.POSITIVE_INFINITY
- // });
- // const fullSearchConfig = Object.assign(this.searchConfig, { pagination: fullPagination });
- // const results = this.searchService.search(fullSearchConfig);
- // results.pipe(
- // getSucceededRemoteData(),
- // map((resultsRD) => resultsRD.payload.page),
- // tap(() => this.selectAllLoading = false)
- // )
- // .subscribe((results) =>
- // this.selection = results
- // .map((searchResult) => searchResult.indexableObject)
- // .filter((dso) => hasNoValue(this.previousSelection.find((object) => object === dso)))
- // );
- // }
-
}
diff --git a/src/app/shared/object-list/selectable-list/selectable-list.reducer.ts b/src/app/shared/object-list/selectable-list/selectable-list.reducer.ts
index 61a56bedd8..e3f0479d7b 100644
--- a/src/app/shared/object-list/selectable-list/selectable-list.reducer.ts
+++ b/src/app/shared/object-list/selectable-list/selectable-list.reducer.ts
@@ -71,10 +71,12 @@ function select(state: SelectableListState, action: SelectableListSelectAction)
function selectSingle(state: SelectableListState, action: SelectableListSelectSingleAction) {
let newSelection;
- if (action.payload.multipleSelectionsAllowed && !isObjectInSelection(state.selection, action.payload.object)) {
- newSelection = [...state.selection, action.payload.object];
- } else {
- newSelection = [action.payload.object];
+ if (!isObjectInSelection(state.selection, action.payload.object)) {
+ if (action.payload.multipleSelectionsAllowed) {
+ newSelection = [...state.selection, action.payload.object];
+ } else {
+ newSelection = [action.payload.object];
+ }
}
return Object.assign({}, state, { selection: newSelection });
}
diff --git a/src/app/shared/object-list/selectable-list/selectable-list.service.ts b/src/app/shared/object-list/selectable-list/selectable-list.service.ts
index 097e7da30f..2ea495691f 100644
--- a/src/app/shared/object-list/selectable-list/selectable-list.service.ts
+++ b/src/app/shared/object-list/selectable-list/selectable-list.service.ts
@@ -37,8 +37,9 @@ export class SelectableListService {
* Select an object in a specific list in the store
* @param {string} id The id of the list on which the object should be selected
* @param {ListableObject} object The object to select
+ * @param {boolean} multipleSelectionsAllowed Defines if the multiple selections are allowed for this selectable list
*/
- selectSingle(id: string, object: ListableObject, multipleSelectionsAllowed?) {
+ selectSingle(id: string, object: ListableObject, multipleSelectionsAllowed?: boolean) {
this.store.dispatch(new SelectableListSelectSingleAction(id, object, multipleSelectionsAllowed));
}
@@ -86,7 +87,7 @@ export class SelectableListService {
isObjectSelected(id: string, object: ListableObject): Observable {
return this.getSelectableList(id).pipe(
filter((state: SelectableListState) => hasValue(state)),
- map((state: SelectableListState) => isNotEmpty(state.selection) && hasValue(state.selection.find((selected) => selected === object))),
+ map((state: SelectableListState) => isNotEmpty(state.selection) && hasValue(state.selection.find((selected) => selected.equals(object)))),
startWith(false),
distinctUntilChanged()
);
diff --git a/src/app/shared/search/search-results/search-results.component.html b/src/app/shared/search/search-results/search-results.component.html
index bbf84f305c..70e527373c 100644
--- a/src/app/shared/search/search-results/search-results.component.html
+++ b/src/app/shared/search/search-results/search-results.component.html
@@ -7,6 +7,8 @@
[hideGear]="true"
[selectable]="selectable"
[selectionConfig]="selectionConfig"
+ (deselectObject)="deselectObject.emit($event)"
+ (selectObject)="selectObject.emit($event)"
>
diff --git a/src/app/shared/search/search-results/search-results.component.ts b/src/app/shared/search/search-results/search-results.component.ts
index 09178e9cad..7bc9f391cd 100644
--- a/src/app/shared/search/search-results/search-results.component.ts
+++ b/src/app/shared/search/search-results/search-results.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input } from '@angular/core';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
import { RemoteData } from '../../../core/data/remote-data';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { fadeIn, fadeInOut } from '../../animations/fade';
@@ -8,6 +8,7 @@ import { SearchResult } from '../search-result.model';
import { PaginatedList } from '../../../core/data/paginated-list';
import { hasNoValue, isNotEmpty } from '../../empty.util';
import { SortOptions } from '../../../core/cache/models/sort-options.model';
+import { ListableObject } from '../../object-collection/shared/listable-object.model';
@Component({
selector: 'ds-search-results',
@@ -58,6 +59,11 @@ export class SearchResultsComponent {
@Input() selectable = false;
@Input() selectionConfig: {repeatable: boolean, listId: string};
+
+ @Output() deselectObject: EventEmitter
= new EventEmitter();
+
+ @Output() selectObject: EventEmitter = new EventEmitter();
+
/**
* Method to change the given string by surrounding it by quotes if not already present.
*/