diff --git a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html
index d2454b28e6..035e6041a6 100644
--- a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html
+++ b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.html
@@ -17,7 +17,7 @@
-
+
diff --git a/src/app/shared/object-list/badges/badges.component.html b/src/app/shared/object-list/badges/badges.component.html
new file mode 100644
index 0000000000..2a5704970c
--- /dev/null
+++ b/src/app/shared/object-list/badges/badges.component.html
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/app/shared/object-list/badges/badges.component.scss b/src/app/shared/object-list/badges/badges.component.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/app/shared/object-list/badges/badges.component.spec.ts b/src/app/shared/object-list/badges/badges.component.spec.ts
new file mode 100644
index 0000000000..1ca24639f8
--- /dev/null
+++ b/src/app/shared/object-list/badges/badges.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BadgesComponent } from './badges.component';
+
+describe('BadgesComponent', () => {
+ let component: BadgesComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ BadgesComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(BadgesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/shared/object-list/badges/badges.component.ts b/src/app/shared/object-list/badges/badges.component.ts
new file mode 100644
index 0000000000..31baba1d2c
--- /dev/null
+++ b/src/app/shared/object-list/badges/badges.component.ts
@@ -0,0 +1,11 @@
+import { Component, Input } from '@angular/core';
+import { DSpaceObject } from '../../../core/shared/dspace-object.model';
+
+@Component({
+ selector: 'ds-badges',
+ templateUrl: './badges.component.html',
+ styleUrls: ['./badges.component.scss']
+})
+export class BadgesComponent {
+ @Input() object: DSpaceObject;
+}
diff --git a/src/app/shared/object-list/badges/status-badge/status-badge.component.html b/src/app/shared/object-list/badges/status-badge/status-badge.component.html
new file mode 100644
index 0000000000..1f28aedf34
--- /dev/null
+++ b/src/app/shared/object-list/badges/status-badge/status-badge.component.html
@@ -0,0 +1,6 @@
+
+ {{ "item.badge.private" | translate }}
+
+
+ {{ "item.badge.withdrawn" | translate }}
+
diff --git a/src/app/shared/object-list/badges/status-badge/status-badge.component.spec.ts b/src/app/shared/object-list/badges/status-badge/status-badge.component.spec.ts
new file mode 100644
index 0000000000..09bc7ea585
--- /dev/null
+++ b/src/app/shared/object-list/badges/status-badge/status-badge.component.spec.ts
@@ -0,0 +1,78 @@
+import { Item } from '../../../../core/shared/item.model';
+import { of as observableOf } from 'rxjs';
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { TranslateModule } from '@ngx-translate/core';
+import { TruncatePipe } from '../../../utils/truncate.pipe';
+import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
+import { By } from '@angular/platform-browser';
+import { StatusBadgeComponent } from './status-badge.component';
+
+let comp: StatusBadgeComponent;
+let fixture: ComponentFixture;
+
+const type = 'authorOfPublication';
+
+const mockItemWithEntityType = Object.assign(new Item(), {
+ bundles: observableOf({}),
+ metadata: {
+ 'dspace.entity.type': [
+ {
+ language: 'en_US',
+ value: type
+ }
+ ]
+ }
+});
+
+const mockItemWithoutEntityType = Object.assign(new Item(), {
+ bundles: observableOf({}),
+ metadata: {
+ 'dc.title': [
+ {
+ language: 'en_US',
+ value: 'This is just another title'
+ }
+ ]
+ }
+});
+
+describe('ItemTypeBadgeComponent', () => {
+ beforeEach(waitForAsync(() => {
+ TestBed.configureTestingModule({
+ imports: [TranslateModule.forRoot()],
+ declarations: [StatusBadgeComponent, TruncatePipe],
+ schemas: [NO_ERRORS_SCHEMA]
+ }).overrideComponent(StatusBadgeComponent, {
+ set: { changeDetection: ChangeDetectionStrategy.Default }
+ }).compileComponents();
+ }));
+
+ beforeEach(waitForAsync(() => {
+ fixture = TestBed.createComponent(StatusBadgeComponent);
+ comp = fixture.componentInstance;
+ }));
+
+ describe('When the item has an entity type', () => {
+ beforeEach(() => {
+ comp.object = mockItemWithEntityType;
+ fixture.detectChanges();
+ });
+
+ it('should show the entity type badge', () => {
+ const badge = fixture.debugElement.query(By.css('span.badge'));
+ expect(badge.nativeElement.textContent).toContain(type.toLowerCase());
+ });
+ });
+
+ describe('When the item has no entity type', () => {
+ beforeEach(() => {
+ comp.object = mockItemWithoutEntityType;
+ fixture.detectChanges();
+ });
+
+ it('should show an item badge', () => {
+ const badge = fixture.debugElement.query(By.css('span.badge'));
+ expect(badge.nativeElement.textContent).toContain('item');
+ });
+ });
+});
diff --git a/src/app/shared/object-list/badges/status-badge/status-badge.component.ts b/src/app/shared/object-list/badges/status-badge/status-badge.component.ts
new file mode 100644
index 0000000000..7f52741c51
--- /dev/null
+++ b/src/app/shared/object-list/badges/status-badge/status-badge.component.ts
@@ -0,0 +1,41 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
+import { hasValue } from '../../../empty.util';
+
+@Component({
+ selector: 'ds-status-badge',
+ templateUrl: './status-badge.component.html'
+})
+/**
+ * Component rendering the status of an item as a badge
+ */
+export class StatusBadgeComponent implements OnInit {
+
+ /**
+ * The component used to retrieve the status from
+ */
+ @Input() object: DSpaceObject;
+
+ /**
+ * Whether or not the "Private" badge should be displayed for this listable object
+ */
+ privateBadge = false;
+
+ /**
+ * Whether or not the "Withdrawn" badge should be displayed for this listable object
+ */
+ withdrawnBadge = false;
+
+ /**
+ * Initialize which badges should be visible
+ */
+ ngOnInit(): void {
+ let objectAsAny = this.object as any;
+ if (hasValue(objectAsAny.indexableObject)) {
+ objectAsAny = objectAsAny.indexableObject;
+ }
+ const objectExists = hasValue(objectAsAny);
+ this.privateBadge = objectExists && hasValue(objectAsAny.isDiscoverable) && !objectAsAny.isDiscoverable;
+ this.withdrawnBadge = objectExists && hasValue(objectAsAny.isWithdrawn) && objectAsAny.isWithdrawn;
+ }
+}
diff --git a/src/app/shared/object-list/badges/status-badge/themed-status-badge.component.ts b/src/app/shared/object-list/badges/status-badge/themed-status-badge.component.ts
new file mode 100644
index 0000000000..d855fda555
--- /dev/null
+++ b/src/app/shared/object-list/badges/status-badge/themed-status-badge.component.ts
@@ -0,0 +1,31 @@
+import { Component, Input } from '@angular/core';
+import { ThemedComponent } from '../../../theme-support/themed.component';
+import { StatusBadgeComponent } from './status-badge.component';
+import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
+import { TypeBadgeComponent } from '../type-badge/type-badge.component';
+
+/**
+ * Themed wrapper for StatusBadgeComponent
+ */
+@Component({
+ selector: 'ds-themed-status-badge',
+ styleUrls: [],
+ templateUrl: '../../../../shared/theme-support/themed.component.html',
+})
+export class ThemedStatusBadgeComponent extends ThemedComponent {
+ @Input() object: DSpaceObject;
+
+ protected inAndOutputNames: (keyof StatusBadgeComponent & keyof this)[] = ['object'];
+
+ protected getComponentName(): string {
+ return 'StatusBadgeComponent';
+ }
+
+ protected importThemedComponent(themeName: string): Promise {
+ return import(`../../../../../themes/${themeName}/app/shared/object-list/badges/status-badge/status-badge.component`);
+ }
+
+ protected importUnthemedComponent(): Promise {
+ return import(`./status-badge.component`);
+ }
+}
diff --git a/src/app/shared/object-list/badges/themed-badges.component.ts b/src/app/shared/object-list/badges/themed-badges.component.ts
new file mode 100644
index 0000000000..8682e33e2e
--- /dev/null
+++ b/src/app/shared/object-list/badges/themed-badges.component.ts
@@ -0,0 +1,32 @@
+import { Component, Input } from '@angular/core';
+import { BadgesComponent } from './badges.component';
+import { ThemedComponent } from '../../theme-support/themed.component';
+import { Observable } from 'rxjs/internal/Observable';
+import { SearchFiltersComponent } from '../../search/search-filters/search-filters.component';
+import { DSpaceObject } from '../../../core/shared/dspace-object.model';
+
+/**
+ * Themed wrapper for BadgesComponent
+ */
+@Component({
+ selector: 'ds-themed-badges',
+ styleUrls: [],
+ templateUrl: '../../../shared/theme-support/themed.component.html',
+})
+export class ThemedBadgesComponent extends ThemedComponent {
+ @Input() object: DSpaceObject;
+
+ protected inAndOutputNames: (keyof BadgesComponent & keyof this)[] = ['object'];
+
+ protected getComponentName(): string {
+ return 'BadgesComponent';
+ }
+
+ protected importThemedComponent(themeName: string): Promise {
+ return import(`../../../../themes/${themeName}/app/shared/object-list/badges/badges.component`);
+ }
+
+ protected importUnthemedComponent(): Promise {
+ return import(`./badges.component`);
+ }
+}
diff --git a/src/app/shared/object-list/badges/type-badge/themed-type-badge.component.ts b/src/app/shared/object-list/badges/type-badge/themed-type-badge.component.ts
new file mode 100644
index 0000000000..58e56dbe88
--- /dev/null
+++ b/src/app/shared/object-list/badges/type-badge/themed-type-badge.component.ts
@@ -0,0 +1,31 @@
+import { Component, Input } from '@angular/core';
+import { ThemedComponent } from '../../../theme-support/themed.component';
+import { TypeBadgeComponent } from './type-badge.component';
+import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
+import { BadgesComponent } from '../badges.component';
+
+/**
+ * Themed wrapper for TypeBadgeComponent
+ */
+@Component({
+ selector: 'ds-themed-type-badge',
+ styleUrls: [],
+ templateUrl: '../../../../shared/theme-support/themed.component.html',
+})
+export class ThemedTypeBadgeComponent extends ThemedComponent {
+ @Input() object: DSpaceObject;
+
+ protected inAndOutputNames: (keyof TypeBadgeComponent & keyof this)[] = ['object'];
+
+ protected getComponentName(): string {
+ return 'TypeBadgeComponent';
+ }
+
+ protected importThemedComponent(themeName: string): Promise {
+ return import(`../../../../../themes/${themeName}/app/shared/object-list/badges/type-badge/type-badge.component`);
+ }
+
+ protected importUnthemedComponent(): Promise {
+ return import(`./type-badge.component`);
+ }
+}
diff --git a/src/app/shared/object-list/type-badge/type-badge.component.html b/src/app/shared/object-list/badges/type-badge/type-badge.component.html
similarity index 66%
rename from src/app/shared/object-list/type-badge/type-badge.component.html
rename to src/app/shared/object-list/badges/type-badge/type-badge.component.html
index 0c2bd7544e..119702c375 100644
--- a/src/app/shared/object-list/type-badge/type-badge.component.html
+++ b/src/app/shared/object-list/badges/type-badge/type-badge.component.html
@@ -1,3 +1,3 @@
-
+
{{ typeMessage | translate }}
-
+
diff --git a/src/app/shared/object-list/type-badge/type-badge.component.spec.ts b/src/app/shared/object-list/badges/type-badge/type-badge.component.spec.ts
similarity index 94%
rename from src/app/shared/object-list/type-badge/type-badge.component.spec.ts
rename to src/app/shared/object-list/badges/type-badge/type-badge.component.spec.ts
index 9a7e22c551..21c12ec372 100644
--- a/src/app/shared/object-list/type-badge/type-badge.component.spec.ts
+++ b/src/app/shared/object-list/badges/type-badge/type-badge.component.spec.ts
@@ -1,8 +1,8 @@
-import { Item } from '../../../core/shared/item.model';
+import { Item } from '../../../../core/shared/item.model';
import { of as observableOf } from 'rxjs';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
-import { TruncatePipe } from '../../utils/truncate.pipe';
+import { TruncatePipe } from '../../../utils/truncate.pipe';
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';
import { TypeBadgeComponent } from './type-badge.component';
diff --git a/src/app/shared/object-list/type-badge/type-badge.component.ts b/src/app/shared/object-list/badges/type-badge/type-badge.component.ts
similarity index 84%
rename from src/app/shared/object-list/type-badge/type-badge.component.ts
rename to src/app/shared/object-list/badges/type-badge/type-badge.component.ts
index 8e843af1e7..2fba2515a9 100644
--- a/src/app/shared/object-list/type-badge/type-badge.component.ts
+++ b/src/app/shared/object-list/badges/type-badge/type-badge.component.ts
@@ -1,7 +1,7 @@
import { Component, Input } from '@angular/core';
-import { DSpaceObject } from '../../../core/shared/dspace-object.model';
-import { hasValue, isEmpty } from '../../empty.util';
-import { getResourceTypeValueFor } from '../../../core/cache/object-cache.reducer';
+import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
+import { hasValue, isEmpty } from '../../../empty.util';
+import { getResourceTypeValueFor } from '../../../../core/cache/object-cache.reducer';
@Component({
selector: 'ds-type-badge',
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html
index c518d39bd9..31f48475a6 100644
--- a/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html
+++ b/src/app/shared/object-list/my-dspace-result-list-element/item-list-preview/item-list-preview.component.html
@@ -2,7 +2,7 @@
-
+
diff --git a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html
index c98003cd1d..739c16a341 100644
--- a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html
+++ b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html
@@ -1,4 +1,4 @@
-
+
diff --git a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html
index e0f0319ffc..8090fe13df 100644
--- a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html
+++ b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html
@@ -1,4 +1,4 @@
-
+
diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html
index 8898632eb5..e6b9acfc6c 100644
--- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html
+++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html
@@ -1,4 +1,4 @@
-
+