mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge branch 'w2p-117573_remove-observable-function-calls-from-template-7.6'
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
@if (registryService.getActiveMetadataField() | async) {
|
@if (activeMetadataField$ | async) {
|
||||||
<h2>{{messagePrefix + '.edit' | translate}}</h2>
|
<h2>{{messagePrefix + '.edit' | translate}}</h2>
|
||||||
} @else {
|
} @else {
|
||||||
<h2>{{messagePrefix + '.create' | translate}}</h2>
|
<h2>{{messagePrefix + '.create' | translate}}</h2>
|
||||||
|
@@ -19,7 +19,7 @@ import {
|
|||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslateService,
|
TranslateService,
|
||||||
} from '@ngx-translate/core';
|
} from '@ngx-translate/core';
|
||||||
import { combineLatest } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
||||||
@@ -109,6 +109,8 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
@Output() submitForm: EventEmitter<any> = new EventEmitter();
|
@Output() submitForm: EventEmitter<any> = new EventEmitter();
|
||||||
|
|
||||||
|
activeMetadataField$: Observable<MetadataField>;
|
||||||
|
|
||||||
constructor(public registryService: RegistryService,
|
constructor(public registryService: RegistryService,
|
||||||
private formBuilderService: FormBuilderService,
|
private formBuilderService: FormBuilderService,
|
||||||
private translateService: TranslateService) {
|
private translateService: TranslateService) {
|
||||||
@@ -117,15 +119,11 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
/**
|
/**
|
||||||
* Initialize the component, setting up the necessary Models for the dynamic form
|
* Initialize the component, setting up the necessary Models for the dynamic form
|
||||||
*/
|
*/
|
||||||
ngOnInit() {
|
ngOnInit(): void {
|
||||||
combineLatest([
|
this.activeMetadataField$ = this.registryService.getActiveMetadataField();
|
||||||
this.translateService.get(`${this.messagePrefix}.element`),
|
|
||||||
this.translateService.get(`${this.messagePrefix}.qualifier`),
|
|
||||||
this.translateService.get(`${this.messagePrefix}.scopenote`),
|
|
||||||
]).subscribe(([element, qualifier, scopenote]) => {
|
|
||||||
this.element = new DynamicInputModel({
|
this.element = new DynamicInputModel({
|
||||||
id: 'element',
|
id: 'element',
|
||||||
label: element,
|
label: this.translateService.instant(`${this.messagePrefix}.element`),
|
||||||
name: 'element',
|
name: 'element',
|
||||||
validators: {
|
validators: {
|
||||||
required: null,
|
required: null,
|
||||||
@@ -140,7 +138,7 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
this.qualifier = new DynamicInputModel({
|
this.qualifier = new DynamicInputModel({
|
||||||
id: 'qualifier',
|
id: 'qualifier',
|
||||||
label: qualifier,
|
label: this.translateService.instant(`${this.messagePrefix}.qualifier`),
|
||||||
name: 'qualifier',
|
name: 'qualifier',
|
||||||
validators: {
|
validators: {
|
||||||
pattern: '^[^. ,]*$',
|
pattern: '^[^. ,]*$',
|
||||||
@@ -154,14 +152,13 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
this.scopeNote = new DynamicTextAreaModel({
|
this.scopeNote = new DynamicTextAreaModel({
|
||||||
id: 'scopeNote',
|
id: 'scopeNote',
|
||||||
label: scopenote,
|
label: this.translateService.instant(`${this.messagePrefix}.scopenote`),
|
||||||
name: 'scopeNote',
|
name: 'scopeNote',
|
||||||
required: false,
|
required: false,
|
||||||
rows: 5,
|
rows: 5,
|
||||||
});
|
});
|
||||||
this.formModel = [
|
this.formModel = [
|
||||||
new DynamicFormGroupModel(
|
new DynamicFormGroupModel({
|
||||||
{
|
|
||||||
id: 'metadatadatafieldgroup',
|
id: 'metadatadatafieldgroup',
|
||||||
group:[this.element, this.qualifier, this.scopeNote],
|
group:[this.element, this.qualifier, this.scopeNote],
|
||||||
}),
|
}),
|
||||||
@@ -182,7 +179,6 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
this.qualifier.disabled = true;
|
this.qualifier.disabled = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<ds-alert [type]="'alert-info'" [content]="'item.edit.authorizations.heading'"></ds-alert>
|
<ds-alert [type]="AlertType.Info" [content]="'item.edit.authorizations.heading'"></ds-alert>
|
||||||
<ds-resource-policies [resourceType]="'item'" [resourceName]="(getItemName() | async)"
|
<ds-resource-policies [resourceType]="'item'" [resourceName]="itemName$ | async"
|
||||||
[resourceUUID]="(getItemUUID() | async)">
|
[resourceUUID]="(item$ | async)?.id">
|
||||||
</ds-resource-policies>
|
</ds-resource-policies>
|
||||||
@for (bundle of (bundles$ | async); track bundle) {
|
@for (bundle of (bundles$ | async); track bundle) {
|
||||||
<ds-resource-policies [resourceType]="'bundle'" [resourceUUID]="bundle.id" [resourceName]="bundle.name">
|
<ds-resource-policies [resourceType]="'bundle'" [resourceUUID]="bundle.id" [resourceName]="bundle.name">
|
||||||
|
@@ -169,17 +169,9 @@ describe('ItemAuthorizationsComponent test suite', () => {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get the item UUID', () => {
|
|
||||||
|
|
||||||
expect(comp.getItemUUID()).toBeObservable(cold('(a|)', {
|
|
||||||
a: item.id,
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get the item\'s bundle', () => {
|
it('should get the item\'s bundle', () => {
|
||||||
|
|
||||||
expect(comp.getItemBundles()).toBeObservable(cold('a', {
|
expect(comp.bundles$).toBeObservable(cold('a', {
|
||||||
a: bundles,
|
a: bundles,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@@ -17,7 +17,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
catchError,
|
catchError,
|
||||||
filter,
|
filter,
|
||||||
first,
|
|
||||||
map,
|
map,
|
||||||
mergeMap,
|
mergeMap,
|
||||||
take,
|
take,
|
||||||
@@ -37,11 +36,11 @@ import {
|
|||||||
getFirstSucceededRemoteDataWithNotEmptyPayload,
|
getFirstSucceededRemoteDataWithNotEmptyPayload,
|
||||||
} from '../../../core/shared/operators';
|
} from '../../../core/shared/operators';
|
||||||
import { AlertComponent } from '../../../shared/alert/alert.component';
|
import { AlertComponent } from '../../../shared/alert/alert.component';
|
||||||
|
import { AlertType } from '../../../shared/alert/alert-type';
|
||||||
import {
|
import {
|
||||||
hasValue,
|
hasValue,
|
||||||
isNotEmpty,
|
isNotEmpty,
|
||||||
} from '../../../shared/empty.util';
|
} from '../../../shared/empty.util';
|
||||||
import { NgForTrackByIdDirective } from '../../../shared/ng-for-track-by-id.directive';
|
|
||||||
import { ResourcePoliciesComponent } from '../../../shared/resource-policies/resource-policies.component';
|
import { ResourcePoliciesComponent } from '../../../shared/resource-policies/resource-policies.component';
|
||||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||||
|
|
||||||
@@ -61,7 +60,6 @@ interface BundleBitstreamsMapEntry {
|
|||||||
ResourcePoliciesComponent,
|
ResourcePoliciesComponent,
|
||||||
NgbCollapseModule,
|
NgbCollapseModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
NgForTrackByIdDirective,
|
|
||||||
AsyncPipe,
|
AsyncPipe,
|
||||||
AlertComponent,
|
AlertComponent,
|
||||||
],
|
],
|
||||||
@@ -88,7 +86,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
|||||||
* The target editing item
|
* The target editing item
|
||||||
* @type {Observable<Item>}
|
* @type {Observable<Item>}
|
||||||
*/
|
*/
|
||||||
private item$: Observable<Item>;
|
item$: Observable<Item>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||||
@@ -127,16 +125,13 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
private bitstreamPageSize = 4;
|
private bitstreamPageSize = 4;
|
||||||
|
|
||||||
/**
|
itemName$: Observable<string>;
|
||||||
* Initialize instance variables
|
|
||||||
*
|
readonly AlertType = AlertType;
|
||||||
* @param {LinkService} linkService
|
|
||||||
* @param {ActivatedRoute} route
|
|
||||||
* @param nameService
|
|
||||||
*/
|
|
||||||
constructor(
|
constructor(
|
||||||
private linkService: LinkService,
|
protected linkService: LinkService,
|
||||||
private route: ActivatedRoute,
|
protected route: ActivatedRoute,
|
||||||
public nameService: DSONameService,
|
public nameService: DSONameService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@@ -146,36 +141,18 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.getBundlesPerItem();
|
this.getBundlesPerItem();
|
||||||
}
|
this.itemName$ = this.getItemName();
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the item's UUID
|
|
||||||
*/
|
|
||||||
getItemUUID(): Observable<string> {
|
|
||||||
return this.item$.pipe(
|
|
||||||
map((item: Item) => item.id),
|
|
||||||
first((UUID: string) => isNotEmpty(UUID)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the item's name
|
* Return the item's name
|
||||||
*/
|
*/
|
||||||
getItemName(): Observable<string> {
|
private getItemName(): Observable<string> {
|
||||||
return this.item$.pipe(
|
return this.item$.pipe(
|
||||||
map((item: Item) => this.nameService.getName(item)),
|
map((item: Item) => this.nameService.getName(item)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return all item's bundles
|
|
||||||
*
|
|
||||||
* @return an observable that emits all item's bundles
|
|
||||||
*/
|
|
||||||
getItemBundles(): Observable<Bundle[]> {
|
|
||||||
return this.bundles$.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all bundles per item
|
* Get all bundles per item
|
||||||
* and all the bitstreams per bundle
|
* and all the bitstreams per bundle
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
<div class="container mb-5">
|
<div class="container mb-5">
|
||||||
<h1>{{'person.orcid.registry.auth' | translate}}</h1>
|
<h1>{{'person.orcid.registry.auth' | translate}}</h1>
|
||||||
@if ((isLinkedToOrcid() | async)) {
|
@if ((isOrcidLinked$ | async)) {
|
||||||
<div data-test="orcidLinked">
|
<div data-test="orcidLinked">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@if ((hasOrcidAuthorizations() | async)) {
|
@if ((hasOrcidAuthorizations$ | async)) {
|
||||||
<div class="col-sm-6 mb-3" data-test="hasOrcidAuthorizations">
|
<div class="col-sm-6 mb-3" data-test="hasOrcidAuthorizations">
|
||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-header">{{ 'person.page.orcid.granted-authorizations'| translate }}</div>
|
<div class="card-header">{{ 'person.page.orcid.granted-authorizations'| translate }}</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="container p-0">
|
<div class="container p-0">
|
||||||
<ul>
|
<ul>
|
||||||
@for (auth of (getOrcidAuthorizations() | async); track auth) {
|
@for (auth of (profileAuthorizationScopes$ | async); track auth) {
|
||||||
<li data-test="orcidAuthorization">
|
<li data-test="orcidAuthorization">
|
||||||
{{getAuthorizationDescription(auth) | translate}}
|
{{getAuthorizationDescription(auth) | translate}}
|
||||||
</li>
|
</li>
|
||||||
@@ -26,16 +26,16 @@
|
|||||||
<div class="card-header">{{ 'person.page.orcid.missing-authorizations'| translate }}</div>
|
<div class="card-header">{{ 'person.page.orcid.missing-authorizations'| translate }}</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@if ((hasMissingOrcidAuthorizations() | async) !== true) {
|
@if ((hasMissingOrcidAuthorizations$ | async) !== true) {
|
||||||
<ds-alert [type]="'alert-success'" data-test="noMissingOrcidAuthorizations">
|
<ds-alert [type]="AlertType.Success" data-test="noMissingOrcidAuthorizations">
|
||||||
{{'person.page.orcid.no-missing-authorizations-message' | translate}}
|
{{'person.page.orcid.no-missing-authorizations-message' | translate}}
|
||||||
</ds-alert>
|
</ds-alert>
|
||||||
}
|
}
|
||||||
@if ((hasMissingOrcidAuthorizations() | async)) {
|
@if ((hasMissingOrcidAuthorizations$ | async)) {
|
||||||
<ds-alert [type]="'alert-warning'" data-test="missingOrcidAuthorizations">
|
<ds-alert [type]="AlertType.Warning" data-test="missingOrcidAuthorizations">
|
||||||
{{'person.page.orcid.missing-authorizations-message' | translate}}
|
{{'person.page.orcid.missing-authorizations-message' | translate}}
|
||||||
<ul>
|
<ul>
|
||||||
@for (auth of (getMissingOrcidAuthorizations() | async); track auth) {
|
@for (auth of (profileAuthorizationScopes$ | async); track auth) {
|
||||||
<li data-test="missingOrcidAuthorization">
|
<li data-test="missingOrcidAuthorization">
|
||||||
{{getAuthorizationDescription(auth) | translate }}
|
{{getAuthorizationDescription(auth) | translate }}
|
||||||
</li>
|
</li>
|
||||||
@@ -48,13 +48,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if ((onlyAdminCanDisconnectProfileFromOrcid() | async) && (ownerCanDisconnectProfileFromOrcid() | async) !== true) {
|
@if ((onlyAdminCanDisconnectProfileFromOrcid$ | async) && (ownerCanDisconnectProfileFromOrcid$ | async) !== true) {
|
||||||
<ds-alert
|
<ds-alert
|
||||||
[type]="'alert-warning'" data-test="unlinkOnlyAdmin">
|
[type]="AlertType.Warning" data-test="unlinkOnlyAdmin">
|
||||||
{{ 'person.page.orcid.remove-orcid-message' | translate}}
|
{{ 'person.page.orcid.remove-orcid-message' | translate}}
|
||||||
</ds-alert>
|
</ds-alert>
|
||||||
}
|
}
|
||||||
@if ((ownerCanDisconnectProfileFromOrcid() | async)) {
|
@if ((ownerCanDisconnectProfileFromOrcid$ | async)) {
|
||||||
<div class="row" data-test="unlinkOwner">
|
<div class="row" data-test="unlinkOwner">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<button type="submit" class="btn btn-danger float-end" (click)="unlinkOrcid()"
|
<button type="submit" class="btn btn-danger float-end" (click)="unlinkOrcid()"
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
class='fas fa-circle-notch fa-spin'></i> {{'person.page.orcid.unlink.processing' | translate}}</span>
|
class='fas fa-circle-notch fa-spin'></i> {{'person.page.orcid.unlink.processing' | translate}}</span>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
@if ((hasMissingOrcidAuthorizations() | async)) {
|
@if ((hasMissingOrcidAuthorizations$ | async)) {
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="btn btn-primary float-end" (click)="linkOrcid()">
|
class="btn btn-primary float-end" (click)="linkOrcid()">
|
||||||
<span><i class="fas fa-check"></i> {{ 'person.page.orcid.grant-authorizations' | translate }}</span>
|
<span><i class="fas fa-check"></i> {{ 'person.page.orcid.grant-authorizations' | translate }}</span>
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-2"><img alt="orcid-logo" src="../../../../assets/images/orcid.logo.icon.svg"/></div>
|
<div class="col-2"><img alt="orcid-logo" src="../../../../assets/images/orcid.logo.icon.svg"/></div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<ds-alert [type]="'alert-info'">{{ getOrcidNotLinkedMessage() | async }}</ds-alert>
|
<ds-alert [type]="AlertType.Info">{{ getOrcidNotLinkedMessage() }}</ds-alert>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -97,103 +97,3 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-template #orcidLinked>
|
|
||||||
<div data-test="orcidLinked">
|
|
||||||
<div class="row">
|
|
||||||
@if ((hasOrcidAuthorizations() | async)) {
|
|
||||||
<div class="col-sm-6 mb-3" data-test="hasOrcidAuthorizations">
|
|
||||||
<div class="card h-100">
|
|
||||||
<div class="card-header">{{ 'person.page.orcid.granted-authorizations'| translate }}</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="container p-0">
|
|
||||||
<ul>
|
|
||||||
@for (auth of (getOrcidAuthorizations() | async); track auth) {
|
|
||||||
<li data-test="orcidAuthorization">
|
|
||||||
{{getAuthorizationDescription(auth) | translate}}
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<div class="col-sm-6 mb-3">
|
|
||||||
<div class="card h-100">
|
|
||||||
<div class="card-header">{{ 'person.page.orcid.missing-authorizations'| translate }}</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="container">
|
|
||||||
@if ((hasMissingOrcidAuthorizations() | async) !== true) {
|
|
||||||
<ds-alert [type]="'alert-success'" data-test="noMissingOrcidAuthorizations">
|
|
||||||
{{'person.page.orcid.no-missing-authorizations-message' | translate}}
|
|
||||||
</ds-alert>
|
|
||||||
}
|
|
||||||
@if ((hasMissingOrcidAuthorizations() | async)) {
|
|
||||||
<ds-alert [type]="'alert-warning'" data-test="missingOrcidAuthorizations">
|
|
||||||
{{'person.page.orcid.missing-authorizations-message' | translate}}
|
|
||||||
<ul>
|
|
||||||
@for (auth of (getMissingOrcidAuthorizations() | async); track auth) {
|
|
||||||
<li data-test="missingOrcidAuthorization">
|
|
||||||
{{getAuthorizationDescription(auth) | translate }}
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</ds-alert>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@if ((onlyAdminCanDisconnectProfileFromOrcid() | async) && (ownerCanDisconnectProfileFromOrcid() | async) !== true) {
|
|
||||||
<ds-alert
|
|
||||||
[type]="'alert-warning'" data-test="unlinkOnlyAdmin">
|
|
||||||
{{ 'person.page.orcid.remove-orcid-message' | translate}}
|
|
||||||
</ds-alert>
|
|
||||||
}
|
|
||||||
@if ((ownerCanDisconnectProfileFromOrcid() | async)) {
|
|
||||||
<div class="row" data-test="unlinkOwner">
|
|
||||||
<div class="col">
|
|
||||||
<button type="submit" class="btn btn-danger float-end" (click)="unlinkOrcid()"
|
|
||||||
[dsBtnDisabled]="(unlinkProcessing | async)">
|
|
||||||
@if ((unlinkProcessing | async) !== true) {
|
|
||||||
<span><i
|
|
||||||
class="fas fa-unlink"></i> {{ 'person.page.orcid.unlink' | translate }}</span>
|
|
||||||
}
|
|
||||||
@if ((unlinkProcessing | async)) {
|
|
||||||
<span><i
|
|
||||||
class='fas fa-circle-notch fa-spin'></i> {{'person.page.orcid.unlink.processing' | translate}}</span>
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
@if ((hasMissingOrcidAuthorizations() | async)) {
|
|
||||||
<button type="submit"
|
|
||||||
class="btn btn-primary float-end" (click)="linkOrcid()">
|
|
||||||
<span><i class="fas fa-check"></i> {{ 'person.page.orcid.grant-authorizations' | translate }}</span>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<ng-template #orcidNotLinked>
|
|
||||||
<div data-test="orcidNotLinked">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-2"><img alt="orcid-logo" src="../../../../assets/images/orcid.logo.icon.svg"/></div>
|
|
||||||
<div class="col">
|
|
||||||
<ds-alert [type]="'alert-info'">{{ getOrcidNotLinkedMessage() | async }}</ds-alert>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<button class="btn btn-primary float-end" (click)="linkOrcid()">
|
|
||||||
<i class="fas fa-link"></i>
|
|
||||||
{{'person.page.orcid.link' | translate}}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ import {
|
|||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||||
import { AlertComponent } from '../../../shared/alert/alert.component';
|
import { AlertComponent } from '../../../shared/alert/alert.component';
|
||||||
|
import { AlertType } from '../../../shared/alert/alert-type';
|
||||||
import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive';
|
import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive';
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
import { createFailedRemoteDataObjectFromError$ } from '../../../shared/remote-data.utils';
|
import { createFailedRemoteDataObjectFromError$ } from '../../../shared/remote-data.utils';
|
||||||
@@ -56,43 +57,49 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
|||||||
/**
|
/**
|
||||||
* The list of exposed orcid authorization scopes for the orcid profile
|
* The list of exposed orcid authorization scopes for the orcid profile
|
||||||
*/
|
*/
|
||||||
profileAuthorizationScopes: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
|
profileAuthorizationScopes$: BehaviorSubject<string[]> = new BehaviorSubject([]);
|
||||||
|
|
||||||
|
hasOrcidAuthorizations$: Observable<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of all orcid authorization scopes missing in the orcid profile
|
* The list of all orcid authorization scopes missing in the orcid profile
|
||||||
*/
|
*/
|
||||||
missingAuthorizationScopes: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
|
missingAuthorizationScopes: BehaviorSubject<string[]> = new BehaviorSubject([]);
|
||||||
|
|
||||||
|
hasMissingOrcidAuthorizations$: Observable<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of all orcid authorization scopes available
|
* The list of all orcid authorization scopes available
|
||||||
*/
|
*/
|
||||||
orcidAuthorizationScopes: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
|
orcidAuthorizationScopes: BehaviorSubject<string[]> = new BehaviorSubject([]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A boolean representing if unlink operation is processing
|
* A boolean representing if unlink operation is processing
|
||||||
*/
|
*/
|
||||||
unlinkProcessing: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
unlinkProcessing: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A boolean representing if orcid profile is linked
|
* A boolean representing if orcid profile is linked
|
||||||
*/
|
*/
|
||||||
private isOrcidLinked$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
isOrcidLinked$: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A boolean representing if only admin can disconnect orcid profile
|
* A boolean representing if only admin can disconnect orcid profile
|
||||||
*/
|
*/
|
||||||
private onlyAdminCanDisconnectProfileFromOrcid$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
onlyAdminCanDisconnectProfileFromOrcid$: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A boolean representing if owner can disconnect orcid profile
|
* A boolean representing if owner can disconnect orcid profile
|
||||||
*/
|
*/
|
||||||
private ownerCanDisconnectProfileFromOrcid$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
ownerCanDisconnectProfileFromOrcid$: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event emitted when orcid profile is unliked successfully
|
* An event emitted when orcid profile is unliked successfully
|
||||||
*/
|
*/
|
||||||
@Output() unlink: EventEmitter<void> = new EventEmitter<void>();
|
@Output() unlink: EventEmitter<void> = new EventEmitter<void>();
|
||||||
|
|
||||||
|
readonly AlertType = AlertType;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private orcidAuthService: OrcidAuthService,
|
private orcidAuthService: OrcidAuthService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
@@ -106,6 +113,8 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
|||||||
this.orcidAuthorizationScopes.next(scopes);
|
this.orcidAuthorizationScopes.next(scopes);
|
||||||
this.initOrcidAuthSettings();
|
this.initOrcidAuthSettings();
|
||||||
});
|
});
|
||||||
|
this.hasOrcidAuthorizations$ = this.hasOrcidAuthorizations();
|
||||||
|
this.hasMissingOrcidAuthorizations$ = this.hasMissingOrcidAuthorizations();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
@@ -118,18 +127,11 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
|||||||
* Check if the list of exposed orcid authorization scopes for the orcid profile has values
|
* Check if the list of exposed orcid authorization scopes for the orcid profile has values
|
||||||
*/
|
*/
|
||||||
hasOrcidAuthorizations(): Observable<boolean> {
|
hasOrcidAuthorizations(): Observable<boolean> {
|
||||||
return this.profileAuthorizationScopes.asObservable().pipe(
|
return this.profileAuthorizationScopes$.pipe(
|
||||||
map((scopes: string[]) => scopes.length > 0),
|
map((scopes: string[]) => scopes.length > 0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the list of exposed orcid authorization scopes for the orcid profile
|
|
||||||
*/
|
|
||||||
getOrcidAuthorizations(): Observable<string[]> {
|
|
||||||
return this.profileAuthorizationScopes.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the list of exposed orcid authorization scopes for the orcid profile has values
|
* Check if the list of exposed orcid authorization scopes for the orcid profile has values
|
||||||
*/
|
*/
|
||||||
@@ -139,26 +141,12 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
getOrcidNotLinkedMessage(): string {
|
||||||
* Return the list of exposed orcid authorization scopes for the orcid profile
|
|
||||||
*/
|
|
||||||
getMissingOrcidAuthorizations(): Observable<string[]> {
|
|
||||||
return this.profileAuthorizationScopes.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a boolean representing if orcid profile is linked
|
|
||||||
*/
|
|
||||||
isLinkedToOrcid(): Observable<boolean> {
|
|
||||||
return this.isOrcidLinked$.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
getOrcidNotLinkedMessage(): Observable<string> {
|
|
||||||
const orcid = this.item.firstMetadataValue('person.identifier.orcid');
|
const orcid = this.item.firstMetadataValue('person.identifier.orcid');
|
||||||
if (orcid) {
|
if (orcid) {
|
||||||
return this.translateService.get('person.page.orcid.orcid-not-linked-message', { 'orcid': orcid });
|
return this.translateService.instant('person.page.orcid.orcid-not-linked-message', { 'orcid': orcid });
|
||||||
} else {
|
} else {
|
||||||
return this.translateService.get('person.page.orcid.no-orcid-message');
|
return this.translateService.instant('person.page.orcid.no-orcid-message');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,13 +159,6 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
|||||||
return 'person.page.orcid.scope.' + scope.substring(1).replace('/', '-');
|
return 'person.page.orcid.scope.' + scope.substring(1).replace('/', '-');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a boolean representing if only admin can disconnect orcid profile
|
|
||||||
*/
|
|
||||||
onlyAdminCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
|
||||||
return this.onlyAdminCanDisconnectProfileFromOrcid$.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a boolean representing if owner can disconnect orcid profile
|
* Return a boolean representing if owner can disconnect orcid profile
|
||||||
*/
|
*/
|
||||||
@@ -243,7 +224,7 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setOrcidAuthorizationsFromItem(): void {
|
private setOrcidAuthorizationsFromItem(): void {
|
||||||
this.profileAuthorizationScopes.next(this.orcidAuthService.getOrcidAuthorizationScopesByItem(this.item));
|
this.profileAuthorizationScopes$.next(this.orcidAuthService.getOrcidAuthorizationScopesByItem(this.item));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -5,16 +5,16 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>{{ 'person.orcid.registry.queue' | translate }}</h2>
|
<h2>{{ 'person.orcid.registry.queue' | translate }}</h2>
|
||||||
|
|
||||||
@if ((processing$ | async) !== true && (getList() | async)?.payload?.totalElements === 0) {
|
@if ((processing$ | async) !== true && (list$ | async)?.payload?.totalElements === 0) {
|
||||||
<ds-alert
|
<ds-alert
|
||||||
[type]="AlertTypeEnum.Info">
|
[type]="AlertTypeEnum.Info">
|
||||||
{{ 'person.page.orcid.sync-queue.empty-message' | translate}}
|
{{ 'person.page.orcid.sync-queue.empty-message' | translate}}
|
||||||
</ds-alert>
|
</ds-alert>
|
||||||
}
|
}
|
||||||
@if ((processing$ | async) !== true && (getList() | async)?.payload?.totalElements > 0) {
|
@if ((processing$ | async) !== true && (list$ | async)?.payload?.totalElements > 0) {
|
||||||
<ds-pagination
|
<ds-pagination
|
||||||
[paginationOptions]="paginationOptions"
|
[paginationOptions]="paginationOptions"
|
||||||
[collectionSize]="(getList() | async)?.payload?.totalElements"
|
[collectionSize]="(list$ | async)?.payload?.totalElements"
|
||||||
[retainScrollPosition]="false" [hideGear]="true" (paginationChange)="updateList()">
|
[retainScrollPosition]="false" [hideGear]="true" (paginationChange)="updateList()">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table id="groups" class="table table-sm table-striped table-hover table-bordered">
|
<table id="groups" class="table table-sm table-striped table-hover table-bordered">
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@for (entry of (getList() | async)?.payload?.page; track entry) {
|
@for (entry of (list$ | async)?.payload?.page; track entry) {
|
||||||
<tr data-test="orcidQueueElementRow">
|
<tr data-test="orcidQueueElementRow">
|
||||||
<td style="width: 15%" class="text-center align-middle">
|
<td style="width: 15%" class="text-center align-middle">
|
||||||
<i [ngClass]="getIconClass(entry)" [ngbTooltip]="getIconTooltip(entry) | translate"
|
<i [ngClass]="getIconClass(entry)" [ngbTooltip]="getIconTooltip(entry) | translate"
|
||||||
|
@@ -80,13 +80,12 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
|
|||||||
/**
|
/**
|
||||||
* A list of orcid queue records
|
* A list of orcid queue records
|
||||||
*/
|
*/
|
||||||
private list$: BehaviorSubject<RemoteData<PaginatedList<OrcidQueue>>> = new BehaviorSubject<RemoteData<PaginatedList<OrcidQueue>>>({} as any);
|
list$: BehaviorSubject<RemoteData<PaginatedList<OrcidQueue>>> = new BehaviorSubject<RemoteData<PaginatedList<OrcidQueue>>>({} as any);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The AlertType enumeration
|
* The AlertType enumeration
|
||||||
* @type {AlertType}
|
|
||||||
*/
|
*/
|
||||||
AlertTypeEnum = AlertType;
|
readonly AlertTypeEnum = AlertType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||||
@@ -132,13 +131,6 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the list of orcid queue records
|
|
||||||
*/
|
|
||||||
getList(): Observable<RemoteData<PaginatedList<OrcidQueue>>> {
|
|
||||||
return this.list$.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the icon class for the queue object type
|
* Return the icon class for the queue object type
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<nav [ngClass]="{'open': (menuCollapsed | async) !== true}"
|
<nav [ngClass]="{'open': (menuCollapsed | async) !== true}"
|
||||||
[@slideMobileNav]="(windowService.isXsOrSm() | async) !== true ? 'default' : ((menuCollapsed | async) ? 'collapsed' : 'expanded')"
|
[@slideMobileNav]="(isMobile$ | async) !== true ? 'default' : ((menuCollapsed | async) ? 'collapsed' : 'expanded')"
|
||||||
class="navbar navbar-light navbar-expand-md px-md-0 navbar-container" role="navigation"
|
class="navbar navbar-light navbar-expand-md px-md-0 navbar-container" role="navigation"
|
||||||
[attr.aria-label]="'nav.main.description' | translate" id="main-navbar">
|
[attr.aria-label]="'nav.main.description' | translate" id="main-navbar">
|
||||||
<!-- TODO remove navbar-container class when https://github.com/twbs/bootstrap/issues/24726 is fixed -->
|
<!-- TODO remove navbar-container class when https://github.com/twbs/bootstrap/issues/24726 is fixed -->
|
||||||
|
@@ -62,20 +62,20 @@ class="fas fa-plus pe-2"></i>{{'process.overview.new' | translate}}</button>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
@if ((processBulkDeleteService.isProcessing$() | async) !== true) {
|
@let isProcessing = (isProcessing$ | async);
|
||||||
<div>{{'process.overview.delete.body' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}</div>
|
@if (isProcessing) {
|
||||||
}
|
|
||||||
@if (processBulkDeleteService.isProcessing$() |async) {
|
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
<span class="spinner-border spinner-border-sm spinner-button" role="status" aria-hidden="true"></span>
|
<span class="spinner-border spinner-border-sm spinner-button" role="status" aria-hidden="true"></span>
|
||||||
<span> {{ 'process.overview.delete.processing' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}</span>
|
<span> {{ 'process.overview.delete.processing' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
} @else {
|
||||||
|
<div>{{'process.overview.delete.body' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}</div>
|
||||||
}
|
}
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<button class="btn btn-primary me-2" [dsBtnDisabled]="processBulkDeleteService.isProcessing$() |async"
|
<button class="btn btn-primary me-2" [dsBtnDisabled]="isProcessing"
|
||||||
(click)="closeModal()">{{'process.detail.delete.cancel' | translate}}</button>
|
(click)="closeModal()">{{'process.detail.delete.cancel' | translate}}</button>
|
||||||
<button id="delete-confirm" class="btn btn-danger"
|
<button id="delete-confirm" class="btn btn-danger"
|
||||||
[dsBtnDisabled]="processBulkDeleteService.isProcessing$() |async"
|
[dsBtnDisabled]="isProcessing"
|
||||||
(click)="deleteSelected()">{{ 'process.overview.delete' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}
|
(click)="deleteSelected()">{{ 'process.overview.delete' | translate: {count: processBulkDeleteService.getAmountOfSelectedProcesses()} }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -12,7 +12,10 @@ import {
|
|||||||
import { RouterLink } from '@angular/router';
|
import { RouterLink } from '@angular/router';
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { Subscription } from 'rxjs';
|
import {
|
||||||
|
Observable,
|
||||||
|
Subscription,
|
||||||
|
} from 'rxjs';
|
||||||
|
|
||||||
import { BtnDisabledDirective } from '../../shared/btn-disabled.directive';
|
import { BtnDisabledDirective } from '../../shared/btn-disabled.directive';
|
||||||
import { hasValue } from '../../shared/empty.util';
|
import { hasValue } from '../../shared/empty.util';
|
||||||
@@ -45,6 +48,8 @@ export class ProcessOverviewComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
isProcessingSub: Subscription;
|
isProcessingSub: Subscription;
|
||||||
|
|
||||||
|
isProcessing$: Observable<boolean>;
|
||||||
|
|
||||||
constructor(protected processOverviewService: ProcessOverviewService,
|
constructor(protected processOverviewService: ProcessOverviewService,
|
||||||
protected modalService: NgbModal,
|
protected modalService: NgbModal,
|
||||||
public processBulkDeleteService: ProcessBulkDeleteService,
|
public processBulkDeleteService: ProcessBulkDeleteService,
|
||||||
@@ -53,6 +58,7 @@ export class ProcessOverviewComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.processBulkDeleteService.clearAllProcesses();
|
this.processBulkDeleteService.clearAllProcesses();
|
||||||
|
this.isProcessing$ = this.processBulkDeleteService.isProcessing$();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
|
@@ -17,15 +17,15 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@if (!researcherProfile) {
|
@if (!researcherProfile) {
|
||||||
|
@let processingCreate = (processingCreate$ | async);
|
||||||
<button class="btn btn-primary me-2"
|
<button class="btn btn-primary me-2"
|
||||||
[dsBtnDisabled]="(isProcessingCreate() | async)"
|
[dsBtnDisabled]="processingCreate"
|
||||||
(click)="createProfile()">
|
(click)="createProfile()">
|
||||||
@if ((isProcessingCreate() | async)) {
|
@if (processingCreate) {
|
||||||
<span>
|
<span>
|
||||||
<i class='fas fa-circle-notch fa-spin'></i> {{'researcher.profile.action.processing' | translate}}
|
<i class='fas fa-circle-notch fa-spin'></i> {{'researcher.profile.action.processing' | translate}}
|
||||||
</span>
|
</span>
|
||||||
}
|
} @else {
|
||||||
@if ((isProcessingCreate() | async) !== true) {
|
|
||||||
<span>
|
<span>
|
||||||
<i class="fas fa-plus"></i> {{'researcher.profile.create.new' | translate}}
|
<i class="fas fa-plus"></i> {{'researcher.profile.create.new' | translate}}
|
||||||
</span>
|
</span>
|
||||||
@@ -37,12 +37,11 @@
|
|||||||
<i class="fas fa-info-circle"></i> {{'researcher.profile.view' | translate}}
|
<i class="fas fa-info-circle"></i> {{'researcher.profile.view' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-danger" [dsBtnDisabled]="!researcherProfile" (click)="deleteProfile(researcherProfile)">
|
<button class="btn btn-danger" [dsBtnDisabled]="!researcherProfile" (click)="deleteProfile(researcherProfile)">
|
||||||
@if ((isProcessingDelete() | async)) {
|
@if ((processingDelete$ | async)) {
|
||||||
<span>
|
<span>
|
||||||
<i class='fas fa-circle-notch fa-spin'></i> {{'researcher.profile.action.processing' | translate}}
|
<i class='fas fa-circle-notch fa-spin'></i> {{'researcher.profile.action.processing' | translate}}
|
||||||
</span>
|
</span>
|
||||||
}
|
} @else {
|
||||||
@if ((isProcessingDelete() | async) !== true) {
|
|
||||||
<span>
|
<span>
|
||||||
<i class="fas fa-trash-alt"></i> {{'researcher.profile.delete' | translate}}
|
<i class="fas fa-trash-alt"></i> {{'researcher.profile.delete' | translate}}
|
||||||
</span>
|
</span>
|
||||||
|
@@ -11,10 +11,7 @@ import {
|
|||||||
TranslateService,
|
TranslateService,
|
||||||
} from '@ngx-translate/core';
|
} from '@ngx-translate/core';
|
||||||
import { UiSwitchModule } from 'ngx-ui-switch';
|
import { UiSwitchModule } from 'ngx-ui-switch';
|
||||||
import {
|
import { BehaviorSubject } from 'rxjs';
|
||||||
BehaviorSubject,
|
|
||||||
Observable,
|
|
||||||
} from 'rxjs';
|
|
||||||
import {
|
import {
|
||||||
map,
|
map,
|
||||||
mergeMap,
|
mergeMap,
|
||||||
@@ -187,24 +184,6 @@ export class ProfilePageResearcherFormComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a boolean representing if a delete operation is pending.
|
|
||||||
*
|
|
||||||
* @return {Observable<boolean>}
|
|
||||||
*/
|
|
||||||
isProcessingDelete(): Observable<boolean> {
|
|
||||||
return this.processingDelete$.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a boolean representing if a create operation is pending.
|
|
||||||
*
|
|
||||||
* @return {Observable<boolean>}
|
|
||||||
*/
|
|
||||||
isProcessingCreate(): Observable<boolean> {
|
|
||||||
return this.processingCreate$.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new profile related to the current user from scratch.
|
* Create a new profile related to the current user from scratch.
|
||||||
*/
|
*/
|
||||||
|
@@ -54,15 +54,15 @@
|
|||||||
</ds-alert>
|
</ds-alert>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (isRecaptchaCookieAccepted() && (googleRecaptchaService.captchaVersion() | async) === 'v2') {
|
@if (isRecaptchaCookieAccepted() && (captchaVersion$ | async) === 'v2') {
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<ds-google-recaptcha [captchaMode]="(googleRecaptchaService.captchaMode() | async)"
|
<ds-google-recaptcha [captchaMode]="(captchaMode$ | async)"
|
||||||
(executeRecaptcha)="register($event)" (checkboxChecked)="onCheckboxChecked($event)"
|
(executeRecaptcha)="register($event)" (checkboxChecked)="onCheckboxChecked($event)"
|
||||||
(showNotification)="showNotification($event)"></ds-google-recaptcha>
|
(showNotification)="showNotification($event)"></ds-google-recaptcha>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if ((!registrationVerification || ((googleRecaptchaService.captchaVersion() | async) !== 'v2' && (googleRecaptchaService.captchaMode() | async) === 'invisible'))) {
|
@if ((!registrationVerification || ((captchaVersion$ | async) !== 'v2' && (captchaMode$ | async) === 'invisible'))) {
|
||||||
<button class="btn btn-primary" [dsBtnDisabled]="form.invalid || registrationVerification && !isRecaptchaCookieAccepted() || disableUntilChecked" (click)="register()">
|
<button class="btn btn-primary" [dsBtnDisabled]="form.invalid || registrationVerification && !isRecaptchaCookieAccepted() || disableUntilChecked" (click)="register()">
|
||||||
{{ MESSAGE_PREFIX + '.submit' | translate }}
|
{{ MESSAGE_PREFIX + '.submit' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
@@ -107,13 +107,9 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
subscriptions: Subscription[] = [];
|
subscriptions: Subscription[] = [];
|
||||||
|
|
||||||
captchaVersion(): Observable<string> {
|
captchaVersion$: Observable<string>;
|
||||||
return this.googleRecaptchaService.captchaVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
captchaMode(): Observable<string> {
|
captchaMode$: Observable<string>;
|
||||||
return this.googleRecaptchaService.captchaMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private epersonRegistrationService: EpersonRegistrationService,
|
private epersonRegistrationService: EpersonRegistrationService,
|
||||||
@@ -135,6 +131,8 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.captchaVersion$ = this.googleRecaptchaService.captchaVersion();
|
||||||
|
this.captchaMode$ = this.googleRecaptchaService.captchaMode();
|
||||||
const validators: ValidatorFn[] = [
|
const validators: ValidatorFn[] = [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.email,
|
Validators.email,
|
||||||
@@ -191,7 +189,7 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit {
|
|||||||
register(tokenV2?) {
|
register(tokenV2?) {
|
||||||
if (!this.form.invalid) {
|
if (!this.form.invalid) {
|
||||||
if (this.registrationVerification) {
|
if (this.registrationVerification) {
|
||||||
this.subscriptions.push(combineLatest([this.captchaVersion(), this.captchaMode()]).pipe(
|
this.subscriptions.push(combineLatest([this.captchaVersion$, this.captchaMode$]).pipe(
|
||||||
switchMap(([captchaVersion, captchaMode]) => {
|
switchMap(([captchaVersion, captchaMode]) => {
|
||||||
if (captchaVersion === 'v3') {
|
if (captchaVersion === 'v3') {
|
||||||
return this.googleRecaptchaService.getRecaptchaToken('register_email');
|
return this.googleRecaptchaService.getRecaptchaToken('register_email');
|
||||||
@@ -254,7 +252,7 @@ export class RegisterEmailFormComponent implements OnDestroy, OnInit {
|
|||||||
*/
|
*/
|
||||||
disableUntilCheckedFcn(): Observable<boolean> {
|
disableUntilCheckedFcn(): Observable<boolean> {
|
||||||
const checked$ = this.checkboxCheckedSubject$.asObservable();
|
const checked$ = this.checkboxCheckedSubject$.asObservable();
|
||||||
return combineLatest([this.captchaVersion(), this.captchaMode(), checked$]).pipe(
|
return combineLatest([this.captchaVersion$, this.captchaMode$, checked$]).pipe(
|
||||||
// disable if checkbox is not checked or if reCaptcha is not in v2 checkbox mode
|
// disable if checkbox is not checked or if reCaptcha is not in v2 checkbox mode
|
||||||
switchMap(([captchaVersion, captchaMode, checked]) => captchaVersion === 'v2' && captchaMode === 'checkbox' ? of(!checked) : of(false)),
|
switchMap(([captchaVersion, captchaMode, checked]) => captchaVersion === 'v2' && captchaMode === 'checkbox' ? of(!checked) : of(false)),
|
||||||
startWith(true),
|
startWith(true),
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
<div class="mt-3" @fadeInOut>
|
<div class="mt-3" @fadeInOut>
|
||||||
@if (isListOfEPerson) {
|
@if (isListOfEPerson) {
|
||||||
<ds-eperson-search-box (search)="onSearch($event)"></ds-eperson-search-box>
|
<ds-eperson-search-box (search)="onSearch($event)"></ds-eperson-search-box>
|
||||||
}
|
} @else {
|
||||||
@if (!isListOfEPerson) {
|
|
||||||
<ds-group-search-box (search)="onSearch($event)"></ds-group-search-box>
|
<ds-group-search-box (search)="onSearch($event)"></ds-group-search-box>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if ((getList() | async)?.payload?.totalElements > 0) {
|
@let list = (list$ | async);
|
||||||
|
@if (list && list.totalElements > 0) {
|
||||||
<ds-pagination
|
<ds-pagination
|
||||||
[paginationOptions]="paginationOptions"
|
[paginationOptions]="paginationOptions"
|
||||||
[collectionSize]="(getList() | async)?.payload?.totalElements"
|
[collectionSize]="list.totalElements"
|
||||||
[retainScrollPosition]="true"
|
[retainScrollPosition]="true"
|
||||||
[hideGear]="true">
|
[hideGear]="true">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
@@ -22,9 +22,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@for (entry of (getList() | async)?.payload?.page; track entry) {
|
@for (entry of list.page; track entry) {
|
||||||
<tr
|
<tr [class.table-primary]="(entrySelectedId$ | async) === entry.id">
|
||||||
[class.table-primary]="isSelected(entry) | async">
|
|
||||||
<td>{{ entry.id }}</td>
|
<td>{{ entry.id }}</td>
|
||||||
<td>{{ dsoNameService.getName(entry) }}</td>
|
<td>{{ dsoNameService.getName(entry) }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
|
@@ -13,7 +13,7 @@ import {
|
|||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { cold } from 'jasmine-marbles';
|
import { hot } from 'jasmine-marbles';
|
||||||
import uniqueId from 'lodash/uniqueId';
|
import uniqueId from 'lodash/uniqueId';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
@@ -49,14 +49,13 @@ const mockDataServiceMap: LazyDataServicesMap = new Map([
|
|||||||
[GROUP.value, () => import('../../core/eperson/group-data.service').then(m => m.GroupDataService)],
|
[GROUP.value, () => import('../../core/eperson/group-data.service').then(m => m.GroupDataService)],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
describe('EpersonGroupListComponent test suite', () => {
|
describe('EpersonGroupListComponent', () => {
|
||||||
let comp: EpersonGroupListComponent;
|
let comp: EpersonGroupListComponent;
|
||||||
let compAsAny: any;
|
let compAsAny: any;
|
||||||
let fixture: ComponentFixture<EpersonGroupListComponent>;
|
let fixture: ComponentFixture<EpersonGroupListComponent>;
|
||||||
let de;
|
|
||||||
let groupService: any;
|
let groupService: any;
|
||||||
let epersonService: any;
|
let epersonService: any;
|
||||||
let paginationService;
|
let paginationService: PaginationServiceStub;
|
||||||
|
|
||||||
const paginationOptions: PaginationComponentOptions = new PaginationComponentOptions();
|
const paginationOptions: PaginationComponentOptions = new PaginationComponentOptions();
|
||||||
paginationOptions.id = uniqueId('eperson-group-list-pagination-test');
|
paginationOptions.id = uniqueId('eperson-group-list-pagination-test');
|
||||||
@@ -129,7 +128,6 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
describe('', () => {
|
describe('', () => {
|
||||||
let testComp: TestComponent;
|
|
||||||
let testFixture: ComponentFixture<TestComponent>;
|
let testFixture: ComponentFixture<TestComponent>;
|
||||||
|
|
||||||
// synchronous beforeEach
|
// synchronous beforeEach
|
||||||
@@ -139,7 +137,6 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
<ds-eperson-group-list [isListOfEPerson]="isListOfEPerson" [initSelected]="initSelected"></ds-eperson-group-list>`;
|
<ds-eperson-group-list [isListOfEPerson]="isListOfEPerson" [initSelected]="initSelected"></ds-eperson-group-list>`;
|
||||||
|
|
||||||
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
|
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
|
||||||
testComp = testFixture.componentInstance;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -167,7 +164,6 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
comp = null;
|
comp = null;
|
||||||
compAsAny = null;
|
compAsAny = null;
|
||||||
de = null;
|
|
||||||
fixture.destroy();
|
fixture.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -181,29 +177,25 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should init entrySelectedId', fakeAsync(() => {
|
it('should init entrySelectedId', fakeAsync(async () => {
|
||||||
spyOn(comp, 'updateList');
|
spyOn(comp, 'updateList');
|
||||||
comp.initSelected = EPersonMock.id;
|
comp.initSelected = EPersonMock.id;
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
await fixture.whenStable();
|
||||||
expect(compAsAny.entrySelectedId.value).toBe(EPersonMock.id);
|
expect(comp.entrySelectedId$.value).toBe(EPersonMock.id);
|
||||||
});
|
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should init the list of eperson', fakeAsync(() => {
|
it('should init the list of eperson', fakeAsync(async () => {
|
||||||
epersonService.searchByScope.and.returnValue(observableOf(epersonPaginatedListRD));
|
epersonService.searchByScope.and.returnValue(observableOf(epersonPaginatedListRD));
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
await fixture.whenStable();
|
||||||
expect(compAsAny.list$.value).toEqual(epersonPaginatedListRD);
|
expect(comp.list$).toBeObservable(hot('(a|)', {
|
||||||
expect(comp.getList()).toBeObservable(cold('a', {
|
a: epersonPaginatedList,
|
||||||
a: epersonPaginatedListRD,
|
|
||||||
}));
|
}));
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should emit select event', () => {
|
it('should emit select event', () => {
|
||||||
@@ -211,23 +203,13 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
comp.emitSelect(EPersonMock);
|
comp.emitSelect(EPersonMock);
|
||||||
|
|
||||||
expect(comp.select.emit).toHaveBeenCalled();
|
expect(comp.select.emit).toHaveBeenCalled();
|
||||||
expect(compAsAny.entrySelectedId.value).toBe(EPersonMock.id);
|
expect(comp.entrySelectedId$.value).toBe(EPersonMock.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true when entry is selected', () => {
|
it('should return the entrySelectedId$ value', () => {
|
||||||
compAsAny.entrySelectedId.next(EPersonMock.id);
|
comp.entrySelectedId$.next(EPersonMock.id);
|
||||||
|
|
||||||
expect(comp.isSelected(EPersonMock)).toBeObservable(cold('a', {
|
expect(comp.entrySelectedId$.value).toBe(EPersonMock.id);
|
||||||
a: true,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when entry is not selected', () => {
|
|
||||||
compAsAny.entrySelectedId.next('');
|
|
||||||
|
|
||||||
expect(comp.isSelected(EPersonMock)).toBeObservable(cold('a', {
|
|
||||||
a: false,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -245,7 +227,6 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
comp = null;
|
comp = null;
|
||||||
compAsAny = null;
|
compAsAny = null;
|
||||||
de = null;
|
|
||||||
fixture.destroy();
|
fixture.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -260,27 +241,24 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should init entrySelectedId', fakeAsync(() => {
|
it('should init entrySelectedId', fakeAsync(async () => {
|
||||||
spyOn(comp, 'updateList');
|
spyOn(comp, 'updateList');
|
||||||
comp.initSelected = GroupMock.id;
|
comp.initSelected = GroupMock.id;
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
await fixture.whenStable();
|
||||||
expect(compAsAny.entrySelectedId.value).toBe(GroupMock.id);
|
expect(comp.entrySelectedId$.value).toBe(GroupMock.id);
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should init the list of group', fakeAsync(() => {
|
it('should init the list of group', fakeAsync(async () => {
|
||||||
groupService.searchGroups.and.returnValue(observableOf(groupPaginatedListRD));
|
groupService.searchGroups.and.returnValue(observableOf(groupPaginatedListRD));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
await fixture.whenStable();
|
||||||
expect(compAsAny.list$.value).toEqual(groupPaginatedListRD);
|
expect(comp.list$).toBeObservable(hot('(a|)', {
|
||||||
expect(comp.getList()).toBeObservable(cold('a', {
|
a: groupPaginatedList,
|
||||||
a: groupPaginatedListRD,
|
|
||||||
}));
|
}));
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should emit select event', () => {
|
it('should emit select event', () => {
|
||||||
@@ -288,27 +266,16 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
comp.emitSelect(GroupMock);
|
comp.emitSelect(GroupMock);
|
||||||
|
|
||||||
expect(comp.select.emit).toHaveBeenCalled();
|
expect(comp.select.emit).toHaveBeenCalled();
|
||||||
expect(compAsAny.entrySelectedId.value).toBe(GroupMock.id);
|
expect(comp.entrySelectedId$.value).toBe(GroupMock.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true when entry is selected', () => {
|
it('should return the entrySelectedId$ value', () => {
|
||||||
compAsAny.entrySelectedId.next(EPersonMock.id);
|
comp.entrySelectedId$.next(GroupMock.id);
|
||||||
|
|
||||||
expect(comp.isSelected(EPersonMock)).toBeObservable(cold('a', {
|
expect(comp.entrySelectedId$.value).toBe(GroupMock.id);
|
||||||
a: true,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when entry is not selected', () => {
|
|
||||||
compAsAny.entrySelectedId.next('');
|
|
||||||
|
|
||||||
expect(comp.isSelected(EPersonMock)).toBeObservable(cold('a', {
|
|
||||||
a: false,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update list on search triggered', () => {
|
it('should update list on search triggered', () => {
|
||||||
const options: PaginationComponentOptions = comp.paginationOptions;
|
|
||||||
const event: SearchEvent = {
|
const event: SearchEvent = {
|
||||||
scope: 'metadata',
|
scope: 'metadata',
|
||||||
query: 'test',
|
query: 'test',
|
||||||
@@ -316,7 +283,7 @@ describe('EpersonGroupListComponent test suite', () => {
|
|||||||
spyOn(comp, 'updateList');
|
spyOn(comp, 'updateList');
|
||||||
comp.onSearch(event);
|
comp.onSearch(event);
|
||||||
|
|
||||||
expect(compAsAny.updateList).toHaveBeenCalledWith('metadata', 'test');
|
expect(comp.updateList).toHaveBeenCalledWith('metadata', 'test');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -14,9 +14,8 @@ import uniqueId from 'lodash/uniqueId';
|
|||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
Observable,
|
Observable,
|
||||||
Subscription,
|
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { switchMap } from 'rxjs/operators';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
APP_DATA_SERVICES_MAP,
|
APP_DATA_SERVICES_MAP,
|
||||||
@@ -25,21 +24,21 @@ import {
|
|||||||
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
|
||||||
import { FindListOptions } from '../../core/data/find-list-options.model';
|
import { FindListOptions } from '../../core/data/find-list-options.model';
|
||||||
import { PaginatedList } from '../../core/data/paginated-list.model';
|
import { PaginatedList } from '../../core/data/paginated-list.model';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
|
||||||
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
|
||||||
import { GroupDataService } from '../../core/eperson/group-data.service';
|
import { GroupDataService } from '../../core/eperson/group-data.service';
|
||||||
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||||
import { EPERSON } from '../../core/eperson/models/eperson.resource-type';
|
import { EPERSON } from '../../core/eperson/models/eperson.resource-type';
|
||||||
|
import { Group } from '../../core/eperson/models/group.model';
|
||||||
import { GROUP } from '../../core/eperson/models/group.resource-type';
|
import { GROUP } from '../../core/eperson/models/group.resource-type';
|
||||||
import { lazyDataService } from '../../core/lazy-data-service';
|
import { lazyDataService } from '../../core/lazy-data-service';
|
||||||
import { PaginationService } from '../../core/pagination/pagination.service';
|
import { PaginationService } from '../../core/pagination/pagination.service';
|
||||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
import {
|
||||||
|
getFirstCompletedRemoteData,
|
||||||
|
getRemoteDataPayload,
|
||||||
|
} from '../../core/shared/operators';
|
||||||
import { ResourceType } from '../../core/shared/resource-type';
|
import { ResourceType } from '../../core/shared/resource-type';
|
||||||
import { fadeInOut } from '../animations/fade';
|
import { fadeInOut } from '../animations/fade';
|
||||||
import {
|
|
||||||
hasValue,
|
|
||||||
isNotEmpty,
|
|
||||||
} from '../empty.util';
|
|
||||||
import { PaginationComponent } from '../pagination/pagination.component';
|
import { PaginationComponent } from '../pagination/pagination.component';
|
||||||
import { PaginationComponentOptions } from '../pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../pagination/pagination-component-options.model';
|
||||||
import { SearchEvent } from './eperson-group-list-event-type';
|
import { SearchEvent } from './eperson-group-list-event-type';
|
||||||
@@ -101,21 +100,13 @@ export class EpersonGroupListComponent implements OnInit, OnDestroy {
|
|||||||
/**
|
/**
|
||||||
* A list of eperson or group
|
* A list of eperson or group
|
||||||
*/
|
*/
|
||||||
private list$: BehaviorSubject<RemoteData<PaginatedList<DSpaceObject>>> = new BehaviorSubject<RemoteData<PaginatedList<DSpaceObject>>>({} as any);
|
list$: Observable<PaginatedList<EPerson | Group>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The eperson or group's id selected
|
* The eperson or group's id selected
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
private entrySelectedId: BehaviorSubject<string> = new BehaviorSubject<string>('');
|
entrySelectedId$: BehaviorSubject<string> = new BehaviorSubject('');
|
||||||
|
|
||||||
/**
|
|
||||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
|
||||||
* @type {Array}
|
|
||||||
*/
|
|
||||||
private subs: Subscription[] = [];
|
|
||||||
|
|
||||||
private pageConfigSub: Subscription;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize instance variables and inject the properly UpdateDataServiceImpl
|
* Initialize instance variables and inject the properly UpdateDataServiceImpl
|
||||||
@@ -143,7 +134,7 @@ export class EpersonGroupListComponent implements OnInit, OnDestroy {
|
|||||||
this.paginationOptions.pageSize = 5;
|
this.paginationOptions.pageSize = 5;
|
||||||
|
|
||||||
if (this.initSelected) {
|
if (this.initSelected) {
|
||||||
this.entrySelectedId.next(this.initSelected);
|
this.entrySelectedId$.next(this.initSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateList(this.currentSearchScope, this.currentSearchQuery);
|
this.updateList(this.currentSearchScope, this.currentSearchQuery);
|
||||||
@@ -158,28 +149,9 @@ export class EpersonGroupListComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
emitSelect(entry: DSpaceObject): void {
|
emitSelect(entry: DSpaceObject): void {
|
||||||
this.select.emit(entry);
|
this.select.emit(entry);
|
||||||
this.entrySelectedId.next(entry.id);
|
this.entrySelectedId$.next(entry.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the list of eperson or group
|
|
||||||
*/
|
|
||||||
getList(): Observable<RemoteData<PaginatedList<DSpaceObject>>> {
|
|
||||||
return this.list$.asObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a boolean representing if a table row is selected
|
|
||||||
*
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
isSelected(entry: DSpaceObject): Observable<boolean> {
|
|
||||||
return this.entrySelectedId.asObservable().pipe(
|
|
||||||
map((selectedId) => isNotEmpty(selectedId) && selectedId === entry.id),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called on search
|
* Method called on search
|
||||||
*/
|
*/
|
||||||
@@ -194,38 +166,26 @@ export class EpersonGroupListComponent implements OnInit, OnDestroy {
|
|||||||
* Retrieve a paginate list of eperson or group
|
* Retrieve a paginate list of eperson or group
|
||||||
*/
|
*/
|
||||||
updateList(scope: string, query: string): void {
|
updateList(scope: string, query: string): void {
|
||||||
if (hasValue(this.pageConfigSub)) {
|
this.list$ = this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions).pipe(
|
||||||
this.pageConfigSub.unsubscribe();
|
switchMap((paginationOptions) => {
|
||||||
}
|
const options: FindListOptions = Object.assign(new FindListOptions(), {
|
||||||
this.pageConfigSub = this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions)
|
|
||||||
.subscribe((paginationOptions) => {
|
|
||||||
const options: FindListOptions = Object.assign({}, new FindListOptions(), {
|
|
||||||
elementsPerPage: paginationOptions.pageSize,
|
elementsPerPage: paginationOptions.pageSize,
|
||||||
currentPage: paginationOptions.currentPage,
|
currentPage: paginationOptions.currentPage,
|
||||||
});
|
});
|
||||||
|
|
||||||
const search$: Observable<RemoteData<PaginatedList<DSpaceObject>>> = this.isListOfEPerson ?
|
return this.isListOfEPerson ?
|
||||||
(this.dataService as EPersonDataService).searchByScope(scope, query, options) :
|
(this.dataService as EPersonDataService).searchByScope(scope, query, options) :
|
||||||
(this.dataService as GroupDataService).searchGroups(query, options);
|
(this.dataService as GroupDataService).searchGroups(query, options);
|
||||||
|
|
||||||
this.subs.push(search$.pipe(getFirstCompletedRemoteData())
|
|
||||||
.subscribe((list: RemoteData<PaginatedList<DSpaceObject>>) => {
|
|
||||||
if (hasValue(this.list$)) {
|
|
||||||
this.list$.next(list);
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
|
getFirstCompletedRemoteData(),
|
||||||
|
getRemoteDataPayload(),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsubscribe from all subscriptions
|
* Unsubscribe from all subscriptions
|
||||||
*/
|
*/
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.list$ = null;
|
|
||||||
this.subs
|
|
||||||
.filter((subscription) => hasValue(subscription))
|
|
||||||
.forEach((subscription) => subscription.unsubscribe());
|
|
||||||
this.paginationService.clearPagination(this.paginationOptions.id);
|
this.paginationService.clearPagination(this.paginationOptions.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -147,10 +147,10 @@ export class HostWindowService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isXsOrSm(): Observable<boolean> {
|
isXsOrSm(): Observable<boolean> {
|
||||||
return observableCombineLatest(
|
return observableCombineLatest([
|
||||||
this.isXs(),
|
this.isXs(),
|
||||||
this.isSm(),
|
this.isSm(),
|
||||||
).pipe(
|
]).pipe(
|
||||||
map(([isXs, isSm]) => isXs || isSm),
|
map(([isXs, isSm]) => isXs || isSm),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
);
|
);
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
@if (shouldShowBottomPager | async) {
|
@if (showBottomPager$ | async) {
|
||||||
<div>
|
<div>
|
||||||
@if (showPaginator) {
|
@if (showPaginator) {
|
||||||
<div class="pagination justify-content-center clearfix bottom">
|
<div class="pagination justify-content-center clearfix bottom">
|
||||||
|
@@ -226,6 +226,11 @@ export class PaginationComponent implements OnChanges, OnDestroy, OnInit {
|
|||||||
|
|
||||||
public showingDetails$: Observable<PaginationDetails>;
|
public showingDetails$: Observable<PaginationDetails>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the current pagination should show a bottom pages
|
||||||
|
*/
|
||||||
|
showBottomPager$: Observable<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||||
* @type {Array}
|
* @type {Array}
|
||||||
@@ -255,7 +260,7 @@ export class PaginationComponent implements OnChanges, OnDestroy, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
if (changes.collectionSize.currentValue !== changes.collectionSize.previousValue) {
|
if (hasValue(changes.collectionSize)) {
|
||||||
this.showingDetails$ = this.getShowingDetails(this.collectionSize);
|
this.showingDetails$ = this.getShowingDetails(this.collectionSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,6 +299,7 @@ export class PaginationComponent implements OnChanges, OnDestroy, OnInit {
|
|||||||
this.sortField$ = this.paginationService.getCurrentSort(this.id, sortOptions).pipe(
|
this.sortField$ = this.paginationService.getCurrentSort(this.id, sortOptions).pipe(
|
||||||
map((currentSort) => currentSort.field),
|
map((currentSort) => currentSort.field),
|
||||||
);
|
);
|
||||||
|
this.showBottomPager$ = this.shouldShowBottomPager;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@@ -2,12 +2,12 @@
|
|||||||
#sectionAdd="ngbDropdown"
|
#sectionAdd="ngbDropdown"
|
||||||
placement="bottom-right"
|
placement="bottom-right"
|
||||||
class="d-inline-block"
|
class="d-inline-block"
|
||||||
[ngClass]="{'w-100': windowService.isXs()}">
|
[ngClass]="{'w-100': isXs$}">
|
||||||
@if (hasSections$ | async) {
|
@if (hasSections$ | async) {
|
||||||
<button class="btn btn-outline-primary dropdown-toggle"
|
<button class="btn btn-outline-primary dropdown-toggle"
|
||||||
id="sectionControls"
|
id="sectionControls"
|
||||||
[dsBtnDisabled]="(hasSections$ | async) !== true"
|
[dsBtnDisabled]="(hasSections$ | async) !== true"
|
||||||
[ngClass]="{'w-100': (windowService.isXs() | async)}"
|
[ngClass]="{'w-100': (isXs$ | async)}"
|
||||||
ngbDropdownToggle>
|
ngbDropdownToggle>
|
||||||
{{ 'submission.sections.general.add-more' | translate }} <i class="fa fa-plus" aria-hidden="true"></i>
|
{{ 'submission.sections.general.add-more' | translate }} <i class="fa fa-plus" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<div ngbDropdownMenu
|
<div ngbDropdownMenu
|
||||||
class="sections-dropdown-menu"
|
class="sections-dropdown-menu"
|
||||||
aria-labelledby="sectionControls"
|
aria-labelledby="sectionControls"
|
||||||
[ngClass]="{'w-100': (windowService.isXs() | async)}">
|
[ngClass]="{'w-100': (isXs$ | async)}">
|
||||||
@if ((hasSections$ | async) !== true) {
|
@if ((hasSections$ | async) !== true) {
|
||||||
<button class="dropdown-item disabled">
|
<button class="dropdown-item disabled">
|
||||||
{{ 'submission.sections.general.no-sections' | translate }}
|
{{ 'submission.sections.general.no-sections' | translate }}
|
||||||
|
@@ -51,6 +51,11 @@ export class SubmissionFormSectionAddComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public hasSections$: Observable<boolean>;
|
public hasSections$: Observable<boolean>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing whether it's a small screen
|
||||||
|
*/
|
||||||
|
isXs$: Observable<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize instance variables
|
* Initialize instance variables
|
||||||
*
|
*
|
||||||
@@ -71,6 +76,7 @@ export class SubmissionFormSectionAddComponent implements OnInit {
|
|||||||
this.hasSections$ = this.sectionList$.pipe(
|
this.hasSections$ = this.sectionList$.pipe(
|
||||||
map((list: SectionDataObject[]) => list.length > 0),
|
map((list: SectionDataObject[]) => list.length > 0),
|
||||||
);
|
);
|
||||||
|
this.isXs$ = this.windowService.isXs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@if ((isLoading() | async) !== true) {
|
@if ((isLoading$ | async) !== true) {
|
||||||
<div class="submission-form-header mb-3 d-flex flex-wrap position-sticky">
|
<div class="submission-form-header mb-3 d-flex flex-wrap position-sticky">
|
||||||
@if ((uploadEnabled$ | async)) {
|
@if ((uploadEnabled$ | async)) {
|
||||||
<div class="w-100">
|
<div class="w-100">
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<div class="submission-form-content">
|
<div class="submission-form-content">
|
||||||
@if ((isLoading() | async)) {
|
@if ((isLoading$ | async)) {
|
||||||
<ds-loading message="Loading..."></ds-loading>
|
<ds-loading message="Loading..."></ds-loading>
|
||||||
}
|
}
|
||||||
@for (object of $any(submissionSections | async); track object) {
|
@for (object of $any(submissionSections | async); track object) {
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
</ds-submission-section-container>
|
</ds-submission-section-container>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if ((isLoading() | async) !== true) {
|
@if ((isLoading$ | async) !== true) {
|
||||||
<div class="submission-form-footer mt-3 mb-3 position-sticky">
|
<div class="submission-form-footer mt-3 mb-3 position-sticky">
|
||||||
<ds-submission-form-footer [submissionId]="submissionId"></ds-submission-form-footer>
|
<ds-submission-form-footer [submissionId]="submissionId"></ds-submission-form-footer>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -147,7 +147,7 @@ describe('SubmissionFormComponent Component', () => {
|
|||||||
expect(compAsAny.submissionSections).toBeUndefined();
|
expect(compAsAny.submissionSections).toBeUndefined();
|
||||||
expect(compAsAny.subs).toEqual([]);
|
expect(compAsAny.subs).toEqual([]);
|
||||||
expect(submissionServiceStub.startAutoSave).not.toHaveBeenCalled();
|
expect(submissionServiceStub.startAutoSave).not.toHaveBeenCalled();
|
||||||
expect(comp.loading).toBeObservable(cold('(a|)', { a: true }));
|
expect(comp.isLoading$).toBeObservable(cold('(a|)', { a: true }));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -124,7 +124,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
|
|||||||
* A boolean representing if a submission form is pending
|
* A boolean representing if a submission form is pending
|
||||||
* @type {Observable<boolean>}
|
* @type {Observable<boolean>}
|
||||||
*/
|
*/
|
||||||
public loading: Observable<boolean> = observableOf(true);
|
public isLoading$: Observable<boolean> = observableOf(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits true when the submission config has bitstream uploading enabled in submission
|
* Emits true when the submission config has bitstream uploading enabled in submission
|
||||||
@@ -196,7 +196,7 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
|
|||||||
this.uploadEnabled$ = this.sectionsService.isSectionTypeAvailable(this.submissionId, SectionsType.Upload);
|
this.uploadEnabled$ = this.sectionsService.isSectionTypeAvailable(this.submissionId, SectionsType.Upload);
|
||||||
|
|
||||||
// check if is submission loading
|
// check if is submission loading
|
||||||
this.loading = this.submissionService.getSubmissionObject(this.submissionId).pipe(
|
this.isLoading$ = this.submissionService.getSubmissionObject(this.submissionId).pipe(
|
||||||
filter(() => this.isActive),
|
filter(() => this.isActive),
|
||||||
map((submission: SubmissionObjectEntry) => submission.isLoading),
|
map((submission: SubmissionObjectEntry) => submission.isLoading),
|
||||||
map((isLoading: boolean) => isLoading),
|
map((isLoading: boolean) => isLoading),
|
||||||
@@ -302,16 +302,6 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if submission form is loading
|
|
||||||
*/
|
|
||||||
isLoading(): Observable<boolean> {
|
|
||||||
return this.loading;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if submission form is loading
|
|
||||||
*/
|
|
||||||
protected getSectionsList(): Observable<any> {
|
protected getSectionsList(): Observable<any> {
|
||||||
return this.submissionService.getSubmissionSections(this.submissionId).pipe(
|
return this.submissionService.getSubmissionSections(this.submissionId).pipe(
|
||||||
filter((sections: SectionDataObject[]) => isNotEmpty(sections)),
|
filter((sections: SectionDataObject[]) => isNotEmpty(sections)),
|
||||||
|
@@ -120,13 +120,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (getCcLicenseLink$()) {
|
@if (ccLicenseLink$) {
|
||||||
<ng-container *ngVar="getCcLicenseLink$() | async as licenseLink">
|
@let licenseLink = (ccLicenseLink$ | async);
|
||||||
@if (!licenseLink) {
|
|
||||||
<div>
|
|
||||||
<ds-loading></ds-loading>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (licenseLink) {
|
@if (licenseLink) {
|
||||||
<div
|
<div
|
||||||
class="mt-2 p-4 bg-light text-dark">
|
class="mt-2 p-4 bg-light text-dark">
|
||||||
@@ -146,6 +141,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
} @else {
|
||||||
|
<ds-loading></ds-loading>
|
||||||
}
|
}
|
||||||
</ng-container>
|
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,9 @@ import {
|
|||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
Inject,
|
Inject,
|
||||||
|
OnChanges,
|
||||||
|
OnInit,
|
||||||
|
SimpleChanges,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import {
|
import {
|
||||||
@@ -42,9 +45,12 @@ import {
|
|||||||
import { WorkspaceitemSectionCcLicenseObject } from '../../../core/submission/models/workspaceitem-section-cc-license.model';
|
import { WorkspaceitemSectionCcLicenseObject } from '../../../core/submission/models/workspaceitem-section-cc-license.model';
|
||||||
import { SubmissionCcLicenseDataService } from '../../../core/submission/submission-cc-license-data.service';
|
import { SubmissionCcLicenseDataService } from '../../../core/submission/submission-cc-license-data.service';
|
||||||
import { SubmissionCcLicenseUrlDataService } from '../../../core/submission/submission-cc-license-url-data.service';
|
import { SubmissionCcLicenseUrlDataService } from '../../../core/submission/submission-cc-license-url-data.service';
|
||||||
import { BtnDisabledDirective } from '../../../shared/btn-disabled.directive';
|
|
||||||
import { DsSelectComponent } from '../../../shared/ds-select/ds-select.component';
|
import { DsSelectComponent } from '../../../shared/ds-select/ds-select.component';
|
||||||
import { isNotEmpty } from '../../../shared/empty.util';
|
import {
|
||||||
|
hasNoValue,
|
||||||
|
hasValue,
|
||||||
|
isNotEmpty,
|
||||||
|
} from '../../../shared/empty.util';
|
||||||
import { ThemedLoadingComponent } from '../../../shared/loading/themed-loading.component';
|
import { ThemedLoadingComponent } from '../../../shared/loading/themed-loading.component';
|
||||||
import { VarDirective } from '../../../shared/utils/var.directive';
|
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||||
import { SectionModelComponent } from '../models/section.model';
|
import { SectionModelComponent } from '../models/section.model';
|
||||||
@@ -68,11 +74,10 @@ import { SectionsType } from '../sections-type';
|
|||||||
NgbDropdownModule,
|
NgbDropdownModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
InfiniteScrollModule,
|
InfiniteScrollModule,
|
||||||
BtnDisabledDirective,
|
|
||||||
],
|
],
|
||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
export class SubmissionSectionCcLicensesComponent extends SectionModelComponent {
|
export class SubmissionSectionCcLicensesComponent extends SectionModelComponent implements OnChanges, OnInit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The form id
|
* The form id
|
||||||
@@ -148,6 +153,8 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
return this.data.accepted;
|
return this.data.accepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccLicenseLink$: Observable<string>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected modalService: NgbModal,
|
protected modalService: NgbModal,
|
||||||
protected sectionService: SectionsService,
|
protected sectionService: SectionsService,
|
||||||
@@ -167,6 +174,19 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
super.ngOnInit();
|
||||||
|
if (hasNoValue(this.ccLicenseLink$)) {
|
||||||
|
this.ccLicenseLink$ = this.getCcLicenseLink$();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
if (hasValue(changes.sectionData) || hasValue(changes.submissionCcLicenses)) {
|
||||||
|
this.ccLicenseLink$ = this.getCcLicenseLink$();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data of this section.
|
* The data of this section.
|
||||||
*/
|
*/
|
||||||
@@ -191,6 +211,7 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
},
|
},
|
||||||
uri: undefined,
|
uri: undefined,
|
||||||
});
|
});
|
||||||
|
this.ccLicenseLink$ = this.getCcLicenseLink$();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -222,6 +243,7 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
},
|
},
|
||||||
accepted: false,
|
accepted: false,
|
||||||
});
|
});
|
||||||
|
this.ccLicenseLink$ = this.getCcLicenseLink$();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,9 +1,4 @@
|
|||||||
<!--
|
@let identifierData = (identifierData$ | async);
|
||||||
Template for the identifiers submission section component
|
|
||||||
@author Kim Shepherd
|
|
||||||
-->
|
|
||||||
<!-- Main identifier data -->
|
|
||||||
<ng-container *ngVar="(getIdentifierData() | async) as identifierData">
|
|
||||||
@if (identifierData && identifierData.identifiers) {
|
@if (identifierData && identifierData.identifiers) {
|
||||||
<div>
|
<div>
|
||||||
<span>{{'submission.sections.identifiers.info' | translate}}</span>
|
<span>{{'submission.sections.identifiers.info' | translate}}</span>
|
||||||
@@ -17,4 +12,3 @@ Template for the identifiers submission section component
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</ng-container>
|
|
||||||
|
@@ -12,11 +12,9 @@ import {
|
|||||||
import {
|
import {
|
||||||
Observable,
|
Observable,
|
||||||
of as observableOf,
|
of as observableOf,
|
||||||
Subscription,
|
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
import { WorkspaceitemSectionIdentifiersObject } from '../../../core/submission/models/workspaceitem-section-identifiers.model';
|
import { WorkspaceitemSectionIdentifiersObject } from '../../../core/submission/models/workspaceitem-section-identifiers.model';
|
||||||
import { AlertType } from '../../../shared/alert/alert-type';
|
|
||||||
import { VarDirective } from '../../../shared/utils/var.directive';
|
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||||
import { SubmissionService } from '../../submission.service';
|
import { SubmissionService } from '../../submission.service';
|
||||||
import { SectionModelComponent } from '../models/section.model';
|
import { SectionModelComponent } from '../models/section.model';
|
||||||
@@ -43,11 +41,6 @@ import { SectionsService } from '../sections.service';
|
|||||||
})
|
})
|
||||||
|
|
||||||
export class SubmissionSectionIdentifiersComponent extends SectionModelComponent implements OnInit {
|
export class SubmissionSectionIdentifiersComponent extends SectionModelComponent implements OnInit {
|
||||||
/**
|
|
||||||
* The Alert categories.
|
|
||||||
* @type {AlertType}
|
|
||||||
*/
|
|
||||||
public AlertTypeEnum = AlertType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable to track if the section is loading.
|
* Variable to track if the section is loading.
|
||||||
@@ -59,14 +52,7 @@ export class SubmissionSectionIdentifiersComponent extends SectionModelComponent
|
|||||||
* Observable identifierData subject
|
* Observable identifierData subject
|
||||||
* @type {Observable<WorkspaceitemSectionIdentifiersObject>}
|
* @type {Observable<WorkspaceitemSectionIdentifiersObject>}
|
||||||
*/
|
*/
|
||||||
public identifierData$: Observable<WorkspaceitemSectionIdentifiersObject> = new Observable<WorkspaceitemSectionIdentifiersObject>();
|
public identifierData$: Observable<WorkspaceitemSectionIdentifiersObject>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
|
||||||
* @type {Array}
|
|
||||||
*/
|
|
||||||
protected subs: Subscription[] = [];
|
|
||||||
public subbedIdentifierData: WorkspaceitemSectionIdentifiersObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize instance variables.
|
* Initialize instance variables.
|
||||||
@@ -87,10 +73,6 @@ export class SubmissionSectionIdentifiersComponent extends SectionModelComponent
|
|||||||
super(injectedCollectionId, injectedSectionData, injectedSubmissionId);
|
super(injectedCollectionId, injectedSectionData, injectedSubmissionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
super.ngOnInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize all instance variables and retrieve configuration.
|
* Initialize all instance variables and retrieve configuration.
|
||||||
*/
|
*/
|
||||||
@@ -99,13 +81,6 @@ export class SubmissionSectionIdentifiersComponent extends SectionModelComponent
|
|||||||
this.identifierData$ = this.getIdentifierData();
|
this.identifierData$ = this.getIdentifierData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if identifier section has read-only visibility
|
|
||||||
*/
|
|
||||||
isReadOnly(): boolean {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsubscribe from all subscriptions, if needed.
|
* Unsubscribe from all subscriptions, if needed.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user