mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Merge branch 'master' into Keep-virtual-metadata-on-relationship-delete
This commit is contained in:
@@ -2,7 +2,8 @@ import { browser, element, by } from 'protractor';
|
|||||||
|
|
||||||
export class ProtractorPage {
|
export class ProtractorPage {
|
||||||
navigateTo() {
|
navigateTo() {
|
||||||
return browser.get('/');
|
return browser.get('/')
|
||||||
|
.then(() => browser.waitForAngular());
|
||||||
}
|
}
|
||||||
|
|
||||||
getPageTitleText() {
|
getPageTitleText() {
|
||||||
|
@@ -15,7 +15,11 @@ module.exports = function (config) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var configuration = {
|
var configuration = {
|
||||||
|
client: {
|
||||||
|
jasmine: {
|
||||||
|
random: false
|
||||||
|
}
|
||||||
|
},
|
||||||
// base path that will be used to resolve all patterns (e.g. files, exclude)
|
// base path that will be used to resolve all patterns (e.g. files, exclude)
|
||||||
basePath: '',
|
basePath: '',
|
||||||
|
|
||||||
|
@@ -75,6 +75,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^6.1.4",
|
"@angular/animations": "^6.1.4",
|
||||||
|
"@angular/cdk": "^6.4.7",
|
||||||
"@angular/cli": "^6.1.5",
|
"@angular/cli": "^6.1.5",
|
||||||
"@angular/common": "^6.1.4",
|
"@angular/common": "^6.1.4",
|
||||||
"@angular/core": "^6.1.4",
|
"@angular/core": "^6.1.4",
|
||||||
@@ -139,6 +140,7 @@
|
|||||||
"text-mask-core": "5.0.1",
|
"text-mask-core": "5.0.1",
|
||||||
"ts-loader": "^5.2.1",
|
"ts-loader": "^5.2.1",
|
||||||
"ts-md5": "^1.2.4",
|
"ts-md5": "^1.2.4",
|
||||||
|
"url-parse": "^1.4.7",
|
||||||
"uuid": "^3.2.1",
|
"uuid": "^3.2.1",
|
||||||
"webfontloader": "1.6.28",
|
"webfontloader": "1.6.28",
|
||||||
"webpack-cli": "^3.1.0",
|
"webpack-cli": "^3.1.0",
|
||||||
@@ -228,7 +230,7 @@
|
|||||||
"rollup-plugin-node-globals": "1.2.1",
|
"rollup-plugin-node-globals": "1.2.1",
|
||||||
"rollup-plugin-node-resolve": "^3.0.3",
|
"rollup-plugin-node-resolve": "^3.0.3",
|
||||||
"rollup-plugin-terser": "^2.0.2",
|
"rollup-plugin-terser": "^2.0.2",
|
||||||
"sass-loader": "7.1.0",
|
"sass-loader": "^7.1.0",
|
||||||
"script-ext-html-webpack-plugin": "2.0.1",
|
"script-ext-html-webpack-plugin": "2.0.1",
|
||||||
"source-map": "0.7.3",
|
"source-map": "0.7.3",
|
||||||
"source-map-loader": "0.2.4",
|
"source-map-loader": "0.2.4",
|
||||||
|
3
resources/fonts/README.md
Normal file
3
resources/fonts/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Supported font formats
|
||||||
|
|
||||||
|
DSpace supports EOT, TTF, OTF, SVG, WOFF and WOFF2 fonts.
|
@@ -244,6 +244,8 @@
|
|||||||
|
|
||||||
"collection.create.head": "Create a Collection",
|
"collection.create.head": "Create a Collection",
|
||||||
|
|
||||||
|
"collection.create.notifications.success": "Successfully created the Collection",
|
||||||
|
|
||||||
"collection.create.sub-head": "Create a Collection for Community {{ parent }}",
|
"collection.create.sub-head": "Create a Collection for Community {{ parent }}",
|
||||||
|
|
||||||
"collection.delete.cancel": "Cancel",
|
"collection.delete.cancel": "Cancel",
|
||||||
@@ -302,6 +304,46 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"collection.edit.logo.label": "Collection logo",
|
||||||
|
|
||||||
|
"collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.",
|
||||||
|
|
||||||
|
"collection.edit.logo.notifications.add.success": "Upload Collection logo successful.",
|
||||||
|
|
||||||
|
"collection.edit.logo.notifications.delete.success.title": "Logo deleted",
|
||||||
|
|
||||||
|
"collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo",
|
||||||
|
|
||||||
|
"collection.edit.logo.notifications.delete.error.title": "Error deleting logo",
|
||||||
|
|
||||||
|
"collection.edit.logo.upload": "Drop a Collection Logo to upload",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"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)",
|
||||||
@@ -340,8 +382,18 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"communityList.tabTitle": "DSpace - Community List",
|
||||||
|
|
||||||
|
"communityList.title": "List of Communities",
|
||||||
|
|
||||||
|
"communityList.showMore": "Show More",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"community.create.head": "Create a Community",
|
"community.create.head": "Create a Community",
|
||||||
|
|
||||||
|
"community.create.notifications.success": "Successfully created the Community",
|
||||||
|
|
||||||
"community.create.sub-head": "Create a Sub-Community for Community {{ parent }}",
|
"community.create.sub-head": "Create a Sub-Community for Community {{ parent }}",
|
||||||
|
|
||||||
"community.delete.cancel": "Cancel",
|
"community.delete.cancel": "Cancel",
|
||||||
@@ -360,6 +412,44 @@
|
|||||||
|
|
||||||
"community.edit.head": "Edit Community",
|
"community.edit.head": "Edit Community",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"community.edit.logo.label": "Community logo",
|
||||||
|
|
||||||
|
"community.edit.logo.notifications.add.error": "Uploading Community logo failed. Please verify the content before retrying.",
|
||||||
|
|
||||||
|
"community.edit.logo.notifications.add.success": "Upload Community logo successful.",
|
||||||
|
|
||||||
|
"community.edit.logo.notifications.delete.success.title": "Logo deleted",
|
||||||
|
|
||||||
|
"community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo",
|
||||||
|
|
||||||
|
"community.edit.logo.notifications.delete.error.title": "Error deleting logo",
|
||||||
|
|
||||||
|
"community.edit.logo.upload": "Drop a Community Logo to upload",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"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)",
|
||||||
@@ -451,6 +541,9 @@
|
|||||||
"footer.link.duraspace": "DuraSpace",
|
"footer.link.duraspace": "DuraSpace",
|
||||||
|
|
||||||
|
|
||||||
|
"form.add": "Add",
|
||||||
|
|
||||||
|
"form.add-help": "Click here to add the current entry and to add another one",
|
||||||
|
|
||||||
"form.cancel": "Cancel",
|
"form.cancel": "Cancel",
|
||||||
|
|
||||||
@@ -476,6 +569,10 @@
|
|||||||
|
|
||||||
"form.loading": "Loading...",
|
"form.loading": "Loading...",
|
||||||
|
|
||||||
|
"form.lookup": "Lookup",
|
||||||
|
|
||||||
|
"form.lookup-help": "Click here to look up an existing relation",
|
||||||
|
|
||||||
"form.no-results": "No results found",
|
"form.no-results": "No results found",
|
||||||
|
|
||||||
"form.no-value": "No value entered",
|
"form.no-value": "No value entered",
|
||||||
@@ -716,7 +813,7 @@
|
|||||||
|
|
||||||
"item.edit.tabs.relationships.head": "Item Relationships",
|
"item.edit.tabs.relationships.head": "Item Relationships",
|
||||||
|
|
||||||
"item.edit.tabs.relationships.title": "Item Edit - Relationships",
|
"item.edit.tabs.relationships.title": "Item Edit - Relationships",
|
||||||
|
|
||||||
"item.edit.tabs.status.buttons.authorizations.button": "Authorizations...",
|
"item.edit.tabs.status.buttons.authorizations.button": "Authorizations...",
|
||||||
|
|
||||||
@@ -814,9 +911,17 @@
|
|||||||
|
|
||||||
"item.page.person.search.title": "Articles by this author",
|
"item.page.person.search.title": "Articles by this author",
|
||||||
|
|
||||||
"item.page.related-items.view-more": "View more",
|
"item.page.related-items.view-more": "Show {{ amount }} more",
|
||||||
|
|
||||||
"item.page.related-items.view-less": "View less",
|
"item.page.related-items.view-less": "Hide last {{ amount }}",
|
||||||
|
|
||||||
|
"item.page.relationships.isAuthorOfPublication": "Publications",
|
||||||
|
|
||||||
|
"item.page.relationships.isJournalOfPublication": "Publications",
|
||||||
|
|
||||||
|
"item.page.relationships.isOrgUnitOfPerson": "Authors",
|
||||||
|
|
||||||
|
"item.page.relationships.isOrgUnitOfProject": "Research Projects",
|
||||||
|
|
||||||
"item.page.subject": "Keywords",
|
"item.page.subject": "Keywords",
|
||||||
|
|
||||||
@@ -1268,6 +1373,8 @@
|
|||||||
|
|
||||||
"project.page.titleprefix": "Research Project: ",
|
"project.page.titleprefix": "Research Project: ",
|
||||||
|
|
||||||
|
"project.search.results.head": "Project Search Results",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"publication.listelement.badge": "Publication",
|
"publication.listelement.badge": "Publication",
|
||||||
@@ -1343,6 +1450,9 @@
|
|||||||
"search.filters.applied.f.subject": "Subject",
|
"search.filters.applied.f.subject": "Subject",
|
||||||
|
|
||||||
"search.filters.applied.f.submitter": "Submitter",
|
"search.filters.applied.f.submitter": "Submitter",
|
||||||
|
"search.filters.applied.f.jobTitle": "Job Title",
|
||||||
|
"search.filters.applied.f.birthDate.max": "End birth date",
|
||||||
|
"search.filters.applied.f.birthDate.min": "Start birth date",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1511,6 +1621,69 @@
|
|||||||
"submission.general.save-later": "Save for later",
|
"submission.general.save-later": "Save for later",
|
||||||
|
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.close": "Close",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.loading": "Loading...",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.placeholder": "Search query",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.search": "Go",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.select-all": "Select all",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.select-page": "Select page",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.tab-title.Author": "Search for Authors",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Search for Journals",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal Issue": "Search for Journal Issues",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal Volume": "Search for Journal Volumes",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.tab-title.Funding Agency": "Search for Funding Agencies",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.tab-title.Funding": "Search for Funding",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Current Selection ({{ count }})",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.title.Journal Issue": "Journal Issues",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.title.Journal Volume": "Journal Volumes",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.title.Journal": "Journals",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.title.Author": "Authors",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.title.Funding": "Funding",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selection-tab.settings": "Settings",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Your selection is currently empty.",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selection-tab.title.Author": "Selected Authors",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selection-tab.title.Journal Volume": "Selected Journal Volume",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.selection-tab.title.Journal Issue": "Selected Issue",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.name-variant.notification.content": "Would you like to save \"{{ value }}\" as a name variant for this person so you and others can reuse it for future submissions? If you don\'t you can still use it for this submission.",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant",
|
||||||
|
|
||||||
|
"submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Use only for this submission",
|
||||||
|
|
||||||
"submission.sections.general.add-more": "Add more",
|
"submission.sections.general.add-more": "Add more",
|
||||||
|
|
||||||
@@ -1680,7 +1853,7 @@
|
|||||||
|
|
||||||
"uploader.drag-message": "Drag & Drop your files here",
|
"uploader.drag-message": "Drag & Drop your files here",
|
||||||
|
|
||||||
"uploader.or": ", or",
|
"uploader.or": ", or ",
|
||||||
|
|
||||||
"uploader.processing": "Processing",
|
"uploader.processing": "Processing",
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ import { PaginatedList } from '../../../core/data/paginated-list';
|
|||||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||||
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
|
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
|
||||||
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
|
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
|
||||||
import { FindAllOptions } from '../../../core/data/request.models';
|
import { FindListOptions } from '../../../core/data/request.models';
|
||||||
import { map, switchMap, take } from 'rxjs/operators';
|
import { map, switchMap, take } from 'rxjs/operators';
|
||||||
import { hasValue } from '../../../shared/empty.util';
|
import { hasValue } from '../../../shared/empty.util';
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
@@ -35,7 +35,7 @@ export class BitstreamFormatsComponent implements OnInit {
|
|||||||
* The current pagination configuration for the page used by the FindAll method
|
* The current pagination configuration for the page used by the FindAll method
|
||||||
* Currently simply renders all bitstream formats
|
* Currently simply renders all bitstream formats
|
||||||
*/
|
*/
|
||||||
config: FindAllOptions = Object.assign(new FindAllOptions(), {
|
config: FindListOptions = Object.assign(new FindListOptions(), {
|
||||||
elementsPerPage: 20
|
elementsPerPage: 20
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ export class BitstreamFormatsComponent implements OnInit {
|
|||||||
* @param event The page change event
|
* @param event The page change event
|
||||||
*/
|
*/
|
||||||
onPageChange(event) {
|
onPageChange(event) {
|
||||||
this.config = Object.assign(new FindAllOptions(), this.config, {
|
this.config = Object.assign(new FindListOptions(), this.config, {
|
||||||
currentPage: event,
|
currentPage: event,
|
||||||
});
|
});
|
||||||
this.pageConfig.currentPage = event;
|
this.pageConfig.currentPage = event;
|
||||||
|
@@ -13,7 +13,6 @@ import { combineLatest as combineLatestObservable } from 'rxjs';
|
|||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { OnClickMenuItemModel } from '../../shared/menu/menu-item/models/onclick.model';
|
import { OnClickMenuItemModel } from '../../shared/menu/menu-item/models/onclick.model';
|
||||||
import { CreateCommunityParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component';
|
import { CreateCommunityParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component';
|
||||||
import { CreateItemParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component';
|
|
||||||
import { CreateCollectionParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component';
|
import { CreateCollectionParentSelectorComponent } from '../../shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component';
|
||||||
import { EditItemSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component';
|
import { EditItemSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component';
|
||||||
import { EditCommunitySelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component';
|
import { EditCommunitySelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component';
|
||||||
|
@@ -1,9 +1,15 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { DynamicInputModel, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
|
import { DynamicFormService, DynamicInputModel, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
|
||||||
import { DynamicFormControlModel } from '@ng-dynamic-forms/core/src/model/dynamic-form-control.model';
|
import { DynamicFormControlModel } from '@ng-dynamic-forms/core/src/model/dynamic-form-control.model';
|
||||||
import { Collection } from '../../core/shared/collection.model';
|
import { Collection } from '../../core/shared/collection.model';
|
||||||
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
||||||
import { NormalizedCollection } from '../../core/cache/models/normalized-collection.model';
|
import { Location } from '@angular/common';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||||
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
|
import { RequestService } from '../../core/data/request.service';
|
||||||
|
import { ObjectCacheService } from '../../core/cache/object-cache.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form used for creating and editing collections
|
* Form used for creating and editing collections
|
||||||
@@ -22,7 +28,7 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> {
|
|||||||
/**
|
/**
|
||||||
* @type {Collection.type} This is a collection-type form
|
* @type {Collection.type} This is a collection-type form
|
||||||
*/
|
*/
|
||||||
protected type = Collection.type;
|
type = Collection.type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The dynamic form fields used for creating/editing a collection
|
* The dynamic form fields used for creating/editing a collection
|
||||||
@@ -65,4 +71,15 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> {
|
|||||||
name: 'dc.description.provenance',
|
name: 'dc.description.provenance',
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public constructor(protected location: Location,
|
||||||
|
protected formService: DynamicFormService,
|
||||||
|
protected translate: TranslateService,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
protected authService: AuthService,
|
||||||
|
protected dsoService: CommunityDataService,
|
||||||
|
protected requestService: RequestService,
|
||||||
|
protected objectCache: ObjectCacheService) {
|
||||||
|
super(location, formService, translate, notificationsService, authService, requestService, objectCache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,29 +1,23 @@
|
|||||||
import { CollectionItemMapperComponent } from './collection-item-mapper.component';
|
import { CollectionItemMapperComponent } from './collection-item-mapper.component';
|
||||||
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
import { SearchFormComponent } from '../../shared/search-form/search-form.component';
|
import { SearchFormComponent } from '../../shared/search-form/search-form.component';
|
||||||
import { SearchPageModule } from '../../+search-page/search-page.module';
|
|
||||||
import { ObjectCollectionComponent } from '../../shared/object-collection/object-collection.component';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { ActivatedRouteStub } from '../../shared/testing/active-router-stub';
|
import { ActivatedRouteStub } from '../../shared/testing/active-router-stub';
|
||||||
import { RouterStub } from '../../shared/testing/router-stub';
|
import { RouterStub } from '../../shared/testing/router-stub';
|
||||||
import { SearchConfigurationService } from '../../+search-page/search-service/search-configuration.service';
|
|
||||||
import { SearchService } from '../../+search-page/search-service/search.service';
|
|
||||||
import { SearchServiceStub } from '../../shared/testing/search-service-stub';
|
import { SearchServiceStub } from '../../shared/testing/search-service-stub';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
||||||
import { ItemDataService } from '../../core/data/item-data.service';
|
import { ItemDataService } from '../../core/data/item-data.service';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { SharedModule } from '../../shared/shared.module';
|
|
||||||
import { Collection } from '../../core/shared/collection.model';
|
import { Collection } from '../../core/shared/collection.model';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { PaginatedSearchOptions } from '../../+search-page/paginated-search-options.model';
|
|
||||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
import { EventEmitter, NgModule } from '@angular/core';
|
import { EventEmitter } from '@angular/core';
|
||||||
import { HostWindowService } from '../../shared/host-window.service';
|
import { HostWindowService } from '../../shared/host-window.service';
|
||||||
import { HostWindowServiceStub } from '../../shared/testing/host-window-service-stub';
|
import { HostWindowServiceStub } from '../../shared/testing/host-window-service-stub';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
@@ -36,13 +30,14 @@ import { ItemSelectComponent } from '../../shared/object-select/item-select/item
|
|||||||
import { ObjectSelectService } from '../../shared/object-select/object-select.service';
|
import { ObjectSelectService } from '../../shared/object-select/object-select.service';
|
||||||
import { ObjectSelectServiceStub } from '../../shared/testing/object-select-service-stub';
|
import { ObjectSelectServiceStub } from '../../shared/testing/object-select-service-stub';
|
||||||
import { VarDirective } from '../../shared/utils/var.directive';
|
import { VarDirective } from '../../shared/utils/var.directive';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
|
||||||
import { of as observableOf, of } from 'rxjs/internal/observable/of';
|
import { of as observableOf, of } from 'rxjs/internal/observable/of';
|
||||||
import { RestResponse } from '../../core/cache/response.models';
|
import { RestResponse } from '../../core/cache/response.models';
|
||||||
import { SearchFixedFilterService } from '../../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
|
||||||
import { RouteService } from '../../core/services/route.service';
|
import { RouteService } from '../../core/services/route.service';
|
||||||
import { ErrorComponent } from '../../shared/error/error.component';
|
import { ErrorComponent } from '../../shared/error/error.component';
|
||||||
import { LoadingComponent } from '../../shared/loading/loading.component';
|
import { LoadingComponent } from '../../shared/loading/loading.component';
|
||||||
|
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
|
||||||
|
import { SearchService } from '../../core/shared/search/search.service';
|
||||||
|
import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model';
|
||||||
|
|
||||||
describe('CollectionItemMapperComponent', () => {
|
describe('CollectionItemMapperComponent', () => {
|
||||||
let comp: CollectionItemMapperComponent;
|
let comp: CollectionItemMapperComponent;
|
||||||
@@ -135,7 +130,6 @@ describe('CollectionItemMapperComponent', () => {
|
|||||||
{ provide: HostWindowService, useValue: new HostWindowServiceStub(0) },
|
{ provide: HostWindowService, useValue: new HostWindowServiceStub(0) },
|
||||||
{ provide: ObjectSelectService, useValue: new ObjectSelectServiceStub() },
|
{ provide: ObjectSelectService, useValue: new ObjectSelectServiceStub() },
|
||||||
{ provide: RouteService, useValue: routeServiceStub },
|
{ provide: RouteService, useValue: routeServiceStub },
|
||||||
{ provide: SearchFixedFilterService, useValue: fixedFilterServiceStub }
|
|
||||||
]
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
@@ -5,12 +5,9 @@ import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
|||||||
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 { Collection } from '../../core/shared/collection.model';
|
import { Collection } from '../../core/shared/collection.model';
|
||||||
import { SearchConfigurationService } from '../../+search-page/search-service/search-configuration.service';
|
|
||||||
import { PaginatedSearchOptions } from '../../+search-page/paginated-search-options.model';
|
|
||||||
import { PaginatedList } from '../../core/data/paginated-list';
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
import { map, startWith, switchMap, take, tap } from 'rxjs/operators';
|
import { map, startWith, switchMap, take } from 'rxjs/operators';
|
||||||
import { getRemoteDataPayload, getSucceededRemoteData, toDSpaceObjectListRD } from '../../core/shared/operators';
|
import { getRemoteDataPayload, getSucceededRemoteData, toDSpaceObjectListRD } from '../../core/shared/operators';
|
||||||
import { SearchService } from '../../+search-page/search-service/search.service';
|
|
||||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||||
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
||||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
@@ -22,6 +19,9 @@ import { isNotEmpty } from '../../shared/empty.util';
|
|||||||
import { RestResponse } from '../../core/cache/response.models';
|
import { RestResponse } from '../../core/cache/response.models';
|
||||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||||
import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.component';
|
import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.component';
|
||||||
|
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
|
||||||
|
import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model';
|
||||||
|
import { SearchService } from '../../core/shared/search/search.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-collection-item-mapper',
|
selector: 'ds-collection-item-mapper',
|
||||||
|
@@ -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';
|
||||||
@@ -39,12 +38,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',
|
||||||
|
@@ -3,16 +3,19 @@
|
|||||||
*ngVar="(collectionRD$ | async) as collectionRD">
|
*ngVar="(collectionRD$ | async) as collectionRD">
|
||||||
<div *ngIf="collectionRD?.hasSucceeded" @fadeInOut>
|
<div *ngIf="collectionRD?.hasSucceeded" @fadeInOut>
|
||||||
<div *ngIf="collectionRD?.payload as collection">
|
<div *ngIf="collectionRD?.payload as collection">
|
||||||
|
<ds-view-tracker [object]="collection"></ds-view-tracker>
|
||||||
<header class="comcol-header border-bottom mb-4 pb-4">
|
<header class="comcol-header border-bottom mb-4 pb-4">
|
||||||
<!-- Collection logo -->
|
<!-- Collection Name -->
|
||||||
<ds-comcol-page-logo *ngIf="logoRD$"
|
|
||||||
[logo]="(logoRD$ | async)?.payload" [alternateText]="'Collection Logo'">
|
|
||||||
[alternateText]="'Collection Logo'">
|
|
||||||
</ds-comcol-page-logo>
|
|
||||||
<!-- Collection Name -->
|
|
||||||
<ds-comcol-page-header
|
<ds-comcol-page-header
|
||||||
[name]="collection.name">
|
[name]="collection.name">
|
||||||
</ds-comcol-page-header>
|
</ds-comcol-page-header>
|
||||||
|
<!-- Collection logo -->
|
||||||
|
<ds-comcol-page-logo *ngIf="logoRD$"
|
||||||
|
[logo]="(logoRD$ | async)?.payload"
|
||||||
|
[alternateText]="'Collection Logo'"
|
||||||
|
[alternateText]="'Collection Logo'">
|
||||||
|
</ds-comcol-page-logo>
|
||||||
|
|
||||||
<!-- Handle -->
|
<!-- Handle -->
|
||||||
<ds-comcol-page-handle
|
<ds-comcol-page-handle
|
||||||
[content]="collection.handle"
|
[content]="collection.handle"
|
||||||
|
@@ -2,8 +2,8 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
|||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { BehaviorSubject, of as observableOf, Observable, Subject } from 'rxjs';
|
import { BehaviorSubject, of as observableOf, Observable, Subject } from 'rxjs';
|
||||||
import { filter, flatMap, map, startWith, switchMap, take, tap } from 'rxjs/operators';
|
import { filter, flatMap, map, startWith, switchMap, take, tap } from 'rxjs/operators';
|
||||||
import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
|
||||||
import { SearchService } from '../+search-page/search-service/search.service';
|
import { SearchService } from '../core/shared/search/search.service';
|
||||||
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
||||||
import { CollectionDataService } from '../core/data/collection-data.service';
|
import { CollectionDataService } from '../core/data/collection-data.service';
|
||||||
import { PaginatedList } from '../core/data/paginated-list';
|
import { PaginatedList } from '../core/data/paginated-list';
|
||||||
|
@@ -7,29 +7,30 @@ 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 { CollectionItemMapperComponent } from './collection-item-mapper/collection-item-mapper.component';
|
import { CollectionItemMapperComponent } from './collection-item-mapper/collection-item-mapper.component';
|
||||||
import { SearchFixedFilterService } from '../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
import { SearchService } from '../core/shared/search/search.service';
|
||||||
|
import { StatisticsModule } from '../statistics/statistics.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
CollectionPageRoutingModule
|
CollectionPageRoutingModule,
|
||||||
|
StatisticsModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
CollectionPageComponent,
|
CollectionPageComponent,
|
||||||
CreateCollectionPageComponent,
|
CreateCollectionPageComponent,
|
||||||
EditCollectionPageComponent,
|
|
||||||
DeleteCollectionPageComponent,
|
DeleteCollectionPageComponent,
|
||||||
CollectionFormComponent,
|
CollectionFormComponent,
|
||||||
CollectionItemMapperComponent
|
CollectionItemMapperComponent
|
||||||
],
|
],
|
||||||
|
exports: [
|
||||||
|
CollectionFormComponent
|
||||||
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SearchService,
|
SearchService,
|
||||||
SearchFixedFilterService
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class CollectionPageModule {
|
export class CollectionPageModule {
|
||||||
|
@@ -4,5 +4,5 @@
|
|||||||
<h2 id="sub-header" class="border-bottom pb-2">{{'collection.create.sub-head' | translate:{ parent: (parentRD$| async)?.payload.name } }}</h2>
|
<h2 id="sub-header" class="border-bottom pb-2">{{'collection.create.sub-head' | translate:{ parent: (parentRD$| async)?.payload.name } }}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ds-collection-form (submitForm)="onSubmit($event)"></ds-collection-form>
|
<ds-collection-form (submitForm)="onSubmit($event)" (finish)="navigateToNewPage()"></ds-collection-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,6 +10,8 @@ import { CollectionDataService } from '../../core/data/collection-data.service';
|
|||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||||
import { CreateCollectionPageComponent } from './create-collection-page.component';
|
import { CreateCollectionPageComponent } from './create-collection-page.component';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
||||||
|
|
||||||
describe('CreateCollectionPageComponent', () => {
|
describe('CreateCollectionPageComponent', () => {
|
||||||
let comp: CreateCollectionPageComponent;
|
let comp: CreateCollectionPageComponent;
|
||||||
@@ -27,6 +29,7 @@ describe('CreateCollectionPageComponent', () => {
|
|||||||
},
|
},
|
||||||
{ provide: RouteService, useValue: { getQueryParameterValue: () => observableOf('1234') } },
|
{ provide: RouteService, useValue: { getQueryParameterValue: () => observableOf('1234') } },
|
||||||
{ provide: Router, useValue: {} },
|
{ provide: Router, useValue: {} },
|
||||||
|
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
@@ -5,6 +5,8 @@ import { Router } from '@angular/router';
|
|||||||
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component';
|
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-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 { CollectionDataService } from '../../core/data/collection-data.service';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that represents the page where a user can create a new Collection
|
* Component that represents the page where a user can create a new Collection
|
||||||
@@ -16,13 +18,16 @@ import { CollectionDataService } from '../../core/data/collection-data.service';
|
|||||||
})
|
})
|
||||||
export class CreateCollectionPageComponent extends CreateComColPageComponent<Collection> {
|
export class CreateCollectionPageComponent extends CreateComColPageComponent<Collection> {
|
||||||
protected frontendURL = '/collections/';
|
protected frontendURL = '/collections/';
|
||||||
|
protected type = Collection.type;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected communityDataService: CommunityDataService,
|
protected communityDataService: CommunityDataService,
|
||||||
protected collectionDataService: CollectionDataService,
|
protected collectionDataService: CollectionDataService,
|
||||||
protected routeService: RouteService,
|
protected routeService: RouteService,
|
||||||
protected router: Router
|
protected router: Router,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
protected translate: TranslateService
|
||||||
) {
|
) {
|
||||||
super(collectionDataService, communityDataService, routeService, router);
|
super(collectionDataService, communityDataService, routeService, router, notificationsService, translate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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"
|
||||||
|
(finish)="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,11 +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"></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 @@
|
|||||||
|
|
@@ -13,13 +13,29 @@ 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 },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -31,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,24 +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';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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/';
|
type = 'collection';
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected collectionDataService: CollectionDataService,
|
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected route: ActivatedRoute
|
protected route: ActivatedRoute
|
||||||
) {
|
) {
|
||||||
super(collectionDataService, router, route);
|
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 {
|
||||||
|
|
||||||
|
}
|
@@ -1,9 +1,16 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { DynamicInputModel, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
|
import { DynamicFormService, DynamicInputModel, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
|
||||||
import { DynamicFormControlModel } from '@ng-dynamic-forms/core/src/model/dynamic-form-control.model';
|
import { DynamicFormControlModel } from '@ng-dynamic-forms/core/src/model/dynamic-form-control.model';
|
||||||
import { Community } from '../../core/shared/community.model';
|
import { Community } from '../../core/shared/community.model';
|
||||||
import { ResourceType } from '../../core/shared/resource-type';
|
import { ResourceType } from '../../core/shared/resource-type';
|
||||||
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||||
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
|
import { RequestService } from '../../core/data/request.service';
|
||||||
|
import { ObjectCacheService } from '../../core/cache/object-cache.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form used for creating and editing communities
|
* Form used for creating and editing communities
|
||||||
@@ -22,7 +29,7 @@ export class CommunityFormComponent extends ComColFormComponent<Community> {
|
|||||||
/**
|
/**
|
||||||
* @type {Community.type} This is a community-type form
|
* @type {Community.type} This is a community-type form
|
||||||
*/
|
*/
|
||||||
protected type = Community.type;
|
type = Community.type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The dynamic form fields used for creating/editing a community
|
* The dynamic form fields used for creating/editing a community
|
||||||
@@ -57,4 +64,15 @@ export class CommunityFormComponent extends ComColFormComponent<Community> {
|
|||||||
name: 'dc.description.tableofcontents',
|
name: 'dc.description.tableofcontents',
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public constructor(protected location: Location,
|
||||||
|
protected formService: DynamicFormService,
|
||||||
|
protected translate: TranslateService,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
protected authService: AuthService,
|
||||||
|
protected dsoService: CommunityDataService,
|
||||||
|
protected requestService: RequestService,
|
||||||
|
protected objectCache: ObjectCacheService) {
|
||||||
|
super(location, formService, translate, notificationsService, authService, requestService, objectCache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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',
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
<div class="container" *ngVar="(communityRD$ | async) as communityRD">
|
<div class="container" *ngVar="(communityRD$ | async) as communityRD">
|
||||||
<div class="community-page" *ngIf="communityRD?.hasSucceeded" @fadeInOut>
|
<div class="community-page" *ngIf="communityRD?.hasSucceeded" @fadeInOut>
|
||||||
<div *ngIf="communityRD?.payload; let communityPayload">
|
<div *ngIf="communityRD?.payload; let communityPayload">
|
||||||
|
<ds-view-tracker [object]="communityPayload"></ds-view-tracker>
|
||||||
<header class="comcol-header border-bottom mb-4 pb-4">
|
<header class="comcol-header border-bottom mb-4 pb-4">
|
||||||
|
<!-- Community name -->
|
||||||
|
<ds-comcol-page-header [name]="communityPayload.name"></ds-comcol-page-header>
|
||||||
<!-- Community logo -->
|
<!-- Community logo -->
|
||||||
<ds-comcol-page-logo *ngIf="logoRD$" [logo]="(logoRD$ | async)?.payload" [alternateText]="'Community Logo'">
|
<ds-comcol-page-logo *ngIf="logoRD$" [logo]="(logoRD$ | async)?.payload" [alternateText]="'Community Logo'">
|
||||||
</ds-comcol-page-logo>
|
</ds-comcol-page-logo>
|
||||||
|
|
||||||
<!-- Community name -->
|
|
||||||
<ds-comcol-page-header [name]="communityPayload.name"></ds-comcol-page-header>
|
|
||||||
<!-- Handle -->
|
<!-- Handle -->
|
||||||
<ds-comcol-page-handle [content]="communityPayload.handle" [title]="'community.page.handle'">
|
<ds-comcol-page-handle [content]="communityPayload.handle" [title]="'community.page.handle'">
|
||||||
</ds-comcol-page-handle>
|
</ds-comcol-page-handle>
|
||||||
|
@@ -6,26 +6,29 @@ import { SharedModule } from '../shared/shared.module';
|
|||||||
import { CommunityPageComponent } from './community-page.component';
|
import { CommunityPageComponent } from './community-page.component';
|
||||||
import { CommunityPageSubCollectionListComponent } from './sub-collection-list/community-page-sub-collection-list.component';
|
import { CommunityPageSubCollectionListComponent } from './sub-collection-list/community-page-sub-collection-list.component';
|
||||||
import { CommunityPageRoutingModule } from './community-page-routing.module';
|
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';
|
||||||
|
import { StatisticsModule } from '../statistics/statistics.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
CommunityPageRoutingModule
|
CommunityPageRoutingModule,
|
||||||
|
StatisticsModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
CommunityPageComponent,
|
CommunityPageComponent,
|
||||||
CommunityPageSubCollectionListComponent,
|
CommunityPageSubCollectionListComponent,
|
||||||
CommunityPageSubCommunityListComponent,
|
CommunityPageSubCommunityListComponent,
|
||||||
CreateCommunityPageComponent,
|
CreateCommunityPageComponent,
|
||||||
EditCommunityPageComponent,
|
|
||||||
DeleteCommunityPageComponent,
|
DeleteCommunityPageComponent,
|
||||||
CommunityFormComponent
|
CommunityFormComponent
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
CommunityFormComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -7,5 +7,5 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ds-community-form (submitForm)="onSubmit($event)"></ds-community-form>
|
<ds-community-form (submitForm)="onSubmit($event)" (finish)="navigateToNewPage()"></ds-community-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,6 +10,8 @@ import { CollectionDataService } from '../../core/data/collection-data.service';
|
|||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||||
import { CreateCommunityPageComponent } from './create-community-page.component';
|
import { CreateCommunityPageComponent } from './create-community-page.component';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
||||||
|
|
||||||
describe('CreateCommunityPageComponent', () => {
|
describe('CreateCommunityPageComponent', () => {
|
||||||
let comp: CreateCommunityPageComponent;
|
let comp: CreateCommunityPageComponent;
|
||||||
@@ -23,6 +25,7 @@ describe('CreateCommunityPageComponent', () => {
|
|||||||
{ provide: CommunityDataService, useValue: { findById: () => observableOf({}) } },
|
{ provide: CommunityDataService, useValue: { findById: () => observableOf({}) } },
|
||||||
{ provide: RouteService, useValue: { getQueryParameterValue: () => observableOf('1234') } },
|
{ provide: RouteService, useValue: { getQueryParameterValue: () => observableOf('1234') } },
|
||||||
{ provide: Router, useValue: {} },
|
{ provide: Router, useValue: {} },
|
||||||
|
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
@@ -4,6 +4,8 @@ import { CommunityDataService } from '../../core/data/community-data.service';
|
|||||||
import { RouteService } from '../../core/services/route.service';
|
import { RouteService } from '../../core/services/route.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component';
|
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that represents the page where a user can create a new Community
|
* Component that represents the page where a user can create a new Community
|
||||||
@@ -15,12 +17,15 @@ import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comc
|
|||||||
})
|
})
|
||||||
export class CreateCommunityPageComponent extends CreateComColPageComponent<Community> {
|
export class CreateCommunityPageComponent extends CreateComColPageComponent<Community> {
|
||||||
protected frontendURL = '/communities/';
|
protected frontendURL = '/communities/';
|
||||||
|
protected type = Community.type;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected communityDataService: CommunityDataService,
|
protected communityDataService: CommunityDataService,
|
||||||
protected routeService: RouteService,
|
protected routeService: RouteService,
|
||||||
protected router: Router
|
protected router: Router,
|
||||||
|
protected notificationsService: NotificationsService,
|
||||||
|
protected translate: TranslateService
|
||||||
) {
|
) {
|
||||||
super(communityDataService, communityDataService, routeService, router);
|
super(communityDataService, communityDataService, routeService, router, notificationsService, translate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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"
|
||||||
|
(finish)="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,12 +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"></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 @@
|
|||||||
|
|
@@ -13,13 +13,29 @@ 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 },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -31,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,25 +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 { getCommunityPageRoute } from '../community-page-routing.module';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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/';
|
type = 'community';
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
protected communityDataService: CommunityDataService,
|
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected route: ActivatedRoute
|
protected route: ActivatedRoute
|
||||||
) {
|
) {
|
||||||
super(communityDataService, router, route);
|
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,55 @@
|
|||||||
|
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',
|
||||||
|
hideReturnButton: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 {
|
||||||
|
|
||||||
|
}
|
@@ -2,12 +2,25 @@ import { NgModule } from '@angular/core';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
import { HomePageComponent } from './home-page.component';
|
import { HomePageComponent } from './home-page.component';
|
||||||
|
import { HomePageResolver } from './home-page.resolver';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forChild([
|
RouterModule.forChild([
|
||||||
{ path: '', component: HomePageComponent, pathMatch: 'full', data: { title: 'home.title' } }
|
{
|
||||||
|
path: '',
|
||||||
|
component: HomePageComponent,
|
||||||
|
pathMatch: 'full',
|
||||||
|
data: {title: 'home.title'},
|
||||||
|
resolve: {
|
||||||
|
site: HomePageResolver
|
||||||
|
}
|
||||||
|
}
|
||||||
])
|
])
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
HomePageResolver
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class HomePageRoutingModule { }
|
export class HomePageRoutingModule {
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
<ds-home-news></ds-home-news>
|
<ds-home-news></ds-home-news>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<ng-container *ngIf="(site$ | async) as site">
|
||||||
|
<ds-view-tracker [object]="site"></ds-view-tracker>
|
||||||
|
</ng-container>
|
||||||
<ds-search-form [inPlaceSearch]="false"></ds-search-form>
|
<ds-search-form [inPlaceSearch]="false"></ds-search-form>
|
||||||
<ds-top-level-community-list></ds-top-level-community-list>
|
<ds-top-level-community-list></ds-top-level-community-list>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,9 +1,26 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { Site } from '../core/shared/site.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-home-page',
|
selector: 'ds-home-page',
|
||||||
styleUrls: ['./home-page.component.scss'],
|
styleUrls: ['./home-page.component.scss'],
|
||||||
templateUrl: './home-page.component.html'
|
templateUrl: './home-page.component.html'
|
||||||
})
|
})
|
||||||
export class HomePageComponent {
|
export class HomePageComponent implements OnInit {
|
||||||
|
|
||||||
|
site$:Observable<Site>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private route:ActivatedRoute,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit():void {
|
||||||
|
this.site$ = this.route.data.pipe(
|
||||||
|
map((data) => data.site as Site),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,12 +6,14 @@ import { HomePageRoutingModule } from './home-page-routing.module';
|
|||||||
|
|
||||||
import { HomePageComponent } from './home-page.component';
|
import { HomePageComponent } from './home-page.component';
|
||||||
import { TopLevelCommunityListComponent } from './top-level-community-list/top-level-community-list.component';
|
import { TopLevelCommunityListComponent } from './top-level-community-list/top-level-community-list.component';
|
||||||
|
import { StatisticsModule } from '../statistics/statistics.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
HomePageRoutingModule
|
HomePageRoutingModule,
|
||||||
|
StatisticsModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
HomePageComponent,
|
HomePageComponent,
|
||||||
|
25
src/app/+home-page/home-page.resolver.ts
Normal file
25
src/app/+home-page/home-page.resolver.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||||
|
import { SiteDataService } from '../core/data/site-data.service';
|
||||||
|
import { Site } from '../core/shared/site.model';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { take } from 'rxjs/operators';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that resolve the Site object for a route
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class HomePageResolver implements Resolve<Site> {
|
||||||
|
constructor(private siteService:SiteDataService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for resolving a site object
|
||||||
|
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
|
||||||
|
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
|
||||||
|
* @returns Observable<Site> Emits the found Site object, or an error if something went wrong
|
||||||
|
*/
|
||||||
|
resolve(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<Site> | Promise<Site> | Site {
|
||||||
|
return this.siteService.find().pipe(take(1));
|
||||||
|
}
|
||||||
|
}
|
@@ -1,15 +1,12 @@
|
|||||||
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { ItemCollectionMapperComponent } from './item-collection-mapper.component';
|
import { ItemCollectionMapperComponent } from './item-collection-mapper.component';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { SearchConfigurationService } from '../../../+search-page/search-service/search-configuration.service';
|
|
||||||
import { SearchService } from '../../../+search-page/search-service/search.service';
|
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
|
|
||||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||||
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
|
||||||
import { RouterStub } from '../../../shared/testing/router-stub';
|
import { RouterStub } from '../../../shared/testing/router-stub';
|
||||||
@@ -19,7 +16,6 @@ import { SearchServiceStub } from '../../../shared/testing/search-service-stub';
|
|||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { SharedModule } from '../../../shared/shared.module';
|
|
||||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
||||||
import { HostWindowService } from '../../../shared/host-window.service';
|
import { HostWindowService } from '../../../shared/host-window.service';
|
||||||
@@ -28,7 +24,6 @@ import { By } from '@angular/platform-browser';
|
|||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { ObjectSelectService } from '../../../shared/object-select/object-select.service';
|
import { ObjectSelectService } from '../../../shared/object-select/object-select.service';
|
||||||
import { ObjectSelectServiceStub } from '../../../shared/testing/object-select-service-stub';
|
import { ObjectSelectServiceStub } from '../../../shared/testing/object-select-service-stub';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
|
||||||
import { of } from 'rxjs/internal/observable/of';
|
import { of } from 'rxjs/internal/observable/of';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import { RestResponse } from '../../../core/cache/response.models';
|
||||||
import { CollectionSelectComponent } from '../../../shared/object-select/collection-select/collection-select.component';
|
import { CollectionSelectComponent } from '../../../shared/object-select/collection-select/collection-select.component';
|
||||||
@@ -39,6 +34,9 @@ import { SearchFormComponent } from '../../../shared/search-form/search-form.com
|
|||||||
import { Collection } from '../../../core/shared/collection.model';
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
import { ErrorComponent } from '../../../shared/error/error.component';
|
import { ErrorComponent } from '../../../shared/error/error.component';
|
||||||
import { LoadingComponent } from '../../../shared/loading/loading.component';
|
import { LoadingComponent } from '../../../shared/loading/loading.component';
|
||||||
|
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||||
|
import { SearchService } from '../../../core/shared/search/search.service';
|
||||||
|
import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model';
|
||||||
|
|
||||||
describe('ItemCollectionMapperComponent', () => {
|
describe('ItemCollectionMapperComponent', () => {
|
||||||
let comp: ItemCollectionMapperComponent;
|
let comp: ItemCollectionMapperComponent;
|
||||||
|
@@ -2,15 +2,12 @@ import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
|||||||
|
|
||||||
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { fadeIn, fadeInOut } from '../../../shared/animations/fade';
|
import { fadeIn, fadeInOut } from '../../../shared/animations/fade';
|
||||||
import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
|
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
import { Collection } from '../../../core/shared/collection.model';
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { getRemoteDataPayload, getSucceededRemoteData, toDSpaceObjectListRD } from '../../../core/shared/operators';
|
import { getRemoteDataPayload, getSucceededRemoteData, toDSpaceObjectListRD } from '../../../core/shared/operators';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { SearchService } from '../../../+search-page/search-service/search.service';
|
|
||||||
import { SearchConfigurationService } from '../../../+search-page/search-service/search-configuration.service';
|
|
||||||
import { map, startWith, switchMap, take } from 'rxjs/operators';
|
import { map, startWith, switchMap, take } from 'rxjs/operators';
|
||||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
@@ -19,6 +16,9 @@ import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'
|
|||||||
import { isNotEmpty } from '../../../shared/empty.util';
|
import { isNotEmpty } from '../../../shared/empty.util';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import { RestResponse } from '../../../core/cache/response.models';
|
||||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||||
|
import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model';
|
||||||
|
import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service';
|
||||||
|
import { SearchService } from '../../../core/shared/search/search.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-collection-mapper',
|
selector: 'ds-item-collection-mapper',
|
||||||
|
@@ -9,7 +9,6 @@ import { ActivatedRoute, Router } from '@angular/router';
|
|||||||
import { ItemMoveComponent } from './item-move.component';
|
import { ItemMoveComponent } from './item-move.component';
|
||||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
import { SearchService } from '../../../+search-page/search-service/search.service';
|
|
||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||||
@@ -18,6 +17,7 @@ import { PaginatedList } from '../../../core/data/paginated-list';
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import { RestResponse } from '../../../core/cache/response.models';
|
||||||
import { Collection } from '../../../core/shared/collection.model';
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
|
import { SearchService } from '../../../core/shared/search/search.service';
|
||||||
|
|
||||||
describe('ItemMoveComponent', () => {
|
describe('ItemMoveComponent', () => {
|
||||||
let comp: ItemMoveComponent;
|
let comp: ItemMoveComponent;
|
||||||
|
@@ -1,12 +1,9 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { SearchService } from '../../../+search-page/search-service/search.service';
|
|
||||||
import { first, map } from 'rxjs/operators';
|
import { first, map } from 'rxjs/operators';
|
||||||
import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
|
import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
|
||||||
import { SearchOptions } from '../../../+search-page/search-options.model';
|
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
import { SearchResult } from '../../../+search-page/search-result.model';
|
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
@@ -17,9 +14,10 @@ import { getItemEditPath } from '../../item-page-routing.module';
|
|||||||
import { Observable, of as observableOf } from 'rxjs';
|
import { Observable, of as observableOf } from 'rxjs';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import { RestResponse } from '../../../core/cache/response.models';
|
||||||
import { Collection } from '../../../core/shared/collection.model';
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
import { tap } from 'rxjs/internal/operators/tap';
|
|
||||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||||
import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
|
import { SearchService } from '../../../core/shared/search/search.service';
|
||||||
|
import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model';
|
||||||
|
import { SearchResult } from '../../../shared/search/search-result.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-move',
|
selector: 'ds-item-move',
|
||||||
|
@@ -12,8 +12,6 @@ import { PaginatedList } from '../../../../core/data/paginated-list';
|
|||||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||||
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
|
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
|
||||||
import {Store} from '@ngrx/store';
|
|
||||||
import {CoreState} from '../../../../core/core.reducers';
|
|
||||||
|
|
||||||
let objectUpdatesService;
|
let objectUpdatesService;
|
||||||
const url = 'http://test-url.com/test-url';
|
const url = 'http://test-url.com/test-url';
|
||||||
@@ -95,9 +93,11 @@ describe('EditRelationshipComponent', () => {
|
|||||||
itemSelection[relatedItem.uuid] = false;
|
itemSelection[relatedItem.uuid] = false;
|
||||||
itemSelection[item.uuid] = true;
|
itemSelection[item.uuid] = true;
|
||||||
|
|
||||||
const store = new Store<CoreState>(undefined, undefined, undefined);
|
objectUpdatesService = {
|
||||||
|
isSelectedVirtualMetadata: () => null,
|
||||||
objectUpdatesService = new ObjectUpdatesService(store);
|
removeSingleFieldUpdate: () => null,
|
||||||
|
saveRemoveFieldUpdate: () => null,
|
||||||
|
};
|
||||||
|
|
||||||
spyOn(objectUpdatesService, 'isSelectedVirtualMetadata').and.callFake((a, b, uuid) => observableOf(itemSelection[uuid]));
|
spyOn(objectUpdatesService, 'isSelectedVirtualMetadata').and.callFake((a, b, uuid) => observableOf(itemSelection[uuid]));
|
||||||
|
|
||||||
@@ -178,18 +178,18 @@ describe('EditRelationshipComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should close the virtual metadata modal and call saveRemoveFieldUpdate with the correct arguments', () => {
|
it('should close the virtual metadata modal and call saveRemoveFieldUpdate with the correct arguments', () => {
|
||||||
expect(comp.closeVirtualMetadataModal).toHaveBeenCalled();
|
fixture.whenStable(() => {
|
||||||
expect(objectUpdatesService.saveRemoveFieldUpdate).toHaveBeenCalledWith(url, Object.assign({}, fieldUpdate1.field, {
|
expect(comp.closeVirtualMetadataModal).toHaveBeenCalled();
|
||||||
keepLeftVirtualMetadata: false,
|
expect(objectUpdatesService.saveRemoveFieldUpdate).toHaveBeenCalledWith(url, Object.assign({}, fieldUpdate1.field, {
|
||||||
keepRightVirtualMetadata: true,
|
keepLeftVirtualMetadata: false,
|
||||||
}));
|
keepRightVirtualMetadata: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('undo', () => {
|
describe('undo', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(objectUpdatesService, 'removeSingleFieldUpdate');
|
|
||||||
comp.undo();
|
comp.undo();
|
||||||
comp.ngOnChanges();
|
comp.ngOnChanges();
|
||||||
});
|
});
|
||||||
@@ -197,7 +197,8 @@ describe('EditRelationshipComponent', () => {
|
|||||||
it('should call removeSingleFieldUpdate with the correct arguments', () => {
|
it('should call removeSingleFieldUpdate with the correct arguments', () => {
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
expect(objectUpdatesService.removeSingleFieldUpdate).toHaveBeenCalledWith(url, fieldUpdate1[0]);
|
expect(spyOn(objectUpdatesService, 'removeSingleFieldUpdate'))
|
||||||
|
.toHaveBeenCalledWith(url, fieldUpdate1[0]);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,31 +1,32 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||||
import { ItemRelationshipsComponent } from './item-relationships.component';
|
import {ItemRelationshipsComponent} from './item-relationships.component';
|
||||||
import { ChangeDetectorRef, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
import {ChangeDetectorRef, DebugElement, NO_ERRORS_SCHEMA} from '@angular/core';
|
||||||
import { INotification, Notification } from '../../../shared/notifications/models/notification.model';
|
import {INotification, Notification} from '../../../shared/notifications/models/notification.model';
|
||||||
import { NotificationType } from '../../../shared/notifications/models/notification-type';
|
import {NotificationType} from '../../../shared/notifications/models/notification-type';
|
||||||
import { RouterStub } from '../../../shared/testing/router-stub';
|
import {RouterStub} from '../../../shared/testing/router-stub';
|
||||||
import { TestScheduler } from 'rxjs/testing';
|
import {TestScheduler} from 'rxjs/testing';
|
||||||
import { SharedModule } from '../../../shared/shared.module';
|
import {SharedModule} from '../../../shared/shared.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
import {ItemDataService} from '../../../core/data/item-data.service';
|
||||||
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
|
import {ObjectUpdatesService} from '../../../core/data/object-updates/object-updates.service';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import {ActivatedRoute, Router} from '@angular/router';
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import {NotificationsService} from '../../../shared/notifications/notifications.service';
|
||||||
import { GLOBAL_CONFIG } from '../../../../config';
|
import {GLOBAL_CONFIG} from '../../../../config';
|
||||||
import { RelationshipType } from '../../../core/shared/item-relationships/relationship-type.model';
|
import {RelationshipType} from '../../../core/shared/item-relationships/relationship-type.model';
|
||||||
import { ResourceType } from '../../../core/shared/resource-type';
|
import {Relationship} from '../../../core/shared/item-relationships/relationship.model';
|
||||||
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
import {combineLatest as observableCombineLatest, of as observableOf} from 'rxjs';
|
||||||
import { of as observableOf, combineLatest as observableCombineLatest } from 'rxjs';
|
import {RemoteData} from '../../../core/data/remote-data';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import {Item} from '../../../core/shared/item.model';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import {PaginatedList} from '../../../core/data/paginated-list';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import {PageInfo} from '../../../core/shared/page-info.model';
|
||||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
import {FieldChangeType} from '../../../core/data/object-updates/object-updates.actions';
|
||||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
import {RelationshipService} from '../../../core/data/relationship.service';
|
||||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
import {ObjectCacheService} from '../../../core/cache/object-cache.service';
|
||||||
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
|
import {getTestScheduler} from 'jasmine-marbles';
|
||||||
import { getTestScheduler } from 'jasmine-marbles';
|
import {RestResponse} from '../../../core/cache/response.models';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import {RequestService} from '../../../core/data/request.service';
|
||||||
import { RequestService } from '../../../core/data/request.service';
|
import {EntityTypeService} from '../../../core/data/entity-type.service';
|
||||||
|
import {ItemType} from '../../../core/shared/item-relationships/item-type.model';
|
||||||
|
|
||||||
let comp: any;
|
let comp: any;
|
||||||
let fixture: ComponentFixture<ItemRelationshipsComponent>;
|
let fixture: ComponentFixture<ItemRelationshipsComponent>;
|
||||||
@@ -34,6 +35,7 @@ let el: HTMLElement;
|
|||||||
let objectUpdatesService;
|
let objectUpdatesService;
|
||||||
let relationshipService;
|
let relationshipService;
|
||||||
let requestService;
|
let requestService;
|
||||||
|
let entityTypeService;
|
||||||
let objectCache;
|
let objectCache;
|
||||||
const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
|
const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
|
||||||
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
|
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');
|
||||||
@@ -58,6 +60,7 @@ let author1;
|
|||||||
let author2;
|
let author2;
|
||||||
let fieldUpdate1;
|
let fieldUpdate1;
|
||||||
let fieldUpdate2;
|
let fieldUpdate2;
|
||||||
|
let entityType;
|
||||||
let relationships;
|
let relationships;
|
||||||
let relationshipType;
|
let relationshipType;
|
||||||
|
|
||||||
@@ -95,6 +98,10 @@ describe('ItemRelationshipsComponent', () => {
|
|||||||
lastModified: date
|
lastModified: date
|
||||||
});
|
});
|
||||||
|
|
||||||
|
entityType = Object.assign(new ItemType(), {
|
||||||
|
id: 'entityType',
|
||||||
|
});
|
||||||
|
|
||||||
author1 = Object.assign(new Item(), {
|
author1 = Object.assign(new Item(), {
|
||||||
id: 'author1',
|
id: 'author1',
|
||||||
uuid: 'author1'
|
uuid: 'author1'
|
||||||
@@ -159,7 +166,9 @@ describe('ItemRelationshipsComponent', () => {
|
|||||||
getRelatedItemsByLabel: observableOf([author1, author2]),
|
getRelatedItemsByLabel: observableOf([author1, author2]),
|
||||||
getItemRelationshipsArray: observableOf(relationships),
|
getItemRelationshipsArray: observableOf(relationships),
|
||||||
deleteRelationship: observableOf(new RestResponse(true, 200, 'OK')),
|
deleteRelationship: observableOf(new RestResponse(true, 200, 'OK')),
|
||||||
getItemResolvedRelatedItemsAndRelationships: observableCombineLatest(observableOf([author1, author2]), observableOf([item, item]), observableOf(relationships))
|
getItemResolvedRelatedItemsAndRelationships: observableCombineLatest(observableOf([author1, author2]), observableOf([item, item]), observableOf(relationships)),
|
||||||
|
getRelationshipsByRelatedItemIds: observableOf(relationships),
|
||||||
|
getRelationshipTypeLabelsByItem: observableOf([relationshipType.leftwardType])
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -174,6 +183,25 @@ describe('ItemRelationshipsComponent', () => {
|
|||||||
remove: undefined
|
remove: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
|
entityTypeService = jasmine.createSpyObj('entityTypeService',
|
||||||
|
{
|
||||||
|
getEntityTypeByLabel: observableOf(new RemoteData(
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
entityType,
|
||||||
|
)),
|
||||||
|
getEntityTypeRelationships: observableOf(new RemoteData(
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
new PaginatedList(new PageInfo(), [relationshipType]),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
scheduler = getTestScheduler();
|
scheduler = getTestScheduler();
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [SharedModule, TranslateModule.forRoot()],
|
imports: [SharedModule, TranslateModule.forRoot()],
|
||||||
@@ -186,6 +214,7 @@ describe('ItemRelationshipsComponent', () => {
|
|||||||
{ provide: NotificationsService, useValue: notificationsService },
|
{ provide: NotificationsService, useValue: notificationsService },
|
||||||
{ provide: GLOBAL_CONFIG, useValue: { item: { edit: { undoTimeout: 10 } } } as any },
|
{ provide: GLOBAL_CONFIG, useValue: { item: { edit: { undoTimeout: 10 } } } as any },
|
||||||
{ provide: RelationshipService, useValue: relationshipService },
|
{ provide: RelationshipService, useValue: relationshipService },
|
||||||
|
{ provide: EntityTypeService, useValue: entityTypeService },
|
||||||
{ provide: ObjectCacheService, useValue: objectCache },
|
{ provide: ObjectCacheService, useValue: objectCache },
|
||||||
{ provide: RequestService, useValue: requestService },
|
{ provide: RequestService, useValue: requestService },
|
||||||
ChangeDetectorRef
|
ChangeDetectorRef
|
||||||
|
@@ -1,33 +1,29 @@
|
|||||||
import { ChangeDetectorRef, Component, Inject, OnDestroy } from '@angular/core';
|
import {ChangeDetectorRef, Component, Inject, OnDestroy} from '@angular/core';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import {Item} from '../../../core/shared/item.model';
|
||||||
import {
|
import {DeleteRelationship, FieldUpdate, FieldUpdates} from '../../../core/data/object-updates/object-updates.reducer';
|
||||||
DeleteRelationship,
|
import {Observable} from 'rxjs/internal/Observable';
|
||||||
FieldUpdate,
|
import {filter, map, switchMap, take} from 'rxjs/operators';
|
||||||
FieldUpdates
|
import {zip as observableZip} from 'rxjs';
|
||||||
} from '../../../core/data/object-updates/object-updates.reducer';
|
import {AbstractItemUpdateComponent} from '../abstract-item-update/abstract-item-update.component';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import {ItemDataService} from '../../../core/data/item-data.service';
|
||||||
import {filter, map, switchMap, take, tap} from 'rxjs/operators';
|
import {ObjectUpdatesService} from '../../../core/data/object-updates/object-updates.service';
|
||||||
import { combineLatest as observableCombineLatest, zip as observableZip } from 'rxjs';
|
import {ActivatedRoute, Router} from '@angular/router';
|
||||||
import { AbstractItemUpdateComponent } from '../abstract-item-update/abstract-item-update.component';
|
import {NotificationsService} from '../../../shared/notifications/notifications.service';
|
||||||
import { ItemDataService } from '../../../core/data/item-data.service';
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
|
import {GLOBAL_CONFIG, GlobalConfig} from '../../../../config';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import {RelationshipService} from '../../../core/data/relationship.service';
|
||||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
import {ErrorResponse, RestResponse} from '../../../core/cache/response.models';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import {RemoteData} from '../../../core/data/remote-data';
|
||||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../../config';
|
import {ObjectCacheService} from '../../../core/cache/object-cache.service';
|
||||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
|
||||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
|
||||||
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
|
||||||
import { ErrorResponse, RestResponse } from '../../../core/cache/response.models';
|
|
||||||
import { isNotEmptyOperator } from '../../../shared/empty.util';
|
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
|
||||||
import { ObjectCacheService } from '../../../core/cache/object-cache.service';
|
|
||||||
import {getRemoteDataPayload, getSucceededRemoteData} from '../../../core/shared/operators';
|
import {getRemoteDataPayload, getSucceededRemoteData} from '../../../core/shared/operators';
|
||||||
import { RequestService } from '../../../core/data/request.service';
|
import {RequestService} from '../../../core/data/request.service';
|
||||||
import { Subscription } from 'rxjs/internal/Subscription';
|
import {Subscription} from 'rxjs/internal/Subscription';
|
||||||
import {RelationshipType} from '../../../core/shared/item-relationships/relationship-type.model';
|
import {RelationshipType} from '../../../core/shared/item-relationships/relationship-type.model';
|
||||||
import {ItemType} from '../../../core/shared/item-relationships/item-type.model';
|
import {ItemType} from '../../../core/shared/item-relationships/item-type.model';
|
||||||
import {EntityTypeService} from '../../../core/data/entity-type.service';
|
import {EntityTypeService} from '../../../core/data/entity-type.service';
|
||||||
|
import {isNotEmptyOperator} from '../../../shared/empty.util';
|
||||||
|
import {FieldChangeType} from '../../../core/data/object-updates/object-updates.actions';
|
||||||
|
import {Relationship} from '../../../core/shared/item-relationships/relationship.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-relationships',
|
selector: 'ds-item-relationships',
|
||||||
@@ -63,6 +59,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent impl
|
|||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected entityTypeService: EntityTypeService,
|
protected entityTypeService: EntityTypeService,
|
||||||
|
protected cdr: ChangeDetectorRef,
|
||||||
) {
|
) {
|
||||||
super(itemService, objectUpdatesService, router, notificationsService, translateService, EnvConfig, route);
|
super(itemService, objectUpdatesService, router, notificationsService, translateService, EnvConfig, route);
|
||||||
}
|
}
|
||||||
@@ -78,6 +75,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent impl
|
|||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
).subscribe((itemRD: RemoteData<Item>) => {
|
).subscribe((itemRD: RemoteData<Item>) => {
|
||||||
this.item = itemRD.payload;
|
this.item = itemRD.payload;
|
||||||
|
this.cdr.detectChanges();
|
||||||
this.initializeUpdates();
|
this.initializeUpdates();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -118,7 +116,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent impl
|
|||||||
*/
|
*/
|
||||||
public submit(): void {
|
public submit(): void {
|
||||||
// Get all the relationships that should be removed
|
// Get all the relationships that should be removed
|
||||||
const removedRelationshipIDs$ = this.relationshipService.getItemRelationshipsArray(this.item).pipe(
|
this.relationshipService.getItemRelationshipsArray(this.item).pipe(
|
||||||
map((relationships: Relationship[]) => relationships.map((relationship) =>
|
map((relationships: Relationship[]) => relationships.map((relationship) =>
|
||||||
Object.assign(new Relationship(), relationship, {uuid: relationship.id})
|
Object.assign(new Relationship(), relationship, {uuid: relationship.id})
|
||||||
)),
|
)),
|
||||||
@@ -131,8 +129,6 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent impl
|
|||||||
.map((fieldUpdate: FieldUpdate) => fieldUpdate.field as DeleteRelationship)
|
.map((fieldUpdate: FieldUpdate) => fieldUpdate.field as DeleteRelationship)
|
||||||
),
|
),
|
||||||
isNotEmptyOperator(),
|
isNotEmptyOperator(),
|
||||||
);
|
|
||||||
removedRelationshipIDs$.pipe(
|
|
||||||
take(1),
|
take(1),
|
||||||
switchMap((deleteRelationships: DeleteRelationship[]) =>
|
switchMap((deleteRelationships: DeleteRelationship[]) =>
|
||||||
observableZip(...deleteRelationships.map((deleteRelationship) => {
|
observableZip(...deleteRelationships.map((deleteRelationship) => {
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
class="d-flex flex-row">
|
class="d-flex flex-row">
|
||||||
<div class="m-2">
|
<div class="m-2">
|
||||||
<label>
|
<label>
|
||||||
<input class="select" type="checkbox">
|
<input class="select" type="checkbox" [checked]="selected">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-column">
|
<div class="flex-column">
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||||
import {of as observableOf} from 'rxjs/internal/observable/of';
|
import {of as observableOf} from 'rxjs/internal/observable/of';
|
||||||
import {TranslateModule} from '@ngx-translate/core';
|
import {TranslateModule} from '@ngx-translate/core';
|
||||||
import {DebugElement, NO_ERRORS_SCHEMA} from '@angular/core';
|
import {DebugElement, NO_ERRORS_SCHEMA} from '@angular/core';
|
||||||
@@ -8,7 +8,7 @@ import {Item} from '../../../core/shared/item.model';
|
|||||||
import {ObjectUpdatesService} from '../../../core/data/object-updates/object-updates.service';
|
import {ObjectUpdatesService} from '../../../core/data/object-updates/object-updates.service';
|
||||||
import {VarDirective} from '../../../shared/utils/var.directive';
|
import {VarDirective} from '../../../shared/utils/var.directive';
|
||||||
|
|
||||||
fdescribe('VirtualMetadataComponent', () => {
|
describe('VirtualMetadataComponent', () => {
|
||||||
|
|
||||||
let comp: VirtualMetadataComponent;
|
let comp: VirtualMetadataComponent;
|
||||||
let fixture: ComponentFixture<VirtualMetadataComponent>;
|
let fixture: ComponentFixture<VirtualMetadataComponent>;
|
||||||
@@ -50,6 +50,7 @@ fdescribe('VirtualMetadataComponent', () => {
|
|||||||
NO_ERRORS_SCHEMA
|
NO_ERRORS_SCHEMA
|
||||||
]
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(VirtualMetadataComponent);
|
fixture = TestBed.createComponent(VirtualMetadataComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
de = fixture.debugElement;
|
de = fixture.debugElement;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
<div class="container" *ngVar="(itemRD$ | async) as itemRD">
|
<div class="container" *ngVar="(itemRD$ | async) as itemRD">
|
||||||
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
|
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
|
||||||
<div *ngIf="itemRD?.payload as item">
|
<div *ngIf="itemRD?.payload as item">
|
||||||
|
<ds-view-tracker [object]="item"></ds-view-tracker>
|
||||||
<ds-item-page-title-field [item]="item"></ds-item-page-title-field>
|
<ds-item-page-title-field [item]="item"></ds-item-page-title-field>
|
||||||
<div class="simple-view-link my-3">
|
<div class="simple-view-link my-3">
|
||||||
<a class="btn btn-outline-primary" [routerLink]="['/items/' + item.id]">
|
<a class="btn btn-outline-primary" [routerLink]="['/items/' + item.id]">
|
||||||
|
@@ -26,6 +26,9 @@ import { MetadataRepresentationListComponent } from './simple/metadata-represent
|
|||||||
import { RelatedEntitiesSearchComponent } from './simple/related-entities/related-entities-search/related-entities-search.component';
|
import { RelatedEntitiesSearchComponent } from './simple/related-entities/related-entities-search/related-entities-search.component';
|
||||||
import { MetadataValuesComponent } from './field-components/metadata-values/metadata-values.component';
|
import { MetadataValuesComponent } from './field-components/metadata-values/metadata-values.component';
|
||||||
import { MetadataFieldWrapperComponent } from './field-components/metadata-field-wrapper/metadata-field-wrapper.component';
|
import { MetadataFieldWrapperComponent } from './field-components/metadata-field-wrapper/metadata-field-wrapper.component';
|
||||||
|
import { TabbedRelatedEntitiesSearchComponent } from './simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component';
|
||||||
|
import { StatisticsModule } from '../statistics/statistics.module';
|
||||||
|
import { AbstractIncrementalListComponent } from './simple/abstract-incremental-list/abstract-incremental-list.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -33,7 +36,8 @@ import { MetadataFieldWrapperComponent } from './field-components/metadata-field
|
|||||||
SharedModule,
|
SharedModule,
|
||||||
ItemPageRoutingModule,
|
ItemPageRoutingModule,
|
||||||
EditItemPageModule,
|
EditItemPageModule,
|
||||||
SearchPageModule
|
SearchPageModule,
|
||||||
|
StatisticsModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
ItemPageComponent,
|
ItemPageComponent,
|
||||||
@@ -53,7 +57,9 @@ import { MetadataFieldWrapperComponent } from './field-components/metadata-field
|
|||||||
ItemComponent,
|
ItemComponent,
|
||||||
GenericItemPageFieldComponent,
|
GenericItemPageFieldComponent,
|
||||||
MetadataRepresentationListComponent,
|
MetadataRepresentationListComponent,
|
||||||
RelatedEntitiesSearchComponent
|
RelatedEntitiesSearchComponent,
|
||||||
|
TabbedRelatedEntitiesSearchComponent,
|
||||||
|
AbstractIncrementalListComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
ItemComponent,
|
ItemComponent,
|
||||||
@@ -63,7 +69,8 @@ import { MetadataFieldWrapperComponent } from './field-components/metadata-field
|
|||||||
RelatedEntitiesSearchComponent,
|
RelatedEntitiesSearchComponent,
|
||||||
RelatedItemsComponent,
|
RelatedItemsComponent,
|
||||||
MetadataRepresentationListComponent,
|
MetadataRepresentationListComponent,
|
||||||
ItemPageTitleFieldComponent
|
ItemPageTitleFieldComponent,
|
||||||
|
TabbedRelatedEntitiesSearchComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
PublicationComponent
|
PublicationComponent
|
||||||
|
@@ -0,0 +1,73 @@
|
|||||||
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { Subscription } from 'rxjs/internal/Subscription';
|
||||||
|
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-abstract-incremental-list',
|
||||||
|
template: ``,
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* An abstract component for displaying an incremental list of objects
|
||||||
|
*/
|
||||||
|
export class AbstractIncrementalListComponent<T> implements OnInit, OnDestroy {
|
||||||
|
/**
|
||||||
|
* The amount to increment the list by
|
||||||
|
* Define this amount in the child component overriding this component
|
||||||
|
*/
|
||||||
|
incrementBy: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All pages of objects to display as an array
|
||||||
|
*/
|
||||||
|
objects: T[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of open subscriptions
|
||||||
|
*/
|
||||||
|
subscriptions: Subscription[];
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.objects = [];
|
||||||
|
this.subscriptions = [];
|
||||||
|
this.increase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a specific page
|
||||||
|
* > Override this method to return a specific page
|
||||||
|
* @param page The page to fetch
|
||||||
|
*/
|
||||||
|
getPage(page: number): T {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase the amount displayed
|
||||||
|
*/
|
||||||
|
increase() {
|
||||||
|
const page = this.getPage(this.objects.length + 1);
|
||||||
|
if (hasValue(page)) {
|
||||||
|
this.objects.push(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrease the amount displayed
|
||||||
|
*/
|
||||||
|
decrease() {
|
||||||
|
if (this.objects.length > 1) {
|
||||||
|
this.objects.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsubscribe from any open subscriptions
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (isNotEmpty(this.subscriptions)) {
|
||||||
|
this.subscriptions.forEach((sub: Subscription) => {
|
||||||
|
sub.unsubscribe();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
<div class="container" *ngVar="(itemRD$ | async) as itemRD">
|
<div class="container" *ngVar="(itemRD$ | async) as itemRD">
|
||||||
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
|
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
|
||||||
<div *ngIf="itemRD?.payload as item">
|
<div *ngIf="itemRD?.payload as item">
|
||||||
|
<ds-view-tracker [object]="item"></ds-view-tracker>
|
||||||
<ds-listable-object-component-loader [object]="item" [viewMode]="viewMode"></ds-listable-object-component-loader>
|
<ds-listable-object-component-loader [object]="item" [viewMode]="viewMode"></ds-listable-object-component-loader>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -4,7 +4,6 @@ import { MockTranslateLoader } from '../../../../shared/mocks/mock-translate-loa
|
|||||||
import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component';
|
import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component';
|
||||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||||
import { ItemDataService } from '../../../../core/data/item-data.service';
|
import { ItemDataService } from '../../../../core/data/item-data.service';
|
||||||
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
|
||||||
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
import { TruncatableService } from '../../../../shared/truncatable/truncatable.service';
|
||||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
@@ -15,6 +14,7 @@ import { createRelationshipsObservable } from '../shared/item.component.spec';
|
|||||||
import { PublicationComponent } from './publication.component';
|
import { PublicationComponent } from './publication.component';
|
||||||
import { MetadataMap } from '../../../../core/shared/metadata.models';
|
import { MetadataMap } from '../../../../core/shared/metadata.models';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||||
|
import { RelationshipService } from '../../../../core/data/relationship.service';
|
||||||
|
|
||||||
const mockItem: Item = Object.assign(new Item(), {
|
const mockItem: Item = Object.assign(new Item(), {
|
||||||
bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||||
@@ -26,12 +26,6 @@ describe('PublicationComponent', () => {
|
|||||||
let comp: PublicationComponent;
|
let comp: PublicationComponent;
|
||||||
let fixture: ComponentFixture<PublicationComponent>;
|
let fixture: ComponentFixture<PublicationComponent>;
|
||||||
|
|
||||||
const searchFixedFilterServiceStub = {
|
|
||||||
/* tslint:disable:no-empty */
|
|
||||||
getQueryByRelations: () => {}
|
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot({
|
imports: [TranslateModule.forRoot({
|
||||||
@@ -43,8 +37,8 @@ describe('PublicationComponent', () => {
|
|||||||
declarations: [PublicationComponent, GenericItemPageFieldComponent, TruncatePipe],
|
declarations: [PublicationComponent, GenericItemPageFieldComponent, TruncatePipe],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ItemDataService, useValue: {}},
|
{provide: ItemDataService, useValue: {}},
|
||||||
{provide: SearchFixedFilterService, useValue: searchFixedFilterServiceStub},
|
{provide: TruncatableService, useValue: {}},
|
||||||
{provide: TruncatableService, useValue: {}}
|
{provide: RelationshipService, useValue: {}}
|
||||||
],
|
],
|
||||||
|
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||||
import { ItemComponent } from '../shared/item.component';
|
|
||||||
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
|
import { ItemComponent } from '../shared/item.component';
|
||||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||||
|
import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that represents a publication Item page
|
* Component that represents a publication Item page
|
||||||
|
@@ -1,14 +1,12 @@
|
|||||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators';
|
import { getSucceededRemoteData } from '../../../../core/shared/operators';
|
||||||
import { hasNoValue, hasValue } from '../../../../shared/empty.util';
|
import { hasValue } from '../../../../shared/empty.util';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
||||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
|
||||||
import { distinctUntilChanged, flatMap, map, switchMap } from 'rxjs/operators';
|
import { distinctUntilChanged, flatMap, map, switchMap } from 'rxjs/operators';
|
||||||
import { zip as observableZip, combineLatest as observableCombineLatest } from 'rxjs';
|
import { combineLatest as observableCombineLatest, zip as observableZip } from 'rxjs';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
|
||||||
import { RelationshipService } from '../../../../core/data/relationship.service';
|
|
||||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||||
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operator for comparing arrays using a mapping function
|
* Operator for comparing arrays using a mapping function
|
||||||
@@ -37,36 +35,6 @@ export const compareArraysUsing = <T>(mapFn: (t: T) => any) =>
|
|||||||
export const compareArraysUsingIds = <T extends { id: string }>() =>
|
export const compareArraysUsingIds = <T extends { id: string }>() =>
|
||||||
compareArraysUsing((t: T) => hasValue(t) ? t.id : undefined);
|
compareArraysUsing((t: T) => hasValue(t) ? t.id : undefined);
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch the relationships which match the type label given
|
|
||||||
* @param {string} label Type label
|
|
||||||
* @param thisId The item's id of which the relations belong to
|
|
||||||
* @returns {(source: Observable<[Relationship[] , RelationshipType[]]>) => Observable<Relationship[]>}
|
|
||||||
*/
|
|
||||||
export const filterRelationsByTypeLabel = (label: string, thisId?: string) =>
|
|
||||||
(source: Observable<[Relationship[], RelationshipType[]]>): Observable<Relationship[]> =>
|
|
||||||
source.pipe(
|
|
||||||
switchMap(([relsCurrentPage, relTypesCurrentPage]) => {
|
|
||||||
const relatedItems$ = observableZip(...relsCurrentPage.map((rel: Relationship) =>
|
|
||||||
observableCombineLatest(
|
|
||||||
rel.leftItem.pipe(getSucceededRemoteData(), getRemoteDataPayload()),
|
|
||||||
rel.rightItem.pipe(getSucceededRemoteData(), getRemoteDataPayload()))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return relatedItems$.pipe(
|
|
||||||
map((arr) => relsCurrentPage.filter((rel: Relationship, idx: number) =>
|
|
||||||
hasValue(relTypesCurrentPage[idx]) && (
|
|
||||||
(hasNoValue(thisId) && (relTypesCurrentPage[idx].leftwardType === label ||
|
|
||||||
relTypesCurrentPage[idx].rightwardType === label)) ||
|
|
||||||
(thisId === arr[idx][0].id && relTypesCurrentPage[idx].leftwardType === label) ||
|
|
||||||
(thisId === arr[idx][1].id && relTypesCurrentPage[idx].rightwardType === label)
|
|
||||||
)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
distinctUntilChanged(compareArraysUsingIds())
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operator for turning a list of relationships into a list of the relevant items
|
* Operator for turning a list of relationships into a list of the relevant items
|
||||||
* @param {string} thisId The item's id of which the relations belong to
|
* @param {string} thisId The item's id of which the relations belong to
|
||||||
@@ -128,17 +96,3 @@ export const paginatedRelationsToItems = (thisId: string) =>
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* Operator for fetching an item's relationships, but filtered by related item IDs (essentially performing a reverse lookup)
|
|
||||||
* Only relationships where leftItem or rightItem's ID is present in the list provided will be returned
|
|
||||||
* @param item
|
|
||||||
* @param relationshipService
|
|
||||||
*/
|
|
||||||
export const getRelationsByRelatedItemIds = (item: Item, relationshipService: RelationshipService) =>
|
|
||||||
(source: Observable<string[]>): Observable<Relationship[]> =>
|
|
||||||
source.pipe(
|
|
||||||
flatMap((relatedItemIds: string[]) => relationshipService.getItemResolvedRelatedItemsAndRelationships(item).pipe(
|
|
||||||
map(([leftItems, rightItems, rels]) => rels.filter((rel: Relationship, index: number) => relatedItemIds.indexOf(leftItems[index].uuid) > -1 || relatedItemIds.indexOf(rightItems[index].uuid) > -1))
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
@@ -9,7 +9,6 @@ import { MockTranslateLoader } from '../../../../shared/mocks/mock-translate-loa
|
|||||||
import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
import { TruncatePipe } from '../../../../shared/utils/truncate.pipe';
|
||||||
import { isNotEmpty } from '../../../../shared/empty.util';
|
import { isNotEmpty } from '../../../../shared/empty.util';
|
||||||
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
|
||||||
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model';
|
||||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||||
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
import { Relationship } from '../../../../core/shared/item-relationships/relationship.model';
|
||||||
@@ -24,6 +23,7 @@ import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-rep
|
|||||||
import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models';
|
import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models';
|
||||||
import { compareArraysUsing, compareArraysUsingIds } from './item-relationships-utils';
|
import { compareArraysUsing, compareArraysUsingIds } from './item-relationships-utils';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||||
|
import { RelationshipService } from '../../../../core/data/relationship.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a generic test for an item-page-fields component using a mockItem and the type of component
|
* Create a generic test for an item-page-fields component using a mockItem and the type of component
|
||||||
@@ -37,12 +37,6 @@ export function getItemPageFieldsTest(mockItem: Item, component) {
|
|||||||
let comp: any;
|
let comp: any;
|
||||||
let fixture: ComponentFixture<any>;
|
let fixture: ComponentFixture<any>;
|
||||||
|
|
||||||
const searchFixedFilterServiceStub = {
|
|
||||||
/* tslint:disable:no-empty */
|
|
||||||
getQueryByRelations: () => {}
|
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot({
|
imports: [TranslateModule.forRoot({
|
||||||
@@ -54,8 +48,8 @@ export function getItemPageFieldsTest(mockItem: Item, component) {
|
|||||||
declarations: [component, GenericItemPageFieldComponent, TruncatePipe],
|
declarations: [component, GenericItemPageFieldComponent, TruncatePipe],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ItemDataService, useValue: {}},
|
{provide: ItemDataService, useValue: {}},
|
||||||
{provide: SearchFixedFilterService, useValue: searchFixedFilterServiceStub},
|
{provide: TruncatableService, useValue: {}},
|
||||||
{provide: TruncatableService, useValue: {}}
|
{provide: RelationshipService, useValue: {}}
|
||||||
],
|
],
|
||||||
|
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Component, Inject, Input } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@@ -1,11 +1,20 @@
|
|||||||
<ds-metadata-field-wrapper *ngIf="representations$ && (representations$ | async)?.length > 0" [label]="label">
|
<ds-metadata-field-wrapper [label]="label">
|
||||||
<ds-metadata-representation-loader *ngFor="let rep of (representations$ | async)"
|
<ng-container *ngFor="let objectPage of objects; let i = index">
|
||||||
[mdRepresentation]="rep">
|
<ng-container *ngVar="(objectPage | async) as representations">
|
||||||
</ds-metadata-representation-loader>
|
<ds-metadata-representation-loader *ngFor="let rep of representations"
|
||||||
<div *ngIf="(representations$ | async)?.length < total" class="mt-2">
|
[mdRepresentation]="rep">
|
||||||
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' | translate}}</a>
|
</ds-metadata-representation-loader>
|
||||||
</div>
|
<ds-loading *ngIf="(i + 1) === objects.length && (i > 0) && (!representations || representations?.length === 0)" message="{{'loading.default' | translate}}"></ds-loading>
|
||||||
<div *ngIf="limit > originalLimit" class="mt-2">
|
<div class="d-inline-block w-100 mt-2" *ngIf="(i + 1) === objects.length && representations?.length > 0">
|
||||||
<a [routerLink]="" (click)="viewLess()">{{'item.page.related-items.view-less' | translate}}</a>
|
<div *ngIf="(objects.length * incrementBy) < total" class="float-left">
|
||||||
</div>
|
<a [routerLink]="" (click)="increase()">{{'item.page.related-items.view-more' |
|
||||||
|
translate:{ amount: (total - (objects.length * incrementBy) < incrementBy) ? total - (objects.length * incrementBy) : incrementBy } }}</a>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="objects.length > 1" class="float-right">
|
||||||
|
<a [routerLink]="" (click)="decrease()">{{'item.page.related-items.view-less' |
|
||||||
|
translate:{ amount: representations?.length } }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
</ds-metadata-field-wrapper>
|
</ds-metadata-field-wrapper>
|
||||||
|
@@ -7,6 +7,8 @@ import { Item } from '../../../core/shared/item.model';
|
|||||||
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
const itemType = 'Person';
|
const itemType = 'Person';
|
||||||
const metadataField = 'dc.contributor.author';
|
const metadataField = 'dc.contributor.author';
|
||||||
@@ -64,7 +66,7 @@ describe('MetadataRepresentationListComponent', () => {
|
|||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot()],
|
imports: [TranslateModule.forRoot()],
|
||||||
declarations: [MetadataRepresentationListComponent],
|
declarations: [MetadataRepresentationListComponent, VarDirective],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: RelationshipService, useValue: relationshipService }
|
{ provide: RelationshipService, useValue: relationshipService }
|
||||||
],
|
],
|
||||||
@@ -88,33 +90,29 @@ describe('MetadataRepresentationListComponent', () => {
|
|||||||
expect(fields.length).toBe(2);
|
expect(fields.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should initialize the original limit', () => {
|
it('should contain one page of items', () => {
|
||||||
expect(comp.originalLimit).toEqual(comp.limit);
|
expect(comp.objects.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when viewMore is called', () => {
|
describe('when increase is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
comp.viewMore();
|
comp.increase();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set the limit to a high number in order to retrieve all metadata representations', () => {
|
it('should add a new page to the list', () => {
|
||||||
expect(comp.limit).toBeGreaterThanOrEqual(999);
|
expect(comp.objects.length).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when viewLess is called', () => {
|
describe('when decrease is called', () => {
|
||||||
let originalLimit;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Store the original value of limit
|
// Add a second page
|
||||||
originalLimit = comp.limit;
|
comp.objects.push(observableOf(undefined));
|
||||||
// Set limit to a random number
|
comp.decrease();
|
||||||
comp.limit = 458;
|
|
||||||
comp.viewLess();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reset the limit to the original value', () => {
|
it('should decrease the list of pages', () => {
|
||||||
expect(comp.limit).toEqual(originalLimit);
|
expect(comp.objects.length).toEqual(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { MetadataRepresentation } from '../../../core/shared/metadata-representation/metadata-representation.model';
|
import { MetadataRepresentation } from '../../../core/shared/metadata-representation/metadata-representation.model';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { combineLatest as observableCombineLatest, Observable, of as observableOf, zip as observableZip } from 'rxjs';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
|
||||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
|
||||||
import { combineLatest as observableCombineLatest, of as observableOf, zip as observableZip } from 'rxjs';
|
|
||||||
import { MetadataValue } from '../../../core/shared/metadata.models';
|
import { MetadataValue } from '../../../core/shared/metadata.models';
|
||||||
import { MetadatumRepresentation } from '../../../core/shared/metadata-representation/metadatum/metadatum-representation.model';
|
|
||||||
import { filter, map, switchMap } from 'rxjs/operators';
|
|
||||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||||
|
import { filter, map, switchMap } from 'rxjs/operators';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
import { Relationship } from '../../../core/shared/item-relationships/relationship.model';
|
||||||
|
import { Item } from '../../../core/shared/item.model';
|
||||||
|
import { MetadatumRepresentation } from '../../../core/shared/metadata-representation/metadatum/metadatum-representation.model';
|
||||||
import { ItemMetadataRepresentation } from '../../../core/shared/metadata-representation/item/item-metadata-representation.model';
|
import { ItemMetadataRepresentation } from '../../../core/shared/metadata-representation/item/item-metadata-representation.model';
|
||||||
|
import { AbstractIncrementalListComponent } from '../abstract-incremental-list/abstract-incremental-list.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-metadata-representation-list',
|
selector: 'ds-metadata-representation-list',
|
||||||
@@ -22,7 +22,7 @@ import { ItemMetadataRepresentation } from '../../../core/shared/metadata-repres
|
|||||||
* It expects an itemType to resolve the metadata to a an item
|
* It expects an itemType to resolve the metadata to a an item
|
||||||
* It expects a label to put on top of the list
|
* It expects a label to put on top of the list
|
||||||
*/
|
*/
|
||||||
export class MetadataRepresentationListComponent implements OnInit {
|
export class MetadataRepresentationListComponent extends AbstractIncrementalListComponent<Observable<MetadataRepresentation[]>> {
|
||||||
/**
|
/**
|
||||||
* The parent of the list of related items to display
|
* The parent of the list of related items to display
|
||||||
*/
|
*/
|
||||||
@@ -44,22 +44,11 @@ export class MetadataRepresentationListComponent implements OnInit {
|
|||||||
@Input() label: string;
|
@Input() label: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The max amount of representations to display
|
* The amount to increment the list by when clicking "view more"
|
||||||
* Defaults to 10
|
* Defaults to 10
|
||||||
* The default can optionally be overridden by providing the limit as input to the component
|
* The default can optionally be overridden by providing the limit as input to the component
|
||||||
*/
|
*/
|
||||||
@Input() limit = 10;
|
@Input() incrementBy = 10;
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of metadata-representations to display
|
|
||||||
*/
|
|
||||||
representations$: Observable<MetadataRepresentation[]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The originally provided limit
|
|
||||||
* Used for resetting the limit to the original value when collapsing the list
|
|
||||||
*/
|
|
||||||
originalLimit: number;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The total amount of metadata values available
|
* The total amount of metadata values available
|
||||||
@@ -67,30 +56,28 @@ export class MetadataRepresentationListComponent implements OnInit {
|
|||||||
total: number;
|
total: number;
|
||||||
|
|
||||||
constructor(public relationshipService: RelationshipService) {
|
constructor(public relationshipService: RelationshipService) {
|
||||||
}
|
super();
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.originalLimit = this.limit;
|
|
||||||
this.setRepresentations();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the metadata representations
|
* Get a specific page
|
||||||
|
* @param page The page to fetch
|
||||||
*/
|
*/
|
||||||
setRepresentations() {
|
getPage(page: number): Observable<MetadataRepresentation[]> {
|
||||||
const metadata = this.parentItem.findMetadataSortedByPlace(this.metadataField);
|
const metadata = this.parentItem.findMetadataSortedByPlace(this.metadataField);
|
||||||
this.total = metadata.length;
|
this.total = metadata.length;
|
||||||
this.representations$ = this.resolveMetadataRepresentations(metadata);
|
return this.resolveMetadataRepresentations(metadata, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve a list of metadata values to a list of metadata representations
|
* Resolve a list of metadata values to a list of metadata representations
|
||||||
* @param metadata
|
* @param metadata The list of all metadata values
|
||||||
|
* @param page The page to return representations for
|
||||||
*/
|
*/
|
||||||
resolveMetadataRepresentations(metadata: MetadataValue[]): Observable<MetadataRepresentation[]> {
|
resolveMetadataRepresentations(metadata: MetadataValue[], page: number): Observable<MetadataRepresentation[]> {
|
||||||
return observableZip(
|
return observableZip(
|
||||||
...metadata
|
...metadata
|
||||||
.slice(0, this.limit)
|
.slice((this.objects.length * this.incrementBy), (this.objects.length * this.incrementBy) + this.incrementBy)
|
||||||
.map((metadatum: any) => Object.assign(new MetadataValue(), metadatum))
|
.map((metadatum: any) => Object.assign(new MetadataValue(), metadatum))
|
||||||
.map((metadatum: MetadataValue) => {
|
.map((metadatum: MetadataValue) => {
|
||||||
if (metadatum.isVirtual) {
|
if (metadatum.isVirtual) {
|
||||||
@@ -115,20 +102,4 @@ export class MetadataRepresentationListComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Expand the list to display all metadata representations
|
|
||||||
*/
|
|
||||||
viewMore() {
|
|
||||||
this.limit = 9999;
|
|
||||||
this.setRepresentations();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collapse the list to display the originally displayed metadata representations
|
|
||||||
*/
|
|
||||||
viewLess() {
|
|
||||||
this.limit = this.originalLimit;
|
|
||||||
this.setRepresentations();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
<ds-filtered-search-page
|
<ds-configuration-search-page
|
||||||
[fixedFilterQuery]="fixedFilter"
|
[fixedFilterQuery]="fixedFilter"
|
||||||
|
[configuration]="configuration"
|
||||||
[configuration$]="configuration$"
|
[configuration$]="configuration$"
|
||||||
[searchEnabled]="searchEnabled"
|
[searchEnabled]="searchEnabled"
|
||||||
[sideBarWidth]="sideBarWidth">
|
[sideBarWidth]="sideBarWidth">
|
||||||
</ds-filtered-search-page>
|
</ds-configuration-search-page>
|
||||||
|
@@ -4,31 +4,23 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
|||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
|
|
||||||
describe('RelatedEntitiesSearchComponent', () => {
|
describe('RelatedEntitiesSearchComponent', () => {
|
||||||
let comp: RelatedEntitiesSearchComponent;
|
let comp: RelatedEntitiesSearchComponent;
|
||||||
let fixture: ComponentFixture<RelatedEntitiesSearchComponent>;
|
let fixture: ComponentFixture<RelatedEntitiesSearchComponent>;
|
||||||
let fixedFilterService: SearchFixedFilterService;
|
|
||||||
|
|
||||||
const mockItem = Object.assign(new Item(), {
|
const mockItem = Object.assign(new Item(), {
|
||||||
id: 'id1'
|
id: 'id1'
|
||||||
});
|
});
|
||||||
const mockRelationType = 'publicationsOfAuthor';
|
const mockRelationType = 'publicationsOfAuthor';
|
||||||
const mockRelationEntityType = 'publication';
|
const mockConfiguration = 'publication';
|
||||||
const mockFilter= `f.${mockRelationType}=${mockItem.id}`;
|
const mockFilter= `f.${mockRelationType}=${mockItem.id}`;
|
||||||
const fixedFilterServiceStub = {
|
|
||||||
getFilterByRelation: () => mockFilter
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
||||||
declarations: [RelatedEntitiesSearchComponent],
|
declarations: [RelatedEntitiesSearchComponent],
|
||||||
providers: [
|
|
||||||
{ provide: SearchFixedFilterService, useValue: fixedFilterServiceStub }
|
|
||||||
],
|
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
@@ -36,10 +28,9 @@ describe('RelatedEntitiesSearchComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(RelatedEntitiesSearchComponent);
|
fixture = TestBed.createComponent(RelatedEntitiesSearchComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
fixedFilterService = (comp as any).fixedFilterService;
|
|
||||||
comp.relationType = mockRelationType;
|
comp.relationType = mockRelationType;
|
||||||
comp.item = mockItem;
|
comp.item = mockItem;
|
||||||
comp.relationEntityType = mockRelationEntityType;
|
comp.configuration = mockConfiguration;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -49,7 +40,7 @@ describe('RelatedEntitiesSearchComponent', () => {
|
|||||||
|
|
||||||
it('should create a configuration$', () => {
|
it('should create a configuration$', () => {
|
||||||
comp.configuration$.subscribe((configuration) => {
|
comp.configuration$.subscribe((configuration) => {
|
||||||
expect(configuration).toEqual(mockRelationEntityType);
|
expect(configuration).toEqual(mockConfiguration);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { SearchFixedFilterService } from '../../../../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
|
||||||
import { isNotEmpty } from '../../../../shared/empty.util';
|
import { isNotEmpty } from '../../../../shared/empty.util';
|
||||||
import { of } from 'rxjs/internal/observable/of';
|
import { of } from 'rxjs/internal/observable/of';
|
||||||
|
import { getFilterByRelation } from '../../../../shared/utils/relation-query.utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-related-entities-search',
|
selector: 'ds-related-entities-search',
|
||||||
@@ -22,18 +22,16 @@ export class RelatedEntitiesSearchComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
@Input() relationType: string;
|
@Input() relationType: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An optional configuration to use for the search options
|
||||||
|
*/
|
||||||
|
@Input() configuration: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item to render relationships for
|
* The item to render relationships for
|
||||||
*/
|
*/
|
||||||
@Input() item: Item;
|
@Input() item: Item;
|
||||||
|
|
||||||
/**
|
|
||||||
* The entity type of the relationship items to be displayed
|
|
||||||
* e.g. 'publication'
|
|
||||||
* This determines the title of the search results (if search is enabled)
|
|
||||||
*/
|
|
||||||
@Input() relationEntityType: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the search bar and title should be displayed (defaults to true)
|
* Whether or not the search bar and title should be displayed (defaults to true)
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
@@ -49,15 +47,12 @@ export class RelatedEntitiesSearchComponent implements OnInit {
|
|||||||
fixedFilter: string;
|
fixedFilter: string;
|
||||||
configuration$: Observable<string>;
|
configuration$: Observable<string>;
|
||||||
|
|
||||||
constructor(private fixedFilterService: SearchFixedFilterService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (isNotEmpty(this.relationType) && isNotEmpty(this.item)) {
|
if (isNotEmpty(this.relationType) && isNotEmpty(this.item)) {
|
||||||
this.fixedFilter = this.fixedFilterService.getFilterByRelation(this.relationType, this.item.id);
|
this.fixedFilter = getFilterByRelation(this.relationType, this.item.id);
|
||||||
}
|
}
|
||||||
if (isNotEmpty(this.relationEntityType)) {
|
if (isNotEmpty(this.configuration)) {
|
||||||
this.configuration$ = of(this.relationEntityType);
|
this.configuration$ = of(this.configuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,22 @@
|
|||||||
|
<ngb-tabset *ngIf="relationTypes.length > 1" [destroyOnHide]="true" #tabs="ngbTabset" [activeId]="activeTab$ | async" (tabChange)="onTabChange($event)">
|
||||||
|
<ngb-tab *ngFor="let relationType of relationTypes" title="{{'item.page.relationships.' + relationType.label | translate}}" [id]="relationType.filter">
|
||||||
|
<ng-template ngbTabContent>
|
||||||
|
<div class="mt-4">
|
||||||
|
<ds-related-entities-search [item]="item"
|
||||||
|
[relationType]="relationType.filter"
|
||||||
|
[configuration]="relationType.configuration"
|
||||||
|
[searchEnabled]="searchEnabled"
|
||||||
|
[sideBarWidth]="sideBarWidth">
|
||||||
|
</ds-related-entities-search>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-tab>
|
||||||
|
</ngb-tabset>
|
||||||
|
<div *ngIf="relationTypes.length === 1" class="mt-4">
|
||||||
|
<ds-related-entities-search *ngVar="relationTypes[0] as relationType" [item]="item"
|
||||||
|
[relationType]="relationType.filter"
|
||||||
|
[configuration]="relationType.configuration"
|
||||||
|
[searchEnabled]="searchEnabled"
|
||||||
|
[sideBarWidth]="sideBarWidth">
|
||||||
|
</ds-related-entities-search>
|
||||||
|
</div>
|
@@ -0,0 +1,82 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { TabbedRelatedEntitiesSearchComponent } from './tabbed-related-entities-search.component';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { MockRouter } from '../../../../shared/mocks/mock-router';
|
||||||
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { VarDirective } from '../../../../shared/utils/var.directive';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
|
describe('TabbedRelatedEntitiesSearchComponent', () => {
|
||||||
|
let comp: TabbedRelatedEntitiesSearchComponent;
|
||||||
|
let fixture: ComponentFixture<TabbedRelatedEntitiesSearchComponent>;
|
||||||
|
|
||||||
|
const mockItem = Object.assign(new Item(), {
|
||||||
|
id: 'id1'
|
||||||
|
});
|
||||||
|
const mockRelationType = 'publications';
|
||||||
|
const relationTypes = [
|
||||||
|
{
|
||||||
|
label: mockRelationType,
|
||||||
|
filter: mockRelationType
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const router = new MockRouter();
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [TranslateModule.forRoot(), NoopAnimationsModule, NgbModule.forRoot()],
|
||||||
|
declarations: [TabbedRelatedEntitiesSearchComponent, VarDirective],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: ActivatedRoute,
|
||||||
|
useValue: {
|
||||||
|
queryParams: observableOf({ tab: mockRelationType })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ provide: Router, useValue: router }
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(TabbedRelatedEntitiesSearchComponent);
|
||||||
|
comp = fixture.componentInstance;
|
||||||
|
comp.item = mockItem;
|
||||||
|
comp.relationTypes = relationTypes;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should initialize the activeTab depending on the current query parameters', () => {
|
||||||
|
comp.activeTab$.subscribe((activeTab) => {
|
||||||
|
expect(activeTab).toEqual(mockRelationType);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onTabChange', () => {
|
||||||
|
const event = {
|
||||||
|
currentId: mockRelationType,
|
||||||
|
nextId: 'nextTab'
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
comp.onTabChange(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call router natigate with the correct arguments', () => {
|
||||||
|
expect(router.navigate).toHaveBeenCalledWith([], {
|
||||||
|
relativeTo: (comp as any).route,
|
||||||
|
queryParams: {
|
||||||
|
tab: event.nextId
|
||||||
|
},
|
||||||
|
queryParamsHandling: 'merge'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@@ -0,0 +1,76 @@
|
|||||||
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-tabbed-related-entities-search',
|
||||||
|
templateUrl: './tabbed-related-entities-search.component.html'
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* A component to show related items as search results, split into tabs by relationship-type
|
||||||
|
* Related items can be facetted, or queried using an
|
||||||
|
* optional search box.
|
||||||
|
*/
|
||||||
|
export class TabbedRelatedEntitiesSearchComponent implements OnInit {
|
||||||
|
/**
|
||||||
|
* The types of relationships to fetch items for
|
||||||
|
* e.g. 'isAuthorOfPublication'
|
||||||
|
*/
|
||||||
|
@Input() relationTypes: Array<{
|
||||||
|
label: string,
|
||||||
|
filter: string,
|
||||||
|
configuration?: string
|
||||||
|
}>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The item to render relationships for
|
||||||
|
*/
|
||||||
|
@Input() item: Item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the search bar and title should be displayed (defaults to true)
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
@Input() searchEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ratio of the sidebar's width compared to the search results (1-12) (defaults to 4)
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
@Input() sideBarWidth = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The active tab
|
||||||
|
*/
|
||||||
|
activeTab$: Observable<string>;
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private router: Router) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the url contains a "tab" query parameter, set this tab to be the active tab
|
||||||
|
*/
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.activeTab$ = this.route.queryParams.pipe(
|
||||||
|
map((params) => params.tab)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a "tab" query parameter to the URL when changing tabs
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
onTabChange(event) {
|
||||||
|
this.router.navigate([], {
|
||||||
|
relativeTo: this.route,
|
||||||
|
queryParams: {
|
||||||
|
tab: event.nextId
|
||||||
|
},
|
||||||
|
queryParamsHandling: 'merge'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
import { Component, Input } from '@angular/core';
|
||||||
import { Item } from '../../../core/shared/item.model';
|
import { Item } from '../../../core/shared/item.model';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
import { FindListOptions } from '../../../core/data/request.models';
|
||||||
import { FindAllOptions } from '../../../core/data/request.models';
|
|
||||||
import { Subscription } from 'rxjs/internal/Subscription';
|
|
||||||
import { ViewMode } from '../../../core/shared/view-mode.model';
|
import { ViewMode } from '../../../core/shared/view-mode.model';
|
||||||
|
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||||
|
import { AbstractIncrementalListComponent } from '../abstract-incremental-list/abstract-incremental-list.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-related-items',
|
selector: 'ds-related-items',
|
||||||
@@ -17,7 +17,7 @@ import { ViewMode } from '../../../core/shared/view-mode.model';
|
|||||||
* This component is used for displaying relations between items
|
* This component is used for displaying relations between items
|
||||||
* It expects a parent item and relationship type, as well as a label to display on top
|
* It expects a parent item and relationship type, as well as a label to display on top
|
||||||
*/
|
*/
|
||||||
export class RelatedItemsComponent implements OnInit, OnDestroy {
|
export class RelatedItemsComponent extends AbstractIncrementalListComponent<Observable<RemoteData<PaginatedList<Item>>>> {
|
||||||
/**
|
/**
|
||||||
* The parent of the list of related items to display
|
* The parent of the list of related items to display
|
||||||
*/
|
*/
|
||||||
@@ -30,79 +30,38 @@ export class RelatedItemsComponent implements OnInit, OnDestroy {
|
|||||||
@Input() relationType: string;
|
@Input() relationType: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default options to start a search request with
|
* The amount to increment the list by when clicking "view more"
|
||||||
* Optional input, should you wish a different page size (or other options)
|
* Defaults to 5
|
||||||
|
* The default can optionally be overridden by providing the limit as input to the component
|
||||||
*/
|
*/
|
||||||
@Input() options = Object.assign(new FindAllOptions(), { elementsPerPage: 5 });
|
@Input() incrementBy = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default options to start a search request with
|
||||||
|
* Optional input
|
||||||
|
*/
|
||||||
|
@Input() options = new FindListOptions();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An i18n label to use as a title for the list (usually describes the relation)
|
* An i18n label to use as a title for the list (usually describes the relation)
|
||||||
*/
|
*/
|
||||||
@Input() label: string;
|
@Input() label: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Completely hide the component until there's at least one item visible
|
|
||||||
*/
|
|
||||||
@HostBinding('class.d-none') hidden = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of related items
|
|
||||||
*/
|
|
||||||
items$: Observable<RemoteData<PaginatedList<Item>>>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search options for displaying all elements in a list
|
|
||||||
*/
|
|
||||||
allOptions = Object.assign(new FindAllOptions(), { elementsPerPage: 9999 });
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The view-mode we're currently on
|
* The view-mode we're currently on
|
||||||
* @type {ElementViewMode}
|
* @type {ViewMode}
|
||||||
*/
|
*/
|
||||||
viewMode = ViewMode.ListElement;
|
viewMode = ViewMode.ListElement;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not the list is currently expanded to show all related items
|
|
||||||
*/
|
|
||||||
showingAll = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscription on items used to update the "hidden" property of this component
|
|
||||||
*/
|
|
||||||
itemSub: Subscription;
|
|
||||||
|
|
||||||
constructor(public relationshipService: RelationshipService) {
|
constructor(public relationshipService: RelationshipService) {
|
||||||
}
|
super();
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.items$ = this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, this.options);
|
|
||||||
this.itemSub = this.items$.subscribe((itemsRD: RemoteData<PaginatedList<Item>>) => {
|
|
||||||
this.hidden = !(itemsRD.hasSucceeded && itemsRD.payload && itemsRD.payload.page.length > 0);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand the list to display all related items
|
* Get a specific page
|
||||||
|
* @param page The page to fetch
|
||||||
*/
|
*/
|
||||||
viewMore() {
|
getPage(page: number): Observable<RemoteData<PaginatedList<Item>>> {
|
||||||
this.items$ = this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, this.allOptions);
|
return this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, Object.assign(this.options, { elementsPerPage: this.incrementBy, currentPage: page }));
|
||||||
this.showingAll = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collapse the list to display the originally displayed items
|
|
||||||
*/
|
|
||||||
viewLess() {
|
|
||||||
this.items$ = this.relationshipService.getRelatedItemsByLabel(this.parentItem, this.relationType, this.options);
|
|
||||||
this.showingAll = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe from the item subscription
|
|
||||||
*/
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
if (this.itemSub) {
|
|
||||||
this.itemSub.unsubscribe();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,20 @@
|
|||||||
<ds-metadata-field-wrapper *ngIf="(items$ | async)?.payload?.page?.length > 0" [label]="label">
|
<ds-metadata-field-wrapper [label]="label">
|
||||||
<ds-listable-object-component-loader *ngFor="let item of (items$ | async)?.payload?.page"
|
<ng-container *ngFor="let objectPage of objects; let i = index">
|
||||||
[object]="item" [viewMode]="viewMode">
|
<ng-container *ngVar="(objectPage | async) as itemsRD">
|
||||||
</ds-listable-object-component-loader>
|
<ds-listable-object-component-loader *ngFor="let item of itemsRD?.payload?.page"
|
||||||
<div *ngIf="(items$ | async)?.payload?.page?.length < (items$ | async)?.payload?.totalElements" class="mt-2" id="view-more">
|
[object]="item" [viewMode]="viewMode">
|
||||||
<a [routerLink]="" (click)="viewMore()">{{'item.page.related-items.view-more' | translate}}</a>
|
</ds-listable-object-component-loader>
|
||||||
</div>
|
<ds-loading *ngIf="(i + 1) === objects.length && (itemsRD || i > 0) && !(itemsRD?.hasSucceeded && itemsRD?.payload && itemsRD?.payload?.page?.length > 0)" message="{{'loading.default' | translate}}"></ds-loading>
|
||||||
<div *ngIf="showingAll" class="mt-2" id="view-less">
|
<div class="d-inline-block w-100 mt-2" *ngIf="(i + 1) === objects.length && itemsRD?.payload?.page?.length > 0">
|
||||||
<a [routerLink]="" (click)="viewLess()">{{'item.page.related-items.view-less' | translate}}</a>
|
<div *ngIf="itemsRD?.payload?.totalPages > objects.length" class="float-left" id="view-more">
|
||||||
</div>
|
<a [routerLink]="" (click)="increase()">{{'item.page.related-items.view-more' |
|
||||||
|
translate:{ amount: (itemsRD?.payload?.totalElements - (incrementBy * objects.length) < incrementBy) ? itemsRD?.payload?.totalElements - (incrementBy * objects.length) : incrementBy } }}</a>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="objects.length > 1" class="float-right" id="view-less">
|
||||||
|
<a [routerLink]="" (click)="decrease()">{{'item.page.related-items.view-less' |
|
||||||
|
translate:{ amount: itemsRD?.payload?.page?.length } }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
</ds-metadata-field-wrapper>
|
</ds-metadata-field-wrapper>
|
||||||
|
@@ -9,6 +9,8 @@ import { createRelationshipsObservable } from '../item-types/shared/item.compone
|
|||||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
||||||
import { RelationshipService } from '../../../core/data/relationship.service';
|
import { RelationshipService } from '../../../core/data/relationship.service';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
const parentItem: Item = Object.assign(new Item(), {
|
const parentItem: Item = Object.assign(new Item(), {
|
||||||
bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
bundles: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||||
@@ -42,7 +44,7 @@ describe('RelatedItemsComponent', () => {
|
|||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot()],
|
imports: [TranslateModule.forRoot()],
|
||||||
declarations: [RelatedItemsComponent],
|
declarations: [RelatedItemsComponent, VarDirective],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: RelationshipService, useValue: relationshipService }
|
{ provide: RelationshipService, useValue: relationshipService }
|
||||||
],
|
],
|
||||||
@@ -65,31 +67,33 @@ describe('RelatedItemsComponent', () => {
|
|||||||
expect(fields.length).toBe(mockItems.length);
|
expect(fields.length).toBe(mockItems.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when viewMore is called', () => {
|
it('should contain one page of items', () => {
|
||||||
|
expect(comp.objects.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when increase is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
comp.viewMore();
|
comp.increase();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call relationship-service\'s getRelatedItemsByLabel with the correct arguments', () => {
|
it('should add a new page to the list', () => {
|
||||||
expect(relationshipService.getRelatedItemsByLabel).toHaveBeenCalledWith(parentItem, relationType, comp.allOptions);
|
expect(comp.objects.length).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set showingAll to true', () => {
|
it('should call relationship-service\'s getRelatedItemsByLabel with the correct arguments (second page)', () => {
|
||||||
expect(comp.showingAll).toEqual(true);
|
expect(relationshipService.getRelatedItemsByLabel).toHaveBeenCalledWith(parentItem, relationType, Object.assign(comp.options, { elementsPerPage: comp.incrementBy, currentPage: 2 }));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when viewLess is called', () => {
|
describe('when decrease is called', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
comp.viewLess();
|
// Add a second page
|
||||||
|
comp.objects.push(observableOf(undefined));
|
||||||
|
comp.decrease();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call relationship-service\'s getRelatedItemsByLabel with the correct arguments', () => {
|
it('should decrease the list of pages', () => {
|
||||||
expect(relationshipService.getRelatedItemsByLabel).toHaveBeenCalledWith(parentItem, relationType, comp.options);
|
expect(comp.objects.length).toEqual(1);
|
||||||
});
|
|
||||||
|
|
||||||
it('should set showingAll to false', () => {
|
|
||||||
expect(comp.showingAll).toEqual(false);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import { of as observableOf } from 'rxjs';
|
import { of as observableOf } from 'rxjs';
|
||||||
|
|
||||||
import { MyDSpaceConfigurationService } from './my-dspace-configuration.service';
|
import { MyDSpaceConfigurationService } from './my-dspace-configuration.service';
|
||||||
import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
|
||||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||||
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
||||||
import { SearchFilter } from '../+search-page/search-filter.model';
|
import { SearchFilter } from '../shared/search/search-filter.model';
|
||||||
import { ActivatedRouteStub } from '../shared/testing/active-router-stub';
|
import { ActivatedRouteStub } from '../shared/testing/active-router-stub';
|
||||||
import { MockRoleService } from '../shared/mocks/mock-role-service';
|
import { MockRoleService } from '../shared/mocks/mock-role-service';
|
||||||
import { cold, hot } from 'jasmine-marbles';
|
import { cold, hot } from 'jasmine-marbles';
|
||||||
@@ -38,12 +38,8 @@ describe('MyDSpaceConfigurationService', () => {
|
|||||||
|
|
||||||
const roleService: any = new MockRoleService();
|
const roleService: any = new MockRoleService();
|
||||||
|
|
||||||
const fixedFilterService = jasmine.createSpyObj('SearchFixedFilterService', {
|
|
||||||
getQueryByFilterName: observableOf(''),
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
service = new MyDSpaceConfigurationService(roleService, fixedFilterService, spy, activatedRoute);
|
service = new MyDSpaceConfigurationService(roleService, spy, activatedRoute);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when the scope is called', () => {
|
describe('when the scope is called', () => {
|
||||||
|
@@ -6,12 +6,11 @@ import { first, map } from 'rxjs/operators';
|
|||||||
|
|
||||||
import { MyDSpaceConfigurationValueType } from './my-dspace-configuration-value-type';
|
import { MyDSpaceConfigurationValueType } from './my-dspace-configuration-value-type';
|
||||||
import { RoleService } from '../core/roles/role.service';
|
import { RoleService } from '../core/roles/role.service';
|
||||||
import { SearchConfigurationOption } from '../+search-page/search-switch-configuration/search-configuration-option.model';
|
import { SearchConfigurationOption } from '../shared/search/search-switch-configuration/search-configuration-option.model';
|
||||||
import { SearchConfigurationService } from '../+search-page/search-service/search-configuration.service';
|
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
|
||||||
import { RouteService } from '../core/services/route.service';
|
|
||||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||||
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
|
||||||
import { SearchFixedFilterService } from '../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
import { RouteService } from '../core/services/route.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that performs all actions that have to do with the current mydspace configuration
|
* Service that performs all actions that have to do with the current mydspace configuration
|
||||||
@@ -55,16 +54,14 @@ export class MyDSpaceConfigurationService extends SearchConfigurationService {
|
|||||||
* Initialize class
|
* Initialize class
|
||||||
*
|
*
|
||||||
* @param {roleService} roleService
|
* @param {roleService} roleService
|
||||||
* @param {SearchFixedFilterService} fixedFilterService
|
|
||||||
* @param {RouteService} routeService
|
* @param {RouteService} routeService
|
||||||
* @param {ActivatedRoute} route
|
* @param {ActivatedRoute} route
|
||||||
*/
|
*/
|
||||||
constructor(protected roleService: RoleService,
|
constructor(protected roleService: RoleService,
|
||||||
protected fixedFilterService: SearchFixedFilterService,
|
|
||||||
protected routeService: RouteService,
|
protected routeService: RouteService,
|
||||||
protected route: ActivatedRoute) {
|
protected route: ActivatedRoute) {
|
||||||
|
|
||||||
super(routeService, fixedFilterService, route);
|
super(routeService, route);
|
||||||
|
|
||||||
// override parent class initialization
|
// override parent class initialization
|
||||||
this._defaults = null;
|
this._defaults = null;
|
||||||
|
@@ -14,7 +14,7 @@ import { UploaderOptions } from '../../shared/uploader/uploader-options.model';
|
|||||||
import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
|
import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
|
||||||
import { NotificationType } from '../../shared/notifications/models/notification-type';
|
import { NotificationType } from '../../shared/notifications/models/notification-type';
|
||||||
import { hasValue } from '../../shared/empty.util';
|
import { hasValue } from '../../shared/empty.util';
|
||||||
import { SearchResult } from '../../+search-page/search-result.model';
|
import { SearchResult } from '../../shared/search/search-result.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component represents the whole mydspace page header
|
* This component represents the whole mydspace page header
|
||||||
@@ -33,12 +33,7 @@ export class MyDSpaceNewSubmissionComponent implements OnDestroy, OnInit {
|
|||||||
/**
|
/**
|
||||||
* The UploaderOptions object
|
* The UploaderOptions object
|
||||||
*/
|
*/
|
||||||
public uploadFilesOptions: UploaderOptions = {
|
public uploadFilesOptions: UploaderOptions = new UploaderOptions();
|
||||||
url: '',
|
|
||||||
authToken: null,
|
|
||||||
disableMultipart: false,
|
|
||||||
itemAlias: null
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscription to unsubscribe from
|
* Subscription to unsubscribe from
|
||||||
|
@@ -1 +1 @@
|
|||||||
@import '../+search-page/search-page.component.scss';
|
@import '../+search-page/search.component.scss';
|
||||||
|
@@ -19,15 +19,14 @@ import { MyDSpacePageComponent, SEARCH_CONFIG_SERVICE } from './my-dspace-page.c
|
|||||||
import { RouteService } from '../core/services/route.service';
|
import { RouteService } from '../core/services/route.service';
|
||||||
import { routeServiceStub } from '../shared/testing/route-service-stub';
|
import { routeServiceStub } from '../shared/testing/route-service-stub';
|
||||||
import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service-stub';
|
import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service-stub';
|
||||||
import { SearchService } from '../+search-page/search-service/search.service';
|
import { SearchService } from '../core/shared/search/search.service';
|
||||||
import { SearchConfigurationService } from '../+search-page/search-service/search-configuration.service';
|
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
|
||||||
import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
|
||||||
import { SidebarService } from '../shared/sidebar/sidebar.service';
|
import { SidebarService } from '../shared/sidebar/sidebar.service';
|
||||||
import { SearchFilterService } from '../+search-page/search-filters/search-filter/search-filter.service';
|
import { SearchFilterService } from '../core/shared/search/search-filter.service';
|
||||||
import { RoleDirective } from '../shared/roles/role.directive';
|
import { RoleDirective } from '../shared/roles/role.directive';
|
||||||
import { RoleService } from '../core/roles/role.service';
|
import { RoleService } from '../core/roles/role.service';
|
||||||
import { MockRoleService } from '../shared/mocks/mock-role-service';
|
import { MockRoleService } from '../shared/mocks/mock-role-service';
|
||||||
import { SearchFixedFilterService } from '../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../shared/testing/utils';
|
import { createSuccessfulRemoteDataObject$ } from '../shared/testing/utils';
|
||||||
|
|
||||||
describe('MyDSpacePageComponent', () => {
|
describe('MyDSpacePageComponent', () => {
|
||||||
@@ -82,8 +81,6 @@ describe('MyDSpacePageComponent', () => {
|
|||||||
collapse: () => this.isCollapsed = observableOf(true),
|
collapse: () => this.isCollapsed = observableOf(true),
|
||||||
expand: () => this.isCollapsed = observableOf(false)
|
expand: () => this.isCollapsed = observableOf(false)
|
||||||
};
|
};
|
||||||
const mockFixedFilterService: SearchFixedFilterService = {
|
|
||||||
} as SearchFixedFilterService;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@@ -123,10 +120,6 @@ describe('MyDSpacePageComponent', () => {
|
|||||||
provide: RoleService,
|
provide: RoleService,
|
||||||
useValue: new MockRoleService()
|
useValue: new MockRoleService()
|
||||||
},
|
},
|
||||||
{
|
|
||||||
provide: SearchFixedFilterService,
|
|
||||||
useValue: mockFixedFilterService
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
}).overrideComponent(MyDSpacePageComponent, {
|
}).overrideComponent(MyDSpacePageComponent, {
|
||||||
|
@@ -15,19 +15,19 @@ import { RemoteData } from '../core/data/remote-data';
|
|||||||
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
||||||
import { pushInOut } from '../shared/animations/push';
|
import { pushInOut } from '../shared/animations/push';
|
||||||
import { HostWindowService } from '../shared/host-window.service';
|
import { HostWindowService } from '../shared/host-window.service';
|
||||||
import { PaginatedSearchOptions } from '../+search-page/paginated-search-options.model';
|
import { PaginatedSearchOptions } from '../shared/search/paginated-search-options.model';
|
||||||
import { SearchService } from '../+search-page/search-service/search.service';
|
import { SearchService } from '../core/shared/search/search.service';
|
||||||
import { SidebarService } from '../shared/sidebar/sidebar.service';
|
import { SidebarService } from '../shared/sidebar/sidebar.service';
|
||||||
import { hasValue } from '../shared/empty.util';
|
import { hasValue } from '../shared/empty.util';
|
||||||
import { getSucceededRemoteData } from '../core/shared/operators';
|
import { getSucceededRemoteData } from '../core/shared/operators';
|
||||||
import { MyDSpaceResponseParsingService } from '../core/data/mydspace-response-parsing.service';
|
import { MyDSpaceResponseParsingService } from '../core/data/mydspace-response-parsing.service';
|
||||||
import { SearchConfigurationOption } from '../+search-page/search-switch-configuration/search-configuration-option.model';
|
import { SearchConfigurationOption } from '../shared/search/search-switch-configuration/search-configuration-option.model';
|
||||||
import { RoleType } from '../core/roles/role-types';
|
import { RoleType } from '../core/roles/role-types';
|
||||||
import { SearchConfigurationService } from '../+search-page/search-service/search-configuration.service';
|
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
|
||||||
import { MyDSpaceConfigurationService } from './my-dspace-configuration.service';
|
import { MyDSpaceConfigurationService } from './my-dspace-configuration.service';
|
||||||
import { ViewMode } from '../core/shared/view-mode.model';
|
import { ViewMode } from '../core/shared/view-mode.model';
|
||||||
import { MyDSpaceRequest } from '../core/data/request.models';
|
import { MyDSpaceRequest } from '../core/data/request.models';
|
||||||
import { SearchResult } from '../+search-page/search-result.model';
|
import { SearchResult } from '../shared/search/search-result.model';
|
||||||
import { Context } from '../core/shared/context.model';
|
import { Context } from '../core/shared/context.model';
|
||||||
|
|
||||||
export const MYDSPACE_ROUTE = '/mydspace';
|
export const MYDSPACE_ROUTE = '/mydspace';
|
||||||
|
@@ -5,7 +5,6 @@ import { SharedModule } from '../shared/shared.module';
|
|||||||
|
|
||||||
import { MyDspacePageRoutingModule } from './my-dspace-page-routing.module';
|
import { MyDspacePageRoutingModule } from './my-dspace-page-routing.module';
|
||||||
import { MyDSpacePageComponent } from './my-dspace-page.component';
|
import { MyDSpacePageComponent } from './my-dspace-page.component';
|
||||||
import { SearchPageModule } from '../+search-page/search-page.module';
|
|
||||||
import { MyDSpaceResultsComponent } from './my-dspace-results/my-dspace-results.component';
|
import { MyDSpaceResultsComponent } from './my-dspace-results/my-dspace-results.component';
|
||||||
import { WorkspaceItemSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workspace-item-search-result/workspace-item-search-result-list-element.component';
|
import { WorkspaceItemSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/workspace-item-search-result/workspace-item-search-result-list-element.component';
|
||||||
import { ClaimedSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component';
|
import { ClaimedSearchResultListElementComponent } from '../shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component';
|
||||||
@@ -27,7 +26,6 @@ import { PoolSearchResultDetailElementComponent } from '../shared/object-detail/
|
|||||||
CommonModule,
|
CommonModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
MyDspacePageRoutingModule,
|
MyDspacePageRoutingModule,
|
||||||
SearchPageModule
|
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
MyDSpacePageComponent,
|
MyDSpacePageComponent,
|
||||||
|
@@ -2,12 +2,12 @@ import { Component, Input } from '@angular/core';
|
|||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||||
import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
||||||
import { SearchOptions } from '../../+search-page/search-options.model';
|
import { SearchOptions } from '../../shared/search/search-options.model';
|
||||||
import { PaginatedList } from '../../core/data/paginated-list';
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
import { ViewMode } from '../../core/shared/view-mode.model';
|
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||||
import { isEmpty } from '../../shared/empty.util';
|
import { isEmpty } from '../../shared/empty.util';
|
||||||
import { SearchResult } from '../../+search-page/search-result.model';
|
|
||||||
import { Context } from '../../core/shared/context.model';
|
import { Context } from '../../core/shared/context.model';
|
||||||
|
import { SearchResult } from '../../shared/search/search-result.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that represents all results for mydspace page
|
* Component that represents all results for mydspace page
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { configureSearchComponentTestingModule } from './search-page.component.spec';
|
import { configureSearchComponentTestingModule } from './search.component.spec';
|
||||||
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
|
||||||
import { ConfigurationSearchPageComponent } from './configuration-search-page.component';
|
import { ConfigurationSearchPageComponent } from './configuration-search-page.component';
|
||||||
|
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
|
||||||
|
|
||||||
describe('ConfigurationSearchPageComponent', () => {
|
describe('ConfigurationSearchPageComponent', () => {
|
||||||
let comp: ConfigurationSearchPageComponent;
|
let comp: ConfigurationSearchPageComponent;
|
||||||
|
@@ -1,23 +1,22 @@
|
|||||||
import { HostWindowService } from '../shared/host-window.service';
|
import { HostWindowService } from '../shared/host-window.service';
|
||||||
import { SearchService } from './search-service/search.service';
|
|
||||||
import { SidebarService } from '../shared/sidebar/sidebar.service';
|
import { SidebarService } from '../shared/sidebar/sidebar.service';
|
||||||
import { SearchPageComponent } from './search-page.component';
|
import { SearchComponent } from './search.component';
|
||||||
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
|
||||||
import { pushInOut } from '../shared/animations/push';
|
import { pushInOut } from '../shared/animations/push';
|
||||||
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { PaginatedSearchOptions } from './paginated-search-options.model';
|
|
||||||
import { SEARCH_CONFIG_SERVICE } from '../+my-dspace-page/my-dspace-page.component';
|
import { SEARCH_CONFIG_SERVICE } from '../+my-dspace-page/my-dspace-page.component';
|
||||||
import { map } from 'rxjs/operators';
|
import { SearchConfigurationService } from '../core/shared/search/search-configuration.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { hasValue } from '../shared/empty.util';
|
||||||
import { RouteService } from '../core/services/route.service';
|
import { RouteService } from '../core/services/route.service';
|
||||||
|
import { SearchService } from '../core/shared/search/search.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component renders a search page using a configuration as input.
|
* This component renders a search page using a configuration as input.
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-configuration-search-page',
|
selector: 'ds-configuration-search-page',
|
||||||
styleUrls: ['./search-page.component.scss'],
|
styleUrls: ['./search.component.scss'],
|
||||||
templateUrl: './search-page.component.html',
|
templateUrl: './search.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
animations: [pushInOut],
|
animations: [pushInOut],
|
||||||
providers: [
|
providers: [
|
||||||
@@ -28,19 +27,26 @@ import { RouteService } from '../core/services/route.service';
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
export class ConfigurationSearchPageComponent extends SearchPageComponent implements OnInit {
|
export class ConfigurationSearchPageComponent extends SearchComponent implements OnInit {
|
||||||
/**
|
/**
|
||||||
* The configuration to use for the search options
|
* The configuration to use for the search options
|
||||||
* If empty, the configuration will be determined by the route parameter called 'configuration'
|
* If empty, the configuration will be determined by the route parameter called 'configuration'
|
||||||
*/
|
*/
|
||||||
@Input() configuration: string;
|
@Input() configuration: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual query for the fixed filter.
|
||||||
|
* If empty, the query will be determined by the route parameter called 'filter'
|
||||||
|
*/
|
||||||
|
@Input() fixedFilterQuery: string;
|
||||||
|
|
||||||
constructor(protected service: SearchService,
|
constructor(protected service: SearchService,
|
||||||
protected sidebarService: SidebarService,
|
protected sidebarService: SidebarService,
|
||||||
protected windowService: HostWindowService,
|
protected windowService: HostWindowService,
|
||||||
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
||||||
protected routeService: RouteService) {
|
protected routeService: RouteService,
|
||||||
super(service, sidebarService, windowService, searchConfigService, routeService);
|
protected router: Router) {
|
||||||
|
super(service, sidebarService, windowService, searchConfigService, routeService, router);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,20 +58,8 @@ export class ConfigurationSearchPageComponent extends SearchPageComponent implem
|
|||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
}
|
if (hasValue(this.configuration)) {
|
||||||
|
this.routeService.setParameter('configuration', this.configuration);
|
||||||
/**
|
}
|
||||||
* Get the current paginated search options after updating the configuration using the configuration input
|
|
||||||
* This is to make sure the configuration is included in the paginated search options, as it is not part of any
|
|
||||||
* query or route parameters
|
|
||||||
* @returns {Observable<PaginatedSearchOptions>}
|
|
||||||
*/
|
|
||||||
protected getSearchOptions(): Observable<PaginatedSearchOptions> {
|
|
||||||
return this.searchConfigService.paginatedSearchOptions.pipe(
|
|
||||||
map((options: PaginatedSearchOptions) => {
|
|
||||||
const config = this.configuration || options.configuration;
|
|
||||||
return Object.assign(options, { configuration: config });
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,21 +0,0 @@
|
|||||||
import { FilteredSearchPageComponent } from './filtered-search-page.component';
|
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { configureSearchComponentTestingModule } from './search-page.component.spec';
|
|
||||||
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
|
||||||
|
|
||||||
describe('FilteredSearchPageComponent', () => {
|
|
||||||
let comp: FilteredSearchPageComponent;
|
|
||||||
let fixture: ComponentFixture<FilteredSearchPageComponent>;
|
|
||||||
let searchConfigService: SearchConfigurationService;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
configureSearchComponentTestingModule(FilteredSearchPageComponent);
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(FilteredSearchPageComponent);
|
|
||||||
comp = fixture.componentInstance;
|
|
||||||
searchConfigService = (comp as any).searchConfigService;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,73 +0,0 @@
|
|||||||
import { HostWindowService } from '../shared/host-window.service';
|
|
||||||
import { SearchService } from './search-service/search.service';
|
|
||||||
import { SidebarService } from '../shared/sidebar/sidebar.service';
|
|
||||||
import { SearchPageComponent } from './search-page.component';
|
|
||||||
import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core';
|
|
||||||
import { pushInOut } from '../shared/animations/push';
|
|
||||||
import { SearchConfigurationService } from './search-service/search-configuration.service';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { PaginatedSearchOptions } from './paginated-search-options.model';
|
|
||||||
import { SEARCH_CONFIG_SERVICE } from '../+my-dspace-page/my-dspace-page.component';
|
|
||||||
import { map } from 'rxjs/operators';
|
|
||||||
import { RouteService } from '../core/services/route.service';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This component renders a simple item page.
|
|
||||||
* The route parameter 'id' is used to request the item it represents.
|
|
||||||
* All fields of the item that should be displayed, are defined in its template.
|
|
||||||
*/
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-filtered-search-page',
|
|
||||||
styleUrls: ['./search-page.component.scss'],
|
|
||||||
templateUrl: './search-page.component.html',
|
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
||||||
animations: [pushInOut],
|
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
provide: SEARCH_CONFIG_SERVICE,
|
|
||||||
useClass: SearchConfigurationService
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
export class FilteredSearchPageComponent extends SearchPageComponent implements OnInit {
|
|
||||||
/**
|
|
||||||
* The actual query for the fixed filter.
|
|
||||||
* If empty, the query will be determined by the route parameter called 'filter'
|
|
||||||
*/
|
|
||||||
@Input() fixedFilterQuery: string;
|
|
||||||
|
|
||||||
constructor(protected service: SearchService,
|
|
||||||
protected sidebarService: SidebarService,
|
|
||||||
protected windowService: HostWindowService,
|
|
||||||
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
|
|
||||||
protected routeService: RouteService) {
|
|
||||||
super(service, sidebarService, windowService, searchConfigService, routeService);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listening to changes in the paginated search options
|
|
||||||
* If something changes, update the search results
|
|
||||||
*
|
|
||||||
* Listen to changes in the scope
|
|
||||||
* If something changes, update the list of scopes for the dropdown
|
|
||||||
*/
|
|
||||||
ngOnInit(): void {
|
|
||||||
super.ngOnInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current paginated search options after updating the fixed filter using the fixedFilterQuery input
|
|
||||||
* This is to make sure the fixed filter is included in the paginated search options, as it is not part of any
|
|
||||||
* query or route parameters
|
|
||||||
* @returns {Observable<PaginatedSearchOptions>}
|
|
||||||
*/
|
|
||||||
protected getSearchOptions(): Observable<PaginatedSearchOptions> {
|
|
||||||
return this.searchConfigService.paginatedSearchOptions.pipe(
|
|
||||||
map((options: PaginatedSearchOptions) => {
|
|
||||||
const filter = this.fixedFilterQuery || options.fixedFilter;
|
|
||||||
return Object.assign(options, { fixedFilter: filter });
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,38 +0,0 @@
|
|||||||
import { SearchFixedFilterService } from './search-fixed-filter.service';
|
|
||||||
import { RequestService } from '../../../core/data/request.service';
|
|
||||||
import { of as observableOf } from 'rxjs';
|
|
||||||
import { RequestEntry } from '../../../core/data/request.reducer';
|
|
||||||
import { FilteredDiscoveryQueryResponse } from '../../../core/cache/response.models';
|
|
||||||
|
|
||||||
describe('SearchFixedFilterService', () => {
|
|
||||||
let service: SearchFixedFilterService;
|
|
||||||
|
|
||||||
const filterQuery = 'filter:query';
|
|
||||||
|
|
||||||
const requestServiceStub = Object.assign({
|
|
||||||
/* tslint:disable:no-empty */
|
|
||||||
configure: () => {
|
|
||||||
},
|
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
generateRequestId: () => 'fake-id',
|
|
||||||
getByHref: () => observableOf(Object.assign(new RequestEntry(), {
|
|
||||||
response: new FilteredDiscoveryQueryResponse(filterQuery, 200, 'OK')
|
|
||||||
}))
|
|
||||||
}) as RequestService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = new SearchFixedFilterService();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when getQueryByRelations is called', () => {
|
|
||||||
const relationType = 'isRelationOf';
|
|
||||||
const itemUUID = 'c5b277e6-2477-48bb-8993-356710c285f3';
|
|
||||||
|
|
||||||
it('should contain the relationType and itemUUID', () => {
|
|
||||||
const query = service.getQueryByRelations(relationType, itemUUID);
|
|
||||||
expect(query.length).toBeGreaterThan(relationType.length + itemUUID.length);
|
|
||||||
expect(query).toContain(relationType);
|
|
||||||
expect(query).toContain(itemUUID);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user