mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Merge branch 'w2p-63669_Edit-Col/Com-Tabs' into w2p-65240_Community-and-collection-logos
Conflicts: resources/i18n/en.json5 src/app/+collection-page/edit-collection-page/edit-collection-page.component.html src/app/+collection-page/edit-collection-page/edit-collection-page.component.spec.ts src/app/+collection-page/edit-collection-page/edit-collection-page.component.ts src/app/+community-page/edit-community-page/edit-community-page.component.html src/app/+community-page/edit-community-page/edit-community-page.component.spec.ts src/app/+community-page/edit-community-page/edit-community-page.component.ts src/app/shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.spec.ts src/app/shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.ts
This commit is contained in:
@@ -139,6 +139,15 @@
|
|||||||
"collection.edit.logo.notifications.delete.error.title": "Error deleting logo",
|
"collection.edit.logo.notifications.delete.error.title": "Error deleting logo",
|
||||||
"collection.edit.logo.upload": "Drop a Collection Logo to upload",
|
"collection.edit.logo.upload": "Drop a Collection Logo to upload",
|
||||||
"collection.edit.notifications.success": "Successfully edited the Collection",
|
"collection.edit.notifications.success": "Successfully edited the Collection",
|
||||||
|
"collection.edit.return": "Return",
|
||||||
|
"collection.edit.tabs.curate.head": "Curate",
|
||||||
|
"collection.edit.tabs.curate.title": "Collection Edit - Curate",
|
||||||
|
"collection.edit.tabs.metadata.head": "Edit Metadata",
|
||||||
|
"collection.edit.tabs.metadata.title": "Collection Edit - Metadata",
|
||||||
|
"collection.edit.tabs.roles.head": "Assign Roles",
|
||||||
|
"collection.edit.tabs.roles.title": "Collection Edit - Roles",
|
||||||
|
"collection.edit.tabs.source.head": "Content Source",
|
||||||
|
"collection.edit.tabs.source.title": "Collection Edit - Content Source",
|
||||||
"collection.form.abstract": "Short Description",
|
"collection.form.abstract": "Short Description",
|
||||||
"collection.form.description": "Introductory text (HTML)",
|
"collection.form.description": "Introductory text (HTML)",
|
||||||
"collection.form.errors.title.required": "Please enter a collection name",
|
"collection.form.errors.title.required": "Please enter a collection name",
|
||||||
@@ -171,6 +180,13 @@
|
|||||||
"community.edit.logo.notifications.delete.error.title": "Error deleting logo",
|
"community.edit.logo.notifications.delete.error.title": "Error deleting logo",
|
||||||
"community.edit.logo.upload": "Drop a Community Logo to upload",
|
"community.edit.logo.upload": "Drop a Community Logo to upload",
|
||||||
"community.edit.notifications.success": "Successfully edited the Community",
|
"community.edit.notifications.success": "Successfully edited the Community",
|
||||||
|
"community.edit.return": "Return",
|
||||||
|
"community.edit.tabs.curate.head": "Curate",
|
||||||
|
"community.edit.tabs.curate.title": "Community Edit - Curate",
|
||||||
|
"community.edit.tabs.metadata.head": "Edit Metadata",
|
||||||
|
"community.edit.tabs.metadata.title": "Community Edit - Metadata",
|
||||||
|
"community.edit.tabs.roles.head": "Assign Roles",
|
||||||
|
"community.edit.tabs.roles.title": "Community Edit - Roles",
|
||||||
"community.form.abstract": "Short Description",
|
"community.form.abstract": "Short Description",
|
||||||
"community.form.description": "Introductory text (HTML)",
|
"community.form.description": "Introductory text (HTML)",
|
||||||
"community.form.errors.title.required": "Please enter a community name",
|
"community.form.errors.title.required": "Please enter a community name",
|
||||||
|
@@ -5,7 +5,6 @@ import { CollectionPageComponent } from './collection-page.component';
|
|||||||
import { CollectionPageResolver } from './collection-page.resolver';
|
import { CollectionPageResolver } from './collection-page.resolver';
|
||||||
import { CreateCollectionPageComponent } from './create-collection-page/create-collection-page.component';
|
import { CreateCollectionPageComponent } from './create-collection-page/create-collection-page.component';
|
||||||
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
||||||
import { EditCollectionPageComponent } from './edit-collection-page/edit-collection-page.component';
|
|
||||||
import { CreateCollectionPageGuard } from './create-collection-page/create-collection-page.guard';
|
import { CreateCollectionPageGuard } from './create-collection-page/create-collection-page.guard';
|
||||||
import { DeleteCollectionPageComponent } from './delete-collection-page/delete-collection-page.component';
|
import { DeleteCollectionPageComponent } from './delete-collection-page/delete-collection-page.component';
|
||||||
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
||||||
@@ -38,12 +37,8 @@ const COLLECTION_EDIT_PATH = ':id/edit';
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: COLLECTION_EDIT_PATH,
|
path: COLLECTION_EDIT_PATH,
|
||||||
pathMatch: 'full',
|
loadChildren: './edit-collection-page/edit-collection-page.module#EditCollectionPageModule',
|
||||||
component: EditCollectionPageComponent,
|
canActivate: [AuthenticatedGuard]
|
||||||
canActivate: [AuthenticatedGuard],
|
|
||||||
resolve: {
|
|
||||||
dso: CollectionPageResolver
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':id/delete',
|
path: ':id/delete',
|
||||||
|
@@ -7,7 +7,6 @@ import { CollectionPageComponent } from './collection-page.component';
|
|||||||
import { CollectionPageRoutingModule } from './collection-page-routing.module';
|
import { CollectionPageRoutingModule } from './collection-page-routing.module';
|
||||||
import { CreateCollectionPageComponent } from './create-collection-page/create-collection-page.component';
|
import { CreateCollectionPageComponent } from './create-collection-page/create-collection-page.component';
|
||||||
import { CollectionFormComponent } from './collection-form/collection-form.component';
|
import { CollectionFormComponent } from './collection-form/collection-form.component';
|
||||||
import { EditCollectionPageComponent } from './edit-collection-page/edit-collection-page.component';
|
|
||||||
import { DeleteCollectionPageComponent } from './delete-collection-page/delete-collection-page.component';
|
import { DeleteCollectionPageComponent } from './delete-collection-page/delete-collection-page.component';
|
||||||
import { SearchService } from '../+search-page/search-service/search.service';
|
import { SearchService } from '../+search-page/search-service/search.service';
|
||||||
|
|
||||||
@@ -20,10 +19,12 @@ import { SearchService } from '../+search-page/search-service/search.service';
|
|||||||
declarations: [
|
declarations: [
|
||||||
CollectionPageComponent,
|
CollectionPageComponent,
|
||||||
CreateCollectionPageComponent,
|
CreateCollectionPageComponent,
|
||||||
EditCollectionPageComponent,
|
|
||||||
DeleteCollectionPageComponent,
|
DeleteCollectionPageComponent,
|
||||||
CollectionFormComponent
|
CollectionFormComponent
|
||||||
],
|
],
|
||||||
|
exports: [
|
||||||
|
CollectionFormComponent
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SearchService
|
SearchService
|
||||||
]
|
]
|
||||||
|
@@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for managing a collection's curation tasks
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-collection-curate',
|
||||||
|
templateUrl: './collection-curate.component.html',
|
||||||
|
})
|
||||||
|
export class CollectionCurateComponent {
|
||||||
|
/* TODO: Implement Collection Edit - Curate */
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
<ds-collection-form (submitForm)="onSubmit($event)"
|
||||||
|
[dso]="(dsoRD$ | async)?.payload"
|
||||||
|
(finishUpload)="navigateToHomePage()"></ds-collection-form>
|
||||||
|
<a class="btn btn-danger"
|
||||||
|
[routerLink]="'/collections/' + (dsoRD$ | async)?.payload.uuid + '/delete'">{{'collection.edit.delete'
|
||||||
|
| translate}}</a>
|
@@ -0,0 +1,42 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { SharedModule } from '../../../shared/shared.module';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { CollectionMetadataComponent } from './collection-metadata.component';
|
||||||
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
|
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
||||||
|
|
||||||
|
describe('CollectionMetadataComponent', () => {
|
||||||
|
let comp: CollectionMetadataComponent;
|
||||||
|
let fixture: ComponentFixture<CollectionMetadataComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
||||||
|
declarations: [CollectionMetadataComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: CollectionDataService, useValue: {} },
|
||||||
|
{ provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: { payload: {} } }) } } },
|
||||||
|
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CollectionMetadataComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('frontendURL', () => {
|
||||||
|
it('should have the right frontendURL set', () => {
|
||||||
|
expect((comp as any).frontendURL).toEqual('/collections/');
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,29 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { ComcolMetadataComponent } from '../../../shared/comcol-forms/edit-comcol-page/comcol-metadata/comcol-metadata.component';
|
||||||
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
|
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for editing a collection's metadata
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-collection-metadata',
|
||||||
|
templateUrl: './collection-metadata.component.html',
|
||||||
|
})
|
||||||
|
export class CollectionMetadataComponent extends ComcolMetadataComponent<Collection> {
|
||||||
|
protected frontendURL = '/collections/';
|
||||||
|
protected type = Collection.type;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
protected collectionDataService: CollectionDataService,
|
||||||
|
protected router: Router,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
protected translate: TranslateService
|
||||||
|
) {
|
||||||
|
super(collectionDataService, router, route, notificationsService, translate);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for managing a collection's roles
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-collection-roles',
|
||||||
|
templateUrl: './collection-roles.component.html',
|
||||||
|
})
|
||||||
|
export class CollectionRolesComponent {
|
||||||
|
/* TODO: Implement Collection Edit - Roles */
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for managing the content source of the collection
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-collection-source',
|
||||||
|
templateUrl: './collection-source.component.html',
|
||||||
|
})
|
||||||
|
export class CollectionSourceComponent {
|
||||||
|
/* TODO: Implement Collection Edit - Content Source */
|
||||||
|
}
|
@@ -1,13 +0,0 @@
|
|||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12 pb-4">
|
|
||||||
<h2 id="header" class="border-bottom pb-2">{{ 'collection.edit.head' | translate }}</h2>
|
|
||||||
<ds-collection-form (submitForm)="onSubmit($event)"
|
|
||||||
[dso]="(dsoRD$ | async)?.payload"
|
|
||||||
(finishUpload)="navigateToHomePage()"></ds-collection-form>
|
|
||||||
<a class="btn btn-danger"
|
|
||||||
[routerLink]="'/collections/' + (dsoRD$ | async)?.payload.uuid + '/delete'">{{'collection.edit.delete'
|
|
||||||
| translate}}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1 +0,0 @@
|
|||||||
|
|
@@ -8,21 +8,34 @@ import { EditCollectionPageComponent } from './edit-collection-page.component';
|
|||||||
import { SharedModule } from '../../shared/shared.module';
|
import { SharedModule } from '../../shared/shared.module';
|
||||||
import { CollectionDataService } from '../../core/data/collection-data.service';
|
import { CollectionDataService } from '../../core/data/collection-data.service';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
|
||||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
|
||||||
|
|
||||||
describe('EditCollectionPageComponent', () => {
|
describe('EditCollectionPageComponent', () => {
|
||||||
let comp: EditCollectionPageComponent;
|
let comp: EditCollectionPageComponent;
|
||||||
let fixture: ComponentFixture<EditCollectionPageComponent>;
|
let fixture: ComponentFixture<EditCollectionPageComponent>;
|
||||||
|
|
||||||
|
const routeStub = {
|
||||||
|
data: observableOf({
|
||||||
|
dso: { payload: {} }
|
||||||
|
}),
|
||||||
|
routeConfig: {
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
snapshot: {
|
||||||
|
firstChild: {
|
||||||
|
routeConfig: {
|
||||||
|
path: 'mockUrl'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
||||||
declarations: [EditCollectionPageComponent],
|
declarations: [EditCollectionPageComponent],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: CollectionDataService, useValue: {} },
|
{ provide: CollectionDataService, useValue: {} },
|
||||||
{ provide: ActivatedRoute, useValue: { data: observableOf({ dso: { payload: {} } }) } },
|
{ provide: ActivatedRoute, useValue: routeStub },
|
||||||
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -34,9 +47,9 @@ describe('EditCollectionPageComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('frontendURL', () => {
|
describe('type', () => {
|
||||||
it('should have the right frontendURL set', () => {
|
it('should have the right type set', () => {
|
||||||
expect((comp as any).frontendURL).toEqual('/collections/');
|
expect((comp as any).type).toEqual('collection');
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2,29 +2,30 @@ import { Component } from '@angular/core';
|
|||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component';
|
import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component';
|
||||||
import { Collection } from '../../core/shared/collection.model';
|
import { Collection } from '../../core/shared/collection.model';
|
||||||
import { CollectionDataService } from '../../core/data/collection-data.service';
|
import { getCollectionPageRoute } from '../collection-page-routing.module';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that represents the page where a user can edit an existing Collection
|
* Component that represents the page where a user can edit an existing Collection
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-edit-collection',
|
selector: 'ds-edit-collection',
|
||||||
styleUrls: ['./edit-collection-page.component.scss'],
|
templateUrl: '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.html'
|
||||||
templateUrl: './edit-collection-page.component.html'
|
|
||||||
})
|
})
|
||||||
export class EditCollectionPageComponent extends EditComColPageComponent<Collection> {
|
export class EditCollectionPageComponent extends EditComColPageComponent<Collection> {
|
||||||
protected frontendURL = '/collections/';
|
protected type = 'collection';
|
||||||
protected type = Collection.type;
|
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected collectionDataService: CollectionDataService,
|
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute
|
||||||
protected notificationsService: NotificationsService,
|
|
||||||
protected translate: TranslateService
|
|
||||||
) {
|
) {
|
||||||
super(collectionDataService, router, route, notificationsService, translate);
|
super(router, route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the collection page url
|
||||||
|
* @param collection The collection for which the url is requested
|
||||||
|
*/
|
||||||
|
getPageUrl(collection: Collection): string {
|
||||||
|
return getCollectionPageRoute(collection.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { EditCollectionPageComponent } from './edit-collection-page.component';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { SharedModule } from '../../shared/shared.module';
|
||||||
|
import { EditCollectionPageRoutingModule } from './edit-collection-page.routing.module';
|
||||||
|
import { CollectionMetadataComponent } from './collection-metadata/collection-metadata.component';
|
||||||
|
import { CollectionPageModule } from '../collection-page.module';
|
||||||
|
import { CollectionRolesComponent } from './collection-roles/collection-roles.component';
|
||||||
|
import { CollectionCurateComponent } from './collection-curate/collection-curate.component';
|
||||||
|
import { CollectionSourceComponent } from './collection-source/collection-source.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module that contains all components related to the Edit Collection page administrator functionality
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
SharedModule,
|
||||||
|
EditCollectionPageRoutingModule,
|
||||||
|
CollectionPageModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
EditCollectionPageComponent,
|
||||||
|
CollectionMetadataComponent,
|
||||||
|
CollectionRolesComponent,
|
||||||
|
CollectionCurateComponent,
|
||||||
|
CollectionSourceComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class EditCollectionPageModule {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,61 @@
|
|||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { EditCollectionPageComponent } from './edit-collection-page.component';
|
||||||
|
import { CollectionPageResolver } from '../collection-page.resolver';
|
||||||
|
import { CollectionMetadataComponent } from './collection-metadata/collection-metadata.component';
|
||||||
|
import { CollectionRolesComponent } from './collection-roles/collection-roles.component';
|
||||||
|
import { CollectionSourceComponent } from './collection-source/collection-source.component';
|
||||||
|
import { CollectionCurateComponent } from './collection-curate/collection-curate.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routing module that handles the routing for the Edit Collection page administrator functionality
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: EditCollectionPageComponent,
|
||||||
|
resolve: {
|
||||||
|
dso: CollectionPageResolver
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
redirectTo: 'metadata',
|
||||||
|
pathMatch: 'full'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'metadata',
|
||||||
|
component: CollectionMetadataComponent,
|
||||||
|
data: {
|
||||||
|
title: 'collection.edit.tabs.metadata.title',
|
||||||
|
hideReturnButton: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'roles',
|
||||||
|
component: CollectionRolesComponent,
|
||||||
|
data: { title: 'collection.edit.tabs.roles.title' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'source',
|
||||||
|
component: CollectionSourceComponent,
|
||||||
|
data: { title: 'collection.edit.tabs.source.title' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'curate',
|
||||||
|
component: CollectionCurateComponent,
|
||||||
|
data: { title: 'collection.edit.tabs.curate.title' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
CollectionPageResolver,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class EditCollectionPageRoutingModule {
|
||||||
|
|
||||||
|
}
|
@@ -5,7 +5,6 @@ import { CommunityPageComponent } from './community-page.component';
|
|||||||
import { CommunityPageResolver } from './community-page.resolver';
|
import { CommunityPageResolver } from './community-page.resolver';
|
||||||
import { CreateCommunityPageComponent } from './create-community-page/create-community-page.component';
|
import { CreateCommunityPageComponent } from './create-community-page/create-community-page.component';
|
||||||
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
||||||
import { EditCommunityPageComponent } from './edit-community-page/edit-community-page.component';
|
|
||||||
import { CreateCommunityPageGuard } from './create-community-page/create-community-page.guard';
|
import { CreateCommunityPageGuard } from './create-community-page/create-community-page.guard';
|
||||||
import { DeleteCommunityPageComponent } from './delete-community-page/delete-community-page.component';
|
import { DeleteCommunityPageComponent } from './delete-community-page/delete-community-page.component';
|
||||||
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
||||||
@@ -38,12 +37,8 @@ const COMMUNITY_EDIT_PATH = ':id/edit';
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: COMMUNITY_EDIT_PATH,
|
path: COMMUNITY_EDIT_PATH,
|
||||||
pathMatch: 'full',
|
loadChildren: './edit-community-page/edit-community-page.module#EditCommunityPageModule',
|
||||||
component: EditCommunityPageComponent,
|
canActivate: [AuthenticatedGuard]
|
||||||
canActivate: [AuthenticatedGuard],
|
|
||||||
resolve: {
|
|
||||||
dso: CommunityPageResolver
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':id/delete',
|
path: ':id/delete',
|
||||||
|
@@ -9,7 +9,6 @@ import { CommunityPageRoutingModule } from './community-page-routing.module';
|
|||||||
import {CommunityPageSubCommunityListComponent} from './sub-community-list/community-page-sub-community-list.component';
|
import {CommunityPageSubCommunityListComponent} from './sub-community-list/community-page-sub-community-list.component';
|
||||||
import { CreateCommunityPageComponent } from './create-community-page/create-community-page.component';
|
import { CreateCommunityPageComponent } from './create-community-page/create-community-page.component';
|
||||||
import { CommunityFormComponent } from './community-form/community-form.component';
|
import { CommunityFormComponent } from './community-form/community-form.component';
|
||||||
import { EditCommunityPageComponent } from './edit-community-page/edit-community-page.component';
|
|
||||||
import { DeleteCommunityPageComponent } from './delete-community-page/delete-community-page.component';
|
import { DeleteCommunityPageComponent } from './delete-community-page/delete-community-page.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@@ -23,9 +22,11 @@ import { DeleteCommunityPageComponent } from './delete-community-page/delete-com
|
|||||||
CommunityPageSubCollectionListComponent,
|
CommunityPageSubCollectionListComponent,
|
||||||
CommunityPageSubCommunityListComponent,
|
CommunityPageSubCommunityListComponent,
|
||||||
CreateCommunityPageComponent,
|
CreateCommunityPageComponent,
|
||||||
EditCommunityPageComponent,
|
|
||||||
DeleteCommunityPageComponent,
|
DeleteCommunityPageComponent,
|
||||||
CommunityFormComponent
|
CommunityFormComponent
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
CommunityFormComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for managing a community's curation tasks
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-community-curate',
|
||||||
|
templateUrl: './community-curate.component.html',
|
||||||
|
})
|
||||||
|
export class CommunityCurateComponent {
|
||||||
|
/* TODO: Implement Community Edit - Curate */
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
<ds-community-form (submitForm)="onSubmit($event)"
|
||||||
|
[dso]="(dsoRD$ | async)?.payload"
|
||||||
|
(finishUpload)="navigateToHomePage()"></ds-community-form>
|
||||||
|
<a class="btn btn-danger"
|
||||||
|
[routerLink]="'/communities/' + (dsoRD$ | async)?.payload.uuid + '/delete'">{{'community.edit.delete'
|
||||||
|
| translate}}</a>
|
@@ -0,0 +1,42 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { SharedModule } from '../../../shared/shared.module';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { CommunityMetadataComponent } from './community-metadata.component';
|
||||||
|
import { CommunityDataService } from '../../../core/data/community-data.service';
|
||||||
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
|
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
||||||
|
|
||||||
|
describe('CommunityMetadataComponent', () => {
|
||||||
|
let comp: CommunityMetadataComponent;
|
||||||
|
let fixture: ComponentFixture<CommunityMetadataComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
||||||
|
declarations: [CommunityMetadataComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: CommunityDataService, useValue: {} },
|
||||||
|
{ provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: { payload: {} } }) } } },
|
||||||
|
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CommunityMetadataComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('frontendURL', () => {
|
||||||
|
it('should have the right frontendURL set', () => {
|
||||||
|
expect((comp as any).frontendURL).toEqual('/communities/');
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,29 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { ComcolMetadataComponent } from '../../../shared/comcol-forms/edit-comcol-page/comcol-metadata/comcol-metadata.component';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { Community } from '../../../core/shared/community.model';
|
||||||
|
import { CommunityDataService } from '../../../core/data/community-data.service';
|
||||||
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for editing a community's metadata
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-community-metadata',
|
||||||
|
templateUrl: './community-metadata.component.html',
|
||||||
|
})
|
||||||
|
export class CommunityMetadataComponent extends ComcolMetadataComponent<Community> {
|
||||||
|
protected frontendURL = '/communities/';
|
||||||
|
protected type = Community.type;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
protected communityDataService: CommunityDataService,
|
||||||
|
protected router: Router,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
protected translate: TranslateService
|
||||||
|
) {
|
||||||
|
super(communityDataService, router, route, notificationsService, translate);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component for managing a community's roles
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-community-roles',
|
||||||
|
templateUrl: './community-roles.component.html',
|
||||||
|
})
|
||||||
|
export class CommunityRolesComponent {
|
||||||
|
/* TODO: Implement Community Edit - Roles */
|
||||||
|
}
|
@@ -1,13 +0,0 @@
|
|||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12 pb-4">
|
|
||||||
<h2 id="header" class="border-bottom pb-2">{{ 'community.edit.head' | translate }}</h2>
|
|
||||||
<ds-community-form (submitForm)="onSubmit($event)"
|
|
||||||
[dso]="(dsoRD$ | async)?.payload"
|
|
||||||
(finishUpload)="navigateToHomePage()"></ds-community-form>
|
|
||||||
<a class="btn btn-danger"
|
|
||||||
[routerLink]="'/communities/' + (dsoRD$ | async)?.payload.uuid + '/delete'">{{'community.edit.delete'
|
|
||||||
| translate}}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -1 +0,0 @@
|
|||||||
|
|
@@ -8,21 +8,34 @@ import { SharedModule } from '../../shared/shared.module';
|
|||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { EditCommunityPageComponent } from './edit-community-page.component';
|
import { EditCommunityPageComponent } from './edit-community-page.component';
|
||||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
|
||||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
|
||||||
|
|
||||||
describe('EditCommunityPageComponent', () => {
|
describe('EditCommunityPageComponent', () => {
|
||||||
let comp: EditCommunityPageComponent;
|
let comp: EditCommunityPageComponent;
|
||||||
let fixture: ComponentFixture<EditCommunityPageComponent>;
|
let fixture: ComponentFixture<EditCommunityPageComponent>;
|
||||||
|
|
||||||
|
const routeStub = {
|
||||||
|
data: observableOf({
|
||||||
|
dso: { payload: {} }
|
||||||
|
}),
|
||||||
|
routeConfig: {
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
snapshot: {
|
||||||
|
firstChild: {
|
||||||
|
routeConfig: {
|
||||||
|
path: 'mockUrl'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
||||||
declarations: [EditCommunityPageComponent],
|
declarations: [EditCommunityPageComponent],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: CommunityDataService, useValue: {} },
|
{ provide: CommunityDataService, useValue: {} },
|
||||||
{ provide: ActivatedRoute, useValue: { data: observableOf({ dso: { payload: {} } }) } },
|
{ provide: ActivatedRoute, useValue: routeStub },
|
||||||
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -34,9 +47,9 @@ describe('EditCommunityPageComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('frontendURL', () => {
|
describe('type', () => {
|
||||||
it('should have the right frontendURL set', () => {
|
it('should have the right type set', () => {
|
||||||
expect((comp as any).frontendURL).toEqual('/communities/');
|
expect((comp as any).type).toEqual('community');
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,30 +1,31 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { Community } from '../../core/shared/community.model';
|
import { Community } from '../../core/shared/community.model';
|
||||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component';
|
import { EditComColPageComponent } from '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { getCommunityPageRoute } from '../community-page-routing.module';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that represents the page where a user can edit an existing Community
|
* Component that represents the page where a user can edit an existing Community
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-edit-community',
|
selector: 'ds-edit-community',
|
||||||
styleUrls: ['./edit-community-page.component.scss'],
|
templateUrl: '../../shared/comcol-forms/edit-comcol-page/edit-comcol-page.component.html'
|
||||||
templateUrl: './edit-community-page.component.html'
|
|
||||||
})
|
})
|
||||||
export class EditCommunityPageComponent extends EditComColPageComponent<Community> {
|
export class EditCommunityPageComponent extends EditComColPageComponent<Community> {
|
||||||
protected frontendURL = '/communities/';
|
protected type = 'community';
|
||||||
protected type = Community.type;
|
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected communityDataService: CommunityDataService,
|
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute
|
||||||
protected notificationsService: NotificationsService,
|
|
||||||
protected translate: TranslateService
|
|
||||||
) {
|
) {
|
||||||
super(communityDataService, router, route, notificationsService, translate);
|
super(router, route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the community page url
|
||||||
|
* @param community The community for which the url is requested
|
||||||
|
*/
|
||||||
|
getPageUrl(community: Community): string {
|
||||||
|
return getCommunityPageRoute(community.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { SharedModule } from '../../shared/shared.module';
|
||||||
|
import { EditCommunityPageRoutingModule } from './edit-community-page.routing.module';
|
||||||
|
import { CommunityPageModule } from '../community-page.module';
|
||||||
|
import { EditCommunityPageComponent } from './edit-community-page.component';
|
||||||
|
import { CommunityCurateComponent } from './community-curate/community-curate.component';
|
||||||
|
import { CommunityMetadataComponent } from './community-metadata/community-metadata.component';
|
||||||
|
import { CommunityRolesComponent } from './community-roles/community-roles.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module that contains all components related to the Edit Community page administrator functionality
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
SharedModule,
|
||||||
|
EditCommunityPageRoutingModule,
|
||||||
|
CommunityPageModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
EditCommunityPageComponent,
|
||||||
|
CommunityCurateComponent,
|
||||||
|
CommunityMetadataComponent,
|
||||||
|
CommunityRolesComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class EditCommunityPageModule {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,52 @@
|
|||||||
|
import { CommunityPageResolver } from '../community-page.resolver';
|
||||||
|
import { EditCommunityPageComponent } from './edit-community-page.component';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommunityMetadataComponent } from './community-metadata/community-metadata.component';
|
||||||
|
import { CommunityRolesComponent } from './community-roles/community-roles.component';
|
||||||
|
import { CommunityCurateComponent } from './community-curate/community-curate.component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routing module that handles the routing for the Edit Community page administrator functionality
|
||||||
|
*/
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: EditCommunityPageComponent,
|
||||||
|
resolve: {
|
||||||
|
dso: CommunityPageResolver
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
redirectTo: 'metadata',
|
||||||
|
pathMatch: 'full'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'metadata',
|
||||||
|
component: CommunityMetadataComponent,
|
||||||
|
data: { title: 'community.edit.tabs.metadata.title' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'roles',
|
||||||
|
component: CommunityRolesComponent,
|
||||||
|
data: { title: 'community.edit.tabs.roles.title' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'curate',
|
||||||
|
component: CommunityCurateComponent,
|
||||||
|
data: { title: 'community.edit.tabs.curate.title' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
CommunityPageResolver,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class EditCommunityPageRoutingModule {
|
||||||
|
|
||||||
|
}
|
@@ -38,8 +38,8 @@ describe('EditRelationshipListComponent', () => {
|
|||||||
relationshipType = Object.assign(new RelationshipType(), {
|
relationshipType = Object.assign(new RelationshipType(), {
|
||||||
id: '1',
|
id: '1',
|
||||||
uuid: '1',
|
uuid: '1',
|
||||||
leftLabel: 'isAuthorOfPublication',
|
leftwardType: 'isAuthorOfPublication',
|
||||||
rightLabel: 'isPublicationOfAuthor'
|
rightwardType: 'isPublicationOfAuthor'
|
||||||
});
|
});
|
||||||
|
|
||||||
relationships = [
|
relationships = [
|
||||||
@@ -119,7 +119,7 @@ describe('EditRelationshipListComponent', () => {
|
|||||||
de = fixture.debugElement;
|
de = fixture.debugElement;
|
||||||
comp.item = item;
|
comp.item = item;
|
||||||
comp.url = url;
|
comp.url = url;
|
||||||
comp.relationshipLabel = relationshipType.leftLabel;
|
comp.relationshipLabel = relationshipType.leftwardType;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -34,8 +34,8 @@ describe('EditRelationshipComponent', () => {
|
|||||||
relationshipType = Object.assign(new RelationshipType(), {
|
relationshipType = Object.assign(new RelationshipType(), {
|
||||||
id: '1',
|
id: '1',
|
||||||
uuid: '1',
|
uuid: '1',
|
||||||
leftLabel: 'isAuthorOfPublication',
|
leftwardType: 'isAuthorOfPublication',
|
||||||
rightLabel: 'isPublicationOfAuthor'
|
rightwardType: 'isPublicationOfAuthor'
|
||||||
});
|
});
|
||||||
|
|
||||||
relationships = [
|
relationships = [
|
||||||
|
@@ -68,8 +68,8 @@ describe('ItemRelationshipsComponent', () => {
|
|||||||
relationshipType = Object.assign(new RelationshipType(), {
|
relationshipType = Object.assign(new RelationshipType(), {
|
||||||
id: '1',
|
id: '1',
|
||||||
uuid: '1',
|
uuid: '1',
|
||||||
leftLabel: 'isAuthorOfPublication',
|
leftwardType: 'isAuthorOfPublication',
|
||||||
rightLabel: 'isPublicationOfAuthor'
|
rightwardType: 'isPublicationOfAuthor'
|
||||||
});
|
});
|
||||||
|
|
||||||
relationships = [
|
relationships = [
|
||||||
|
@@ -60,10 +60,10 @@ export const filterRelationsByTypeLabel = (label: string, thisId?: string) =>
|
|||||||
return relatedItems$.pipe(
|
return relatedItems$.pipe(
|
||||||
map((arr) => relsCurrentPage.filter((rel: Relationship, idx: number) =>
|
map((arr) => relsCurrentPage.filter((rel: Relationship, idx: number) =>
|
||||||
hasValue(relTypesCurrentPage[idx]) && (
|
hasValue(relTypesCurrentPage[idx]) && (
|
||||||
(hasNoValue(thisId) && (relTypesCurrentPage[idx].leftLabel === label ||
|
(hasNoValue(thisId) && (relTypesCurrentPage[idx].leftwardType === label ||
|
||||||
relTypesCurrentPage[idx].rightLabel === label)) ||
|
relTypesCurrentPage[idx].rightwardType === label)) ||
|
||||||
(thisId === arr[idx][0].id && relTypesCurrentPage[idx].leftLabel === label) ||
|
(thisId === arr[idx][0].id && relTypesCurrentPage[idx].leftwardType === label) ||
|
||||||
(thisId === arr[idx][1].id && relTypesCurrentPage[idx].rightLabel === label)
|
(thisId === arr[idx][1].id && relTypesCurrentPage[idx].rightwardType === label)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
@@ -23,7 +23,7 @@ export class NormalizedRelationshipType extends NormalizedObject<RelationshipTyp
|
|||||||
* The label that describes the Relation to the left of this RelationshipType
|
* The label that describes the Relation to the left of this RelationshipType
|
||||||
*/
|
*/
|
||||||
@autoserialize
|
@autoserialize
|
||||||
leftLabel: string;
|
leftwardType: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum amount of Relationships allowed to the left of this RelationshipType
|
* The maximum amount of Relationships allowed to the left of this RelationshipType
|
||||||
@@ -41,7 +41,7 @@ export class NormalizedRelationshipType extends NormalizedObject<RelationshipTyp
|
|||||||
* The label that describes the Relation to the right of this RelationshipType
|
* The label that describes the Relation to the right of this RelationshipType
|
||||||
*/
|
*/
|
||||||
@autoserialize
|
@autoserialize
|
||||||
rightLabel: string;
|
rightwardType: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum amount of Relationships allowed to the right of this RelationshipType
|
* The maximum amount of Relationships allowed to the right of this RelationshipType
|
||||||
|
@@ -5,7 +5,6 @@ import { getMockRemoteDataBuildService } from '../../shared/mocks/mock-remote-da
|
|||||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||||
import { RequestEntry } from './request.reducer';
|
import { RequestEntry } from './request.reducer';
|
||||||
import { RelationshipType } from '../shared/item-relationships/relationship-type.model';
|
import { RelationshipType } from '../shared/item-relationships/relationship-type.model';
|
||||||
import { ResourceType } from '../shared/resource-type';
|
|
||||||
import { Relationship } from '../shared/item-relationships/relationship.model';
|
import { Relationship } from '../shared/item-relationships/relationship.model';
|
||||||
import { RemoteData } from './remote-data';
|
import { RemoteData } from './remote-data';
|
||||||
import { getMockRequestService } from '../../shared/mocks/mock-request.service';
|
import { getMockRequestService } from '../../shared/mocks/mock-request.service';
|
||||||
@@ -33,8 +32,8 @@ describe('RelationshipService', () => {
|
|||||||
const relationshipType = Object.assign(new RelationshipType(), {
|
const relationshipType = Object.assign(new RelationshipType(), {
|
||||||
id: '1',
|
id: '1',
|
||||||
uuid: '1',
|
uuid: '1',
|
||||||
leftLabel: 'isAuthorOfPublication',
|
leftwardType: 'isAuthorOfPublication',
|
||||||
rightLabel: 'isPublicationOfAuthor'
|
rightwardType: 'isPublicationOfAuthor'
|
||||||
});
|
});
|
||||||
|
|
||||||
const relationship1 = Object.assign(new Relationship(), {
|
const relationship1 = Object.assign(new Relationship(), {
|
||||||
@@ -129,7 +128,7 @@ describe('RelationshipService', () => {
|
|||||||
describe('getItemRelationshipLabels', () => {
|
describe('getItemRelationshipLabels', () => {
|
||||||
it('should return the correct labels', () => {
|
it('should return the correct labels', () => {
|
||||||
service.getItemRelationshipLabels(item).subscribe((result) => {
|
service.getItemRelationshipLabels(item).subscribe((result) => {
|
||||||
expect(result).toEqual([relationshipType.rightLabel]);
|
expect(result).toEqual([relationshipType.rightwardType]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -144,7 +143,7 @@ describe('RelationshipService', () => {
|
|||||||
|
|
||||||
describe('getRelatedItemsByLabel', () => {
|
describe('getRelatedItemsByLabel', () => {
|
||||||
it('should return the related items by label', () => {
|
it('should return the related items by label', () => {
|
||||||
service.getRelatedItemsByLabel(item, relationshipType.rightLabel).subscribe((result) => {
|
service.getRelatedItemsByLabel(item, relationshipType.rightwardType).subscribe((result) => {
|
||||||
expect(result).toEqual(relatedItems);
|
expect(result).toEqual(relatedItems);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -182,9 +182,9 @@ export class RelationshipService {
|
|||||||
map(([leftItems, rightItems, relTypesCurrentPage]) => {
|
map(([leftItems, rightItems, relTypesCurrentPage]) => {
|
||||||
return relTypesCurrentPage.map((type, index) => {
|
return relTypesCurrentPage.map((type, index) => {
|
||||||
if (leftItems[index].uuid === item.uuid) {
|
if (leftItems[index].uuid === item.uuid) {
|
||||||
return type.leftLabel;
|
return type.leftwardType;
|
||||||
} else {
|
} else {
|
||||||
return type.rightLabel;
|
return type.rightwardType;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
@@ -33,7 +33,7 @@ export class RelationshipType implements CacheableObject {
|
|||||||
/**
|
/**
|
||||||
* The label that describes the Relation to the left of this RelationshipType
|
* The label that describes the Relation to the left of this RelationshipType
|
||||||
*/
|
*/
|
||||||
leftLabel: string;
|
leftwardType: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum amount of Relationships allowed to the left of this RelationshipType
|
* The maximum amount of Relationships allowed to the left of this RelationshipType
|
||||||
@@ -48,7 +48,7 @@ export class RelationshipType implements CacheableObject {
|
|||||||
/**
|
/**
|
||||||
* The label that describes the Relation to the right of this RelationshipType
|
* The label that describes the Relation to the right of this RelationshipType
|
||||||
*/
|
*/
|
||||||
rightLabel: string;
|
rightwardType: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum amount of Relationships allowed to the right of this RelationshipType
|
* The maximum amount of Relationships allowed to the right of this RelationshipType
|
||||||
|
@@ -0,0 +1,189 @@
|
|||||||
|
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { CommunityDataService } from '../../../../core/data/community-data.service';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { Community } from '../../../../core/shared/community.model';
|
||||||
|
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||||
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { SharedModule } from '../../../shared.module';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { DataService } from '../../../../core/data/data.service';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { ComcolMetadataComponent } from './comcol-metadata.component';
|
||||||
|
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../testing/utils';
|
||||||
|
import { ComColDataService } from '../../../../core/data/comcol-data.service';
|
||||||
|
import { NotificationsServiceStub } from '../../../testing/notifications-service-stub';
|
||||||
|
import { NotificationsService } from '../../../notifications/notifications.service';
|
||||||
|
|
||||||
|
describe('ComColMetadataComponent', () => {
|
||||||
|
let comp: ComcolMetadataComponent<DSpaceObject>;
|
||||||
|
let fixture: ComponentFixture<ComcolMetadataComponent<DSpaceObject>>;
|
||||||
|
let dsoDataService: CommunityDataService;
|
||||||
|
let router: Router;
|
||||||
|
|
||||||
|
let community;
|
||||||
|
let newCommunity;
|
||||||
|
let communityDataServiceStub;
|
||||||
|
let routerStub;
|
||||||
|
let routeStub;
|
||||||
|
|
||||||
|
const logoEndpoint = 'rest/api/logo/endpoint';
|
||||||
|
|
||||||
|
function initializeVars() {
|
||||||
|
community = Object.assign(new Community(), {
|
||||||
|
uuid: 'a20da287-e174-466a-9926-f66b9300d347',
|
||||||
|
metadata: [{
|
||||||
|
key: 'dc.title',
|
||||||
|
value: 'test community'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
newCommunity = Object.assign(new Community(), {
|
||||||
|
uuid: '1ff59938-a69a-4e62-b9a4-718569c55d48',
|
||||||
|
metadata: [{
|
||||||
|
key: 'dc.title',
|
||||||
|
value: 'new community'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
communityDataServiceStub = {
|
||||||
|
update: (com, uuid?) => createSuccessfulRemoteDataObject$(newCommunity),
|
||||||
|
getLogoEndpoint: () => observableOf(logoEndpoint)
|
||||||
|
};
|
||||||
|
|
||||||
|
routerStub = {
|
||||||
|
navigate: (commands) => commands
|
||||||
|
};
|
||||||
|
|
||||||
|
routeStub = {
|
||||||
|
parent: {
|
||||||
|
data: observableOf({
|
||||||
|
dso: new RemoteData(false, false, true, null, community)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
initializeVars();
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
||||||
|
providers: [
|
||||||
|
{ provide: ComColDataService, useValue: communityDataServiceStub },
|
||||||
|
{ provide: Router, useValue: routerStub },
|
||||||
|
{ provide: ActivatedRoute, useValue: routeStub },
|
||||||
|
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ComcolMetadataComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
(comp as any).type = Community.type;
|
||||||
|
fixture.detectChanges();
|
||||||
|
dsoDataService = (comp as any).dsoDataService;
|
||||||
|
router = (comp as any).router;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onSubmit', () => {
|
||||||
|
let data;
|
||||||
|
|
||||||
|
describe('with an empty queue in the uploader', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data = {
|
||||||
|
dso: Object.assign(new Community(), {
|
||||||
|
metadata: [{
|
||||||
|
key: 'dc.title',
|
||||||
|
value: 'test'
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
uploader: {
|
||||||
|
options: {
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
queue: [],
|
||||||
|
/* tslint:disable:no-empty */
|
||||||
|
uploadAll: () => {}
|
||||||
|
/* tslint:enable:no-empty */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should navigate when successful', () => {
|
||||||
|
spyOn(router, 'navigate');
|
||||||
|
comp.onSubmit(data);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not navigate on failure', () => {
|
||||||
|
spyOn(router, 'navigate');
|
||||||
|
spyOn(dsoDataService, 'update').and.returnValue(createFailedRemoteDataObject$(newCommunity));
|
||||||
|
comp.onSubmit(data);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(router.navigate).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with at least one item in the uploader\'s queue', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
data = {
|
||||||
|
dso: Object.assign(new Community(), {
|
||||||
|
metadata: [{
|
||||||
|
key: 'dc.title',
|
||||||
|
value: 'test'
|
||||||
|
}]
|
||||||
|
}),
|
||||||
|
uploader: {
|
||||||
|
options: {
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
queue: [
|
||||||
|
{}
|
||||||
|
],
|
||||||
|
/* tslint:disable:no-empty */
|
||||||
|
uploadAll: () => {}
|
||||||
|
/* tslint:enable:no-empty */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not navigate', () => {
|
||||||
|
spyOn(router, 'navigate');
|
||||||
|
comp.onSubmit(data);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(router.navigate).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the uploader\'s url to the logo\'s endpoint', () => {
|
||||||
|
comp.onSubmit(data);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(data.uploader.options.url).toEqual(logoEndpoint);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the uploader\'s uploadAll', () => {
|
||||||
|
spyOn(data.uploader, 'uploadAll');
|
||||||
|
comp.onSubmit(data);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(data.uploader.uploadAll).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('navigateToHomePage', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(router, 'navigate');
|
||||||
|
comp.navigateToHomePage();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should navigate', () => {
|
||||||
|
expect(router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -0,0 +1,84 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
||||||
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { first, map, take } from 'rxjs/operators';
|
||||||
|
import { getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||||
|
import { isNotUndefined } from '../../../empty.util';
|
||||||
|
import { DataService } from '../../../../core/data/data.service';
|
||||||
|
import { ResourceType } from '../../../../core/shared/resource-type';
|
||||||
|
import { ComColDataService } from '../../../../core/data/comcol-data.service';
|
||||||
|
import { NotificationsService } from '../../../notifications/notifications.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-comcol-metadata',
|
||||||
|
template: ''
|
||||||
|
})
|
||||||
|
export class ComcolMetadataComponent<TDomain extends DSpaceObject> implements OnInit {
|
||||||
|
/**
|
||||||
|
* Frontend endpoint for this type of DSO
|
||||||
|
*/
|
||||||
|
protected frontendURL: string;
|
||||||
|
/**
|
||||||
|
* The initial DSO object
|
||||||
|
*/
|
||||||
|
public dsoRD$: Observable<RemoteData<TDomain>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the dso
|
||||||
|
*/
|
||||||
|
protected type: ResourceType;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
protected dsoDataService: ComColDataService<TDomain>,
|
||||||
|
protected router: Router,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
protected translate: TranslateService
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.dsoRD$ = this.route.parent.data.pipe(first(), map((data) => data.dso));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing DSO based on the submitted user data and navigates to the edited object's home page
|
||||||
|
* @param event The event returned by the community/collection form. Contains the new dso and logo uploader
|
||||||
|
*/
|
||||||
|
onSubmit(event) {
|
||||||
|
const dso = event.dso;
|
||||||
|
const uploader = event.uploader;
|
||||||
|
|
||||||
|
this.dsoDataService.update(dso)
|
||||||
|
.pipe(getSucceededRemoteData())
|
||||||
|
.subscribe((dsoRD: RemoteData<TDomain>) => {
|
||||||
|
if (isNotUndefined(dsoRD)) {
|
||||||
|
const newUUID = dsoRD.payload.uuid;
|
||||||
|
if (uploader.queue.length > 0) {
|
||||||
|
this.dsoDataService.getLogoEndpoint(newUUID).pipe(take(1)).subscribe((href: string) => {
|
||||||
|
uploader.options.url = href;
|
||||||
|
uploader.uploadAll();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.router.navigate([this.frontendURL + newUUID]);
|
||||||
|
}
|
||||||
|
this.notificationsService.success(null, this.translate.get(this.type.value + '.edit.notifications.success'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to the home page of the object
|
||||||
|
*/
|
||||||
|
navigateToHomePage() {
|
||||||
|
this.dsoRD$.pipe(
|
||||||
|
getSucceededRemoteData(),
|
||||||
|
take(1)
|
||||||
|
).subscribe((dsoRD: RemoteData<TDomain>) => {
|
||||||
|
this.router.navigate([this.frontendURL + dsoRD.payload.id]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h2 class="border-bottom">{{ type + '.edit.head' | translate }}</h2>
|
||||||
|
<div class="pt-2">
|
||||||
|
<ul class="nav nav-tabs justify-content-start mb-2">
|
||||||
|
<li *ngFor="let page of pages" class="nav-item">
|
||||||
|
<a class="nav-link"
|
||||||
|
[ngClass]="{'active' : page === currentPage}"
|
||||||
|
[routerLink]="['./' + page]">
|
||||||
|
{{ type + '.edit.tabs.' + page + '.head' | translate}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-pane active">
|
||||||
|
<div class="mb-4">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
<a *ngIf="!hideReturnButton" [routerLink]="getPageUrl((dsoRD$ | async)?.payload)" class="btn btn-outline-secondary">{{ type + '.edit.return' | translate }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@@ -1,5 +1,4 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { CommunityDataService } from '../../../core/data/community-data.service';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
@@ -10,29 +9,16 @@ import { RouterTestingModule } from '@angular/router/testing';
|
|||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { EditComColPageComponent } from './edit-comcol-page.component';
|
import { EditComColPageComponent } from './edit-comcol-page.component';
|
||||||
import {
|
|
||||||
createFailedRemoteDataObject$,
|
|
||||||
createSuccessfulRemoteDataObject$
|
|
||||||
} from '../../testing/utils';
|
|
||||||
import { ComColDataService } from '../../../core/data/comcol-data.service';
|
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
|
||||||
import { NotificationsService } from '../../notifications/notifications.service';
|
|
||||||
import { NotificationsServiceStub } from '../../testing/notifications-service-stub';
|
|
||||||
|
|
||||||
describe('EditComColPageComponent', () => {
|
describe('EditComColPageComponent', () => {
|
||||||
let comp: EditComColPageComponent<DSpaceObject>;
|
let comp: EditComColPageComponent<DSpaceObject>;
|
||||||
let fixture: ComponentFixture<EditComColPageComponent<DSpaceObject>>;
|
let fixture: ComponentFixture<EditComColPageComponent<DSpaceObject>>;
|
||||||
let dsoDataService: CommunityDataService;
|
|
||||||
let router: Router;
|
let router: Router;
|
||||||
|
|
||||||
let community;
|
let community;
|
||||||
let newCommunity;
|
|
||||||
let communityDataServiceStub;
|
|
||||||
let routerStub;
|
let routerStub;
|
||||||
let routeStub;
|
let routeStub;
|
||||||
|
|
||||||
const logoEndpoint = 'rest/api/logo/endpoint';
|
|
||||||
|
|
||||||
function initializeVars() {
|
function initializeVars() {
|
||||||
community = Object.assign(new Community(), {
|
community = Object.assign(new Community(), {
|
||||||
uuid: 'a20da287-e174-466a-9926-f66b9300d347',
|
uuid: 'a20da287-e174-466a-9926-f66b9300d347',
|
||||||
@@ -42,27 +28,33 @@ describe('EditComColPageComponent', () => {
|
|||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
newCommunity = Object.assign(new Community(), {
|
|
||||||
uuid: '1ff59938-a69a-4e62-b9a4-718569c55d48',
|
|
||||||
metadata: [{
|
|
||||||
key: 'dc.title',
|
|
||||||
value: 'new community'
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
|
|
||||||
communityDataServiceStub = {
|
|
||||||
update: (com, uuid?) => createSuccessfulRemoteDataObject$(newCommunity),
|
|
||||||
getLogoEndpoint: () => observableOf(logoEndpoint)
|
|
||||||
};
|
|
||||||
|
|
||||||
routerStub = {
|
routerStub = {
|
||||||
navigate: (commands) => commands
|
navigate: (commands) => commands,
|
||||||
|
events: observableOf({}),
|
||||||
|
url: 'mockUrl'
|
||||||
};
|
};
|
||||||
|
|
||||||
routeStub = {
|
routeStub = {
|
||||||
data: observableOf({
|
data: observableOf({
|
||||||
dso: new RemoteData(false, false, true, null, community)
|
dso: community
|
||||||
})
|
}),
|
||||||
|
routeConfig: {
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'mockUrl',
|
||||||
|
data: {
|
||||||
|
hideReturnButton: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
snapshot: {
|
||||||
|
firstChild: {
|
||||||
|
routeConfig: {
|
||||||
|
path: 'mockUrl'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -72,10 +64,8 @@ describe('EditComColPageComponent', () => {
|
|||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: ComColDataService, useValue: communityDataServiceStub },
|
|
||||||
{ provide: Router, useValue: routerStub },
|
{ provide: Router, useValue: routerStub },
|
||||||
{ provide: ActivatedRoute, useValue: routeStub },
|
{ provide: ActivatedRoute, useValue: routeStub },
|
||||||
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -84,105 +74,17 @@ describe('EditComColPageComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(EditComColPageComponent);
|
fixture = TestBed.createComponent(EditComColPageComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
(comp as any).type = Community.type;
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
dsoDataService = (comp as any).dsoDataService;
|
|
||||||
router = (comp as any).router;
|
router = (comp as any).router;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('onSubmit', () => {
|
describe('getPageUrl', () => {
|
||||||
let data;
|
let url;
|
||||||
|
|
||||||
describe('with an empty queue in the uploader', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
data = {
|
|
||||||
dso: Object.assign(new Community(), {
|
|
||||||
metadata: [{
|
|
||||||
key: 'dc.title',
|
|
||||||
value: 'test'
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
uploader: {
|
|
||||||
options: {
|
|
||||||
url: ''
|
|
||||||
},
|
|
||||||
queue: [],
|
|
||||||
/* tslint:disable:no-empty */
|
|
||||||
uploadAll: () => {}
|
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should navigate when successful', () => {
|
|
||||||
spyOn(router, 'navigate');
|
|
||||||
comp.onSubmit(data);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(router.navigate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not navigate on failure', () => {
|
|
||||||
spyOn(router, 'navigate');
|
|
||||||
spyOn(dsoDataService, 'update').and.returnValue(createFailedRemoteDataObject$(newCommunity));
|
|
||||||
comp.onSubmit(data);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(router.navigate).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with at least one item in the uploader\'s queue', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
data = {
|
|
||||||
dso: Object.assign(new Community(), {
|
|
||||||
metadata: [{
|
|
||||||
key: 'dc.title',
|
|
||||||
value: 'test'
|
|
||||||
}]
|
|
||||||
}),
|
|
||||||
uploader: {
|
|
||||||
options: {
|
|
||||||
url: ''
|
|
||||||
},
|
|
||||||
queue: [
|
|
||||||
{}
|
|
||||||
],
|
|
||||||
/* tslint:disable:no-empty */
|
|
||||||
uploadAll: () => {}
|
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not navigate', () => {
|
|
||||||
spyOn(router, 'navigate');
|
|
||||||
comp.onSubmit(data);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(router.navigate).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set the uploader\'s url to the logo\'s endpoint', () => {
|
|
||||||
comp.onSubmit(data);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(data.uploader.options.url).toEqual(logoEndpoint);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call the uploader\'s uploadAll', () => {
|
|
||||||
spyOn(data.uploader, 'uploadAll');
|
|
||||||
comp.onSubmit(data);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(data.uploader.uploadAll).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('navigateToHomePage', () => {
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(router, 'navigate');
|
url = comp.getPageUrl(community);
|
||||||
comp.navigateToHomePage();
|
|
||||||
});
|
});
|
||||||
|
it('should return the current url as a fallback', () => {
|
||||||
it('should navigate', () => {
|
expect(url).toEqual(routerStub.url);
|
||||||
expect(router.navigate).toHaveBeenCalled();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2,15 +2,11 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { isNotUndefined } from '../../empty.util';
|
import { isNotEmpty, isNotUndefined } from '../../empty.util';
|
||||||
import { first, map, take } from 'rxjs/operators';
|
import { first, map } from 'rxjs/operators';
|
||||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||||
import { DataService } from '../../../core/data/data.service';
|
import { DataService } from '../../../core/data/data.service';
|
||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { ComColDataService } from '../../../core/data/comcol-data.service';
|
|
||||||
import { NotificationsService } from '../../notifications/notifications.service';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
|
||||||
import { ResourceType } from '../../../core/shared/resource-type';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component representing the edit page for communities and collections
|
* Component representing the edit page for communities and collections
|
||||||
@@ -21,67 +17,54 @@ import { ResourceType } from '../../../core/shared/resource-type';
|
|||||||
})
|
})
|
||||||
export class EditComColPageComponent<TDomain extends DSpaceObject> implements OnInit {
|
export class EditComColPageComponent<TDomain extends DSpaceObject> implements OnInit {
|
||||||
/**
|
/**
|
||||||
* Frontend endpoint for this type of DSO
|
* The type of DSpaceObject (used to create i18n messages)
|
||||||
*/
|
*/
|
||||||
protected frontendURL: string;
|
protected type: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The initial DSO object
|
* The current page outlet string
|
||||||
|
*/
|
||||||
|
public currentPage: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All possible page outlet strings
|
||||||
|
*/
|
||||||
|
public pages: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DSO to render the edit page for
|
||||||
*/
|
*/
|
||||||
public dsoRD$: Observable<RemoteData<TDomain>>;
|
public dsoRD$: Observable<RemoteData<TDomain>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the dso
|
* Hide the default return button?
|
||||||
*/
|
*/
|
||||||
protected type: ResourceType;
|
public hideReturnButton: boolean;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected dsoDataService: ComColDataService<TDomain>,
|
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute
|
||||||
protected notificationsService: NotificationsService,
|
|
||||||
protected translate: TranslateService
|
|
||||||
) {
|
) {
|
||||||
|
this.router.events.subscribe(() => {
|
||||||
|
this.currentPage = this.route.snapshot.firstChild.routeConfig.path;
|
||||||
|
this.hideReturnButton = this.route.routeConfig.children
|
||||||
|
.find((child: any) => child.path === this.currentPage).data.hideReturnButton;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.pages = this.route.routeConfig.children
|
||||||
|
.map((child: any) => child.path)
|
||||||
|
.filter((path: string) => isNotEmpty(path)); // ignore reroutes
|
||||||
this.dsoRD$ = this.route.data.pipe(first(), map((data) => data.dso));
|
this.dsoRD$ = this.route.data.pipe(first(), map((data) => data.dso));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates an existing DSO based on the submitted user data and navigates to the edited object's home page
|
* Get the dso's page url
|
||||||
* @param event The event returned by the community/collection form. Contains the new dso and logo uploader
|
* This method is expected to be overridden in the edit community/collection page components
|
||||||
|
* @param dso The DSpaceObject for which the url is requested
|
||||||
*/
|
*/
|
||||||
onSubmit(event) {
|
getPageUrl(dso: TDomain): string {
|
||||||
const dso = event.dso;
|
return this.router.url;
|
||||||
const uploader = event.uploader;
|
|
||||||
|
|
||||||
this.dsoDataService.update(dso)
|
|
||||||
.pipe(getSucceededRemoteData())
|
|
||||||
.subscribe((dsoRD: RemoteData<TDomain>) => {
|
|
||||||
if (isNotUndefined(dsoRD)) {
|
|
||||||
const newUUID = dsoRD.payload.uuid;
|
|
||||||
if (uploader.queue.length > 0) {
|
|
||||||
this.dsoDataService.getLogoEndpoint(newUUID).pipe(take(1)).subscribe((href: string) => {
|
|
||||||
uploader.options.url = href;
|
|
||||||
uploader.uploadAll();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.router.navigate([this.frontendURL + newUUID]);
|
|
||||||
}
|
|
||||||
this.notificationsService.success(null, this.translate.get(this.type.value + '.edit.notifications.success'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Navigate to the home page of the object
|
|
||||||
*/
|
|
||||||
navigateToHomePage() {
|
|
||||||
this.dsoRD$.pipe(
|
|
||||||
getSucceededRemoteData(),
|
|
||||||
take(1)
|
|
||||||
).subscribe((dsoRD: RemoteData<TDomain>) => {
|
|
||||||
this.router.navigate([this.frontendURL + dsoRD.payload.id]);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -138,6 +138,8 @@ import { RoleDirective } from './roles/role.directive';
|
|||||||
import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component';
|
import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component';
|
||||||
import { ClaimedTaskActionsReturnToPoolComponent } from './mydspace-actions/claimed-task/return-to-pool/claimed-task-actions-return-to-pool.component';
|
import { ClaimedTaskActionsReturnToPoolComponent } from './mydspace-actions/claimed-task/return-to-pool/claimed-task-actions-return-to-pool.component';
|
||||||
import { ItemDetailPreviewFieldComponent } from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview-field/item-detail-preview-field.component';
|
import { ItemDetailPreviewFieldComponent } from './object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview-field/item-detail-preview-field.component';
|
||||||
|
import { AbstractTrackableComponent } from './trackable/abstract-trackable.component';
|
||||||
|
import { ComcolMetadataComponent } from './comcol-forms/edit-comcol-page/comcol-metadata/comcol-metadata.component';
|
||||||
import { FilterInputSuggestionsComponent } from './input-suggestions/filter-suggestions/filter-input-suggestions.component';
|
import { FilterInputSuggestionsComponent } from './input-suggestions/filter-suggestions/filter-input-suggestions.component';
|
||||||
import { DsoInputSuggestionsComponent } from './input-suggestions/dso-input-suggestions/dso-input-suggestions.component';
|
import { DsoInputSuggestionsComponent } from './input-suggestions/dso-input-suggestions/dso-input-suggestions.component';
|
||||||
import { TypedItemSearchResultGridElementComponent } from './object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
|
import { TypedItemSearchResultGridElementComponent } from './object-grid/item-grid-element/item-types/typed-item-search-result-grid-element.component';
|
||||||
@@ -266,6 +268,8 @@ const COMPONENTS = [
|
|||||||
TypedItemSearchResultGridElementComponent,
|
TypedItemSearchResultGridElementComponent,
|
||||||
ItemTypeSwitcherComponent,
|
ItemTypeSwitcherComponent,
|
||||||
BrowseByComponent,
|
BrowseByComponent,
|
||||||
|
AbstractTrackableComponent,
|
||||||
|
ComcolMetadataComponent,
|
||||||
ItemTypeBadgeComponent
|
ItemTypeBadgeComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -321,6 +325,7 @@ const SHARED_ITEM_PAGE_COMPONENTS = [
|
|||||||
const PROVIDERS = [
|
const PROVIDERS = [
|
||||||
TruncatableService,
|
TruncatableService,
|
||||||
MockAdminGuard,
|
MockAdminGuard,
|
||||||
|
AbstractTrackableComponent,
|
||||||
{
|
{
|
||||||
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
||||||
useValue: dsDynamicFormControlMapFn
|
useValue: dsDynamicFormControlMapFn
|
||||||
|
101
src/app/shared/trackable/abstract-trackable.component.spec.ts
Normal file
101
src/app/shared/trackable/abstract-trackable.component.spec.ts
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { AbstractTrackableComponent } from './abstract-trackable.component';
|
||||||
|
import { INotification, Notification } from '../notifications/models/notification.model';
|
||||||
|
import { NotificationType } from '../notifications/models/notification-type';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service';
|
||||||
|
import { NotificationsService } from '../notifications/notifications.service';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { TestScheduler } from 'rxjs/testing';
|
||||||
|
import { getTestScheduler } from 'jasmine-marbles';
|
||||||
|
|
||||||
|
describe('AbstractTrackableComponent', () => {
|
||||||
|
let comp: AbstractTrackableComponent;
|
||||||
|
let fixture: ComponentFixture<AbstractTrackableComponent>;
|
||||||
|
let objectUpdatesService;
|
||||||
|
let scheduler: TestScheduler;
|
||||||
|
|
||||||
|
const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
|
||||||
|
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
|
||||||
|
const successNotification: INotification = new Notification('id', NotificationType.Success, 'success');
|
||||||
|
|
||||||
|
const notificationsService = jasmine.createSpyObj('notificationsService',
|
||||||
|
{
|
||||||
|
info: infoNotification,
|
||||||
|
warning: warningNotification,
|
||||||
|
success: successNotification
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const url = 'http://test-url.com/test-url';
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService',
|
||||||
|
{
|
||||||
|
saveAddFieldUpdate: {},
|
||||||
|
discardFieldUpdates: {},
|
||||||
|
reinstateFieldUpdates: observableOf(true),
|
||||||
|
initialize: {},
|
||||||
|
hasUpdates: observableOf(true),
|
||||||
|
isReinstatable: observableOf(false), // should always return something --> its in ngOnInit
|
||||||
|
isValidPage: observableOf(true)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scheduler = getTestScheduler();
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [TranslateModule.forRoot()],
|
||||||
|
declarations: [AbstractTrackableComponent],
|
||||||
|
providers: [
|
||||||
|
{provide: ObjectUpdatesService, useValue: objectUpdatesService},
|
||||||
|
{provide: NotificationsService, useValue: notificationsService},
|
||||||
|
], schemas: [
|
||||||
|
NO_ERRORS_SCHEMA
|
||||||
|
]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AbstractTrackableComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
comp.url = url;
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should discard object updates', () => {
|
||||||
|
comp.discard();
|
||||||
|
|
||||||
|
expect(objectUpdatesService.discardFieldUpdates).toHaveBeenCalledWith(url, infoNotification);
|
||||||
|
});
|
||||||
|
it('should undo the discard of object updates', () => {
|
||||||
|
comp.reinstate();
|
||||||
|
|
||||||
|
expect(objectUpdatesService.reinstateFieldUpdates).toHaveBeenCalledWith(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isReinstatable', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
objectUpdatesService.isReinstatable.and.returnValue(observableOf(true));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an observable that emits true', () => {
|
||||||
|
const expected = '(a|)';
|
||||||
|
scheduler.expectObservable(comp.isReinstatable()).toBe(expected, {a: true});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasChanges', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
objectUpdatesService.hasUpdates.and.returnValue(observableOf(true));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an observable that emits true', () => {
|
||||||
|
const expected = '(a|)';
|
||||||
|
scheduler.expectObservable(comp.hasChanges()).toBe(expected, {a: true});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
78
src/app/shared/trackable/abstract-trackable.component.ts
Normal file
78
src/app/shared/trackable/abstract-trackable.component.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service';
|
||||||
|
import { NotificationsService } from '../notifications/notifications.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract Component that is able to track changes made in the inheriting component using the ObjectUpdateService
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-abstract-trackable',
|
||||||
|
template: ''
|
||||||
|
})
|
||||||
|
export class AbstractTrackableComponent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The time span for being able to undo discarding changes
|
||||||
|
*/
|
||||||
|
public discardTimeOut: number;
|
||||||
|
public message: string;
|
||||||
|
public url: string;
|
||||||
|
public notificationsPrefix = 'static-pages.form.notification';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public objectUpdatesService: ObjectUpdatesService,
|
||||||
|
public notificationsService: NotificationsService,
|
||||||
|
public translateService: TranslateService,
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the object updates service to discard all current changes to this item
|
||||||
|
* Shows a notification to remind the user that they can undo this
|
||||||
|
*/
|
||||||
|
discard() {
|
||||||
|
const undoNotification = this.notificationsService.info(this.getNotificationTitle('discarded'), this.getNotificationContent('discarded'), {timeOut: this.discardTimeOut});
|
||||||
|
this.objectUpdatesService.discardFieldUpdates(this.url, undoNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the object updates service to undo discarding all changes to this item
|
||||||
|
*/
|
||||||
|
reinstate() {
|
||||||
|
this.objectUpdatesService.reinstateFieldUpdates(this.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether or not the object is currently reinstatable
|
||||||
|
*/
|
||||||
|
isReinstatable(): Observable<boolean> {
|
||||||
|
return this.objectUpdatesService.isReinstatable(this.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether or not there are currently updates for this object
|
||||||
|
*/
|
||||||
|
hasChanges(): Observable<boolean> {
|
||||||
|
return this.objectUpdatesService.hasUpdates(this.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get translated notification title
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
private getNotificationTitle(key: string) {
|
||||||
|
return this.translateService.instant(this.notificationsPrefix + key + '.title');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get translated notification content
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
private getNotificationContent(key: string) {
|
||||||
|
return this.translateService.instant(this.notificationsPrefix + key + '.content');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user