diff --git a/resources/i18n/en.json5 b/resources/i18n/en.json5 index c2ec3cbf30..df3f4dc8ca 100644 --- a/resources/i18n/en.json5 +++ b/resources/i18n/en.json5 @@ -170,6 +170,8 @@ + "admin.search.breadcrumbs": "Administrative Search", + "admin.search.collection.edit": "Edit", "admin.search.community.edit": "Edit", @@ -192,7 +194,7 @@ "admin.search.item.withdrawn": "Withdrawn", - "admin.search.title": "Admin Search", + "admin.search.title": "Administrative Search", @@ -1520,6 +1522,8 @@ "search.filters.applied.f.dateSubmitted": "Date submitted", + "search.filters.applied.f.discoverable": "Private", + "search.filters.applied.f.entityType": "Item Type", "search.filters.applied.f.has_content_in_original_bundle": "Has files", @@ -1531,10 +1535,15 @@ "search.filters.applied.f.subject": "Subject", "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", + "search.filters.applied.f.withdrawn": "Withdrawn", + "search.filters.filter.author.head": "Author", @@ -1571,6 +1580,10 @@ "search.filters.filter.dateSubmitted.placeholder": "Date submitted", + "search.filters.filter.discoverable.head": "Private", + + "search.filters.filter.withdrawn.head": "Withdrawn", + "search.filters.filter.entityType.head": "Item Type", "search.filters.filter.entityType.placeholder": "Item Type", @@ -1637,6 +1650,14 @@ "search.filters.has_content_in_original_bundle.false": "No", + "search.filters.discoverable.true": "No", + + "search.filters.discoverable.false": "Yes", + + "search.filters.withdrawn.true": "Yes", + + "search.filters.withdrawn.false": "No", + "search.filters.head": "Filters", @@ -2017,7 +2038,7 @@ "title": "DSpace", - "discoverableAndUndiscoverableItems.search.results.head": "Admin Search", + "discoverableAndUndiscoverableItems.search.results.head": "Administrative Search", "uploader.browse": "browse", diff --git a/src/app/+admin/admin-routing.module.ts b/src/app/+admin/admin-routing.module.ts index d750d22058..7864f91ad9 100644 --- a/src/app/+admin/admin-routing.module.ts +++ b/src/app/+admin/admin-routing.module.ts @@ -3,6 +3,7 @@ import { NgModule } from '@angular/core'; import { URLCombiner } from '../core/url-combiner/url-combiner'; import { getAdminModulePath } from '../app-routing.module'; import { AdminSearchPageComponent } from './admin-search-page/admin-search-page.component'; +import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; const REGISTRIES_MODULE_PATH = 'registries'; @@ -17,7 +18,7 @@ export function getRegistriesModulePath() { path: REGISTRIES_MODULE_PATH, loadChildren: './admin-registries/admin-registries.module#AdminRegistriesModule' }, - { path: 'search', component: AdminSearchPageComponent, data: { title: 'admin.search.title' } }, + { path: 'search', resolve: { breadcrumb: I18nBreadcrumbResolver }, component: AdminSearchPageComponent, data: { title: 'admin.search.title', breadcrumbKey: 'admin.search' } }, ]) ] }) diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 4cf5efae41..854a86b798 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,7 +3,6 @@ import { RouterModule } from '@angular/router'; import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component'; import { AuthenticatedGuard } from './core/auth/authenticated.guard'; -import { Breadcrumb } from './breadcrumbs/breadcrumb/breadcrumb.model'; import { DSpaceObject } from './core/shared/dspace-object.model'; import { Community } from './core/shared/community.model'; import { getCommunityPageRoute } from './+community-page/community-page-routing.module'; @@ -11,7 +10,6 @@ import { Collection } from './core/shared/collection.model'; import { Item } from './core/shared/item.model'; import { getItemPageRoute } from './+item-page/item-page-routing.module'; import { getCollectionPageRoute } from './+collection-page/collection-page-routing.module'; -import { BrowseByDSOBreadcrumbResolver } from './+browse-by/browse-by-dso-breadcrumb.resolver'; const ITEM_MODULE_PATH = 'items'; diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html index af339109c6..ce1d32c3a7 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-issue/journal-issue-search-result-grid-element.component.html @@ -1,6 +1,8 @@
- + +
@@ -32,5 +34,6 @@ class="lead btn btn-primary viewButton">View
+
diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html index 2c7f24662a..261d6dc004 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal-volume/journal-volume-search-result-grid-element.component.html @@ -1,36 +1,39 @@ - -
- -
- - -
-
- + +
+ + +
+ + +
+
+
-
- - -

+
+ + +

+
+

+ + -

- - - -

-

- - - -

-
- View -
+

+

+ + + +

+
+ View
- + +
+ diff --git a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html index d6b9c4a62e..435d9194c4 100644 --- a/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html +++ b/src/app/entity-groups/journal-entities/item-grid-elements/search-result-grid-elements/journal/journal-search-result-grid-element.component.html @@ -1,6 +1,8 @@ +
diff --git a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/org-unit/org-unit-search-result-grid-element.component.html b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/org-unit/org-unit-search-result-grid-element.component.html index 0fb1ec02f8..2a2e71b8ca 100644 --- a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/org-unit/org-unit-search-result-grid-element.component.html +++ b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/org-unit/org-unit-search-result-grid-element.component.html @@ -1,6 +1,8 @@
- + +
@@ -34,8 +36,9 @@

View + class="lead btn btn-primary viewButton">View
+
diff --git a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html index 321ecd4a47..93de2fd28e 100644 --- a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html +++ b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/person/person-search-result-grid-element.component.html @@ -1,5 +1,6 @@ +
diff --git a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html index c39de6bc2a..55aa9d5f0f 100644 --- a/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html +++ b/src/app/entity-groups/research-entities/item-grid-elements/search-result-grid-elements/project/project-search-result-grid-element.component.html @@ -1,6 +1,8 @@
- + +
@@ -27,5 +29,6 @@ class="lead btn btn-primary viewButton">View
+
diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.html b/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.html new file mode 100644 index 0000000000..db41da7c2c --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.html @@ -0,0 +1,11 @@ + + + + diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.scss b/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.spec.ts b/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.spec.ts new file mode 100644 index 0000000000..bd7aa841b8 --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.spec.ts @@ -0,0 +1,60 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { CollectionAdminSearchResultGridElementComponent } from './collection-admin-search-result-grid-element.component'; +import { TranslateModule } from '@ngx-translate/core'; +import { TruncatableService } from '../../../truncatable/truncatable.service'; +import { CollectionElementLinkType } from '../../../object-collection/collection-element-link.type'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { CollectionSearchResult } from '../../../object-collection/shared/collection-search-result.model'; +import { Collection } from '../../../../core/shared/collection.model'; +import { By } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; +import { getCollectionEditPath } from '../../../../+collection-page/collection-page-routing.module'; + +describe('CollectionAdminSearchResultListElementComponent', () => { + let component: CollectionAdminSearchResultGridElementComponent; + let fixture: ComponentFixture; + let id; + let searchResult; + + function init() { + id = '780b2588-bda5-4112-a1cd-0b15000a5339'; + searchResult = new CollectionSearchResult(); + searchResult.indexableObject = new Collection(); + searchResult.indexableObject.uuid = id; + } + beforeEach(async(() => { + init(); + TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot(), + RouterTestingModule.withRoutes([]) + ], + declarations: [CollectionAdminSearchResultGridElementComponent], + providers: [{ provide: TruncatableService, useValue: {} }], + schemas: [NO_ERRORS_SCHEMA] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CollectionAdminSearchResultGridElementComponent); + component = fixture.componentInstance; + component.object = searchResult; + component.linkTypes = CollectionElementLinkType; + component.index = 0; + component.viewModes = ViewMode; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should render an edit button with the correct link', () => { + const a = fixture.debugElement.query(By.css('a')); + const link = a.nativeElement.href; + expect(link).toContain(getCollectionEditPath(id)); + }) +}); diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.ts b/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.ts new file mode 100644 index 0000000000..8730c98b0e --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { listableObjectComponent } from '../../../object-collection/shared/listable-object/listable-object.decorator'; +import { Context } from '../../../../core/shared/context.model'; +import { CollectionSearchResult } from '../../../object-collection/shared/collection-search-result.model'; +import { Collection } from '../../../../core/shared/collection.model'; +import { getCollectionEditPath } from '../../../../+collection-page/collection-page-routing.module'; +import { SearchResultGridElementComponent } from '../../search-result-grid-element/search-result-grid-element.component'; + +@listableObjectComponent(CollectionSearchResult, ViewMode.GridElement, Context.AdminSearch) +@Component({ + selector: 'ds-collection-admin-search-result-list-element', + styleUrls: ['./collection-admin-search-result-grid-element.component.scss'], + templateUrl: './collection-admin-search-result-grid-element.component.html' +}) +/** + * The component for displaying a list element for a collection search result on the admin search page + */ +export class CollectionAdminSearchResultGridElementComponent extends SearchResultGridElementComponent { + + /** + * Returns the path to the edit page of this collection + */ + getEditPath(): string { + return getCollectionEditPath(this.dso.uuid) + } +} diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.html b/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.html new file mode 100644 index 0000000000..ca38804592 --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.html @@ -0,0 +1,11 @@ + + + + diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.scss b/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.spec.ts b/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.spec.ts new file mode 100644 index 0000000000..4d39d52017 --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.spec.ts @@ -0,0 +1,60 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { TranslateModule } from '@ngx-translate/core'; +import { TruncatableService } from '../../../truncatable/truncatable.service'; +import { CollectionElementLinkType } from '../../../object-collection/collection-element-link.type'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { Collection } from '../../../../core/shared/collection.model'; +import { By } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; +import { CommunityAdminSearchResultGridElementComponent } from './community-admin-search-result-grid-element.component'; +import { CommunitySearchResult } from '../../../object-collection/shared/community-search-result.model'; +import { getCommunityEditPath } from '../../../../+community-page/community-page-routing.module'; + +describe('CommunityAdminSearchResultListElementComponent', () => { + let component: CommunityAdminSearchResultGridElementComponent; + let fixture: ComponentFixture; + let id; + let searchResult; + + function init() { + id = '780b2588-bda5-4112-a1cd-0b15000a5339'; + searchResult = new CommunitySearchResult(); + searchResult.indexableObject = new Collection(); + searchResult.indexableObject.uuid = id; + } + beforeEach(async(() => { + init(); + TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot(), + RouterTestingModule.withRoutes([]) + ], + declarations: [CommunityAdminSearchResultGridElementComponent], + providers: [{ provide: TruncatableService, useValue: {} }], + schemas: [NO_ERRORS_SCHEMA] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CommunityAdminSearchResultGridElementComponent); + component = fixture.componentInstance; + component.object = searchResult; + component.linkTypes = CollectionElementLinkType; + component.index = 0; + component.viewModes = ViewMode; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should render an edit button with the correct link', () => { + const a = fixture.debugElement.query(By.css('a')); + const link = a.nativeElement.href; + expect(link).toContain(getCommunityEditPath(id)); + }) +}); diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.ts b/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.ts new file mode 100644 index 0000000000..becf0bc887 --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { listableObjectComponent } from '../../../object-collection/shared/listable-object/listable-object.decorator'; +import { Context } from '../../../../core/shared/context.model'; +import { CommunitySearchResult } from '../../../object-collection/shared/community-search-result.model'; +import { Community } from '../../../../core/shared/community.model'; +import { getCommunityEditPath } from '../../../../+community-page/community-page-routing.module'; +import { SearchResultGridElementComponent } from '../../search-result-grid-element/search-result-grid-element.component'; + +@listableObjectComponent(CommunitySearchResult, ViewMode.GridElement, Context.AdminSearch) +@Component({ + selector: 'ds-community-admin-search-result-grid-element', + styleUrls: ['./community-admin-search-result-grid-element.component.scss'], + templateUrl: './community-admin-search-result-grid-element.component.html' +}) +/** + * The component for displaying a list element for a community search result on the admin search page + */ +export class CommunityAdminSearchResultGridElementComponent extends SearchResultGridElementComponent { + + /** + * Returns the path to the edit page of this community + */ + getEditPath(): string { + return getCommunityEditPath(this.dso.uuid) + } +} diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.html b/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.html new file mode 100644 index 0000000000..54cbe7603a --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.html @@ -0,0 +1,39 @@ + + +
+
+ {{ "admin.search.item.private" | translate }} +
+
+ {{ "admin.search.item.withdrawn" | translate }} +
+
+ diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.scss b/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.spec.ts b/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.spec.ts new file mode 100644 index 0000000000..d9edb410c0 --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.spec.ts @@ -0,0 +1,120 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { TranslateModule } from '@ngx-translate/core'; +import { TruncatableService } from '../../../truncatable/truncatable.service'; +import { CollectionElementLinkType } from '../../../object-collection/collection-element-link.type'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { Collection } from '../../../../core/shared/collection.model'; +import { By } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; +import { ItemSearchResult } from '../../../object-collection/shared/item-search-result.model'; +import { ItemAdminSearchResultGridElementComponent } from './item-admin-search-result-grid-element.component'; +import { getItemEditPath } from '../../../../+item-page/item-page-routing.module'; +import { URLCombiner } from '../../../../core/url-combiner/url-combiner'; +import { ITEM_EDIT_DELETE_PATH, ITEM_EDIT_MOVE_PATH, ITEM_EDIT_REINSTATE_PATH, ITEM_EDIT_WITHDRAW_PATH } from '../../../../+item-page/edit-item-page/edit-item-page.routing.module'; + +describe('ItemAdminSearchResultListElementComponent', () => { + let component: ItemAdminSearchResultGridElementComponent; + let fixture: ComponentFixture; + let id; + let searchResult; + + function init() { + id = '780b2588-bda5-4112-a1cd-0b15000a5339'; + searchResult = new ItemSearchResult(); + searchResult.indexableObject = new Collection(); + searchResult.indexableObject.uuid = id; + } + beforeEach(async(() => { + init(); + TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot(), + RouterTestingModule.withRoutes([]) + ], + declarations: [ItemAdminSearchResultGridElementComponent], + providers: [{ provide: TruncatableService, useValue: {} }], + schemas: [NO_ERRORS_SCHEMA] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemAdminSearchResultGridElementComponent); + component = fixture.componentInstance; + component.object = searchResult; + component.linkTypes = CollectionElementLinkType; + component.index = 0; + component.viewModes = ViewMode; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should render an edit button with the correct link', () => { + const button = fixture.debugElement.query(By.css('a.edit-link')); + const link = button.nativeElement.href; + expect(link).toContain(getItemEditPath(id)); + }); + + it('should render a delete button with the correct link', () => { + const button = fixture.debugElement.query(By.css('a.delete-link')); + const link = button.nativeElement.href; + expect(link).toContain(new URLCombiner(getItemEditPath(id), ITEM_EDIT_DELETE_PATH).toString()); + }); + + it('should render a move button with the correct link', () => { + const a = fixture.debugElement.query(By.css('a.move-link')); + const link = a.nativeElement.href; + expect(link).toContain(new URLCombiner(getItemEditPath(id), ITEM_EDIT_MOVE_PATH).toString()); + }); + + describe('when the item is not withdrawn', () => { + beforeEach(() => { + component.dso.isWithdrawn = false; + fixture.detectChanges(); + }); + + it('should not show the withdrawn badge', () => { + const badge = fixture.debugElement.query(By.css('div.withdrawn-badge')); + expect(badge).toBeNull(); + }); + + it('should render a withdraw button with the correct link', () => { + const a = fixture.debugElement.query(By.css('a.withdraw-link')); + const link = a.nativeElement.href; + expect(link).toContain(new URLCombiner(getItemEditPath(id), ITEM_EDIT_WITHDRAW_PATH).toString()); + }); + + it('should not render a reinstate button with the correct link', () => { + const a = fixture.debugElement.query(By.css('a.reinstate-link')); + expect(a).toBeNull(); + }); + }); + + describe('when the item is withdrawn', () => { + beforeEach(() => { + component.dso.isWithdrawn = true; + fixture.detectChanges(); + }); + + it('should show the withdrawn badge', () => { + const badge = fixture.debugElement.query(By.css('div.withdrawn-badge')); + expect(badge).not.toBeNull(); + }); + + it('should render a withdraw button with the correct link', () => { + const a = fixture.debugElement.query(By.css('a.withdraw-link')); + expect(a).toBeNull(); + }); + + it('should not render a reinstate button with the correct link', () => { + const a = fixture.debugElement.query(By.css('a.reinstate-link')); + const link = a.nativeElement.href; + expect(link).toContain(new URLCombiner(getItemEditPath(id), ITEM_EDIT_REINSTATE_PATH).toString()); + }); + }) +}); diff --git a/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.ts b/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.ts new file mode 100644 index 0000000000..8ac4f3904c --- /dev/null +++ b/src/app/shared/object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.ts @@ -0,0 +1,124 @@ +import { Component, ComponentFactoryResolver, ElementRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; +import { Item } from '../../../../core/shared/item.model'; +import { ViewMode } from '../../../../core/shared/view-mode.model'; +import { getListableObjectComponent, listableObjectComponent } from '../../../object-collection/shared/listable-object/listable-object.decorator'; +import { Context } from '../../../../core/shared/context.model'; +import { ItemSearchResult } from '../../../object-collection/shared/item-search-result.model'; +import { getItemEditPath } from '../../../../+item-page/item-page-routing.module'; +import { URLCombiner } from '../../../../core/url-combiner/url-combiner'; +import { + ITEM_EDIT_DELETE_PATH, + ITEM_EDIT_MOVE_PATH, + ITEM_EDIT_PRIVATE_PATH, + ITEM_EDIT_PUBLIC_PATH, + ITEM_EDIT_REINSTATE_PATH, + ITEM_EDIT_WITHDRAW_PATH +} from '../../../../+item-page/edit-item-page/edit-item-page.routing.module'; +import { SearchResultGridElementComponent } from '../../search-result-grid-element/search-result-grid-element.component'; +import { TruncatableService } from '../../../truncatable/truncatable.service'; +import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; +import { GenericConstructor } from '../../../../core/shared/generic-constructor'; +import { ListableObjectDirective } from '../../../object-collection/shared/listable-object/listable-object.directive'; + +@listableObjectComponent(ItemSearchResult, ViewMode.GridElement, Context.AdminSearch) +@Component({ + selector: 'ds-item-admin-search-result-grid-element', + styleUrls: ['./item-admin-search-result-grid-element.component.scss'], + templateUrl: './item-admin-search-result-grid-element.component.html' +}) +/** + * The component for displaying a list element for an item search result on the admin search page + */ +export class ItemAdminSearchResultGridElementComponent extends SearchResultGridElementComponent implements OnInit { + @ViewChild(ListableObjectDirective, {static: true}) listableObjectDirective: ListableObjectDirective; + @ViewChild('badges', {static: true}) badges: ElementRef; + @ViewChild('buttons', {static: true}) buttons: ElementRef; + + constructor(protected truncatableService: TruncatableService, + protected bitstreamDataService: BitstreamDataService, + private componentFactoryResolver: ComponentFactoryResolver, + private viewContainerRef: ViewContainerRef) { + super(truncatableService, bitstreamDataService); + } + + /** + * Setup the dynamic child component + */ + ngOnInit(): void { + super.ngOnInit(); + const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.getComponent()); + + const viewContainerRef = this.listableObjectDirective.viewContainerRef; + viewContainerRef.clear(); + + const componentRef = viewContainerRef.createComponent( + componentFactory, + 0, + undefined, + [ + [this.badges.nativeElement], + [this.buttons.nativeElement] + ]); + (componentRef.instance as any).object = this.object; + (componentRef.instance as any).index = this.index; + (componentRef.instance as any).linkType = this.linkType; + (componentRef.instance as any).listID = this.listID; + } + + /** + * Fetch the component depending on the item's relationship type, view mode and context + * @returns {GenericConstructor} + */ + private getComponent(): GenericConstructor { + return getListableObjectComponent(this.object.getRenderTypes(), ViewMode.GridElement, undefined) + } + + /** + * Returns the path to the edit page of this item + */ + getEditPath(): string { + return getItemEditPath(this.dso.uuid) + } + + /** + * Returns the path to the move page of this item + */ + getMovePath(): string { + return new URLCombiner(this.getEditPath(), ITEM_EDIT_MOVE_PATH).toString(); + } + + /** + * Returns the path to the delete page of this item + */ + getDeletePath(): string { + return new URLCombiner(this.getEditPath(), ITEM_EDIT_DELETE_PATH).toString(); + } + + /** + * Returns the path to the withdraw page of this item + */ + getWithdrawPath(): string { + return new URLCombiner(this.getEditPath(), ITEM_EDIT_WITHDRAW_PATH).toString(); + } + + /** + * Returns the path to the reinstate page of this item + */ + getReinstatePath(): string { + return new URLCombiner(this.getEditPath(), ITEM_EDIT_REINSTATE_PATH).toString(); + } + + /** + * Returns the path to the page where the user can make this item private + */ + getPrivatePath(): string { + return new URLCombiner(this.getEditPath(), ITEM_EDIT_PRIVATE_PATH).toString(); + } + + /** + * Returns the path to the page where the user can make this item public + */ + getPublicPath(): string { + return new URLCombiner(this.getEditPath(), ITEM_EDIT_PUBLIC_PATH).toString(); + } +} diff --git a/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.html b/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.html index 0c45316e30..a2933fd0ec 100644 --- a/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.html +++ b/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.html @@ -14,4 +14,5 @@ View + diff --git a/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.html b/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.html index d0a9aa700e..8d5f288498 100644 --- a/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.html +++ b/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.html @@ -1,17 +1,18 @@
- - - - - + + + + + -
-

{{dso.name}}

-

{{dso.shortDescription}}

-
- View +
+

{{dso.name}}

+

{{dso.shortDescription}}

+
+ View +
-
+
diff --git a/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.html b/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.html index 41c16c6eab..0dfa7b8d34 100644 --- a/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.html +++ b/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.html @@ -1,5 +1,6 @@ +
diff --git a/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.ts b/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.ts index 76618f18f2..c96e73d365 100644 --- a/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.ts +++ b/src/app/shared/object-grid/search-result-grid-element/item-search-result/publication/publication-search-result-grid-element.component.ts @@ -7,6 +7,7 @@ import { Item } from '../../../../../core/shared/item.model'; import { ItemSearchResult } from '../../../../object-collection/shared/item-search-result.model'; @listableObjectComponent('PublicationSearchResult', ViewMode.GridElement) +@listableObjectComponent(ItemSearchResult, ViewMode.GridElement) @Component({ selector: 'ds-publication-search-result-grid-element', styleUrls: ['./publication-search-result-grid-element.component.scss'], diff --git a/src/app/shared/object-list/admin-search-result-list-element/collection-search-result/collection-admin-search-result-list-element.component.html b/src/app/shared/object-list/admin-search-result-list-element/collection-search-result/collection-admin-search-result-list-element.component.html index 8cf98b6680..78bb8a3e67 100644 --- a/src/app/shared/object-list/admin-search-result-list-element/collection-search-result/collection-admin-search-result-list-element.component.html +++ b/src/app/shared/object-list/admin-search-result-list-element/collection-search-result/collection-admin-search-result-list-element.component.html @@ -1,8 +1,9 @@ - - - {{"admin.search.collection.edit" | translate}} - + + diff --git a/src/app/shared/object-list/admin-search-result-list-element/community-search-result/community-admin-search-result-list-element.component.html b/src/app/shared/object-list/admin-search-result-list-element/community-search-result/community-admin-search-result-list-element.component.html index 43917e0399..9333edbc55 100644 --- a/src/app/shared/object-list/admin-search-result-list-element/community-search-result/community-admin-search-result-list-element.component.html +++ b/src/app/shared/object-list/admin-search-result-list-element/community-search-result/community-admin-search-result-list-element.component.html @@ -1,8 +1,9 @@ - - - {{"admin.search.community.edit" | translate}} - + + diff --git a/src/app/shared/object-list/admin-search-result-list-element/item-search-result/item-admin-search-result-list-element.component.html b/src/app/shared/object-list/admin-search-result-list-element/item-search-result/item-admin-search-result-list-element.component.html index 5730e3f859..83c769ae0a 100644 --- a/src/app/shared/object-list/admin-search-result-list-element/item-search-result/item-admin-search-result-list-element.component.html +++ b/src/app/shared/object-list/admin-search-result-list-element/item-search-result/item-admin-search-result-list-element.component.html @@ -10,30 +10,30 @@ [linkType]="linkType" [listID]="listID"> - + {{"admin.search.item.edit" | translate}} - + {{"admin.search.item.withdraw" | translate}} - + {{"admin.search.item.reinstate" | translate}} - + {{"admin.search.item.make-private" | translate}} - + {{"admin.search.item.make-public" | translate}} - + {{"admin.search.item.delete" | translate}} - + {{"admin.search.item.move" | translate}} diff --git a/src/app/shared/search/search-filter.model.ts b/src/app/shared/search/search-filter.model.ts index 9e93bafed8..ee55bec242 100644 --- a/src/app/shared/search/search-filter.model.ts +++ b/src/app/shared/search/search-filter.model.ts @@ -1,7 +1,6 @@ /** * Represents a search filter */ -import { hasValue } from '../empty.util'; export class SearchFilter { key: string; @@ -11,10 +10,6 @@ export class SearchFilter { constructor(key: string, values: string[], operator?: string) { this.key = key; this.values = values; - if (hasValue(operator)) { - this.operator = operator; - } else { - this.operator = 'query'; - } + this.operator = operator; } } diff --git a/src/app/shared/search/search-options.model.ts b/src/app/shared/search/search-options.model.ts index a8b115abd3..7d5f4dd207 100644 --- a/src/app/shared/search/search-options.model.ts +++ b/src/app/shared/search/search-options.model.ts @@ -50,7 +50,7 @@ export class SearchOptions { if (isNotEmpty(this.filters)) { this.filters.forEach((filter: SearchFilter) => { filter.values.forEach((value) => { - const filterValue = value.includes(',') ? `${value}` : `${value},${filter.operator}`; + const filterValue = value.includes(',') ? `${value}` : value + (filter.operator ? ',' + filter.operator : ''); args.push(`${filter.key}=${filterValue}`) }); }); diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c5bfb4e81a..84738559ee 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -181,6 +181,9 @@ import { ItemAdminSearchResultListElementComponent } from './object-list/admin-s import { CommunityAdminSearchResultListElementComponent } from './object-list/admin-search-result-list-element/community-search-result/community-admin-search-result-list-element.component'; import { CollectionAdminSearchResultListElementComponent } from './object-list/admin-search-result-list-element/collection-search-result/collection-admin-search-result-list-element.component'; import { MissingTranslationHelper } from './translate/missing-translation.helper'; +import { ItemAdminSearchResultGridElementComponent } from './object-grid/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component'; +import { CommunityAdminSearchResultGridElementComponent } from './object-grid/admin-search-result-grid-element/community-search-result/community-admin-search-result-grid-element.component'; +import { CollectionAdminSearchResultGridElementComponent } from './object-grid/admin-search-result-grid-element/collection-search-result/collection-admin-search-result-grid-element.component'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -347,11 +350,13 @@ const COMPONENTS = [ ExternalSourceEntryImportModalComponent, ImportableListItemControlComponent, ExistingMetadataListElementComponent, + PublicationSearchResultListElementComponent, ItemAdminSearchResultListElementComponent, CommunityAdminSearchResultListElementComponent, CollectionAdminSearchResultListElementComponent, - PublicationSearchResultListElementComponent, - ExistingMetadataListElementComponent + ItemAdminSearchResultGridElementComponent, + CommunityAdminSearchResultGridElementComponent, + CollectionAdminSearchResultGridElementComponent ]; const ENTRY_COMPONENTS = [ @@ -418,6 +423,9 @@ const ENTRY_COMPONENTS = [ ItemAdminSearchResultListElementComponent, CommunityAdminSearchResultListElementComponent, CollectionAdminSearchResultListElementComponent, + ItemAdminSearchResultGridElementComponent, + CommunityAdminSearchResultGridElementComponent, + CollectionAdminSearchResultGridElementComponent ]; const SHARED_ITEM_PAGE_COMPONENTS = [ diff --git a/src/app/shared/translate/missing-translation.helper.ts b/src/app/shared/translate/missing-translation.helper.ts index cac984ecd5..f071652cef 100644 --- a/src/app/shared/translate/missing-translation.helper.ts +++ b/src/app/shared/translate/missing-translation.helper.ts @@ -1,4 +1,4 @@ -import {MissingTranslationHandler, MissingTranslationHandlerParams} from '@ngx-translate/core'; +import { MissingTranslationHandler, MissingTranslationHandlerParams } from '@ngx-translate/core'; export class MissingTranslationHelper implements MissingTranslationHandler { handle(params: MissingTranslationHandlerParams) {