mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
[CST-3620] Changes to show lookup button next to the field
This commit is contained in:
@@ -35,6 +35,14 @@
|
|||||||
<option *ngFor="let lang of model.languageCodes" [value]="lang.code">{{lang.display}}</option>
|
<option *ngFor="let lang of model.languageCodes" [value]="lang.code">{{lang.display}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div *ngIf="isRelationship && !isVirtual()" class="col-auto text-center">
|
||||||
|
<button class="btn btn-secondary"
|
||||||
|
type="button"
|
||||||
|
ngbTooltip="{{'form.lookup-help' | translate}}"
|
||||||
|
placement="top"
|
||||||
|
(click)="openLookup(); $event.stopPropagation();">{{'form.lookup' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngTemplateOutlet="endTemplate?.templateRef; context: model"></ng-container>
|
<ng-container *ngTemplateOutlet="endTemplate?.templateRef; context: model"></ng-container>
|
||||||
<ng-container *ngIf="value?.isVirtual">
|
<ng-container *ngIf="value?.isVirtual">
|
||||||
|
@@ -37,6 +37,7 @@ import {
|
|||||||
DynamicFormControl,
|
DynamicFormControl,
|
||||||
DynamicFormControlContainerComponent,
|
DynamicFormControlContainerComponent,
|
||||||
DynamicFormControlEvent,
|
DynamicFormControlEvent,
|
||||||
|
DynamicFormControlEventType,
|
||||||
DynamicFormControlModel,
|
DynamicFormControlModel,
|
||||||
DynamicFormLayout,
|
DynamicFormLayout,
|
||||||
DynamicFormLayoutService,
|
DynamicFormLayoutService,
|
||||||
@@ -82,10 +83,12 @@ import { find, map, startWith, switchMap, take } from 'rxjs/operators';
|
|||||||
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
|
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
|
||||||
import { SearchResult } from '../../../search/search-result.model';
|
import { SearchResult } from '../../../search/search-result.model';
|
||||||
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
||||||
|
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { RelationshipService } from '../../../../core/data/relationship.service';
|
import { RelationshipService } from '../../../../core/data/relationship.service';
|
||||||
import { SelectableListService } from '../../../object-list/selectable-list/selectable-list.service';
|
import { SelectableListService } from '../../../object-list/selectable-list/selectable-list.service';
|
||||||
import { DsDynamicDisabledComponent } from './models/disabled/dynamic-disabled.component';
|
import { DsDynamicDisabledComponent } from './models/disabled/dynamic-disabled.component';
|
||||||
import { DYNAMIC_FORM_CONTROL_TYPE_DISABLED } from './models/disabled/dynamic-disabled.model';
|
import { DYNAMIC_FORM_CONTROL_TYPE_DISABLED } from './models/disabled/dynamic-disabled.model';
|
||||||
|
import { DsDynamicLookupRelationModalComponent } from './relation-lookup-modal/dynamic-lookup-relation-modal.component';
|
||||||
import {
|
import {
|
||||||
getAllSucceededRemoteData,
|
getAllSucceededRemoteData,
|
||||||
getFirstSucceededRemoteData,
|
getFirstSucceededRemoteData,
|
||||||
@@ -107,6 +110,7 @@ import { Collection } from '../../../../core/shared/collection.model';
|
|||||||
import { MetadataValue, VIRTUAL_METADATA_PREFIX } from '../../../../core/shared/metadata.models';
|
import { MetadataValue, VIRTUAL_METADATA_PREFIX } from '../../../../core/shared/metadata.models';
|
||||||
import { FormService } from '../../form.service';
|
import { FormService } from '../../form.service';
|
||||||
import { SelectableListState } from '../../../object-list/selectable-list/selectable-list.reducer';
|
import { SelectableListState } from '../../../object-list/selectable-list/selectable-list.reducer';
|
||||||
|
import { SubmissionService } from '../../../../submission/submission.service';
|
||||||
import { followLink } from '../../../utils/follow-link-config.model';
|
import { followLink } from '../../../utils/follow-link-config.model';
|
||||||
import { paginatedRelationsToItems } from '../../../../+item-page/simple/item-types/shared/item-relationships-utils';
|
import { paginatedRelationsToItems } from '../../../../+item-page/simple/item-types/shared/item-relationships-utils';
|
||||||
import { RelationshipOptions } from '../models/relationship-options.model';
|
import { RelationshipOptions } from '../models/relationship-options.model';
|
||||||
@@ -202,6 +206,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
@Input() model: any;
|
@Input() model: any;
|
||||||
relationshipValue$: Observable<ReorderableRelationship>;
|
relationshipValue$: Observable<ReorderableRelationship>;
|
||||||
isRelationship: boolean;
|
isRelationship: boolean;
|
||||||
|
modalRef: NgbModalRef;
|
||||||
item: Item;
|
item: Item;
|
||||||
item$: Observable<Item>;
|
item$: Observable<Item>;
|
||||||
collection: Collection;
|
collection: Collection;
|
||||||
@@ -234,6 +239,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
protected validationService: DynamicFormValidationService,
|
protected validationService: DynamicFormValidationService,
|
||||||
protected translateService: TranslateService,
|
protected translateService: TranslateService,
|
||||||
protected relationService: DynamicFormRelationService,
|
protected relationService: DynamicFormRelationService,
|
||||||
|
private modalService: NgbModal,
|
||||||
private relationshipService: RelationshipService,
|
private relationshipService: RelationshipService,
|
||||||
private selectableListService: SelectableListService,
|
private selectableListService: SelectableListService,
|
||||||
private itemService: ItemDataService,
|
private itemService: ItemDataService,
|
||||||
@@ -243,6 +249,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
private ref: ChangeDetectorRef,
|
private ref: ChangeDetectorRef,
|
||||||
private formService: FormService,
|
private formService: FormService,
|
||||||
private formBuilderService: FormBuilderService,
|
private formBuilderService: FormBuilderService,
|
||||||
|
private submissionService: SubmissionService
|
||||||
) {
|
) {
|
||||||
super(ref, componentFactoryResolver, layoutService, validationService, dynamicFormComponentService, relationService);
|
super(ref, componentFactoryResolver, layoutService, validationService, dynamicFormComponentService, relationService);
|
||||||
}
|
}
|
||||||
@@ -257,6 +264,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
if (this.isRelationship || isWrapperAroundRelationshipList) {
|
if (this.isRelationship || isWrapperAroundRelationshipList) {
|
||||||
const config = this.model.relationshipConfig || this.model.relationship;
|
const config = this.model.relationshipConfig || this.model.relationship;
|
||||||
const relationshipOptions = Object.assign(new RelationshipOptions(), config);
|
const relationshipOptions = Object.assign(new RelationshipOptions(), config);
|
||||||
|
this.listId = `list-${this.model.submissionId}-${relationshipOptions.relationshipType}`;
|
||||||
this.setItem();
|
this.setItem();
|
||||||
|
|
||||||
if (isWrapperAroundRelationshipList || !this.model.repeatable) {
|
if (isWrapperAroundRelationshipList || !this.model.repeatable) {
|
||||||
@@ -366,10 +374,68 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasRelationship() {
|
||||||
|
return isNotEmpty(this.model) && this.model.hasOwnProperty('relationship') && isNotEmpty(this.model.relationship);
|
||||||
|
}
|
||||||
|
|
||||||
|
isVirtual() {
|
||||||
|
const value: FormFieldMetadataValueObject = this.model.metadataValue;
|
||||||
|
return isNotEmpty(value) && value.isVirtual;
|
||||||
|
}
|
||||||
|
|
||||||
public hasResultsSelected(): Observable<boolean> {
|
public hasResultsSelected(): Observable<boolean> {
|
||||||
return this.model.value.pipe(map((list: SearchResult<DSpaceObject>[]) => isNotEmpty(list)));
|
return this.model.value.pipe(map((list: SearchResult<DSpaceObject>[]) => isNotEmpty(list)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a modal where the user can select relationships to be added to item being submitted
|
||||||
|
*/
|
||||||
|
openLookup() {
|
||||||
|
this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, {
|
||||||
|
size: 'lg'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasValue(this.model.value)) {
|
||||||
|
this.focus.emit({
|
||||||
|
$event: new Event('focus'),
|
||||||
|
context: this.context,
|
||||||
|
control: this.control,
|
||||||
|
model: this.model,
|
||||||
|
type: DynamicFormControlEventType.Focus
|
||||||
|
} as DynamicFormControlEvent);
|
||||||
|
|
||||||
|
this.model.value = null;
|
||||||
|
this.change.emit({
|
||||||
|
$event: new Event('change'),
|
||||||
|
context: this.context,
|
||||||
|
control: this.control,
|
||||||
|
model: this.model,
|
||||||
|
type: DynamicFormControlEventType.Change
|
||||||
|
} as DynamicFormControlEvent);
|
||||||
|
|
||||||
|
this.submissionService.dispatchSave(this.model.submissionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const modalComp = this.modalRef.componentInstance;
|
||||||
|
|
||||||
|
if (hasValue(this.model.value) && !this.model.readOnly) {
|
||||||
|
if (typeof this.model.value === 'string') {
|
||||||
|
modalComp.query = this.model.value;
|
||||||
|
} else if (typeof this.model.value.value === 'string') {
|
||||||
|
modalComp.query = this.model.value.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modalComp.repeatable = this.model.repeatable;
|
||||||
|
modalComp.listId = this.listId;
|
||||||
|
modalComp.relationshipOptions = this.model.relationship;
|
||||||
|
modalComp.label = this.model.relationship.relationshipType;
|
||||||
|
modalComp.metadataFields = this.model.metadataFields;
|
||||||
|
modalComp.item = this.item;
|
||||||
|
modalComp.collection = this.collection;
|
||||||
|
modalComp.submissionId = this.model.submissionId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for the remove event,
|
* Callback for the remove event,
|
||||||
* remove the current control from its array
|
* remove the current control from its array
|
||||||
|
@@ -147,7 +147,6 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.setItem();
|
this.setItem();
|
||||||
this.submissionService.dispatchSave(this.submissionId);
|
|
||||||
this.selection$ = this.selectableListService
|
this.selection$ = this.selectableListService
|
||||||
.getSelectableList(this.listId)
|
.getSelectableList(this.listId)
|
||||||
.pipe(map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : []));
|
.pipe(map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : []));
|
||||||
|
@@ -14,7 +14,6 @@
|
|||||||
<!--Array with repeatable items-->
|
<!--Array with repeatable items-->
|
||||||
<div *ngIf="(!context.notRepeatable) && !isVirtual(context, index)"
|
<div *ngIf="(!context.notRepeatable) && !isVirtual(context, index)"
|
||||||
class="col-xs-2 d-flex flex-column justify-content-sm-start align-items-end">
|
class="col-xs-2 d-flex flex-column justify-content-sm-start align-items-end">
|
||||||
<div class="btn-group" role="group" aria-label="remove button">
|
|
||||||
<button type="button" class="btn btn-secondary"
|
<button type="button" class="btn btn-secondary"
|
||||||
title="{{'form.remove' | translate}}"
|
title="{{'form.remove' | translate}}"
|
||||||
(click)="removeItem($event, context, index)"
|
(click)="removeItem($event, context, index)"
|
||||||
@@ -22,7 +21,6 @@
|
|||||||
<span attr.aria-label="{{'form.remove' | translate}}"><i class="fas fa-trash" aria-hidden="true"></i></span>
|
<span attr.aria-label="{{'form.remove' | translate}}"><i class="fas fa-trash" aria-hidden="true"></i></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div *ngIf="(!context.notRepeatable) && index === (group.context.groups.length - 1)" class="clearfix pl-4 w-100">
|
<div *ngIf="(!context.notRepeatable) && index === (group.context.groups.length - 1)" class="clearfix pl-4 w-100">
|
||||||
<div class="btn-group" role="group" aria-label="remove button">
|
<div class="btn-group" role="group" aria-label="remove button">
|
||||||
<button type="button" class="ds-form-add-more btn btn-link"
|
<button type="button" class="ds-form-add-more btn btn-link"
|
||||||
@@ -31,13 +29,6 @@
|
|||||||
(click)="insertItem($event, group.context, group.context.groups.length)">
|
(click)="insertItem($event, group.context, group.context.groups.length)">
|
||||||
<span attr.aria-label="{{'form.add' | translate}}"><i class="fas fa-plus"></i> {{'form.add' | translate}}</span>
|
<span attr.aria-label="{{'form.add' | translate}}"><i class="fas fa-plus"></i> {{'form.add' | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="hasRelationship(context, index)"
|
|
||||||
type="button" class="ds-form-add-more btn btn-link"
|
|
||||||
title="{{'form.add' | translate}}"
|
|
||||||
[disabled]="isItemReadOnly(context, index)"
|
|
||||||
(click)="openLookup(context, index)">
|
|
||||||
<span attr.aria-label="{{'form.add' | translate}}"><i class="fas fa-search-plus"></i> {{'form.lookup' | translate}}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -54,6 +45,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
</ds-dynamic-form>
|
</ds-dynamic-form>
|
||||||
|
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
|
@@ -10,15 +10,13 @@ import {
|
|||||||
DynamicFormGroupModel,
|
DynamicFormGroupModel,
|
||||||
DynamicFormLayout,
|
DynamicFormLayout,
|
||||||
} from '@ng-dynamic-forms/core';
|
} from '@ng-dynamic-forms/core';
|
||||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { findIndex } from 'lodash';
|
import { findIndex } from 'lodash';
|
||||||
|
|
||||||
import { FormBuilderService } from './builder/form-builder.service';
|
import { FormBuilderService } from './builder/form-builder.service';
|
||||||
import { hasValue, isNotEmpty, isNotNull, isNull } from '../empty.util';
|
import { hasValue, isNotEmpty, isNotNull, isNull } from '../empty.util';
|
||||||
import { FormService } from './form.service';
|
import { FormService } from './form.service';
|
||||||
import { FormEntry, FormError } from './form.reducer';
|
import { FormEntry, FormError } from './form.reducer';
|
||||||
import { DsDynamicLookupRelationModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component';
|
|
||||||
import { RelationshipOptions } from './builder/models/relationship-options.model';
|
|
||||||
import { FormFieldMetadataValueObject } from './builder/models/form-field-metadata-value.model';
|
import { FormFieldMetadataValueObject } from './builder/models/form-field-metadata-value.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,8 +99,7 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
constructor(private formService: FormService,
|
constructor(private formService: FormService,
|
||||||
protected changeDetectorRef: ChangeDetectorRef,
|
protected changeDetectorRef: ChangeDetectorRef,
|
||||||
private formBuilderService: FormBuilderService,
|
private formBuilderService: FormBuilderService) {
|
||||||
private modalService: NgbModal) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,7 +166,6 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
filter((formState: FormEntry) => !!formState && (isNotEmpty(formState.errors) || isNotEmpty(this.formErrors))),
|
filter((formState: FormEntry) => !!formState && (isNotEmpty(formState.errors) || isNotEmpty(this.formErrors))),
|
||||||
map((formState) => formState.errors),
|
map((formState) => formState.errors),
|
||||||
distinctUntilChanged())
|
distinctUntilChanged())
|
||||||
// .delay(100) // this terrible delay is here to prevent the detection change error
|
|
||||||
.subscribe((errors: FormError[]) => {
|
.subscribe((errors: FormError[]) => {
|
||||||
const { formGroup, formModel } = this;
|
const { formGroup, formModel } = this;
|
||||||
errors
|
errors
|
||||||
@@ -320,42 +316,6 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
return isNotEmpty(value) && value.isVirtual;
|
return isNotEmpty(value) && value.isVirtual;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasRelationship(arrayContext: DynamicFormArrayModel, index: number) {
|
|
||||||
const context = arrayContext.groups[index];
|
|
||||||
const model = context.group[0] as any;
|
|
||||||
return isNotEmpty(model) && model.hasOwnProperty('relationship') && isNotEmpty(model.relationship);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a modal where the user can select relationships to be added to item being submitted
|
|
||||||
*/
|
|
||||||
openLookup(arrayContext: DynamicFormArrayModel, index: number) {
|
|
||||||
const context = arrayContext.groups[index];
|
|
||||||
const model = context.group[0] as any;
|
|
||||||
this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, {
|
|
||||||
size: 'lg'
|
|
||||||
});
|
|
||||||
const modalComp = this.modalRef.componentInstance;
|
|
||||||
|
|
||||||
if (hasValue(model.value) && !model.readOnly) {
|
|
||||||
if (typeof model.value === 'string') {
|
|
||||||
modalComp.query = model.value;
|
|
||||||
} else if (typeof model.value.value === 'string') {
|
|
||||||
modalComp.query = model.value.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = model.relationshipConfig || model.relationship;
|
|
||||||
const relationshipOptions = Object.assign(new RelationshipOptions(), config);
|
|
||||||
|
|
||||||
modalComp.repeatable = model.repeatable;
|
|
||||||
modalComp.listId = `list-${model.submissionId}-${relationshipOptions.relationshipType}`;
|
|
||||||
modalComp.relationshipOptions = model.relationship;
|
|
||||||
modalComp.label = model.relationship.relationshipType;
|
|
||||||
modalComp.metadataFields = model.metadataFields;
|
|
||||||
modalComp.submissionId = model.submissionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getEvent($event: any, arrayContext: DynamicFormArrayModel, index: number, type: string): DynamicFormControlEvent {
|
protected getEvent($event: any, arrayContext: DynamicFormArrayModel, index: number, type: string): DynamicFormControlEvent {
|
||||||
const context = arrayContext.groups[index];
|
const context = arrayContext.groups[index];
|
||||||
const itemGroupModel = context.context;
|
const itemGroupModel = context.context;
|
||||||
|
Reference in New Issue
Block a user